Browse Source

Add ChangeDetection.io widget

Bruno Rossetto 2 years ago
parent
commit
86d1f5c6c3

+ 218 - 214
public/locales/en/common.json

@@ -1,216 +1,220 @@
 {
-    "common": {
-        "bytes": "{{value, bytes}}",
-        "bits": "{{value, bytes(bits: true)}}",
-        "bbytes": "{{value, bytes(binary: true)}}",
-        "bbits": "{{value, bytes(bits: true, binary: true)}}",
-        "byterate": "{{value, rate}}",
-        "bitrate": "{{value, rate(bits: true)}}",
-        "percent": "{{value, percent}}",
-        "number": "{{value, number}}",
-        "ms": "{{value, number}}"
-    },
-    "widget": {
-        "missing_type": "Missing Widget Type: {{type}}",
-        "api_error": "API Error",
-        "status": "Status"
-    },
-    "weather": {
-      "current": "Current Location",
-      "allow": "Click to allow",
-      "updating": "Updating",
-      "wait": "Please wait"
-    },
-    "search": {
-        "placeholder": "Search…"
-    },
-    "resources": {
-        "cpu": "CPU",
-        "total": "Total",
-        "free": "Free",
-        "used": "Used",
-        "load": "Load"
-    },
-    "unifi": {
-        "users": "Users",
-        "uptime": "System Uptime",
-        "days": "Days",
-        "wan": "WAN",
-        "lan_users": "LAN Users",
-        "wlan_users": "WLAN Users",
-        "up": "UP",
-        "down": "DOWN",
-        "wait": "Please wait"
-    },
-    "docker": {
-        "rx": "RX",
-        "tx": "TX",
-        "mem": "MEM",
-        "cpu": "CPU",
-        "offline": "Offline"
-    },
-    "emby": {
-        "playing": "Playing",
-        "transcoding": "Transcoding",
-        "bitrate": "Bitrate",
-        "no_active": "No Active Streams"
-    },
-    "tautulli": {
-        "playing": "Playing",
-        "transcoding": "Transcoding",
-        "bitrate": "Bitrate",
-        "no_active": "No Active Streams"
-    },
-    "nzbget": {
-        "rate": "Rate",
-        "remaining": "Remaining",
-        "downloaded": "Downloaded"
-    },
-    "plex": {
-        "streams": "Active Streams",
-        "movies": "Movies",
-        "tv": "TV Shows"
-    },
-    "sabnzbd": {
-        "rate": "Rate",
-        "queue": "Queue",
-        "timeleft": "Time Left"
-    },
-    "rutorrent": {
-        "active": "Active",
-        "upload": "Upload",
-        "download": "Download"
-    },
-    "transmission": {
-        "download": "Download",
-        "upload": "Upload",
-        "leech": "Leech",
-        "seed": "Seed"
-    },
-    "qbittorrent": {
-        "download": "Download",
-        "upload": "Upload",
-        "leech": "Leech",
-        "seed": "Seed"
-    },
-    "sonarr": {
-        "wanted": "Wanted",
-        "queued": "Queued",
-        "series": "Series"
-    },
-    "radarr": {
-        "wanted": "Wanted",
-        "queued": "Queued",
-        "movies": "Movies"
-    },
-    "lidarr": {
-        "wanted": "Wanted",
-        "queued": "Queued",
-        "albums": "Albums"
-    },
-    "readarr": {
-        "wanted": "Wanted",
-        "queued": "Queued",
-        "books": "Books"
-    },
-    "bazarr": {
-        "missingEpisodes": "Missing Episodes",
-        "missingMovies": "Missing Movies"
-    },
-    "ombi": {
-        "pending": "Pending",
-        "approved": "Approved",
-        "available": "Available"
-    },
-    "jellyseerr": {
-        "pending": "Pending",
-        "approved": "Approved",
-        "available": "Available"
-    },
-    "overseerr": {
-      "pending": "Pending",
-      "approved": "Approved",
-      "available": "Available"
-    },
-    "pihole": {
-        "queries": "Queries",
-        "blocked": "Blocked",
-        "gravity": "Gravity"
-    },
-    "adguard": {
-      "queries": "Queries",
-      "blocked": "Blocked",
-      "filtered": "Filtered",
-      "latency": "Latency"
-    },
-    "speedtest": {
-        "upload": "Upload",
-        "download": "Download",
-        "ping": "Ping"
-    },
-    "portainer": {
-        "running": "Running",
-        "stopped": "Stopped",
-        "total": "Total"
-    },
-    "traefik": {
-        "routers": "Routers",
-        "services": "Services",
-        "middleware": "Middleware"
-    },
-    "npm": {
-        "enabled": "Enabled",
-        "disabled": "Disabled",
-        "total": "Total"
-    },
-    "coinmarketcap": {
-        "configure": "Configure one or more crypto currencies to track",
-        "1hour": "1 Hour",
-        "1day": "1 Day",
-        "7days": "7 Days",
-        "30days": "30 Days"
-    },
-    "gotify": {
-        "apps": "Applications",
-        "clients": "Clients",
-        "messages": "Messages"
-    },
-    "prowlarr":{
-        "enableIndexers": "Indexers",
-        "numberOfGrabs": "Grabs",
-        "numberOfQueries": "Queries",
-        "numberOfFailGrabs": "Fail Grabs",
-        "numberOfFailQueries": "Fail Queries"
-    },
-    "jackett": {
-        "configured": "Configured",
-        "errored": "Errored"
-    },
-    "strelaysrv": {
-        "numActiveSessions": "Sessions",
-        "numConnections": "Connections",
-        "dataRelayed": "Relayed",
-        "transferRate": "Rate"
-    },
-    "mastodon": {
-        "user_count": "Users",
-        "status_count": "Posts",
-        "domain_count": "Domains"
-    },
-    "authentik": {
-        "users": "Users",
-        "loginsLast24H": "Logins (24h)",
-        "failedLoginsLast24H": "Failed Logins (24h)"
-    },
-    "proxmox": {
-        "mem": "MEM",
-        "cpu": "CPU",
-        "lxc": "LXC",
-        "vms": "VMs"
-    },
-    "glances": {
-        "cpu": "CPU",
-        "mem": "MEM",
-        "wait": "Please wait"
-    }
+  "common": {
+    "bytes": "{{value, bytes}}",
+    "bits": "{{value, bytes(bits: true)}}",
+    "bbytes": "{{value, bytes(binary: true)}}",
+    "bbits": "{{value, bytes(bits: true, binary: true)}}",
+    "byterate": "{{value, rate}}",
+    "bitrate": "{{value, rate(bits: true)}}",
+    "percent": "{{value, percent}}",
+    "number": "{{value, number}}",
+    "ms": "{{value, number}}"
+  },
+  "widget": {
+    "missing_type": "Missing Widget Type: {{type}}",
+    "api_error": "API Error",
+    "status": "Status"
+  },
+  "weather": {
+    "current": "Current Location",
+    "allow": "Click to allow",
+    "updating": "Updating",
+    "wait": "Please wait"
+  },
+  "search": {
+    "placeholder": "Search…"
+  },
+  "resources": {
+    "cpu": "CPU",
+    "total": "Total",
+    "free": "Free",
+    "used": "Used",
+    "load": "Load"
+  },
+  "unifi": {
+    "users": "Users",
+    "uptime": "System Uptime",
+    "days": "Days",
+    "wan": "WAN",
+    "lan_users": "LAN Users",
+    "wlan_users": "WLAN Users",
+    "up": "UP",
+    "down": "DOWN",
+    "wait": "Please wait"
+  },
+  "docker": {
+    "rx": "RX",
+    "tx": "TX",
+    "mem": "MEM",
+    "cpu": "CPU",
+    "offline": "Offline"
+  },
+  "emby": {
+    "playing": "Playing",
+    "transcoding": "Transcoding",
+    "bitrate": "Bitrate",
+    "no_active": "No Active Streams"
+  },
+  "changedetectionio": {
+    "totalObserved": "Total Observed",
+    "diffsDetected": "Diffs Detected"
+  },
+  "tautulli": {
+    "playing": "Playing",
+    "transcoding": "Transcoding",
+    "bitrate": "Bitrate",
+    "no_active": "No Active Streams"
+  },
+  "nzbget": {
+    "rate": "Rate",
+    "remaining": "Remaining",
+    "downloaded": "Downloaded"
+  },
+  "plex": {
+    "streams": "Active Streams",
+    "movies": "Movies",
+    "tv": "TV Shows"
+  },
+  "sabnzbd": {
+    "rate": "Rate",
+    "queue": "Queue",
+    "timeleft": "Time Left"
+  },
+  "rutorrent": {
+    "active": "Active",
+    "upload": "Upload",
+    "download": "Download"
+  },
+  "transmission": {
+    "download": "Download",
+    "upload": "Upload",
+    "leech": "Leech",
+    "seed": "Seed"
+  },
+  "qbittorrent": {
+    "download": "Download",
+    "upload": "Upload",
+    "leech": "Leech",
+    "seed": "Seed"
+  },
+  "sonarr": {
+    "wanted": "Wanted",
+    "queued": "Queued",
+    "series": "Series"
+  },
+  "radarr": {
+    "wanted": "Wanted",
+    "queued": "Queued",
+    "movies": "Movies"
+  },
+  "lidarr": {
+    "wanted": "Wanted",
+    "queued": "Queued",
+    "albums": "Albums"
+  },
+  "readarr": {
+    "wanted": "Wanted",
+    "queued": "Queued",
+    "books": "Books"
+  },
+  "bazarr": {
+    "missingEpisodes": "Missing Episodes",
+    "missingMovies": "Missing Movies"
+  },
+  "ombi": {
+    "pending": "Pending",
+    "approved": "Approved",
+    "available": "Available"
+  },
+  "jellyseerr": {
+    "pending": "Pending",
+    "approved": "Approved",
+    "available": "Available"
+  },
+  "overseerr": {
+    "pending": "Pending",
+    "approved": "Approved",
+    "available": "Available"
+  },
+  "pihole": {
+    "queries": "Queries",
+    "blocked": "Blocked",
+    "gravity": "Gravity"
+  },
+  "adguard": {
+    "queries": "Queries",
+    "blocked": "Blocked",
+    "filtered": "Filtered",
+    "latency": "Latency"
+  },
+  "speedtest": {
+    "upload": "Upload",
+    "download": "Download",
+    "ping": "Ping"
+  },
+  "portainer": {
+    "running": "Running",
+    "stopped": "Stopped",
+    "total": "Total"
+  },
+  "traefik": {
+    "routers": "Routers",
+    "services": "Services",
+    "middleware": "Middleware"
+  },
+  "npm": {
+    "enabled": "Enabled",
+    "disabled": "Disabled",
+    "total": "Total"
+  },
+  "coinmarketcap": {
+    "configure": "Configure one or more crypto currencies to track",
+    "1hour": "1 Hour",
+    "1day": "1 Day",
+    "7days": "7 Days",
+    "30days": "30 Days"
+  },
+  "gotify": {
+    "apps": "Applications",
+    "clients": "Clients",
+    "messages": "Messages"
+  },
+  "prowlarr": {
+    "enableIndexers": "Indexers",
+    "numberOfGrabs": "Grabs",
+    "numberOfQueries": "Queries",
+    "numberOfFailGrabs": "Fail Grabs",
+    "numberOfFailQueries": "Fail Queries"
+  },
+  "jackett": {
+    "configured": "Configured",
+    "errored": "Errored"
+  },
+  "strelaysrv": {
+    "numActiveSessions": "Sessions",
+    "numConnections": "Connections",
+    "dataRelayed": "Relayed",
+    "transferRate": "Rate"
+  },
+  "mastodon": {
+    "user_count": "Users",
+    "status_count": "Posts",
+    "domain_count": "Domains"
+  },
+  "authentik": {
+    "users": "Users",
+    "loginsLast24H": "Logins (24h)",
+    "failedLoginsLast24H": "Failed Logins (24h)"
+  },
+  "proxmox": {
+    "mem": "MEM",
+    "cpu": "CPU",
+    "lxc": "LXC",
+    "vms": "VMs"
+  },
+  "glances": {
+    "cpu": "CPU",
+    "mem": "MEM",
+    "wait": "Please wait"
+  }
 }

+ 33 - 0
src/widgets/changedetectionio/component.jsx

@@ -0,0 +1,33 @@
+import { useTranslation } from "next-i18next";
+
+import Container from "components/services/widget/container";
+import Block from "components/services/widget/block";
+import useWidgetAPI from "utils/proxy/use-widget-api";
+
+export default function Component({ service }) {
+  const { t } = useTranslation();
+
+  const { widget } = service;
+
+  const { data } = useWidgetAPI(widget, "info");
+
+  if (!data) {
+    return <Container error="widget.api_error" />;
+  }
+
+  const totalObserved = Object.keys(data).length;
+  let diffsDetected = 0;
+
+  Object.keys(data).forEach((key) => {
+    if (data[key].last_checked === data[key].last_changed) {
+      diffsDetected += 1;
+    }
+  });
+
+  return (
+    <Container service={service}>
+      <Block label="changedetectionio.diffsDetected" value={t("common.number", { value: diffsDetected })} />
+      <Block label="changedetectionio.totalObserved" value={t("common.number", { value: totalObserved })} />
+    </Container>
+  );
+}

+ 15 - 0
src/widgets/changedetectionio/widget.js

@@ -0,0 +1,15 @@
+import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
+
+const widget = {
+  api: "{url}/api/v1/{endpoint}",
+  proxyHandler: credentialedProxyHandler,
+
+  mappings: {
+    info: {
+      method: "GET",
+      endpoint: "watch",
+    },
+  },
+};
+
+export default widget;

+ 1 - 0
src/widgets/components.js

@@ -4,6 +4,7 @@ const components = {
   adguard: dynamic(() => import("./adguard/component")),
   authentik: dynamic(() => import("./authentik/component")),
   bazarr: dynamic(() => import("./bazarr/component")),
+  changedetectionio: dynamic(() => import("./changedetectionio/component")),
   coinmarketcap: dynamic(() => import("./coinmarketcap/component")),
   docker: dynamic(() => import("./docker/component")),
   emby: dynamic(() => import("./emby/component")),

+ 3 - 1
src/widgets/widgets.js

@@ -1,6 +1,7 @@
 import adguard from "./adguard/widget";
 import authentik from "./authentik/widget";
 import bazarr from "./bazarr/widget";
+import changedetectionio from "./changedetectionio/widget";
 import coinmarketcap from "./coinmarketcap/widget";
 import emby from "./emby/widget";
 import gotify from "./gotify/widget";
@@ -34,6 +35,7 @@ const widgets = {
   adguard,
   authentik,
   bazarr,
+  changedetectionio,
   coinmarketcap,
   emby,
   gotify,
@@ -63,7 +65,7 @@ const widgets = {
   traefik,
   transmission,
   unifi,
-  unifi_console: unifi
+  unifi_console: unifi,
 };
 
 export default widgets;