]> git.immae.eu Git - github/bastienwirtz/homer.git/commitdiff
qBittorrent service (#540)
authorShagon94 <Shagon94@gmail.com>
Sun, 30 Oct 2022 17:32:51 +0000 (18:32 +0100)
committerGitHub <noreply@github.com>
Sun, 30 Oct 2022 17:32:51 +0000 (10:32 -0700)
qBittorrent service

docs/customservices.md
dummy-data/README.md
dummy-data/qBittorrent/api/v2/torrents/info [new file with mode: 0644]
dummy-data/qBittorrent/api/v2/transfer/info [new file with mode: 0644]
src/components/services/qBittorrent.vue [new file with mode: 0644]

index 3c4f5ade4e231f89d12682714a8023c447cbe6fc..e84afdb498c13b5f96b9cf931116c76bc13a3031 100644 (file)
@@ -7,24 +7,27 @@ if your homer instance is secured behind some form of authentication or access r
 
 Available services are in `src/components/`. Here is an overview of all custom services that are available
 within Homer:
-+ [PiHole](#pihole)
-+ [OpenWeatherMap](#openweathermap)
-+ [Medusa](#medusa)
-+ [Lidarr, Prowlarr, Sonarr and Radarr](#lidarr-prowlarr-sonarr-and-radarr)
-+ [PaperlessNG](#paperlessng)
-+ [Ping](#ping)
-+ [Prometheus](#prometheus)
-+ [AdGuard Home](#adguard-home)
-+ [Portainer](#portainer)
-+ [Emby / Jellyfin](#emby--jellyfin)
-+ [Uptime Kuma](#uptime-kuma)
-+ [Tautulli](#tautulli)
-+ [Mealie](#mealie)
-+ [Healthchecks](#healthchecks)
-+ [Proxmox](#proxmox)
 
-If you experiencing any issue, please have a look to the [troubleshooting](troubleshooting.md) page.
+- [Custom Services](#custom-services)
+  - [Common options](#common-options)
+  - [PiHole](#pihole)
+  - [OpenWeatherMap](#openweathermap)
+  - [Medusa](#medusa)
+  - [Lidarr, Prowlarr, Sonarr and Radarr](#lidarr-prowlarr-sonarr-and-radarr)
+  - [PaperlessNG](#paperlessng)
+  - [Ping](#ping)
+  - [Prometheus](#prometheus)
+  - [AdGuard Home](#adguard-home)
+  - [Portainer](#portainer)
+  - [Emby / Jellyfin](#emby--jellyfin)
+  - [Uptime Kuma](#uptime-kuma)
+  - [Tautulli](#tautulli)
+  - [Mealie](#mealie)
+  - [Healthchecks](#healthchecks)
+  - [Proxmox](#proxmox)
+  - [qBittorrent](#qbittorrent)
 
+If you experiencing any issue, please have a look to the [troubleshooting](troubleshooting.md) page.
 
 ## Common options
 
@@ -272,4 +275,23 @@ Configuration example:
   warning_value: 50
   danger_value: 80
   api_token: "PVEAPIToken=root@pam!your-api-token-name=your-api-token-key"
-```
\ No newline at end of file
+```
+
+## qBittorrent
+
+This service displays the global upload and download rates, as well as the number of torrents
+listed. The service communicates with the qBittorrent API interface which needs
+to be accessible from the browser. Please consult
+[the instructions](https://github.com/qbittorrent/qBittorrent/pull/12579)
+for setting up qBittorrent and make sure the correct CORS-settings are applied. Examples for various
+servers can be found at [enable-cors.org](https://enable-cors.org/server.html).
+
+```yaml
+- name: "qBittorrent"
+  logo: "assets/tools/sample.png"
+  url: "http://192.168.1.2:8080" # Your rTorrent web UI, f.e. ruTorrent or Flood.
+  type: "qBittorrent"
+  rateInterval: 2000 # Interval for updating the download and upload rates.
+  torrentInterval: 5000 # Interval for updating the torrent count.
+  target: "_blank" # optional html a tag target attribute
+```
index eeff4ecb458de5a2fd05af33dd9e58553432a06e..6db4712edcb2abecd7b353f02bf05ad10c5a08eb 100644 (file)
@@ -1,15 +1,16 @@
 # Dummy data
 
-This directory content makes possible to test custom services cards or create a demo without actually running the service. 
+This directory content makes possible to test custom services cards or create a demo without actually running the service.
 The principle is simple: save a sample output of the API used in the service in a static file in this directory. The path must be identical as the service endpoint to be used seamlessly.
 
-## How to add a new services sample
+## How to add a new services sample
 
-- create a directory for your service, and any sub-folder existing in the service api path. 
+- create a directory for your service, and any sub-folder existing in the service api path.
 - save the api output in a file named after the service endpoint.
 
 Example:
-```
+
+```sh
 mkdir pihole
-curl http://my-pihole.me/admin/api.php -o pihole/api.php # /admin is omited because for PiHole, the implementation expect it to be in the base url (`url` or `enpoint` property)
-```
\ No newline at end of file
+curl http://my-pihole.me/admin/api.php -o pihole/api.php # /admin is omited because for PiHole, the implementation expect it to be in the base url (`url` or `endpoint` property)
+```
diff --git a/dummy-data/qBittorrent/api/v2/torrents/info b/dummy-data/qBittorrent/api/v2/torrents/info
new file mode 100644 (file)
index 0000000..e1bc722
--- /dev/null
@@ -0,0 +1,53 @@
+[
+  {
+    "added_on": 1666985518,
+    "amount_left": 0,
+    "auto_tmm": false,
+    "availability": -1,
+    "category": "",
+    "completed": 1474873344,
+    "completion_on": 1666985584,
+    "content_path": "/downloads/ubuntu-22.04.1-live-server-amd64.iso",
+    "dl_limit": -1,
+    "dlspeed": 0,
+    "download_path": "",
+    "downloaded": 1513976240,
+    "downloaded_session": 0,
+    "eta": 8640000,
+    "f_l_piece_prio": false,
+    "force_start": false,
+    "hash": "cf3ea75e2ebbd30e0da6e6e215e2226bf35f2e33",
+    "infohash_v1": "cf3ea75e2ebbd30e0da6e6e215e2226bf35f2e33",
+    "infohash_v2": "",
+    "last_activity": 1666985588,
+    "magnet_uri": "magnet:?xt=urn:btih:cf3ea75e2ebbd30e0da6e6e215e2226bf35f2e33&dn=ubuntu-22.04.1-live-server-amd64.iso&tr=https%3a%2f%2ftorrent.ubuntu.com%2fannounce&tr=https%3a%2f%2fipv6.torrent.ubuntu.com%2fannounce",
+    "max_ratio": 0,
+    "max_seeding_time": -1,
+    "name": "ubuntu-22.04.1-live-server-amd64.iso",
+    "num_complete": 0,
+    "num_incomplete": 583,
+    "num_leechs": 0,
+    "num_seeds": 0,
+    "priority": 0,
+    "progress": 1,
+    "ratio": 1.7163413343924075e-05,
+    "ratio_limit": -2,
+    "save_path": "/downloads/",
+    "seeding_time": 4,
+    "seeding_time_limit": -2,
+    "seen_complete": 1666985584,
+    "seq_dl": false,
+    "size": 1474873344,
+    "state": "pausedUP",
+    "super_seeding": false,
+    "tags": "",
+    "time_active": 69,
+    "total_size": 1474873344,
+    "tracker": "",
+    "trackers_count": 2,
+    "up_limit": -1,
+    "uploaded": 25985,
+    "uploaded_session": 0,
+    "upspeed": 0
+  }
+]
\ No newline at end of file
diff --git a/dummy-data/qBittorrent/api/v2/transfer/info b/dummy-data/qBittorrent/api/v2/transfer/info
new file mode 100644 (file)
index 0000000..dd7b318
--- /dev/null
@@ -0,0 +1,10 @@
+{
+       "connection_status": "connected",
+       "dht_nodes": 318,
+       "dl_info_data": 23481469329,
+       "dl_info_speed": 1234567,
+       "dl_rate_limit": 40960000,
+       "up_info_data": 1788370216,
+       "up_info_speed": 765432,
+       "up_rate_limit": 10547200
+}
\ No newline at end of file
diff --git a/src/components/services/qBittorrent.vue b/src/components/services/qBittorrent.vue
new file mode 100644 (file)
index 0000000..1f1ef49
--- /dev/null
@@ -0,0 +1,120 @@
+<template>\r
+  <Generic :item="item">\r
+    <template #content>\r
+      <p class="title is-4">{{ item.name }}</p>\r
+      <p class="subtitle is-6">\r
+        <span v-if="error" class="error">An error has occurred.</span>\r
+        <template v-else>\r
+          <span class="down monospace">\r
+            <p class="fas fa-download "></p> {{ downRate }}\r
+          </span>\r
+          <span class="up monospace">\r
+            <p class="fas fa-upload"></p> {{ upRate }}\r
+          </span>\r
+        </template>\r
+      </p>\r
+    </template>\r
+    <template #indicator>\r
+      <span v-if="!error" class="count">{{ count }}\r
+        <template v-if="count === 1">torrent</template>\r
+        <template v-else>torrents</template>\r
+      </span>\r
+    </template>\r
+  </Generic>\r
+</template>\r
+\r
+<script>\r
+import service from "@/mixins/service.js";\r
+import Generic from "./Generic.vue";\r
+const units = ["B", "KB", "MB", "GB"];\r
+\r
+// Take the rate in bytes and keep dividing it by 1k until the lowest\r
+// value for which we have a unit is determined. Return the value with\r
+// up to two decimals as a string and unit/s appended.\r
+const displayRate = (rate) => {\r
+  let i = 0;\r
+\r
+  while (rate > 1000 && i < units.length) {\r
+    rate /= 1000;\r
+    i++;\r
+  }\r
+  return (\r
+    Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(\r
+      rate || 0\r
+    ) + ` ${units[i]}/s`\r
+  );\r
+};\r
+\r
+export default {\r
+  name: "qBittorrent",\r
+  mixins: [service],\r
+  props: { item: Object },\r
+  components: { Generic },\r
+  data: () => ({ dl: null, ul: null, count: null, error: null }),\r
+  computed: {\r
+    downRate: function () {\r
+      return displayRate(this.dl);\r
+    },\r
+    upRate: function () {\r
+      return displayRate(this.ul);\r
+    },\r
+  },\r
+  created() {\r
+    const rateInterval = parseInt(this.item.rateInterval, 10) || 0;\r
+    const torrentInterval = parseInt(this.item.torrentInterval, 10) || 0;\r
+    if (rateInterval > 0) {\r
+      setInterval(() => this.getRate(), rateInterval);\r
+    }\r
+    if (torrentInterval > 0) {\r
+      setInterval(() => this.fetchCount(), torrentInterval);\r
+    }\r
+\r
+    this.getRate();\r
+    this.fetchCount();\r
+  },\r
+  methods: {\r
+    fetchCount: async function () {\r
+      try {\r
+        const body = await this.fetch('/api/v2/torrents/info');\r
+        this.error = false;\r
+        this.count = body.length;\r
+      } catch (e) {\r
+        this.error = true;\r
+        console.error(e);\r
+      }\r
+    },\r
+    getRate: async function () {\r
+      try {\r
+        const body = await this.fetch('/api/v2/transfer/info');\r
+        this.error = false;\r
+        this.dl = body.dl_info_speed;\r
+        this.ul = body.up_info_speed;\r
+      } catch (e) {\r
+        this.error = true;\r
+        console.error(e);\r
+      }\r
+    },\r
+  },\r
+};\r
+\r
+</script>\r
+\r
+<style scoped lang="scss">\r
+.error {\r
+  color: #e51111 !important;\r
+}\r
+\r
+.down {\r
+  margin-right: 1em;\r
+}\r
+\r
+.count {\r
+  color: var(--text);\r
+  font-size: 0.8em;\r
+}\r
+\r
+.monospace {\r
+  font-weight: 300;\r
+  font-family: monospace;\r
+}\r
+</style>
\ No newline at end of file