Merge remote-tracking branch 'origin/main' into JDRssDownloader

This commit is contained in:
Karl Hudgell 2023-06-06 18:14:15 +01:00
commit 7a3ebac8f0
11 changed files with 284 additions and 107 deletions

View File

@ -658,5 +658,8 @@
"totalShows": "Tracked Shows",
"retryCache": "Retry Cache",
"feedCache": "Feed Cache"
},
"wgeasy": {
"clients": "Total Clients"
}
}

View File

@ -397,7 +397,7 @@
"queue": "À traiter",
"processed": "Traité",
"errored": "En erreur",
"saved": "Economisé"
"saved": "Gagné"
},
"miniflux": {
"read": "Lu",

View File

@ -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"
}
}

View File

@ -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ı"
}
}

View File

@ -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}`;
}

View File

@ -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")),
};

View File

@ -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": {

View File

@ -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 <Container service={service} error={wgeasyAPIError} />;
}
if (!wgeasyData) {
return (
<Container service={service}>
<Block label="wgeasy.clients" />
</Container>
);
}
return (
<Container service={service}>
<Block label="wgeasy.clients" value={t("common.number", { value: wgeasyData.clientCount })} />
</Container>
);
}

118
src/widgets/wgeasy/proxy.js Normal file
View File

@ -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);
}

View File

@ -0,0 +1,14 @@
import nextpvrProxyHandler from "./proxy";
const widget = {
api: "{url}/api/{endpoint}",
proxyHandler: nextpvrProxyHandler,
mappings: {
unified: {
endpoint: "/",
},
},
};
export default widget;

View File

@ -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,
};