Skip to content

Commit fdec61d

Browse files
committed
WhatsupDocker Enhanced
1 parent b75f99c commit fdec61d

File tree

5 files changed

+191
-0
lines changed

5 files changed

+191
-0
lines changed

WhatsupDocker/WhatsupDocker.php

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<?php
2+
3+
namespace App\SupportedApps\WhatsupDocker;
4+
5+
class WhatsupDocker extends \App\SupportedApps implements \App\EnhancedApps
6+
{
7+
8+
public $config;
9+
10+
//protected $login_first = true; // Uncomment if api requests need to be authed first
11+
//protected $method = 'POST'; // Uncomment if requests to the API should be set by POST
12+
13+
public function __construct()
14+
{
15+
//$this->jar = new \GuzzleHttp\Cookie\CookieJar; // Uncomment if cookies need to be set
16+
}
17+
18+
public function test()
19+
{
20+
// If auth credentials are provided, test the authenticated endpoint
21+
if ($this->hasAuthCredentials()) {
22+
// Test containers endpoint which requires authentication
23+
$test = parent::appTest($this->url('api/containers'), $this->getAttrs());
24+
echo $test->status;
25+
} else {
26+
// No auth configured, test the public app endpoint
27+
$test = parent::appTest($this->url('api/app'), $this->getAttrs());
28+
echo $test->status;
29+
}
30+
}
31+
32+
public function livestats()
33+
{
34+
$status = 'inactive';
35+
36+
try {
37+
// Get watched containers from WUD API
38+
$res = parent::execute($this->url('api/containers'), $this->getAttrs());
39+
$containers = json_decode($res->getBody(), true);
40+
41+
if ($containers && is_array($containers)) {
42+
$status = 'active';
43+
44+
// Calculate container statistics
45+
$totalContainers = count($containers);
46+
$updatableContainers = 0;
47+
$watchedContainers = 0;
48+
49+
foreach ($containers as $container) {
50+
// Count updatable containers (based on API doc structure)
51+
if (isset($container['updateAvailable']) && $container['updateAvailable'] === true) {
52+
$updatableContainers++;
53+
}
54+
55+
// All containers returned by /api/containers are watched containers
56+
$watchedContainers++;
57+
}
58+
59+
$details = ['visiblestats' => []];
60+
61+
// Show configured stats, or all if none selected
62+
$availableStats = isset($this->config->availablestats) && !empty($this->config->availablestats)
63+
? $this->config->availablestats
64+
: array_keys(self::getAvailableStats());
65+
66+
foreach ($availableStats as $stat) {
67+
$newstat = new \stdClass();
68+
$newstat->title = self::getAvailableStats()[$stat];
69+
70+
switch ($stat) {
71+
case 'TotalContainers':
72+
$newstat->value = $totalContainers;
73+
break;
74+
case 'UpdatableContainers':
75+
$newstat->value = $updatableContainers;
76+
break;
77+
case 'WatchedContainers':
78+
$newstat->value = $watchedContainers;
79+
break;
80+
default:
81+
$newstat->value = 0;
82+
}
83+
84+
$details['visiblestats'][] = $newstat;
85+
}
86+
87+
return parent::getLiveStats($status, $details);
88+
}
89+
} catch (Exception $e) {
90+
// If auth is configured but containers API fails, don't fallback
91+
if ($this->hasAuthCredentials()) {
92+
$status = 'inactive';
93+
} else {
94+
// No auth configured, try basic status check with app endpoint
95+
try {
96+
$res = parent::execute($this->url('api/app'), $this->getAttrs());
97+
if ($res->getStatusCode() === 200) {
98+
$status = 'active';
99+
}
100+
} catch (Exception $e2) {
101+
$status = 'inactive';
102+
}
103+
}
104+
}
105+
106+
return parent::getLiveStats($status, []);
107+
}
108+
109+
private function hasAuthCredentials()
110+
{
111+
return !empty($this->config->username) && !empty($this->config->password);
112+
}
113+
114+
private function getAttrs()
115+
{
116+
$attrs = [
117+
'headers' => [
118+
'Accept' => 'application/json',
119+
'Content-Type' => 'application/json',
120+
]
121+
];
122+
123+
// Add basic authentication if both username and password are configured
124+
if ($this->hasAuthCredentials()) {
125+
$attrs['auth'] = [$this->config->username, $this->config->password];
126+
}
127+
128+
return $attrs;
129+
}
130+
131+
public function url($endpoint)
132+
{
133+
$base_url = parent::normaliseurl($this->config->url);
134+
// Ensure trailing slash for WUD API
135+
if (!str_ends_with($base_url, '/')) {
136+
$base_url .= '/';
137+
}
138+
return $base_url . $endpoint;
139+
}
140+
141+
public static function getAvailableStats()
142+
{
143+
return [
144+
'TotalContainers' => 'Total',
145+
'UpdatableContainers' => 'Updatable',
146+
'WatchedContainers' => 'Watched',
147+
];
148+
}
149+
}

WhatsupDocker/app.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"appid": "471b1748546610893a56b7d9254afa4752f630b9",
3+
"name": "What's up Docker",
4+
"website": "https://github.com/getwud/wud",
5+
"license": "MIT License",
6+
"description": "Gets you notified when new versions of your Docker containers are available and lets you react the way you want.",
7+
"enhanced": true,
8+
"tile_background": "dark",
9+
"icon": "whatsupdocker.png",
10+
"sha": "2f0356bc2cafcca5232e02d1283d2a2bd401ef81"
11+
}

WhatsupDocker/config.blade.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<h2>{{ __('app.apps.config') }} ({{ __('app.optional') }}) @include('items.enable')</h2>
2+
<div class="items">
3+
<div class="input">
4+
<label>{{ strtoupper(__('app.url')) }}</label>
5+
{!! Form::text('config[override_url]', null, array('placeholder' => __('app.apps.override'), 'id' => 'override_url', 'class' => 'form-control')) !!}
6+
</div>
7+
<div class="input">
8+
<label>{{ __('app.apps.username') }}</label>
9+
{!! Form::text('config[username]', null, array('placeholder' => __('app.apps.username'), 'data-config' => 'username', 'class' => 'form-control config-item')) !!}
10+
</div>
11+
<div class="input">
12+
<label>{{ __('app.apps.password') }}</label>
13+
{!! Form::input('password', 'config[password]', '', ['placeholder' => __('app.apps.password'), 'data-config' => 'password', 'class' => 'form-control config-item']) !!}
14+
</div>
15+
<div class="input">
16+
<label>Statistics to show</label>
17+
{!! Form::select('config[availablestats][]', \App\SupportedApps\WhatsupDocker\WhatsupDocker::getAvailableStats(), isset($item) ? $item->getConfig()->availablestats ?? null : null, ['multiple' => 'multiple']) !!}
18+
</div>
19+
<div class="input">
20+
<button style="margin-top: 32px;" class="btn test" id="test_config">Test</button>
21+
</div>
22+
</div>
23+

WhatsupDocker/livestats.blade.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<ul class="livestats">
2+
@foreach ($visiblestats as $stat)
3+
<li>
4+
<span class="title">{!! $stat->title !!}</span>
5+
<strong>{!! $stat->value !!}</strong>
6+
</li>
7+
@endforeach
8+
</ul>

WhatsupDocker/whatsupdocker.png

13.1 KB
Loading

0 commit comments

Comments
 (0)