Merge branch 'benphelps:main' into main

This commit is contained in:
Karl0ss 2023-07-06 07:58:51 +01:00 committed by GitHub
commit dd2b7df350
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 597 additions and 208 deletions

1
package-lock.json generated
View File

@ -21,7 +21,6 @@
"minecraft-ping-js": "^1.0.2", "minecraft-ping-js": "^1.0.2",
"next": "^12.3.1", "next": "^12.3.1",
"next-i18next": "^12.0.1", "next-i18next": "^12.0.1",
"osx-temperature-sensor": "*",
"pretty-bytes": "^6.0.0", "pretty-bytes": "^6.0.0",
"raw-body": "^2.5.1", "raw-body": "^2.5.1",
"react": "^18.2.0", "react": "^18.2.0",

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadCount": "Queue Count", "downloadCount": "Queue Count",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadCount": "Queue Count", "downloadCount": "Queue Count",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

4
public/locales/en/common.json Executable file → Normal file
View File

@ -659,5 +659,9 @@
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size", "downloadTotalBytes": "Size",
"downloadSpeed": "Speed" "downloadSpeed": "Speed"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -646,9 +646,13 @@
"down_alerts": "Alertas" "down_alerts": "Alertas"
}, },
"jdownloader": { "jdownloader": {
"downloadCount": "Recuento de las colas", "downloadCount": "Cola",
"downloadSpeed": "Velocidad de Descarga", "downloadSpeed": "Velocidad",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Restante",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Tamaño"
},
"kavita": {
"seriesCount": "Serie",
"totalFiles": "Archivos"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -5,8 +5,8 @@
"status": "Statut", "status": "Statut",
"information": "Information", "information": "Information",
"url": "URL", "url": "URL",
"raw_error": "Raw Error", "raw_error": "Erreur brute",
"response_data": "Response Data" "response_data": "Données de réponse"
}, },
"search": { "search": {
"placeholder": "Recherche…" "placeholder": "Recherche…"
@ -578,7 +578,7 @@
"homeassistant": { "homeassistant": {
"people_home": "People Home", "people_home": "People Home",
"lights_on": "Lumières allumées", "lights_on": "Lumières allumées",
"switches_on": "Switches On" "switches_on": "Commutateur On"
}, },
"freshrss": { "freshrss": {
"unread": "Non lu", "unread": "Non lu",
@ -648,7 +648,11 @@
"jdownloader": { "jdownloader": {
"downloadCount": "Total en attente", "downloadCount": "Total en attente",
"downloadSpeed": "Vitesse de téléchargement", "downloadSpeed": "Vitesse de téléchargement",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Restant",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Taille"
},
"kavita": {
"seriesCount": "Séries",
"totalFiles": "Fichiers"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -126,21 +126,21 @@
"wanted": "Zatraženo", "wanted": "Zatraženo",
"queued": "U redu čekanja", "queued": "U redu čekanja",
"series": "Serije", "series": "Serije",
"unknown": "Unknown", "unknown": "Nepoznato",
"queue": "Queue" "queue": "Red čekanja"
}, },
"radarr": { "radarr": {
"wanted": "Zatraženo", "wanted": "Zatraženo",
"queued": "U redu čekanja", "queued": "U redu čekanja",
"movies": "Filmovi", "movies": "Filmovi",
"missing": "Nedostaje", "missing": "Nedostaje",
"queue": "Queue", "queue": "Red čekanja",
"unknown": "Unknown" "unknown": "Nepoznato"
}, },
"lidarr": { "lidarr": {
"wanted": "Zatraženo", "wanted": "Zatraženo",
"queued": "U redu čekanja", "queued": "U redu čekanja",
"artists": "Artists" "artists": "Umjetnici"
}, },
"readarr": { "readarr": {
"wanted": "Zatraženo", "wanted": "Zatraženo",
@ -646,9 +646,13 @@
"down_alerts": "Obavijest o rušenju" "down_alerts": "Obavijest o rušenju"
}, },
"jdownloader": { "jdownloader": {
"downloadCount": "Queue Count", "downloadCount": "Red čekanja",
"downloadSpeed": "Download Speed", "downloadSpeed": "Brzina",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Preostalo",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Veličina"
},
"kavita": {
"seriesCount": "Serije",
"totalFiles": "Datoteke"
} }
} }

View File

@ -67,10 +67,10 @@
"transcoding": "Átkódolás", "transcoding": "Átkódolás",
"bitrate": "Bitráta", "bitrate": "Bitráta",
"no_active": "Nincs aktív lejátszás", "no_active": "Nincs aktív lejátszás",
"movies": "Movies", "movies": "Film",
"series": "Series", "series": "Sorozat",
"episodes": "Episodes", "episodes": "Epizód",
"songs": "Songs" "songs": "Zeneszám"
}, },
"tautulli": { "tautulli": {
"playing": "Lejátszás folyamatban", "playing": "Lejátszás folyamatban",
@ -254,16 +254,16 @@
"diffsDetected": "Diffs Detected" "diffsDetected": "Diffs Detected"
}, },
"wmo": { "wmo": {
"0-day": "Sunny", "0-day": "Napos",
"0-night": "Clear", "0-night": "Derült",
"3-day": "Cloudy", "3-day": "Cloudy",
"3-night": "Cloudy", "3-night": "Cloudy",
"45-day": "Foggy", "45-day": "Foggy",
"53-day": "Drizzle", "53-day": "Drizzle",
"56-night": "Light Freezing Drizzle", "56-night": "Light Freezing Drizzle",
"57-day": "Freezing Drizzle", "57-day": "Freezing Drizzle",
"1-day": "Mainly Sunny", "1-day": "Többnyire napos",
"1-night": "Mainly Clear", "1-night": "Többnyire derült",
"2-day": "Partly Cloudy", "2-day": "Partly Cloudy",
"2-night": "Partly Cloudy", "2-night": "Partly Cloudy",
"45-night": "Foggy", "45-night": "Foggy",
@ -373,7 +373,7 @@
"hd": "HD" "hd": "HD"
}, },
"ping": { "ping": {
"error": "Error", "error": "Hiba",
"ping": "Ping" "ping": "Ping"
}, },
"scrutiny": { "scrutiny": {
@ -570,10 +570,10 @@
"gross_percent_max": "All time" "gross_percent_max": "All time"
}, },
"audiobookshelf": { "audiobookshelf": {
"podcasts": "Podcasts", "podcasts": "Podcast",
"books": "Books", "books": "Könyv",
"podcastsDuration": "Duration", "podcastsDuration": "Időtartam",
"booksDuration": "Duration" "booksDuration": "Időtartam"
}, },
"homeassistant": { "homeassistant": {
"people_home": "People Home", "people_home": "People Home",
@ -650,5 +650,9 @@
"downloadCount": "Queue Count", "downloadCount": "Queue Count",
"downloadTotalBytes": "Size", "downloadTotalBytes": "Size",
"downloadBytesRemaining": "Remaining" "downloadBytesRemaining": "Remaining"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -7,12 +7,12 @@
"rx": "RX", "rx": "RX",
"error": "Errore", "error": "Errore",
"unknown": "Sconosciuto", "unknown": "Sconosciuto",
"running": "Running", "running": "In esecuzione",
"starting": "Starting", "starting": "In avvio",
"unhealthy": "Unhealthy", "unhealthy": "Unhealthy",
"not_found": "Not Found", "not_found": "Non trovato",
"exited": "Exited", "exited": "Uscito",
"partial": "Partial", "partial": "Parziale",
"healthy": "Healthy" "healthy": "Healthy"
}, },
"emby": { "emby": {
@ -20,10 +20,10 @@
"transcoding": "Transcodifica", "transcoding": "Transcodifica",
"bitrate": "Bitrate", "bitrate": "Bitrate",
"no_active": "Nessuno Stream Attivo", "no_active": "Nessuno Stream Attivo",
"movies": "Movies", "movies": "Film",
"series": "Series", "series": "Serie",
"episodes": "Episodes", "episodes": "Episodi",
"songs": "Songs" "songs": "Canzoni"
}, },
"tautulli": { "tautulli": {
"playing": "In riproduzione", "playing": "In riproduzione",
@ -82,16 +82,16 @@
"series": "Serie", "series": "Serie",
"wanted": "Richiesti", "wanted": "Richiesti",
"queued": "In coda", "queued": "In coda",
"queue": "Queue", "queue": "Coda",
"unknown": "Unknown" "unknown": "Sconosciuto"
}, },
"radarr": { "radarr": {
"wanted": "Richiesti", "wanted": "Richiesti",
"queued": "In coda", "queued": "In coda",
"movies": "Film", "movies": "Film",
"missing": "Mancanti", "missing": "Mancanti",
"queue": "Queue", "queue": "Coda",
"unknown": "Unknown" "unknown": "Sconosciuto"
}, },
"readarr": { "readarr": {
"wanted": "Richiesti", "wanted": "Richiesti",
@ -112,7 +112,7 @@
"queries": "Richieste", "queries": "Richieste",
"blocked": "Bloccati", "blocked": "Bloccati",
"gravity": "Severità", "gravity": "Severità",
"blocked_percent": "Blocked %" "blocked_percent": "Bloccato %"
}, },
"npm": { "npm": {
"enabled": "Attivi", "enabled": "Attivi",
@ -175,9 +175,9 @@
"missingMovies": "Film Mancanti" "missingMovies": "Film Mancanti"
}, },
"lidarr": { "lidarr": {
"wanted": "Mancanti", "wanted": "Richiesto",
"queued": "In coda", "queued": "In coda",
"artists": "Artists" "artists": "Artisti"
}, },
"adguard": { "adguard": {
"queries": "Interrogazioni", "queries": "Interrogazioni",
@ -228,13 +228,13 @@
"devices": "Dispositivi", "devices": "Dispositivi",
"lan_devices": "Dispositivi LAN", "lan_devices": "Dispositivi LAN",
"wlan_devices": "Dispositivi WLAN", "wlan_devices": "Dispositivi WLAN",
"empty_data": "Subsystem status unknown" "empty_data": "Stato del sottosistema sconosciuto"
}, },
"plex": { "plex": {
"streams": "Trasmissioni attive", "streams": "Trasmissioni attive",
"movies": "Film", "movies": "Film",
"tv": "Programma televisivo", "tv": "Programma televisivo",
"albums": "Albums" "albums": "Album"
}, },
"glances": { "glances": {
"cpu": "CPU", "cpu": "CPU",
@ -243,11 +243,11 @@
"uptime": "UP", "uptime": "UP",
"days": "d", "days": "d",
"hours": "h", "hours": "h",
"load": "Load", "load": "Carico",
"warn": "Warn", "warn": "Avviso",
"total": "Total", "total": "Totale",
"free": "Free", "free": "Libero",
"used": "Used" "used": "Usato"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Totale Osservato", "totalObserved": "Totale Osservato",
@ -314,9 +314,9 @@
"quicklaunch": { "quicklaunch": {
"bookmark": "Segnalibro", "bookmark": "Segnalibro",
"service": "Servizio", "service": "Servizio",
"search": "Search", "search": "Cerca",
"custom": "Custom", "custom": "Personalizzato",
"visit": "Visit", "visit": "Visita",
"url": "URL" "url": "URL"
}, },
"homebridge": { "homebridge": {
@ -327,7 +327,7 @@
"child_bridges": "Child Bridges", "child_bridges": "Child Bridges",
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "In attesa",
"down": "Down" "down": "Down"
}, },
"autobrr": { "autobrr": {
@ -432,7 +432,7 @@
"cpuLoad": "Carico della CPU", "cpuLoad": "Carico della CPU",
"memoryUsed": "Memoria Utilizzata", "memoryUsed": "Memoria Utilizzata",
"uptime": "Tempo di attività", "uptime": "Tempo di attività",
"numberOfLeases": "Lease" "numberOfLeases": "Rilasci"
}, },
"xteve": { "xteve": {
"streams_all": "Tutti gli stream", "streams_all": "Tutti gli stream",
@ -440,215 +440,219 @@
"streams_xepg": "Canali XEPG" "streams_xepg": "Canali XEPG"
}, },
"opnsense": { "opnsense": {
"cpu": "Carico CPU", "cpu": "Carico della CPU",
"memory": "Memoria in uso", "memory": "Memoria in uso",
"wanUpload": "WAN Upload", "wanUpload": "WAN Upload",
"wanDownload": "WAN Download" "wanDownload": "WAN Download"
}, },
"moonraker": { "moonraker": {
"printer_state": "Printer State", "printer_state": "Stato stampante",
"print_status": "Print Status", "print_status": "Stato Stampante",
"print_progress": "Progress", "print_progress": "Avanzamento",
"layers": "Layers" "layers": "Livelli"
}, },
"medusa": { "medusa": {
"wanted": "Wanted", "wanted": "Richiesto",
"queued": "Queued", "queued": "In coda",
"series": "Series" "series": "Serie"
}, },
"octoprint": { "octoprint": {
"printer_state": "Status", "printer_state": "Stato",
"temp_tool": "Tool temp", "temp_tool": "Tool temp",
"temp_bed": "Bed temp", "temp_bed": "Bed temp",
"job_completion": "Completion" "job_completion": "Completamento"
}, },
"cloudflared": { "cloudflared": {
"origin_ip": "Origin IP", "origin_ip": "IP sorgente",
"status": "Status" "status": "Stato"
}, },
"proxmoxbackupserver": { "proxmoxbackupserver": {
"datastore_usage": "Datastore", "datastore_usage": "Datastore",
"failed_tasks_24h": "Failed Tasks 24h", "failed_tasks_24h": "Attività Non Riuscite 24h",
"cpu_usage": "CPU", "cpu_usage": "CPU",
"memory_usage": "Memory" "memory_usage": "Memoria"
}, },
"immich": { "immich": {
"users": "Users", "users": "Utenti",
"photos": "Photos", "photos": "Foto",
"videos": "Videos", "videos": "Video",
"storage": "Storage" "storage": "Memoria"
}, },
"uptimekuma": { "uptimekuma": {
"up": "Sites Up", "up": "Siti On",
"down": "Sites Down", "down": "Siti Down",
"uptime": "Uptime", "uptime": "Uptime",
"incident": "Incident", "incident": "Incidente",
"m": "m" "m": "m"
}, },
"komga": { "komga": {
"libraries": "Libraries", "libraries": "Librerie",
"series": "Series", "series": "Serie",
"books": "Books" "books": "Libri"
}, },
"mylar": { "mylar": {
"series": "Series", "series": "Serie",
"issues": "Issues", "issues": "Problemi",
"wanted": "Wanted" "wanted": "Richiesto"
}, },
"photoprism": { "photoprism": {
"albums": "Albums", "albums": "Album",
"photos": "Photos", "photos": "Foto",
"videos": "Videos", "videos": "Video",
"people": "People" "people": "Persone"
}, },
"diskstation": { "diskstation": {
"days": "Days", "days": "Giorni",
"uptime": "Uptime", "uptime": "Uptime",
"volumeAvailable": "Available" "volumeAvailable": "Disponibile"
}, },
"fileflows": { "fileflows": {
"queue": "Queue", "queue": "Coda",
"processing": "Processing", "processing": "In Lavorazione",
"processed": "Processed", "processed": "Elaborato",
"time": "Time" "time": "Tempo"
}, },
"grafana": { "grafana": {
"dashboards": "Dashboards", "dashboards": "Dashboards",
"datasources": "Data Sources", "datasources": "Origine dei Dati",
"totalalerts": "Total Alerts", "totalalerts": "Avvisi Totali",
"alertstriggered": "Alerts Triggered" "alertstriggered": "Avvisi Attivati"
}, },
"nextcloud": { "nextcloud": {
"memoryusage": "Memory Usage", "memoryusage": "Uso della Memoria",
"cpuload": "Cpu Load", "cpuload": "Carico della CPU",
"freespace": "Free Space", "freespace": "Spazio Libero",
"activeusers": "Active Users", "activeusers": "Utenti Attivi",
"numfiles": "Files", "numfiles": "File",
"numshares": "Shared Items" "numshares": "Oggetti Condivisi"
}, },
"kopia": { "kopia": {
"status": "Status", "status": "Stato",
"size": "Size", "size": "Dimensione",
"lastrun": "Last Run", "lastrun": "Ultima esecuzione",
"nextrun": "Next Run", "nextrun": "Prossima esecuzione",
"failed": "Failed" "failed": "Fallito"
}, },
"unmanic": { "unmanic": {
"active_workers": "Active Workers", "active_workers": "Lavoratori Attivi",
"total_workers": "Total Workers", "total_workers": "Lavoratori Totali",
"records_total": "Queue Length" "records_total": "Lunghezza della Coda"
}, },
"healthchecks": { "healthchecks": {
"new": "New", "new": "Nuovo",
"up": "Online", "up": "Online",
"grace": "In Grace Period", "grace": "Periodo di Tolleranza",
"down": "Offline", "down": "Offline",
"paused": "Paused", "paused": "In Pausa",
"status": "Status", "status": "Stato",
"last_ping": "Last Ping", "last_ping": "Ultimo Ping",
"never": "No pings yet" "never": "Ancora nessun ping"
}, },
"pterodactyl": { "pterodactyl": {
"servers": "Servers", "servers": "Server",
"nodes": "Nodes" "nodes": "Nodi"
}, },
"prometheus": { "prometheus": {
"targets_up": "Targets Up", "targets_up": "Targets Up",
"targets_down": "Targets Down", "targets_down": "Targets Down",
"targets_total": "Total Targets" "targets_total": "Targets Totali"
}, },
"minecraft": { "minecraft": {
"players": "Players", "players": "Giocatori",
"version": "Version", "version": "Versione",
"status": "Status", "status": "Stato",
"up": "Online", "up": "Online",
"down": "Offline" "down": "Offline"
}, },
"ghostfolio": { "ghostfolio": {
"gross_percent_today": "Today", "gross_percent_today": "Oggi",
"gross_percent_1y": "One year", "gross_percent_1y": "Un anno",
"gross_percent_max": "All time" "gross_percent_max": "Sempre"
}, },
"audiobookshelf": { "audiobookshelf": {
"podcasts": "Podcasts", "podcasts": "Podcast",
"books": "Books", "books": "Libri",
"podcastsDuration": "Duration", "podcastsDuration": "Durata",
"booksDuration": "Duration" "booksDuration": "Durata"
}, },
"homeassistant": { "homeassistant": {
"people_home": "People Home", "people_home": "Persone a Casa",
"lights_on": "Lights On", "lights_on": "Luci Accese",
"switches_on": "Switches On" "switches_on": "Switch Accesi"
}, },
"freshrss": { "freshrss": {
"subscriptions": "Subscriptions", "subscriptions": "Iscrizioni",
"unread": "Unread" "unread": "Non letto"
}, },
"channelsdvrserver": { "channelsdvrserver": {
"shows": "Shows", "shows": "Spettacoli",
"recordings": "Recordings", "recordings": "Registrazioni",
"scheduled": "Scheduled", "scheduled": "Programmati",
"passes": "Passes" "passes": "Tessere"
}, },
"whatsupdocker": { "whatsupdocker": {
"monitoring": "Monitoring", "monitoring": "Monitoraggio",
"updates": "Updates" "updates": "Aggiornamenti"
}, },
"tailscale": { "tailscale": {
"never": "Never", "never": "Mai",
"address": "Address", "address": "Indirizzo",
"expires": "Expires", "expires": "Scade",
"last_seen": "Last Seen", "last_seen": "Ultima visualizzazione",
"now": "Now", "now": "Adesso",
"years": "{{number}}y", "years": "{{number}}y",
"weeks": "{{number}}w", "weeks": "{{number}}w",
"hours": "{{number}}h", "hours": "{{number}}h",
"minutes": "{{number}}m", "minutes": "{{number}}m",
"seconds": "{{number}}s", "seconds": "{{number}}s",
"ago": "{{value}} Ago", "ago": "{{value}} Fa",
"days": "{{number}}d" "days": "{{number}}d"
}, },
"qnap": { "qnap": {
"cpuUsage": "CPU Usage", "cpuUsage": "Utilizzo CPU",
"memUsage": "MEM Usage", "memUsage": "Utilizzo MEM",
"systemTempC": "System Temp", "systemTempC": "Temp sistema",
"poolUsage": "Pool Usage", "poolUsage": "Utilizzo Pool",
"volumeUsage": "Volume Usage", "volumeUsage": "Utilizzo Volume",
"invalid": "Invalid" "invalid": "Invalido"
}, },
"pfsense": { "pfsense": {
"load": "Load Avg", "load": "Carico Medio",
"memory": "Mem Usage", "memory": "Uso Memoria",
"wanStatus": "WAN Status", "wanStatus": "Stato WAN",
"up": "Up", "up": "Up",
"down": "Down", "down": "Down",
"temp": "Temp", "temp": "Temperatura",
"disk": "Disk Usage", "disk": "Uso Disco",
"wanIP": "WAN IP" "wanIP": "IP WAN"
}, },
"caddy": { "caddy": {
"upstreams": "Upstreams", "upstreams": "Upstream",
"requests": "Current requests", "requests": "Richieste correnti",
"requests_failed": "Failed requests" "requests_failed": "Richieste fallite"
}, },
"evcc": { "evcc": {
"pv_power": "Production", "pv_power": "Produzione",
"battery_soc": "Battery", "battery_soc": "Batteria",
"grid_power": "Grid", "grid_power": "Griglia",
"home_power": "Consumption", "home_power": "Consumo",
"charge_power": "Charger", "charge_power": "Caricatore",
"watt_hour": "Wh" "watt_hour": "Wh"
}, },
"pialert": { "pialert": {
"total": "Total", "total": "Totali",
"connected": "Connected", "connected": "Connesso",
"new_devices": "New Devices", "new_devices": "Nuovi Dispositivi",
"down_alerts": "Down Alerts" "down_alerts": "Avvisi di Disservizio"
}, },
"jdownloader": { "jdownloader": {
"downloadCount": "Queue Count", "downloadCount": "Coda",
"downloadSpeed": "Download Speed", "downloadSpeed": "Velocità Download",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Residuo",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Dimensione"
},
"kavita": {
"seriesCount": "Serie",
"totalFiles": "File"
} }
} }

View File

@ -239,7 +239,7 @@
"queries": "クエリ", "queries": "クエリ",
"blocked": "ブロック中", "blocked": "ブロック中",
"gravity": "グラビティ", "gravity": "グラビティ",
"blocked_percent": "Blocked %" "blocked_percent": "ブロック %"
}, },
"adguard": { "adguard": {
"queries": "クエリ", "queries": "クエリ",
@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -659,5 +659,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"totalFiles": "Files",
"seriesCount": "Series"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"totalFiles": "Files",
"seriesCount": "Series"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -646,9 +646,13 @@
"down_alerts": "Сповіщення про збій" "down_alerts": "Сповіщення про збій"
}, },
"jdownloader": { "jdownloader": {
"downloadCount": "Всього в черзі", "downloadCount": "Черга",
"downloadSpeed": "Швидкість завантаження", "downloadSpeed": "Швидкість",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Залишилося",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Розмір"
},
"kavita": {
"seriesCount": "Серій",
"totalFiles": "Файлів"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -632,7 +632,7 @@
"requests_failed": "失败请求" "requests_failed": "失败请求"
}, },
"evcc": { "evcc": {
"pv_power": "Production", "pv_power": "正式环境",
"battery_soc": "Battery", "battery_soc": "Battery",
"grid_power": "Grid", "grid_power": "Grid",
"home_power": "Consumption", "home_power": "Consumption",
@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -650,5 +650,9 @@
"downloadSpeed": "Download Speed", "downloadSpeed": "Download Speed",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
},
"kavita": {
"seriesCount": "Series",
"totalFiles": "Files"
} }
} }

View File

@ -1,13 +1,41 @@
import classNames from "classnames";
import { Disclosure, Transition } from '@headlessui/react';
import { MdKeyboardArrowDown } from "react-icons/md";
import ErrorBoundary from "components/errorboundry"; import ErrorBoundary from "components/errorboundry";
import List from "components/bookmarks/list"; import List from "components/bookmarks/list";
export default function BookmarksGroup({ group }) { export default function BookmarksGroup({ group, disableCollapse }) {
return ( return (
<div key={group.name} className="flex-1"> <div key={group.name} className="flex-1">
<h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium">{group.name}</h2> <Disclosure defaultOpen>
<ErrorBoundary> {({ open }) => (
<List bookmarks={group.bookmarks} /> <>
</ErrorBoundary> <Disclosure.Button disabled={disableCollapse} className="flex w-full select-none items-center group">
<h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium">{group.name}</h2>
<MdKeyboardArrowDown className={classNames(
disableCollapse ? 'hidden' : '',
'transition-opacity opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl',
open ? 'rotate-180 transform' : ''
)} />
</Disclosure.Button>
<Transition
enter="transition duration-200 ease-out"
enterFrom="transform scale-75 opacity-0"
enterTo="transform scale-100 opacity-100"
leave="transition duration-75 ease-out"
leaveFrom="transform scale-100 opacity-100"
leaveTo="transform scale-75 opacity-0"
>
<Disclosure.Panel>
<ErrorBoundary>
<List bookmarks={group.bookmarks} />
</ErrorBoundary>
</Disclosure.Panel>
</Transition>
</>
)}
</Disclosure>
</div> </div>
); );
} }

View File

@ -1,9 +1,12 @@
import classNames from "classnames"; import classNames from "classnames";
import { Disclosure, Transition } from '@headlessui/react';
import { MdKeyboardArrowDown } from "react-icons/md";
import List from "components/services/list"; import List from "components/services/list";
import ResolvedIcon from "components/resolvedicon"; import ResolvedIcon from "components/resolvedicon";
export default function ServicesGroup({ group, services, layout, fiveColumns }) { export default function ServicesGroup({ group, services, layout, fiveColumns, disableCollapse }) {
return ( return (
<div <div
key={services.name} key={services.name}
@ -13,15 +16,37 @@ export default function ServicesGroup({ group, services, layout, fiveColumns })
"flex-1 p-1" "flex-1 p-1"
)} )}
> >
<div className="flex select-none items-center"> <Disclosure defaultOpen>
{layout?.icon && {({ open }) => (
<div className="flex-shrink-0 mr-2 w-7 h-7"> <>
<ResolvedIcon icon={layout.icon} /> <Disclosure.Button disabled={disableCollapse} className="flex w-full select-none items-center group">
</div> {layout?.icon &&
} <div className="flex-shrink-0 mr-2 w-7 h-7">
<h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium">{services.name}</h2> <ResolvedIcon icon={layout.icon} />
</div> </div>
<List group={group} services={services.services} layout={layout} /> }
<h2 className="flex text-theme-800 dark:text-theme-300 text-xl font-medium">{services.name}</h2>
<MdKeyboardArrowDown className={classNames(
disableCollapse ? 'hidden' : '',
'transition-opacity opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl',
open ? 'rotate-180 transform' : ''
)} />
</Disclosure.Button>
<Transition
enter="transition duration-200 ease-out"
enterFrom="transform scale-75 opacity-0"
enterTo="transform scale-100 opacity-100"
leave="transition duration-75 ease-out"
leaveFrom="transform scale-100 opacity-100"
leaveTo="transform scale-75 opacity-0"
>
<Disclosure.Panel>
<List group={group} services={services.services} layout={layout} />
</Disclosure.Panel>
</Transition>
</>
)}
</Disclosure>
</div> </div>
); );
} }

View File

@ -294,7 +294,13 @@ function Home({ initialSettings }) {
{services?.length > 0 && ( {services?.length > 0 && (
<div className="flex flex-wrap p-4 sm:p-8 sm:pt-4 items-start pb-2"> <div className="flex flex-wrap p-4 sm:p-8 sm:pt-4 items-start pb-2">
{services.map((group) => ( {services.map((group) => (
<ServicesGroup key={group.name} group={group.name} services={group} layout={initialSettings.layout?.[group.name]} fiveColumns={settings.fiveColumns} /> <ServicesGroup
key={group.name}
group={group.name}
services={group}
layout={initialSettings.layout?.[group.name]}
fiveColumns={settings.fiveColumns}
disableCollapse={settings.disableCollapse} />
))} ))}
</div> </div>
)} )}
@ -302,7 +308,10 @@ function Home({ initialSettings }) {
{bookmarks?.length > 0 && ( {bookmarks?.length > 0 && (
<div className={`grow flex flex-wrap pt-0 p-4 sm:p-8 gap-2 grid-cols-1 lg:grid-cols-2 lg:grid-cols-${Math.min(6, bookmarks.length)}`}> <div className={`grow flex flex-wrap pt-0 p-4 sm:p-8 gap-2 grid-cols-1 lg:grid-cols-2 lg:grid-cols-${Math.min(6, bookmarks.length)}`}>
{bookmarks.map((group) => ( {bookmarks.map((group) => (
<BookmarksGroup key={group.name} group={group} /> <BookmarksGroup
key={group.name}
group={group}
disableCollapse={settings.disableCollapse} />
))} ))}
</div> </div>
)} )}

View File

@ -291,8 +291,15 @@ export function cleanServiceGroups(groups) {
enableQueue, // sonarr/radarr enableQueue, // sonarr/radarr
} = cleanedService.widget; } = cleanedService.widget;
const fieldsList = typeof fields === 'string' ? JSON.parse(fields) : fields; let fieldsList = fields;
if (typeof fields === 'string') {
try { JSON.parse(fields) }
catch (e) {
logger.error("Invalid fields list detected in config for service '%s'", service.name);
fieldsList = null;
}
}
cleanedService.widget = { cleanedService.widget = {
type, type,
fields: fieldsList || null, fields: fieldsList || null,

View File

@ -1,6 +1,6 @@
/* eslint-disable prefer-promise-reject-errors */ /* eslint-disable prefer-promise-reject-errors */
/* eslint-disable no-param-reassign */ /* eslint-disable no-param-reassign */
import { createUnzip } from "node:zlib"; import { createUnzip, constants as zlibConstants } from "node:zlib";
import { http, https } from "follow-redirects"; import { http, https } from "follow-redirects";
@ -34,7 +34,14 @@ function handleRequest(requestor, url, params) {
let responseContent = response; let responseContent = response;
if (contentEncoding === 'gzip' || contentEncoding === 'deflate') { if (contentEncoding === 'gzip' || contentEncoding === 'deflate') {
responseContent = createUnzip(); // https://github.com/request/request/blob/3c0cddc7c8eb60b470e9519da85896ed7ee0081e/request.js#L1018-L1025
// Be more lenient with decoding compressed responses, in case of invalid gzip responses that are still accepted
// by common browsers.
responseContent = createUnzip({
flush: zlibConstants.Z_SYNC_FLUSH,
finishFlush: zlibConstants.Z_SYNC_FLUSH
});
// zlib errors // zlib errors
responseContent.on("error", (e) => { responseContent.on("error", (e) => {
logger.error(e); logger.error(e);
@ -103,6 +110,6 @@ export async function httpProxy(url, params = {}) {
constructedUrl.pathname constructedUrl.pathname
); );
logger.error(err); logger.error(err);
return [500, "application/json", { error: {message: err?.message ?? "Unknown error", url, rawError: err} }, null]; return [500, "application/json", { error: { message: err?.message ?? "Unknown error", url, rawError: err } }, null];
} }
} }

View File

@ -34,6 +34,7 @@ const components = {
jdownloader: dynamic(() => import("./jdownloader/component")), jdownloader: dynamic(() => import("./jdownloader/component")),
jellyfin: dynamic(() => import("./emby/component")), jellyfin: dynamic(() => import("./emby/component")),
jellyseerr: dynamic(() => import("./jellyseerr/component")), jellyseerr: dynamic(() => import("./jellyseerr/component")),
kavita: dynamic(() => import("./kavita/component")),
komga: dynamic(() => import("./komga/component")), komga: dynamic(() => import("./komga/component")),
kopia: dynamic(() => import("./kopia/component")), kopia: dynamic(() => import("./kopia/component")),
lidarr: dynamic(() => import("./lidarr/component")), lidarr: dynamic(() => import("./lidarr/component")),
@ -94,4 +95,4 @@ const components = {
xteve: dynamic(() => import("./xteve/component")), xteve: dynamic(() => import("./xteve/component")),
}; };
export default components; export default components;

View File

@ -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: kavitaData, error: kavitaError } = useWidgetAPI(widget, "info");
if (kavitaError) {
return <Container service={service} error={kavitaError} />;
}
if (!kavitaData) {
return (
<Container service={service}>
<Block label="kavita.seriesCount" />
<Block label="kavita.totalFiles" />
</Container>
);
}
return (
<Container service={service}>
<Block label="kavita.seriesCount" value={t("common.number", { value: kavitaData.seriesCount })} />
<Block label="kavita.totalFiles" value={t("common.number", { value: kavitaData.totalFiles })} />
</Container>
);
}

View File

@ -0,0 +1,96 @@
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 = "kavitaProxyHandler";
const sessionTokenCacheKey = `${proxyName}__sessionToken`;
const logger = createLogger(proxyName);
async function login(widget, service) {
const endpoint = "Account/login";
const api = widgets?.[widget.type]?.api
const loginUrl = new URL(formatApiCall(api, { endpoint, ...widget }));
const loginBody = { username: widget.username, password: widget.password };
const headers = { "Content-Type": "application/json", "accept": "text/plain" };
const [, , data,] = await httpProxy(loginUrl, {
method: "POST",
body: JSON.stringify(loginBody),
headers,
});
try {
const { token: accessToken } = JSON.parse(data.toString());
cache.put(`${sessionTokenCacheKey}.${service}`, accessToken);
return { accessToken };
} catch (e) {
logger.error("Unable to login to Kavita API: %s", e);
}
return { token: false };
}
async function apiCall(widget, endpoint, service) {
const key = `${sessionTokenCacheKey}.${service}`;
const headers = {
"content-type": "application/json",
"Authorization": `Bearer ${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 || status === 403) {
logger.debug("Kavita API rejected the request, attempting to obtain new session token");
const { accessToken } = await login(widget, service);
headers.Authorization = `Bearer ${accessToken}`;
// 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 Kavita: %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 KavitaProxyHandler(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: statsData } = await apiCall(widget, "Stats/server/stats", service);
return res.status(200).send({
seriesCount: statsData?.seriesCount,
totalFiles: statsData?.totalFiles
});
}

View File

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

View File

@ -28,6 +28,7 @@ import immich from "./immich/widget";
import jackett from "./jackett/widget"; import jackett from "./jackett/widget";
import jellyseerr from "./jellyseerr/widget"; import jellyseerr from "./jellyseerr/widget";
import jdownloader from "./jdownloader/widget"; import jdownloader from "./jdownloader/widget";
import kavita from "./kavita/widget";
import komga from "./komga/widget"; import komga from "./komga/widget";
import kopia from "./kopia/widget"; import kopia from "./kopia/widget";
import lidarr from "./lidarr/widget"; import lidarr from "./lidarr/widget";
@ -104,7 +105,7 @@ const widgets = {
diskstation, diskstation,
downloadstation, downloadstation,
emby, emby,
evcc, evcc,
fileflows, fileflows,
flood, flood,
freshrss, freshrss,
@ -123,6 +124,7 @@ const widgets = {
jdrssdownloader, jdrssdownloader,
jdownloader, jdownloader,
jellyseerr, jellyseerr,
kavita,
komga, komga,
kopia, kopia,
lidarr, lidarr,

View File

@ -9,6 +9,11 @@ module.exports = {
"./src/components/**/*.{js,ts,jsx,tsx}", "./src/components/**/*.{js,ts,jsx,tsx}",
"./src/widgets/**/*.{js,ts,jsx,tsx}", "./src/widgets/**/*.{js,ts,jsx,tsx}",
], ],
variants: {
extend: {
display: ["group-hover"],
},
},
theme: { theme: {
extend: { extend: {
colors: { colors: {