Skip to content

Commit 267fb84

Browse files
authored
WhatsUpDocker_Enhanced (#853)
* WhatsUpDocker_Enhanced * PHP-CS fixing
1 parent 22f7929 commit 267fb84

File tree

5 files changed

+190
-0
lines changed

5 files changed

+190
-0
lines changed

WhatsupDocker/WhatsupDocker.php

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

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)