diff --git a/public/locales/ar/common.json b/public/locales/ar/common.json index 5e61a401..78acd26f 100644 --- a/public/locales/ar/common.json +++ b/public/locales/ar/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "scheduled": "Scheduled", + "passes": "Passes", + "shows": "Shows", + "recordings": "Recordings" } } diff --git a/public/locales/bg/common.json b/public/locales/bg/common.json index 4d600c41..ab7a655f 100644 --- a/public/locales/bg/common.json +++ b/public/locales/bg/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/ca/common.json b/public/locales/ca/common.json index be4940c8..5df98b04 100644 --- a/public/locales/ca/common.json +++ b/public/locales/ca/common.json @@ -183,7 +183,7 @@ "qbittorrent": { "download": "Descàrrega", "upload": "Pujada", - "leech": "Companys", + "leech": "Clients", "seed": "Llavors" }, "mastodon": { @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/cs/common.json b/public/locales/cs/common.json index b45387b0..458017bf 100644 --- a/public/locales/cs/common.json +++ b/public/locales/cs/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/da/common.json b/public/locales/da/common.json index 0a577b75..39e6b71c 100644 --- a/public/locales/da/common.json +++ b/public/locales/da/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/de/common.json b/public/locales/de/common.json index 0d59288c..aa89b204 100644 --- a/public/locales/de/common.json +++ b/public/locales/de/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/el/common.json b/public/locales/el/common.json index ba9964ee..e757f906 100644 --- a/public/locales/el/common.json +++ b/public/locales/el/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/en/common.json b/public/locales/en/common.json index c46e6c38..2da02110 100755 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -98,10 +98,20 @@ "leech": "Leech", "seed": "Seed" }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, "changedetectionio": { "totalObserved": "Total Observed", "diffsDetected": "Diffs Detected" }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" + }, "tautulli": { "playing": "Playing", "transcoding": "Transcoding", diff --git a/public/locales/eo/common.json b/public/locales/eo/common.json index e9047f54..7935fe63 100644 --- a/public/locales/eo/common.json +++ b/public/locales/eo/common.json @@ -1,18 +1,18 @@ { "widget": { - "missing_type": "Missing Widget Type: {{type}}", - "api_error": "API Error", + "missing_type": "Manka Tipo de Fenestraĵo: {{type}}", + "api_error": "Eraro de API", "information": "Informo", "status": "Stato", "url": "URL", - "raw_error": "Raw Error", - "response_data": "Response Data" + "raw_error": "Kruda Eraro", + "response_data": "Respondoj de Demandoj" }, "weather": { "current": "Aktuala loko", - "allow": "Click to allow", - "updating": "Updating", - "wait": "Please wait" + "allow": "Klaku por permesi", + "updating": "Ĝisdatiganta", + "wait": "Bonvolu atendi" }, "search": { "placeholder": "Serĉi…" @@ -26,58 +26,58 @@ "mem": "MEM", "temp": "TEMP", "months": "mo", - "max": "Max", + "max": "Maks", "uptime": "UP", - "days": "d", + "days": "t", "hours": "h", "minutes": "m" }, "unifi": { "users": "Uzantoj", - "uptime": "System Uptime", + "uptime": "Uptempo de la Sistemo", "days": "Tagoj", "wan": "WAN", "lan": "LAN", "wlan": "WLAN", "devices": "Aparatoj", - "lan_devices": "LAN Devices", - "wlan_devices": "WLAN Devices", - "lan_users": "LAN Users", - "wlan_users": "WLAN Users", + "lan_devices": "LAN-Aparatoj", + "wlan_devices": "WLAN-Aparatoj", + "lan_users": "LAN-Uzantoj", + "wlan_users": "WLAN-Uzantoj", "up": "UP", "down": "DOWN", - "wait": "Please wait", - "empty_data": "Subsystem status unknown" + "wait": "Bonvolu atendi", + "empty_data": "Subsistemostatuso nekonata" }, "docker": { "rx": "RX", "tx": "TX", - "mem": "Memoro", - "cpu": "Ĉefprocesoro", - "offline": "Offline", + "mem": "MEM", + "cpu": "CPO", + "offline": "Malkonekta", "error": "Eraro", "unknown": "Nekonata", - "running": "Running", - "starting": "Starting", - "unhealthy": "Unhealthy", - "not_found": "Not Found", - "exited": "Exited", - "partial": "Partial", - "healthy": "Healthy" + "running": "Rulata", + "starting": "Lanĉante", + "unhealthy": "Malsana", + "not_found": "Ne trovita", + "exited": "Eliris", + "partial": "Parta", + "healthy": "Sana" }, "ping": { "error": "Eraro", - "ping": "Ping" + "ping": "Sondaĵo" }, "emby": { "playing": "Ludante", - "transcoding": "Transcoding", - "bitrate": "Bitrate", + "transcoding": "Transkodigo", + "bitrate": "Bitrapido", "no_active": "No Active Streams", - "movies": "Movies", - "series": "Series", - "episodes": "Episodes", - "songs": "Songs" + "movies": "Filmoj", + "series": "Serioj", + "episodes": "Epizodoj", + "songs": "Kantoj" }, "changedetectionio": { "totalObserved": "Total Observed", @@ -382,8 +382,8 @@ "total": "Totalo" }, "flood": { - "download": "Download", - "upload": "Upload", + "download": "Elŝuti", + "upload": "Alŝuti", "leech": "Leech", "seed": "Seed" }, @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/es/common.json b/public/locales/es/common.json index 85f4f650..f2d9fe85 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -18,7 +18,7 @@ "load": "Carga", "cpu": "CPU", "mem": "MEM", - "temp": "TEMPORAL", + "temp": "TEMP", "max": "Máx.", "uptime": "ARRIBA", "months": "Meses", @@ -183,7 +183,7 @@ "qbittorrent": { "download": "Bajada", "upload": "Subida", - "leech": "Compañeros", + "leech": "Pares", "seed": "Semillas" }, "mastodon": { @@ -564,8 +564,18 @@ "booksDuration": "Duración" }, "homeassistant": { - "people_home": "People Home", - "lights_on": "Lights On", - "switches_on": "Switches On" + "people_home": "Inicio de personas", + "lights_on": "Luces encendidas", + "switches_on": "Encendido" + }, + "freshrss": { + "subscriptions": "Suscripciones", + "unread": "Sin leer" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/fi/common.json b/public/locales/fi/common.json index a8653709..7dfd0631 100644 --- a/public/locales/fi/common.json +++ b/public/locales/fi/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/fr/common.json b/public/locales/fr/common.json index 08dcfd9e..7cf76751 100644 --- a/public/locales/fr/common.json +++ b/public/locales/fr/common.json @@ -234,9 +234,9 @@ "cpu": "Cpu", "mem": "Mém", "wait": "Merci de patienter", - "temp": "TEMP", - "uptime": "UP", - "days": "d", + "temp": "Temp", + "uptime": "Up", + "days": "j", "hours": "h" }, "changedetectionio": { @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lumières allumées", "switches_on": "Switches On" + }, + "freshrss": { + "unread": "Non lu", + "subscriptions": "Abonnements" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/he/common.json b/public/locales/he/common.json index aadd2648..cc87c89f 100644 --- a/public/locales/he/common.json +++ b/public/locales/he/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/hi/common.json b/public/locales/hi/common.json index bea203ed..dd10e1c2 100644 --- a/public/locales/hi/common.json +++ b/public/locales/hi/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/hr/common.json b/public/locales/hr/common.json index f70816bf..a4feafbf 100644 --- a/public/locales/hr/common.json +++ b/public/locales/hr/common.json @@ -564,8 +564,18 @@ "booksDuration": "Trajanje" }, "homeassistant": { - "people_home": "People Home", - "lights_on": "Lights On", - "switches_on": "Switches On" + "people_home": "Ljudi doma", + "lights_on": "Upaljena svjetla", + "switches_on": "Prekidači uključeni" + }, + "freshrss": { + "subscriptions": "Pretplate", + "unread": "Nepročitano" + }, + "channelsdvrserver": { + "scheduled": "Scheduled", + "passes": "Passes", + "shows": "Shows", + "recordings": "Recordings" } } diff --git a/public/locales/hu/common.json b/public/locales/hu/common.json index 6b13a9ac..8fa320ce 100644 --- a/public/locales/hu/common.json +++ b/public/locales/hu/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/it/common.json b/public/locales/it/common.json index 70d6d84a..7096f3cc 100644 --- a/public/locales/it/common.json +++ b/public/locales/it/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/ja/common.json b/public/locales/ja/common.json index f9fef837..13b8013f 100644 --- a/public/locales/ja/common.json +++ b/public/locales/ja/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/ko/common.json b/public/locales/ko/common.json index 9c0e6669..08371d8f 100644 --- a/public/locales/ko/common.json +++ b/public/locales/ko/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/lv/common.json b/public/locales/lv/common.json index b1d18a23..7b8f524b 100644 --- a/public/locales/lv/common.json +++ b/public/locales/lv/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/ms/common.json b/public/locales/ms/common.json index 03ed61da..c54ca3b2 100644 --- a/public/locales/ms/common.json +++ b/public/locales/ms/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/nb-NO/common.json b/public/locales/nb-NO/common.json index 6fbbbb6b..289e4cce 100644 --- a/public/locales/nb-NO/common.json +++ b/public/locales/nb-NO/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/nl/common.json b/public/locales/nl/common.json index 8d6022f1..20d8ee3d 100644 --- a/public/locales/nl/common.json +++ b/public/locales/nl/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/pl/common.json b/public/locales/pl/common.json index da01b0bd..4ebd35b7 100644 --- a/public/locales/pl/common.json +++ b/public/locales/pl/common.json @@ -15,10 +15,10 @@ "free": "Wolne", "cpu": "CPU", "mem": "PAM", - "temp": "TYMCZASOWE", + "temp": "TEMP.", "max": "Max", "uptime": "UP", - "months": "misiąc", + "months": "miesiąc", "days": "dni", "hours": "h", "minutes": "minuty" @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/pt-BR/common.json b/public/locales/pt-BR/common.json index 246c357d..60d48a8a 100644 --- a/public/locales/pt-BR/common.json +++ b/public/locales/pt-BR/common.json @@ -54,8 +54,8 @@ "mem": "MEM", "max": "Máximo", "temp": "TEMP", - "uptime": "CIMA", - "months": "mo", + "uptime": "LIGADO", + "months": "mês", "days": "d", "hours": "h", "minutes": "m" @@ -235,7 +235,7 @@ "mem": "MEM", "wait": "Por favor aguarde", "temp": "TEMP", - "uptime": "CIMA", + "uptime": "LIGADO", "days": "d", "hours": "h" }, @@ -316,9 +316,9 @@ "up_to_date": "Atualizado", "child_bridges": "Pontes Filhas", "child_bridges_status": "{{ok}}/{{total}}", - "up": "Cima", + "up": "Ligado", "pending": "Pendente", - "down": "Baixo" + "down": "Desligado" }, "autobrr": { "approvedPushes": "Aprovado", @@ -564,8 +564,18 @@ "booksDuration": "Duração" }, "homeassistant": { - "people_home": "People Home", - "lights_on": "Lights On", - "switches_on": "Switches On" + "people_home": "Pessoas em Casa", + "lights_on": "Luzes Ligadas", + "switches_on": "Interruptores Ligados" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/pt/common.json b/public/locales/pt/common.json index d3c66402..13094508 100644 --- a/public/locales/pt/common.json +++ b/public/locales/pt/common.json @@ -21,7 +21,7 @@ "max": "Máximo", "temp": "TEMP", "uptime": "CIMA", - "months": "mo", + "months": "mês", "days": "d", "hours": "h", "minutes": "m" @@ -573,8 +573,18 @@ "booksDuration": "Duração" }, "homeassistant": { - "people_home": "People Home", - "lights_on": "Lights On", - "switches_on": "Switches On" + "people_home": "Pessoas em Casa", + "lights_on": "Luzes Acesas", + "switches_on": "Interruptores Ligados" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/ro/common.json b/public/locales/ro/common.json index 9ab9a696..5f8cb985 100644 --- a/public/locales/ro/common.json +++ b/public/locales/ro/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/ru/common.json b/public/locales/ru/common.json index b1b8b627..31f71f87 100644 --- a/public/locales/ru/common.json +++ b/public/locales/ru/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/sk/common.json b/public/locales/sk/common.json index 9bb20969..c56f52ff 100644 --- a/public/locales/sk/common.json +++ b/public/locales/sk/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/sl/common.json b/public/locales/sl/common.json new file mode 100644 index 00000000..75a63235 --- /dev/null +++ b/public/locales/sl/common.json @@ -0,0 +1,581 @@ +{ + "common": { + "bibyterate": "{{value, rate(bits: false; binary: true)}}", + "bibitrate": "{{value, rate(bits: true; binary: true)}}" + }, + "jellyseerr": { + "available": "Available", + "pending": "Pending", + "approved": "Approved" + }, + "overseerr": { + "pending": "Pending", + "processing": "Processing", + "approved": "Approved", + "available": "Available" + }, + "pihole": { + "queries": "Queries", + "blocked": "Blocked", + "gravity": "Gravity" + }, + "adguard": { + "filtered": "Filtered", + "latency": "Latency", + "queries": "Queries", + "blocked": "Blocked" + }, + "opnsense": { + "wanUpload": "WAN Upload", + "wanDownload": "WAN Download", + "cpu": "CPU Load", + "memory": "Active Memory" + }, + "octoprint": { + "temp_bed": "Bed temp", + "job_completion": "Completion", + "printer_state": "Status", + "temp_tool": "Tool temp" + }, + "cloudflared": { + "origin_ip": "Origin IP", + "status": "Status" + }, + "proxmoxbackupserver": { + "datastore_usage": "Datastore", + "failed_tasks_24h": "Failed Tasks 24h", + "cpu_usage": "CPU", + "memory_usage": "Memory" + }, + "mylar": { + "wanted": "Wanted", + "series": "Series", + "issues": "Issues" + }, + "photoprism": { + "albums": "Albums", + "photos": "Photos", + "videos": "Videos", + "people": "People" + }, + "grafana": { + "alertstriggered": "Alerts Triggered", + "dashboards": "Dashboards", + "datasources": "Data Sources", + "totalalerts": "Total Alerts" + }, + "nextcloud": { + "cpuload": "Cpu Load", + "memoryusage": "Memory Usage", + "freespace": "Free Space", + "activeusers": "Active Users" + }, + "kopia": { + "status": "Status", + "size": "Size", + "lastrun": "Last Run", + "nextrun": "Next Run", + "failed": "Failed" + }, + "pterodactyl": { + "nodes": "Nodes", + "servers": "Servers" + }, + "widget": { + "missing_type": "Manjka tip widgeta: {{type}}", + "api_error": "API napaka", + "information": "Informacija", + "raw_error": "Surova napaka", + "response_data": "Podatki iz odgovora", + "status": "Status", + "url": "URL" + }, + "weather": { + "current": "Trenutna lokacija", + "allow": "Kliknite za dovolitev", + "updating": "Posodabljam", + "wait": "Prosimo počakajte" + }, + "search": { + "placeholder": "Iskanje…" + }, + "resources": { + "cpu": "CPU", + "mem": "MEM", + "total": "Skupaj", + "free": "Prosto", + "used": "V uporabi", + "load": "Bremenitev", + "temp": "TEMP", + "max": "Maks.", + "uptime": "Gor", + "months": "me", + "days": "d", + "hours": "u", + "minutes": "m" + }, + "unifi": { + "devices": "Naprave", + "lan_devices": "LAN naprave", + "wlan_devices": "WLAN naprave", + "lan_users": "LAN uporabniki", + "wlan_users": "WLAN uporabniki", + "up": "Gor", + "down": "Dol", + "wait": "Prosimo počakajte", + "users": "Uporabniki", + "uptime": "Čas delovanja", + "days": "Dni", + "wan": "WAN", + "lan": "LAN", + "wlan": "WLAN", + "empty_data": "Neznani status podsistema" + }, + "docker": { + "rx": "RX", + "tx": "TX", + "mem": "MEM", + "cpu": "CPU", + "running": "Deluje", + "offline": "Ni povezan", + "error": "Napaka", + "unknown": "Neznano", + "healthy": "Zdrav", + "starting": "Se zaganja", + "unhealthy": "Ni zdrav", + "not_found": "Ni najden", + "exited": "V izhodu", + "partial": "Delni" + }, + "ping": { + "error": "Napaka", + "ping": "Ping" + }, + "emby": { + "playing": "Predvaja", + "transcoding": "Transkodira", + "bitrate": "Pasovna širina", + "no_active": "Ni aktivne vsebine", + "movies": "Filmi", + "series": "Serije", + "episodes": "Epizode", + "songs": "Pesmi" + }, + "tautulli": { + "transcoding": "Transkodira", + "bitrate": "Pasovna širina", + "playing": "Predvaja", + "no_active": "Ni aktivne vsebine" + }, + "flood": { + "download": "Prenos", + "upload": "Nalaganje", + "leech": "Pijavka", + "seed": "Sejanje" + }, + "changedetectionio": { + "totalObserved": "Skupaj opazovano", + "diffsDetected": "Zaznanih sprememb" + }, + "omada": { + "connectedAp": "Povezanih AP", + "activeUser": "Aktivne naprave", + "alerts": "Opozorila", + "connectedGateway": "Povezan prehod", + "connectedSwitches": "Povezana stikala" + }, + "nzbget": { + "rate": "Razmerje", + "remaining": "Še preostane", + "downloaded": "Preneseno" + }, + "plex": { + "streams": "Aktivna vsebina", + "movies": "Filmi", + "tv": "TV serije" + }, + "sabnzbd": { + "rate": "Razmerje", + "queue": "Vrsta", + "timeleft": "Preostali čas" + }, + "rutorrent": { + "active": "Aktiven", + "upload": "Nalaganje", + "download": "Prenašanje" + }, + "transmission": { + "download": "Prenos", + "upload": "Nalaganje", + "leech": "Pijavka", + "seed": "Sejanje" + }, + "qbittorrent": { + "download": "Prenos", + "upload": "Nalaganje", + "leech": "Pijavka", + "seed": "Sejanje" + }, + "deluge": { + "download": "Prenos", + "upload": "Upload", + "leech": "Pijavka", + "seed": "Sejanje" + }, + "downloadstation": { + "download": "Prenos", + "upload": "Nalaganje", + "leech": "Pijavka", + "seed": "Sejanje" + }, + "sonarr": { + "wanted": "Wanted", + "queued": "Queued", + "series": "Series" + }, + "radarr": { + "wanted": "Wanted", + "missing": "Missing", + "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" + }, + "speedtest": { + "upload": "Upload", + "download": "Download", + "ping": "Ping" + }, + "portainer": { + "running": "Running", + "stopped": "Stopped", + "total": "Total" + }, + "tdarr": { + "queue": "Queue", + "processed": "Processed", + "errored": "Errored", + "saved": "Saved" + }, + "npm": { + "disabled": "Disabled", + "total": "Total", + "enabled": "Enabled" + }, + "coinmarketcap": { + "configure": "Configure one or more crypto currencies to track", + "1hour": "1 Hour", + "1day": "1 Day", + "7days": "7 Days", + "30days": "30 Days" + }, + "traefik": { + "routers": "Routers", + "services": "Services", + "middleware": "Middleware" + }, + "gotify": { + "apps": "Applications", + "clients": "Clients", + "messages": "Messages" + }, + "navidrome": { + "nothing_streaming": "No Active Streams", + "please_wait": "Please Wait" + }, + "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" + }, + "medusa": { + "wanted": "Wanted", + "queued": "Queued", + "series": "Series" + }, + "minecraft": { + "players": "Players", + "version": "Version", + "status": "Status", + "up": "Online", + "down": "Offline" + }, + "miniflux": { + "read": "Read", + "unread": "Unread" + }, + "proxmox": { + "lxc": "LXC", + "vms": "VMs", + "mem": "MEM", + "cpu": "CPU" + }, + "glances": { + "cpu": "CPU", + "mem": "MEM", + "wait": "Please wait", + "temp": "TEMP", + "uptime": "UP", + "days": "d", + "hours": "h" + }, + "authentik": { + "users": "Users", + "loginsLast24H": "Logins (24h)", + "failedLoginsLast24H": "Failed Logins (24h)" + }, + "quicklaunch": { + "bookmark": "Bookmark", + "service": "Service", + "search": "Search", + "custom": "Custom", + "url": "URL", + "visit": "Visit" + }, + "wmo": { + "3-night": "Cloudy", + "45-day": "Foggy", + "0-day": "Sunny", + "0-night": "Clear", + "1-day": "Mainly Sunny", + "1-night": "Mainly Clear", + "45-night": "Foggy", + "2-day": "Partly Cloudy", + "2-night": "Partly Cloudy", + "3-day": "Cloudy", + "48-day": "Foggy", + "48-night": "Foggy", + "51-day": "Light Drizzle", + "51-night": "Light Drizzle", + "53-day": "Drizzle", + "53-night": "Drizzle", + "55-day": "Heavy Drizzle", + "55-night": "Heavy Drizzle", + "56-day": "Light Freezing Drizzle", + "56-night": "Light Freezing Drizzle", + "57-day": "Freezing Drizzle", + "63-night": "Rain", + "65-day": "Heavy Rain", + "65-night": "Heavy Rain", + "66-day": "Freezing Rain", + "66-night": "Freezing Rain", + "57-night": "Freezing Drizzle", + "61-day": "Light Rain", + "61-night": "Light Rain", + "67-day": "Freezing Rain", + "63-day": "Rain", + "67-night": "Freezing Rain", + "71-day": "Light Snow", + "71-night": "Light Snow", + "73-day": "Snow", + "73-night": "Snow", + "75-day": "Heavy Snow", + "75-night": "Heavy Snow", + "77-day": "Snow Grains", + "77-night": "Snow Grains", + "80-day": "Light Showers", + "85-night": "Snow Showers", + "86-day": "Snow Showers", + "80-night": "Light Showers", + "81-day": "Showers", + "81-night": "Showers", + "82-day": "Heavy Showers", + "82-night": "Heavy Showers", + "85-day": "Snow Showers", + "86-night": "Snow Showers", + "95-day": "Thunderstorm", + "95-night": "Thunderstorm", + "96-day": "Thunderstorm With Hail", + "96-night": "Thunderstorm With Hail", + "99-day": "Thunderstorm With Hail", + "99-night": "Thunderstorm With Hail" + }, + "homebridge": { + "child_bridges": "Child Bridges", + "child_bridges_status": "{{ok}}/{{total}}", + "up": "Up", + "available_update": "System", + "updates": "Updates", + "update_available": "Update Available", + "up_to_date": "Up to Date", + "pending": "Pending", + "down": "Down" + }, + "healthchecks": { + "new": "New", + "up": "Online", + "grace": "In Grace Period", + "down": "Offline", + "paused": "Paused", + "status": "Status", + "last_ping": "Last Ping", + "never": "No pings yet" + }, + "watchtower": { + "containers_scanned": "Scanned", + "containers_updated": "Updated", + "containers_failed": "Failed" + }, + "autobrr": { + "approvedPushes": "Approved", + "rejectedPushes": "Rejected", + "filters": "Filters", + "indexers": "Indexers" + }, + "tubearchivist": { + "downloads": "Queue", + "videos": "Videos", + "channels": "Channels", + "playlists": "Playlists" + }, + "truenas": { + "load": "System Load", + "uptime": "Uptime", + "alerts": "Alerts", + "time": "{{value, number(style: unit; unitDisplay: long;)}}" + }, + "pyload": { + "speed": "Speed", + "active": "Active", + "queue": "Queue", + "total": "Total" + }, + "gluetun": { + "public_ip": "Public IP", + "region": "Region", + "country": "Country" + }, + "hdhomerun": { + "channels": "Channels", + "hd": "HD" + }, + "scrutiny": { + "passed": "Passed", + "failed": "Failed", + "unknown": "Unknown" + }, + "paperlessngx": { + "inbox": "Inbox", + "total": "Total" + }, + "nextdns": { + "wait": "Please Wait", + "no_devices": "No Device Data Received" + }, + "mikrotik": { + "cpuLoad": "CPU Load", + "memoryUsed": "Memory Used", + "uptime": "Uptime", + "numberOfLeases": "Leases" + }, + "xteve": { + "streams_all": "All Streams", + "streams_active": "Active Streams", + "streams_xepg": "XEPG Channels" + }, + "moonraker": { + "printer_state": "Printer State", + "print_status": "Print Status", + "print_progress": "Progress", + "layers": "Layers" + }, + "immich": { + "users": "Users", + "photos": "Photos", + "videos": "Videos", + "storage": "Storage" + }, + "uptimekuma": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Uptime", + "incident": "Incident", + "m": "m" + }, + "komga": { + "libraries": "Libraries", + "series": "Series", + "books": "Books" + }, + "diskstation": { + "days": "Days", + "uptime": "Uptime", + "volumeAvailable": "Available" + }, + "fileflows": { + "queue": "Queue", + "processing": "Processing", + "processed": "Processed", + "time": "Time" + }, + "prometheus": { + "targets_up": "Targets Up", + "targets_down": "Targets Down", + "targets_total": "Total Targets" + }, + "unmanic": { + "active_workers": "Active Workers", + "total_workers": "Total Workers", + "records_total": "Queue Length" + }, + "ghostfolio": { + "gross_percent_today": "Today", + "gross_percent_1y": "One year", + "gross_percent_max": "All time" + }, + "audiobookshelf": { + "podcasts": "Podcasts", + "books": "Books", + "podcastsDuration": "Duration", + "booksDuration": "Duration" + }, + "homeassistant": { + "people_home": "People Home", + "lights_on": "Lights On", + "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" + } +} diff --git a/public/locales/sr/common.json b/public/locales/sr/common.json index ca552a01..397c015d 100644 --- a/public/locales/sr/common.json +++ b/public/locales/sr/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/sv/common.json b/public/locales/sv/common.json index 93595d25..c31c5e9d 100644 --- a/public/locales/sv/common.json +++ b/public/locales/sv/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/te/common.json b/public/locales/te/common.json index c929c2cf..7eb3bf0e 100644 --- a/public/locales/te/common.json +++ b/public/locales/te/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/th/common.json b/public/locales/th/common.json index 4775c118..25dbd27e 100644 --- a/public/locales/th/common.json +++ b/public/locales/th/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "scheduled": "Scheduled", + "passes": "Passes", + "shows": "Shows", + "recordings": "Recordings" } } diff --git a/public/locales/tr/common.json b/public/locales/tr/common.json index 8f821783..4c1c0609 100644 --- a/public/locales/tr/common.json +++ b/public/locales/tr/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/uk/common.json b/public/locales/uk/common.json index 038f53f5..0e11a292 100644 --- a/public/locales/uk/common.json +++ b/public/locales/uk/common.json @@ -564,8 +564,18 @@ "booksDuration": "Тривалість" }, "homeassistant": { - "people_home": "People Home", + "people_home": "Люди вдома", "lights_on": "Світло ввімкнено", "switches_on": "Вмикається" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/vi/common.json b/public/locales/vi/common.json index 9090d98c..d0263ee7 100644 --- a/public/locales/vi/common.json +++ b/public/locales/vi/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/yue/common.json b/public/locales/yue/common.json index 0e8b8247..ae2d82b3 100644 --- a/public/locales/yue/common.json +++ b/public/locales/yue/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/zh-CN/common.json b/public/locales/zh-CN/common.json index fd77e685..674f9932 100644 --- a/public/locales/zh-CN/common.json +++ b/public/locales/zh-CN/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/public/locales/zh-Hant/common.json b/public/locales/zh-Hant/common.json index ec8df407..4cf5fc16 100644 --- a/public/locales/zh-Hant/common.json +++ b/public/locales/zh-Hant/common.json @@ -567,5 +567,15 @@ "people_home": "People Home", "lights_on": "Lights On", "switches_on": "Switches On" + }, + "freshrss": { + "subscriptions": "Subscriptions", + "unread": "Unread" + }, + "channelsdvrserver": { + "shows": "Shows", + "recordings": "Recordings", + "scheduled": "Scheduled", + "passes": "Passes" } } diff --git a/src/components/services/ping.jsx b/src/components/services/ping.jsx index e3056232..7358b172 100644 --- a/src/components/services/ping.jsx +++ b/src/components/services/ping.jsx @@ -25,7 +25,7 @@ export default function Ping({ service }) { const statusText = `${service.ping}: HTTP status ${data.status}`; - if (data && data.status !== 200) { + if (data.status > 403) { return (
{data.status}
@@ -33,12 +33,10 @@ export default function Ping({ service }) { ); } - if (data && data.status === 200) { - return ( -
-
{t("common.ms", { value: data.latency, style: "unit", unit: "millisecond", unitDisplay: "narrow", maximumFractionDigits: 0 })}
-
- ); - } + return ( +
+
{t("common.ms", { value: data.latency, style: "unit", unit: "millisecond", unitDisplay: "narrow", maximumFractionDigits: 0 })}
+
+ ); } diff --git a/src/components/widgets/glances/glances.jsx b/src/components/widgets/glances/glances.jsx index a6f4dfa8..fc0d21ed 100644 --- a/src/components/widgets/glances/glances.jsx +++ b/src/components/widgets/glances/glances.jsx @@ -6,7 +6,7 @@ import { useTranslation } from "next-i18next"; import UsageBar from "../resources/usage-bar"; -const cpuSensorLabels = ["cpu_thermal", "Core"]; +const cpuSensorLabels = ["cpu_thermal", "Core", "Tctl"]; function convertToFahrenheit(t) { return t * 9/5 + 32 diff --git a/src/pages/api/ping.js b/src/pages/api/ping.js index 66eab281..1fdb1f80 100644 --- a/src/pages/api/ping.js +++ b/src/pages/api/ping.js @@ -21,7 +21,7 @@ export default async function handler(req, res) { }); let endTime = performance.now(); - if (status >= 400) { + if (status > 403) { // try one more time as a GET in case HEAD is rejected for whatever reason startTime = performance.now(); [status] = await httpProxy(pingURL); diff --git a/src/pages/index.jsx b/src/pages/index.jsx index fc294c6c..55109be9 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -318,15 +318,26 @@ function Home({ initialSettings }) { export default function Wrapper({ initialSettings, fallback }) { const wrappedStyle = {}; + let backgroundBlur = false; + let backgroundSaturate = false; + let backgroundBrightness = false; if (initialSettings && initialSettings.background) { - const opacity = initialSettings.backgroundOpacity ?? 1; + let opacity = initialSettings.backgroundOpacity ?? 1; + let backgroundImage = initialSettings.background; + if (typeof initialSettings.background === 'object') { + backgroundImage = initialSettings.background.image; + backgroundBlur = initialSettings.background.blur !== undefined; + backgroundSaturate = initialSettings.background.saturate !== undefined; + backgroundBrightness = initialSettings.background.brightness !== undefined; + if (initialSettings.background.opacity !== undefined) opacity = initialSettings.background.opacity / 100; + } const opacityValue = 1 - opacity; wrappedStyle.backgroundImage = ` linear-gradient( rgb(var(--bg-color) / ${opacityValue}), rgb(var(--bg-color) / ${opacityValue}) ), - url(${initialSettings.background})`; + url(${backgroundImage})`; wrappedStyle.backgroundPosition = "center"; wrappedStyle.backgroundSize = "cover"; } @@ -345,7 +356,15 @@ export default function Wrapper({ initialSettings, fallback }) { className="fixed overflow-auto w-full h-full bg-theme-50 dark:bg-theme-800 transition-all" style={wrappedStyle} > - +
+ +
); diff --git a/src/widgets/channelsdvrserver/component.jsx b/src/widgets/channelsdvrserver/component.jsx new file mode 100644 index 00000000..d989c9a8 --- /dev/null +++ b/src/widgets/channelsdvrserver/component.jsx @@ -0,0 +1,36 @@ +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: channelsData, error: channelsError } = useWidgetAPI(widget, "status"); + + if (channelsError) { + return ; + } + + if (!channelsData) { + return ( + + + + + + + ); + } + + return ( + + + + + + + ); +} diff --git a/src/widgets/channelsdvrserver/widget.js b/src/widgets/channelsdvrserver/widget.js new file mode 100644 index 00000000..bb945892 --- /dev/null +++ b/src/widgets/channelsdvrserver/widget.js @@ -0,0 +1,14 @@ +import genericProxyHandler from "utils/proxy/handlers/generic"; + +const widget = { + api: "{url}/{endpoint}", + proxyHandler: genericProxyHandler, + + mappings: { + status: { + endpoint: "dvr", + }, + }, +}; + +export default widget; diff --git a/src/widgets/components.js b/src/widgets/components.js index d5d1ecc2..1cbff2ae 100644 --- a/src/widgets/components.js +++ b/src/widgets/components.js @@ -7,6 +7,7 @@ const components = { autobrr: dynamic(() => import("./autobrr/component")), bazarr: dynamic(() => import("./bazarr/component")), changedetectionio: dynamic(() => import("./changedetectionio/component")), + channelsdvrserver: dynamic(() => import("./channelsdvrserver/component")), cloudflared: dynamic(() => import("./cloudflared/component")), coinmarketcap: dynamic(() => import("./coinmarketcap/component")), deluge: dynamic(() => import("./deluge/component")), @@ -17,6 +18,7 @@ const components = { emby: dynamic(() => import("./emby/component")), fileflows: dynamic(() => import("./fileflows/component")), flood: dynamic(() => import("./flood/component")), + freshrss: dynamic(() => import("./freshrss/component")), ghostfolio: dynamic(() => import("./ghostfolio/component")), gluetun: dynamic(() => import("./gluetun/component")), gotify: dynamic(() => import("./gotify/component")), diff --git a/src/widgets/freshrss/component.jsx b/src/widgets/freshrss/component.jsx new file mode 100644 index 00000000..9381beb1 --- /dev/null +++ b/src/widgets/freshrss/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: freshrssData, error: freshrssError } = useWidgetAPI(widget, "info"); + + if (freshrssError) { + return ; + } + + if (!freshrssData) { + return ( + + + + + ); + } + + return ( + + + + + ); +} diff --git a/src/widgets/freshrss/proxy.js b/src/widgets/freshrss/proxy.js new file mode 100644 index 00000000..a5f2239e --- /dev/null +++ b/src/widgets/freshrss/proxy.js @@ -0,0 +1,97 @@ +import cache from "memory-cache"; + +import { httpProxy } from "utils/proxy/http"; +import { formatApiCall } from "utils/proxy/api-helpers"; +import getServiceWidget from "utils/config/service-helpers"; +import createLogger from "utils/logger"; +import widgets from "widgets/widgets"; + +const proxyName = "freshrssProxyHandler"; +const sessionTokenCacheKey = `${proxyName}__sessionToken`; +const logger = createLogger(proxyName); + +async function login(widget, service) { + const endpoint = "accounts/ClientLogin"; + const api = widgets?.[widget.type]?.api + const loginUrl = new URL(formatApiCall(api, { endpoint, ...widget })); + const headers = { "Content-Type": "application/x-www-form-urlencoded" }; + + const [, , data,] = await httpProxy(loginUrl, { + method: "POST", + body: new URLSearchParams({ + Email: widget.username, + Passwd: widget.password + }).toString(), + headers, + }); + + try { + const [, token] = data.toString().split("\n").find(line => line.startsWith("Auth=")).split("=") + cache.put(`${sessionTokenCacheKey}.${service}`, token); + return { token }; + } catch (e) { + logger.error("Unable to login to FreshRSS API: %s", e); + } + + return { token: false }; +} + +async function apiCall(widget, endpoint, service) { + const key = `${sessionTokenCacheKey}.${service}`; + const headers = { + "Authorization": `GoogleLogin auth=${cache.get(key)}`, + } + const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget })); + const method = "GET"; + + let [status, contentType, data, responseHeaders] = await httpProxy(url, { + method, + headers, + }); + + if (status === 401) { + logger.debug("FreshRSS API rejected the request, attempting to obtain new session token"); + const { token } = await login(widget, service); + headers.Authorization = `GoogleLogin auth=${token}`; + + // retry the request, now with the new session token + [status, contentType, data, responseHeaders] = await httpProxy(url, { + method, + headers, + }); + } + + if (status !== 200) { + logger.error("Error getting data from FreshRSS: %s status %d. Data: %s", url, status, data); + return { status, contentType, data: null, responseHeaders }; + } + + return { status, contentType, data: JSON.parse(data.toString()), responseHeaders }; +} + +export default async function freshrssProxyHandler(req, res) { + const { group, service } = req.query; + + if (!group || !service) { + logger.debug("Invalid or missing service '%s' or group '%s'", service, group); + return res.status(400).json({ error: "Invalid proxy service type" }); + } + + const widget = await getServiceWidget(group, service); + if (!widget) { + logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group); + return res.status(400).json({ error: "Invalid proxy service type" }); + } + + if (!cache.get(`${sessionTokenCacheKey}.${service}`)) { + await login(widget, service); + } + + const { data: subscriptionData } = await apiCall(widget, "reader/api/0/subscription/list", service); + const { data: unreadCountData } = await apiCall(widget, "reader/api/0/unread-count", service); + + return res.status(200).send({ + subscriptions: subscriptionData?.subscriptions.length, + unread: unreadCountData?.max + }); +} diff --git a/src/widgets/freshrss/widget.js b/src/widgets/freshrss/widget.js new file mode 100644 index 00000000..2e025762 --- /dev/null +++ b/src/widgets/freshrss/widget.js @@ -0,0 +1,13 @@ +import freshrssProxyHandler from "./proxy"; + +const widget = { + api: "{url}/api/greader.php/{endpoint}?output=json", + proxyHandler: freshrssProxyHandler, + mappings: { + info: { + endpoint: "/" + } + } +}; + +export default widget; diff --git a/src/widgets/homebridge/proxy.js b/src/widgets/homebridge/proxy.js index 018aa78f..b0a75a03 100644 --- a/src/widgets/homebridge/proxy.js +++ b/src/widgets/homebridge/proxy.js @@ -52,7 +52,7 @@ async function apiCall(widget, endpoint, service) { if (status === 401 || status === 403) { logger.debug("Homebridge API rejected the request, attempting to obtain new session token"); - const { accessToken } = login(widget, service); + const { accessToken } = await login(widget, service); headers.Authorization = `Bearer ${accessToken}`; // retry the request, now with the new session token diff --git a/src/widgets/transmission/proxy.js b/src/widgets/transmission/proxy.js index 83ca141e..a57f2fb6 100644 --- a/src/widgets/transmission/proxy.js +++ b/src/widgets/transmission/proxy.js @@ -33,7 +33,9 @@ export default async function transmissionProxyHandler(req, res) { cache.put(`${headerCacheKey}.${service}`, headers); } - const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget })); + const api = `${widget.url}${widget.rpcUrl || widgets[widget.type].rpcUrl}rpc`; + + const url = new URL(formatApiCall(api, { endpoint, ...widget })); const csrfHeaderName = "x-transmission-session-id"; const method = "POST"; diff --git a/src/widgets/transmission/widget.js b/src/widgets/transmission/widget.js index 321f25ba..ef76046d 100644 --- a/src/widgets/transmission/widget.js +++ b/src/widgets/transmission/widget.js @@ -1,7 +1,7 @@ import transmissionProxyHandler from "./proxy"; const widget = { - api: "{url}/transmission/rpc", + rpcUrl: "/transmission/", proxyHandler: transmissionProxyHandler, }; diff --git a/src/widgets/widgets.js b/src/widgets/widgets.js index 6404b785..63d66590 100644 --- a/src/widgets/widgets.js +++ b/src/widgets/widgets.js @@ -4,6 +4,7 @@ import authentik from "./authentik/widget"; import autobrr from "./autobrr/widget"; import bazarr from "./bazarr/widget"; import changedetectionio from "./changedetectionio/widget"; +import channelsdvrserver from "./channelsdvrserver/widget"; import cloudflared from "./cloudflared/widget"; import coinmarketcap from "./coinmarketcap/widget"; import deluge from "./deluge/widget"; @@ -12,7 +13,8 @@ import downloadstation from "./downloadstation/widget"; import emby from "./emby/widget"; import fileflows from "./fileflows/widget"; import flood from "./flood/widget"; -import ghostfolio from "./ghostfolio/widget" +import freshrss from "./freshrss/widget"; +import ghostfolio from "./ghostfolio/widget"; import gluetun from "./gluetun/widget"; import gotify from "./gotify/widget"; import grafana from "./grafana/widget"; @@ -83,6 +85,7 @@ const widgets = { autobrr, bazarr, changedetectionio, + channelsdvrserver, cloudflared, coinmarketcap, deluge, @@ -91,6 +94,7 @@ const widgets = { emby, fileflows, flood, + freshrss, ghostfolio, gluetun, gotify,