diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index 873586e5..185fce08 100755
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -658,5 +658,8 @@
"totalShows": "Tracked Shows",
"retryCache": "Retry Cache",
"feedCache": "Feed Cache"
+ },
+ "wgeasy": {
+ "clients": "Total Clients"
}
}
\ No newline at end of file
diff --git a/public/locales/fr/common.json b/public/locales/fr/common.json
index 2e9e0e0d..a85eb438 100644
--- a/public/locales/fr/common.json
+++ b/public/locales/fr/common.json
@@ -397,7 +397,7 @@
"queue": "À traiter",
"processed": "Traité",
"errored": "En erreur",
- "saved": "Economisé"
+ "saved": "Gagné"
},
"miniflux": {
"read": "Lu",
diff --git a/public/locales/hr/common.json b/public/locales/hr/common.json
index db20a999..268a1f89 100644
--- a/public/locales/hr/common.json
+++ b/public/locales/hr/common.json
@@ -239,11 +239,11 @@
"uptime": "UP",
"days": "d",
"hours": "h",
- "used": "Used",
- "load": "Load",
- "warn": "Warn",
- "total": "Total",
- "free": "Free"
+ "used": "Korišteno",
+ "load": "Opterećenje",
+ "warn": "Upozori",
+ "total": "Ukupno",
+ "free": "Slobodno"
},
"changedetectionio": {
"totalObserved": "Ukupno promatrano",
@@ -478,7 +478,7 @@
"up": "Aktivne stranice",
"down": "Neaktivne stranice",
"uptime": "Radno vrijeme",
- "incident": "Incident",
+ "incident": "Slučaj",
"m": "min"
},
"komga": {
@@ -609,36 +609,36 @@
"poolUsage": "Korištenje memorijskog skupa",
"cpuUsage": "Korištenje procesora",
"memUsage": "Korištenje memorije",
- "volumeUsage": "Volume Usage",
- "invalid": "Invalid"
+ "volumeUsage": "Korištenje jedinice memorije",
+ "invalid": "Neispravno"
},
"pfsense": {
- "load": "Load Avg",
- "memory": "Mem Usage",
- "wanStatus": "WAN Status",
+ "load": "Prosječno opterećenje",
+ "memory": "Korištenje memorije",
+ "wanStatus": "Stanje WAN-a",
"up": "Up",
"down": "Down",
- "temp": "Temp",
- "disk": "Disk Usage",
+ "temp": "Temperatura",
+ "disk": "Korištenje diska",
"wanIP": "WAN IP"
},
"caddy": {
- "upstreams": "Upstreams",
- "requests": "Current requests",
- "requests_failed": "Failed requests"
+ "upstreams": "Glavne grane",
+ "requests": "Aktualni zahtjevi",
+ "requests_failed": "Neuspjeli zahtjevi"
},
"evcc": {
- "pv_power": "Production",
- "battery_soc": "Battery",
- "grid_power": "Grid",
- "home_power": "Consumption",
- "charge_power": "Charger",
+ "pv_power": "Proizvodnja",
+ "battery_soc": "Baterija",
+ "grid_power": "Raspored",
+ "home_power": "Potrošnja",
+ "charge_power": "Punjač",
"watt_hour": "Wh"
},
"pialert": {
- "total": "Total",
- "connected": "Connected",
- "new_devices": "New Devices",
- "down_alerts": "Down Alerts"
+ "total": "Ukupno",
+ "connected": "Povezano",
+ "new_devices": "Novi uređaji",
+ "down_alerts": "Obavijest o rušenju"
}
}
diff --git a/public/locales/tr/common.json b/public/locales/tr/common.json
index d5be780e..a2a872f4 100644
--- a/public/locales/tr/common.json
+++ b/public/locales/tr/common.json
@@ -24,13 +24,13 @@
"used": "Kullanımda",
"load": "Yük",
"mem": "MEM",
- "temp": "TEMP",
- "max": "Max",
- "uptime": "UP",
- "months": "mo",
- "days": "d",
- "hours": "h",
- "minutes": "m"
+ "temp": "Geçici",
+ "max": "En Yüksek",
+ "uptime": "Çalışma Süresi",
+ "months": "Ay",
+ "days": "Gün",
+ "hours": "Saat",
+ "minutes": "Dakika"
},
"unifi": {
"users": "Kullanıcılar",
@@ -57,23 +57,23 @@
"offline": "Çevrimdışı",
"error": "Hata",
"unknown": "Bilinmiyor",
- "running": "Running",
- "starting": "Starting",
- "unhealthy": "Unhealthy",
- "not_found": "Not Found",
- "exited": "Exited",
- "partial": "Partial",
- "healthy": "Healthy"
+ "running": "Çalışan",
+ "starting": "Başlatılıyor",
+ "unhealthy": "Sağlıksız",
+ "not_found": "Bulunamadı",
+ "exited": "Durduruldu",
+ "partial": "Parçalı",
+ "healthy": "Sağlık"
},
"emby": {
"playing": "Oynatılıyor",
"transcoding": "Dönüştürülüyor",
"bitrate": "Bit Oranı",
"no_active": "Aktif akış yok",
- "movies": "Movies",
- "series": "Series",
- "episodes": "Episodes",
- "songs": "Songs"
+ "movies": "Filmler",
+ "series": "Diziler",
+ "episodes": "Bölümler",
+ "songs": "Şarkılar"
},
"tautulli": {
"playing": "Oynatılıyor",
@@ -90,7 +90,7 @@
"streams": "Aktif Akış",
"movies": "Filmler",
"tv": "TV Showları",
- "albums": "Albums"
+ "albums": "Albümler"
},
"sabnzbd": {
"rate": "Oran",
@@ -159,7 +159,7 @@
"queries": "Sorgular",
"blocked": "Engellenen",
"gravity": "Yer Çekimi",
- "blocked_percent": "Blocked %"
+ "blocked_percent": "Engellenen %"
},
"adguard": {
"queries": "Sorgular",
@@ -235,15 +235,15 @@
"glances": {
"cpu": "İşlemci",
"wait": "Lütfen bekleyiniz",
- "temp": "TEMP",
- "uptime": "UP",
- "days": "d",
- "hours": "h",
- "load": "Load",
- "warn": "Warn",
- "total": "Total",
- "free": "Free",
- "used": "Used"
+ "temp": "Sıcaklık",
+ "uptime": "Çalışma Süresi",
+ "days": "Gün",
+ "hours": "Saat",
+ "load": "Yük",
+ "warn": "Uyarı",
+ "total": "Toplam",
+ "free": "Boş",
+ "used": "Kullanım"
},
"changedetectionio": {
"totalObserved": "Toplam Gözlenen",
@@ -311,9 +311,9 @@
"bookmark": "Yer İmi",
"service": "Hizmet",
"search": "Ara",
- "custom": "Custom",
- "visit": "Visit",
- "url": "URL"
+ "custom": "Özel",
+ "visit": "Ziyaret",
+ "url": "Link"
},
"homebridge": {
"available_update": "Sistem",
@@ -384,14 +384,14 @@
"deluge": {
"download": "İndir",
"upload": "Yükle",
- "leech": "Leech",
+ "leech": "Tüketici",
"seed": "Tohum"
},
"flood": {
"download": "İndir",
"upload": "Yükle",
- "leech": "Leech",
- "seed": "Tohum"
+ "leech": "Tüketici",
+ "seed": "Sağlayıcı"
},
"tdarr": {
"queue": "Sıra",
@@ -421,7 +421,7 @@
"downloadstation": {
"download": "İndir",
"upload": "Yükle",
- "leech": "Leech",
+ "leech": "Tüketici",
"seed": "Tohum"
},
"mikrotik": {
@@ -448,7 +448,7 @@
"layers": "Katmanlar"
},
"medusa": {
- "wanted": "Wanted",
+ "wanted": "Aranan",
"queued": "Kuyrukta",
"series": "Seri"
},
@@ -554,11 +554,11 @@
"targets_total": "Total Targets"
},
"minecraft": {
- "players": "Players",
- "version": "Version",
- "status": "Status",
- "up": "Online",
- "down": "Offline"
+ "players": "Oyuncular",
+ "version": "Versiyon",
+ "status": "Durum",
+ "up": "Çevrimiçi",
+ "down": "Çevrimdışı"
},
"ghostfolio": {
"gross_percent_today": "Today",
@@ -577,40 +577,40 @@
"switches_on": "Switches On"
},
"freshrss": {
- "subscriptions": "Subscriptions",
- "unread": "Unread"
+ "subscriptions": "Abonelikler",
+ "unread": "Okunmamış"
},
"channelsdvrserver": {
- "shows": "Shows",
- "recordings": "Recordings",
- "scheduled": "Scheduled",
- "passes": "Passes"
+ "shows": "Diziler",
+ "recordings": "Kayıtlar",
+ "scheduled": "Planlanmış",
+ "passes": "Geçilenler"
},
"whatsupdocker": {
"monitoring": "Monitoring",
"updates": "Updates"
},
"tailscale": {
- "never": "Never",
- "last_seen": "Last Seen",
- "now": "Now",
- "years": "{{number}}y",
- "weeks": "{{number}}w",
- "days": "{{number}}d",
- "hours": "{{number}}h",
- "minutes": "{{number}}m",
- "seconds": "{{number}}s",
- "ago": "{{value}} Ago",
- "address": "Address",
- "expires": "Expires"
+ "never": "Asla",
+ "last_seen": "Son Görülme",
+ "now": "Şimdi",
+ "years": "{{number}} Yıl",
+ "weeks": "{{number}} Hafta",
+ "days": "{{number}} Gün",
+ "hours": "{{number}} Saat",
+ "minutes": "{{number}} Dakika",
+ "seconds": "{{number}} Saniye",
+ "ago": "{{value}} Önce",
+ "address": "Adres",
+ "expires": "Geciken"
},
"qnap": {
- "cpuUsage": "CPU Usage",
- "memUsage": "MEM Usage",
- "systemTempC": "System Temp",
- "poolUsage": "Pool Usage",
- "volumeUsage": "Volume Usage",
- "invalid": "Invalid"
+ "cpuUsage": "İşlemci Kullanımı",
+ "memUsage": "Bellek Kullanımı",
+ "systemTempC": "Sistem Sıcaklığı",
+ "poolUsage": "Havuz Kullanımı",
+ "volumeUsage": "Alan Kullanımı",
+ "invalid": "Geçersiz"
},
"pfsense": {
"load": "Load Avg",
@@ -623,22 +623,22 @@
"wanIP": "WAN IP"
},
"caddy": {
- "upstreams": "Upstreams",
- "requests": "Current requests",
- "requests_failed": "Failed requests"
+ "upstreams": "Akış",
+ "requests": "Anlık İstekler",
+ "requests_failed": "Başarısız İstekler"
},
"evcc": {
- "pv_power": "Production",
- "battery_soc": "Battery",
- "grid_power": "Grid",
- "home_power": "Consumption",
- "charge_power": "Charger",
- "watt_hour": "Wh"
+ "pv_power": "Üretim",
+ "battery_soc": "Batarya",
+ "grid_power": "Güç",
+ "home_power": "Tüketim",
+ "charge_power": "Şarj",
+ "watt_hour": "Watt/Saat"
},
"pialert": {
- "total": "Total",
- "connected": "Connected",
- "new_devices": "New Devices",
- "down_alerts": "Down Alerts"
+ "total": "Toplam",
+ "connected": "Bağlandı",
+ "new_devices": "Yeni Cihazlar",
+ "down_alerts": "Düşme Uyarıları"
}
}
diff --git a/src/utils/proxy/handlers/credentialed.js b/src/utils/proxy/handlers/credentialed.js
index 5d4b7e3b..8fa975d0 100644
--- a/src/utils/proxy/handlers/credentialed.js
+++ b/src/utils/proxy/handlers/credentialed.js
@@ -55,6 +55,12 @@ export default async function credentialedProxyHandler(req, res, map) {
} else {
headers.Authorization = `Basic ${Buffer.from(`${widget.username}:${widget.password}`).toString("base64")}`;
}
+ } else if (widget.type === "paperlessngx") {
+ if (widget.key) {
+ headers.Authorization = `Token ${widget.key}`;
+ } else {
+ headers.Authorization = `Basic ${Buffer.from(`${widget.username}:${widget.password}`).toString("base64")}`;
+ }
} else {
headers["X-API-Key"] = `${widget.key}`;
}
diff --git a/src/widgets/components.js b/src/widgets/components.js
index b6a7ca82..bb8171d0 100644
--- a/src/widgets/components.js
+++ b/src/widgets/components.js
@@ -90,6 +90,7 @@ const components = {
uptimekuma: dynamic(() => import("./uptimekuma/component")),
watchtower: dynamic(() => import("./watchtower/component")),
whatsupdocker: dynamic(() => import("./whatsupdocker/component")),
+ wgeasy: dynamic(() => import("./wgeasy/component")),
xteve: dynamic(() => import("./xteve/component")),
};
diff --git a/src/widgets/paperlessngx/widget.js b/src/widgets/paperlessngx/widget.js
index 8af8079d..de37f595 100644
--- a/src/widgets/paperlessngx/widget.js
+++ b/src/widgets/paperlessngx/widget.js
@@ -1,8 +1,8 @@
-import genericProxyHandler from "utils/proxy/handlers/generic";
+import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
const widget = {
api: "{url}/api/{endpoint}",
- proxyHandler: genericProxyHandler,
+ proxyHandler: credentialedProxyHandler,
mappings: {
"statistics": {
diff --git a/src/widgets/wgeasy/component.jsx b/src/widgets/wgeasy/component.jsx
new file mode 100644
index 00000000..e2434f51
--- /dev/null
+++ b/src/widgets/wgeasy/component.jsx
@@ -0,0 +1,33 @@
+import { useTranslation } from "next-i18next";
+
+import Block from "components/services/widget/block";
+import Container from "components/services/widget/container";
+import useWidgetAPI from "utils/proxy/use-widget-api";
+
+export default function Component({ service }) {
+ const { t } = useTranslation();
+
+ const { widget } = service;
+
+ const { data: wgeasyData, error: wgeasyAPIError } = useWidgetAPI(widget, "unified", {
+ refreshInterval: 5000,
+ });
+
+ if (wgeasyAPIError) {
+ return ;
+ }
+
+ if (!wgeasyData) {
+ return (
+
+
+
+ );
+ }
+
+ return (
+
+
+
+ );
+}
diff --git a/src/widgets/wgeasy/proxy.js b/src/widgets/wgeasy/proxy.js
new file mode 100644
index 00000000..233e80da
--- /dev/null
+++ b/src/widgets/wgeasy/proxy.js
@@ -0,0 +1,118 @@
+/* eslint-disable no-underscore-dangle */
+import { formatApiCall } from "utils/proxy/api-helpers";
+import { httpProxy } from "utils/proxy/http";
+import getServiceWidget from "utils/config/service-helpers";
+import createLogger from "utils/logger";
+import widgets from "widgets/widgets";
+
+
+const proxyName = "wgeasyProxyHandler";
+
+const logger = createLogger(proxyName);
+let globalSid = null;
+
+async function getWidget(req) {
+ const { group, service } = req.query;
+ if (!group || !service) {
+ logger.debug("Invalid or missing service '%s' or group '%s'", service, group);
+ return null;
+ }
+ const widget = await getServiceWidget(group, service);
+ if (!widget) {
+ logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group);
+ return null;
+ }
+
+ return widget;
+}
+
+
+async function loginToWGEasy(endpoint, widget) {
+ const api = widgets?.[widget.type]?.api;
+ if (!api) {
+ return [403, null];
+ }
+ // Create new session on WgEasy
+ let url = new URL(formatApiCall(api, { endpoint, ...widget }));
+
+ let [status, contentType, data, responseHeaders] = await httpProxy(url, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ password: widget.password,
+ })
+ });
+
+ if (status !== 204) {
+ logger.error("HTTP %d communicating with NextPVR. Data: %s", status, data.toString());
+ return [status, data, responseHeaders];
+ }
+ try {
+ globalSid = responseHeaders["set-cookie"][0]
+ } catch (e) {
+ logger.error("Error decoding NextPVR API data. Data: %s", data.toString());
+ return [status, null];
+ }
+ logger.info('gettingSID')
+ return [status, true];
+}
+
+
+async function fetchDataFromWGeasy(endpoint, widget, sid) {
+ const api = widgets?.[widget.type]?.api;
+ if (!api) {
+ return [403, null];
+ }
+ const url = `${new URL(formatApiCall(api, { endpoint, ...widget }))}`
+ const [status, contentType, data] = await httpProxy(url, {
+ method: 'GET',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Cookie': sid
+ },
+ });
+
+ if (status !== 200) {
+ logger.error("HTTP %d communicating with WGeasy. Data: %s", status, data.toString());
+ return [status, data];
+ }
+
+ try {
+ return [status, JSON.parse(data), contentType];
+ } catch (e) {
+ logger.error("Error decoding WGeasy API data. Data: %s", data.toString());
+ return [status, null];
+ }
+}
+
+export default async function WGeasyProxyHandler(req, res) {
+ const widget = await getWidget(req);
+
+ if (!globalSid) {
+ await loginToWGEasy('session', widget);
+ }
+ if (!widget) {
+ return res.status(400).json({ error: "Invalid proxy service type" });
+ }
+
+ logger.debug("Getting data from WGeasy API");
+ // Calculate the number of clients
+ let [status, apiData] = await fetchDataFromWGeasy('wireguard/client', widget, globalSid);
+
+ if (status !== 200) {
+ return res.status(status).json({ error: { message: "HTTP error communicating with WGeasy API", data: Buffer.from(apiData).toString() } });
+ }
+ let clientCount;
+ clientCount = apiData.length;
+
+ const data = {
+ clientCount
+ };
+
+ return res.status(status).send(data);
+
+}
+
+
diff --git a/src/widgets/wgeasy/widget.js b/src/widgets/wgeasy/widget.js
new file mode 100644
index 00000000..fcb5bef6
--- /dev/null
+++ b/src/widgets/wgeasy/widget.js
@@ -0,0 +1,14 @@
+import nextpvrProxyHandler from "./proxy";
+
+const widget = {
+ api: "{url}/api/{endpoint}",
+ proxyHandler: nextpvrProxyHandler,
+
+ mappings: {
+ unified: {
+ endpoint: "/",
+ },
+ },
+};
+
+export default widget;
diff --git a/src/widgets/widgets.js b/src/widgets/widgets.js
index a2a00ff7..36b06c2e 100644
--- a/src/widgets/widgets.js
+++ b/src/widgets/widgets.js
@@ -83,6 +83,7 @@ import unmanic from "./unmanic/widget";
import uptimekuma from "./uptimekuma/widget";
import watchtower from "./watchtower/widget";
import whatsupdocker from "./whatsupdocker/widget";
+import wgeasy from "./wgeasy/widget";
import xteve from "./xteve/widget";
import jdrssdownloader from "./jdrssdownloader/widget";
@@ -175,6 +176,7 @@ const widgets = {
uptimekuma,
watchtower,
whatsupdocker,
+ wgeasy,
xteve,
};