diff --git a/blueprints/pages/deluge.yml b/blueprints/pages/deluge.yml
new file mode 100644
index 0000000..12bd88f
--- /dev/null
+++ b/blueprints/pages/deluge.yml
@@ -0,0 +1,73 @@
+title: Deluge Bridge
+
+sections:
+ deluge:
+ type: fields
+ fields:
+ delugeUrl:
+ label: Deluge URL
+ type: url
+ width: 1/2
+ delugePassword:
+ label: Deluge Password
+ type: text
+ width: 1/2
+ minDownSpeed:
+ label: Minimum Download Speed
+ type: number
+ min: 0
+ default: 4096
+ after: KiB/s
+ width: 1/2
+ maxDownSpeed:
+ label: Maximum Download Speed
+ type: number
+ min: 0
+ default: 10240
+ after: KiB/s
+ width: 1/2
+ minUpSpeed:
+ label: Minimum Upload Speed
+ type: number
+ min: 0
+ default: 512
+ after: KiB/s
+ width: 1/2
+ maxUpSpeed:
+ label: Maximum Upload Speed
+ type: number
+ min: 0
+ default: 4096
+ after: KiB/s
+ width: 1/2
+ maxTimeAtMin:
+ label: Maximum Time At Minimum Speed
+ type: number
+ min: 0
+ default: 240
+ after: minutes
+ jellyfin:
+ type: fields
+ fields:
+ jellyfinUrl:
+ label: Jellyfin URL
+ type: url
+ width: 1/2
+ jellyfinApiKey:
+ label: Jellyfin API Key
+ type: text
+ width: 1/2
+ currentStreams:
+ label: Current Streams
+ type: number
+ min: 0
+ default: 0
+ disabled: true
+ width: 1/2
+ lastSeen:
+ label: Last Seen Stream
+ type: number
+ min: 0
+ default: 0
+ disabled: true
+ width: 1/2
diff --git a/controllers/deluge.php b/controllers/deluge.php
new file mode 100644
index 0000000..3b7acc2
--- /dev/null
+++ b/controllers/deluge.php
@@ -0,0 +1,147 @@
+
+ *
+ * This file is part of Kirby Deluge.
+ *
+ * Kirby Deluge is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
+ *
+ * Kirby Deluge is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License along with Kirby Deluge. If not, see .
+ */
+
+return function ($page) {
+ $currentStreams = $page->currentStreams()->toInt();
+ $lastSeen = $page->lastSeen()->toInt();
+
+ $curl = curl_init($page->delugeUrl()->toString() . "/json");
+ $curlOptions = [
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_HEADER => true,
+ CURLOPT_HTTPHEADER => ["Accept: application/json", "Content-Type: application/json"],
+ CURLOPT_ENCODING => "",
+ CURLOPT_COOKIEJAR => "",
+ CURLOPT_CONNECTTIMEOUT => 10,
+ CURLOPT_TIMEOUT => 10,
+ CURLOPT_SSL_VERIFYPEER => true,
+ CURLINFO_HEADER_OUT => true,
+ ];
+ curl_setopt_array($curl, $curlOptions);
+
+ $reqId = 0;
+ $response = site()->makeRequest($curl, $reqId, "auth.login", [$page->delugePassword()->toString()]);
+ $reqId++;
+
+ if (get("s") == "inc") {
+ // Increment number of streams and ensure speeds are set to minimums.
+ $currentStreams++;
+ $lastSeen = time();
+
+ site()->makeRequest($curl, $reqId, "core.set_config", [["max_download_speed" => $page->minDownSpeed()->toInt()]]);
+ $reqId++;
+ site()->makeRequest($curl, $reqId, "core.set_config", [["max_upload_speed" => $page->minUpSpeed()->toInt()]]);
+ } elseif (get("s") == "dec") {
+ // Decrement number of streams and, if 0 active streams, ensure speeds are set to maximum.
+ $currentStreams--;
+
+ if ($lastSeen > 0) {
+ if ($lastSeen < time() - ($page->maxTimeAtMin()->toInt() * 60)) {
+ // Assume all sessions have finished and clear them.
+ $currentStreams = 0;
+ $lastSeen = 0;
+ }
+ }
+
+ if ($currentStreams <= 0) {
+ site()->makeRequest($curl, $reqId, "core.set_config", [["max_download_speed" => $page->maxDownSpeed()->toInt()]]);
+ $reqId++;
+ site()->makeRequest($curl, $reqId, "core.set_config", [["max_upload_speed" => $page->maxUpSpeed()->toInt()]]);
+ }
+ } elseif (get("s") == "reset") {
+ // Reset streams and speeds back to 0 and maximum respectively.
+ $currentStreams = 0;
+ $lastSeen = 0;
+
+ site()->makeRequest($curl, $reqId, "core.set_config", [["max_download_speed" => $page->maxDownSpeed()->toInt()]]);
+ $reqId++;
+ site()->makeRequest($curl, $reqId, "core.set_config", [["max_upload_speed" => $page->maxUpSpeed()->toInt()]]);
+ } elseif (get("s") == "update") {
+ // Forceably get a list of active sessions from Jellyfin and update Deluge accordingly.
+ $jfCurl = curl_init($page->jellyfinUrl()->toString() . "/Sessions");
+ $jfCurlOptions = [
+ CURLOPT_RETURNTRANSFER => true,
+ // CURLOPT_HEADER => true,
+ CURLOPT_HTTPHEADER => ["Accept: application/json", "Content-Type: application/json", "Authorization: MediaBrowser Token=\"{$page->jellyfinApiKey()->toString()}\""],
+ CURLOPT_ENCODING => "",
+ CURLOPT_COOKIEJAR => "",
+ CURLOPT_CONNECTTIMEOUT => 10,
+ CURLOPT_TIMEOUT => 10,
+ CURLOPT_SSL_VERIFYPEER => true,
+ CURLINFO_HEADER_OUT => true,
+ CURLOPT_VERBOSE => true,
+ ];
+ curl_setopt_array($jfCurl, $jfCurlOptions);
+
+ $sessions = site()->makeRequest($jfCurl, $reqId, "get");
+ $reqId++;
+ curl_close($jfCurl);
+
+ $sessionsActive = 0;
+ if (!is_null($sessions)) {
+ foreach ($sessions as $session) {
+ if (isset($session["NowPlayingItem"])) {
+ if ($session["NowPlayingItem"]["Type"] !== "Audio") {
+ $sessionsActive++;
+ }
+ }
+ }
+
+ if ($sessionsActive == 0) {
+ // There are no sessions active. Set to maximum speed.
+ $currentStreams = 0;
+ $lastSeen = 0;
+
+ site()->makeRequest($curl, $reqId, "core.set_config", [["max_download_speed" => $page->maxDownSpeed()->toInt()]]);
+ $reqId++;
+ site()->makeRequest($curl, $reqId, "core.set_config", [["max_upload_speed" => $page->maxUpSpeed()->toInt()]]);
+ } else {
+ // There are sessions active. Set to minimum speed.
+ $currentStreams = $sessionsActive;
+ $lastSeen = time();
+
+ site()->makeRequest($curl, $reqId, "core.set_config", [["max_download_speed" => $page->minDownSpeed()->toInt()]]);
+ $reqId++;
+ site()->makeRequest($curl, $reqId, "core.set_config", [["max_upload_speed" => $page->minUpSpeed()->toInt()]]);
+ }
+ } else {
+ // We couldn't access Jellyfin. Assume there's something wrong and that no sessions are active.
+ $currentStreams = 0;
+ $lastSeen = 0;
+
+ site()->makeRequest($curl, $reqId, "core.set_config", [["max_download_speed" => $page->maxDownSpeed()->toInt()]]);
+ $reqId++;
+ site()->makeRequest($curl, $reqId, "core.set_config", [["max_upload_speed" => $page->maxUpSpeed()->toInt()]]);
+ }
+ }
+
+ // We should never have less than 0 streams active.
+ $currentStreams = $currentStreams < 0 ? 0 : $currentStreams;
+
+ $page = kirby()->impersonate("kirby", function () use ($page, $currentStreams, $lastSeen) {
+ return $page->update([
+ "currentStreams" => $currentStreams,
+ "lastSeen" => $lastSeen,
+ ]);
+ });
+
+ curl_close($curl);
+
+ if (!($user = kirby()->user() and $user->role()->isAdmin())) {
+ // Limit access to page to administrators only.
+ echo new Response(Data::encode(["currentStreams" => $currentStreams, "lastSeen" => $lastSeen], "json"), "text/json");
+ exit();
+ }
+
+ return compact("page");
+};
diff --git a/index.php b/index.php
index 7b5959b..5c280e5 100644
--- a/index.php
+++ b/index.php
@@ -14,6 +14,15 @@
Kirby::plugin(
name: "hobbyhome/deluge",
extends: [
+ "blueprints" => [
+ "pages/deluge" => __DIR__ . "/blueprints/pages/deluge.yml",
+ ],
+ "templates" => [
+ "deluge" => __DIR__ . "/templates/deluge.php",
+ ],
+ "controllers" => [
+ "deluge" => require __DIR__ . "/controllers/deluge.php",
+ ],
],
info: [
"authors" => [[
diff --git a/templates/deluge.php b/templates/deluge.php
new file mode 100644
index 0000000..1073e51
--- /dev/null
+++ b/templates/deluge.php
@@ -0,0 +1,23 @@
+= snippet("header") ?>
+
+= snippet("page/title") ?>
+
+
+
Current Streams: = $page->currentStreams() ?>
+ currentStreams()->toInt() > 0) : ?>
+
Last Seen: = date('l \t\h\e\ jS \of F Y \a\t g:ia', $page->lastSeen()->toInt()) ?>
+
+
+
+
+
+= snippet("footer") ?>