This commit is contained in:
Michael Shamoon 2022-11-20 23:59:13 -08:00
commit e4c0a62fd9
37 changed files with 406 additions and 116 deletions

View File

@ -103,7 +103,9 @@
"tx": "TX", "tx": "TX",
"mem": "الرام", "mem": "الرام",
"cpu": "المعالج", "cpu": "المعالج",
"offline": "غير متصل" "offline": "غير متصل",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "يعمل الان", "playing": "يعمل الان",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -55,7 +55,9 @@
"rx": "RX", "rx": "RX",
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "CPU" "cpu": "CPU",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Възпроизвежда", "playing": "Възпроизвежда",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"ping": "Ping",
"error": "Error"
} }
} }

View File

@ -45,7 +45,9 @@
"tx": "Transmès", "tx": "Transmès",
"mem": "Memòria", "mem": "Memòria",
"cpu": "Processador", "cpu": "Processador",
"offline": "Fora de línia" "offline": "Fora de línia",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Reproduint", "playing": "Reproduint",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -57,7 +57,9 @@
"tx": "TX", "tx": "TX",
"mem": "RAM", "mem": "RAM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Offline" "offline": "Offline",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Přehrává", "playing": "Přehrává",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -181,7 +181,9 @@
"rx": "RX", "rx": "RX",
"tx": "TX", "tx": "TX",
"mem": "RAM", "mem": "RAM",
"offline": "Offline" "offline": "Offline",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Afspiller", "playing": "Afspiller",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -23,7 +23,9 @@
"tx": "Tx", "tx": "Tx",
"mem": "Mem", "mem": "Mem",
"cpu": "Prozessor", "cpu": "Prozessor",
"offline": "Offline" "offline": "Offline",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Spielen", "playing": "Spielen",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"ping": "Ping",
"error": "Error"
} }
} }

View File

@ -56,7 +56,13 @@
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Offline" "offline": "Offline",
"error": "Error",
"unknown": "Unknown"
},
"ping": {
"error": "Error",
"ping": "Ping"
}, },
"emby": { "emby": {
"playing": "Playing", "playing": "Playing",

View File

@ -3,10 +3,10 @@
"missing_type": "Falta el tipo de widget: {{type}}", "missing_type": "Falta el tipo de widget: {{type}}",
"api_error": "Error de API", "api_error": "Error de API",
"status": "Estado", "status": "Estado",
"information": "Information", "information": "Información",
"url": "URL", "url": "URL",
"raw_error": "Raw Error", "raw_error": "Error sin procesar",
"response_data": "Response Data" "response_data": "Datos de respuesta"
}, },
"search": { "search": {
"placeholder": "Buscar…" "placeholder": "Buscar…"
@ -23,7 +23,9 @@
"tx": "Transmitido", "tx": "Transmitido",
"mem": "Memoria", "mem": "Memoria",
"cpu": "Procesador", "cpu": "Procesador",
"offline": "Desconectado" "offline": "Desconectado",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Reproduciendo", "playing": "Reproduciendo",
@ -325,7 +327,11 @@
"country": "País" "country": "País"
}, },
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Canales",
"hd": "HD" "hd": "Alta definición"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -29,7 +29,9 @@
"tx": "TX", "tx": "TX",
"mem": "RAM", "mem": "RAM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Offline" "offline": "Offline",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Toistaa", "playing": "Toistaa",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -23,7 +23,9 @@
"tx": "Tx", "tx": "Tx",
"mem": "Mém", "mem": "Mém",
"cpu": "Cpu", "cpu": "Cpu",
"offline": "Hors ligne" "offline": "Hors ligne",
"error": "Erreur",
"unknown": "Inconnu"
}, },
"emby": { "emby": {
"playing": "En lecture", "playing": "En lecture",
@ -325,7 +327,11 @@
"country": "Pays" "country": "Pays"
}, },
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Canaux",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Erreur",
"ping": "Ping"
} }
} }

View File

@ -29,7 +29,9 @@
"tx": "TX", "tx": "TX",
"mem": "זיכרון", "mem": "זיכרון",
"cpu": "מעבד", "cpu": "מעבד",
"offline": "כבוי" "offline": "כבוי",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "מנגן", "playing": "מנגן",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -79,7 +79,9 @@
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Offline" "offline": "Offline",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Playing", "playing": "Playing",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -59,17 +59,19 @@
"missing_type": "Nedostajuća vrsta widgeta: {{type}}", "missing_type": "Nedostajuća vrsta widgeta: {{type}}",
"api_error": "API greška", "api_error": "API greška",
"status": "Stanje", "status": "Stanje",
"information": "Information", "information": "Informacije",
"url": "URL", "url": "URL",
"raw_error": "Raw Error", "raw_error": "Raw greška",
"response_data": "Response Data" "response_data": "Podaci odgovora"
}, },
"docker": { "docker": {
"rx": "RX", "rx": "RX",
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Nepovezan" "offline": "Nepovezan",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Reprodukcija", "playing": "Reprodukcija",
@ -320,12 +322,16 @@
"total": "Ukupno" "total": "Ukupno"
}, },
"gluetun": { "gluetun": {
"public_ip": "Public IP", "public_ip": "Javni IP",
"region": "Region", "region": "Regija",
"country": "Country" "country": "Zemlja"
}, },
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Kanali",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -11,7 +11,9 @@
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Offline" "offline": "Offline",
"error": "Error",
"unknown": "Unknown"
}, },
"lidarr": { "lidarr": {
"albums": "Albumok", "albums": "Albumok",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -4,7 +4,9 @@
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Offline", "offline": "Offline",
"rx": "RX" "rx": "RX",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "In riproduzione", "playing": "In riproduzione",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -150,7 +150,9 @@
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Luar talian" "offline": "Luar talian",
"error": "Error",
"unknown": "Unknown"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Jumlah Diperhatikan", "totalObserved": "Jumlah Diperhatikan",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -23,7 +23,9 @@
"tx": "Sendt", "tx": "Sendt",
"mem": "Minne", "mem": "Minne",
"cpu": "Prosessor", "cpu": "Prosessor",
"offline": "Frakoblet" "offline": "Frakoblet",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Spiller", "playing": "Spiller",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -20,7 +20,9 @@
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Offline" "offline": "Offline",
"error": "Error",
"unknown": "Unknown"
}, },
"speedtest": { "speedtest": {
"upload": "Upload", "upload": "Upload",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -53,17 +53,19 @@
"missing_type": "Brakujący typ widżetu: {{type}}", "missing_type": "Brakujący typ widżetu: {{type}}",
"api_error": "Błąd API", "api_error": "Błąd API",
"status": "Stan", "status": "Stan",
"url": "URL", "url": "Adres URL",
"information": "Information", "information": "Informacje",
"raw_error": "Raw Error", "raw_error": "Niesformatowany błąd",
"response_data": "Response Data" "response_data": "Dane odpowiedzi"
}, },
"docker": { "docker": {
"rx": "RX", "rx": "Rx",
"tx": "TX", "tx": "Tx",
"mem": "MEM", "mem": "Pamięć",
"cpu": "CPU", "cpu": "Procesor",
"offline": "Offline" "offline": "Offline",
"error": "Błąd",
"unknown": "Nieznany"
}, },
"nzbget": { "nzbget": {
"rate": "Szybkość", "rate": "Szybkość",
@ -95,7 +97,7 @@
"wanted": "Poszukiwane", "wanted": "Poszukiwane",
"queued": "W kolejce", "queued": "W kolejce",
"movies": "Filmy", "movies": "Filmy",
"missing": "Missing" "missing": "Brakujące"
}, },
"lidarr": { "lidarr": {
"wanted": "Poszukiwane", "wanted": "Poszukiwane",
@ -166,14 +168,14 @@
}, },
"mastodon": { "mastodon": {
"user_count": "Użytkownicy", "user_count": "Użytkownicy",
"status_count": "Posts", "status_count": "Posty",
"domain_count": "Domeny" "domain_count": "Domeny"
}, },
"strelaysrv": { "strelaysrv": {
"numActiveSessions": "Sesje", "numActiveSessions": "Sesje",
"numConnections": "Połączenia", "numConnections": "Połączenia",
"dataRelayed": "Relayed", "dataRelayed": "Przekazane",
"transferRate": "Rate" "transferRate": "Przesył"
}, },
"authentik": { "authentik": {
"users": "Użytkownicy", "users": "Użytkownicy",
@ -181,10 +183,10 @@
"failedLoginsLast24H": "Nieudane logowania (24h)" "failedLoginsLast24H": "Nieudane logowania (24h)"
}, },
"proxmox": { "proxmox": {
"mem": "MEM", "mem": "Pamięć",
"cpu": "CPU", "cpu": "Procesor",
"lxc": "LXC", "lxc": "Kontenery LXC",
"vms": "VMs" "vms": "Maszyn wirtualnych"
}, },
"unifi": { "unifi": {
"users": "Użytkownicy", "users": "Użytkownicy",
@ -203,25 +205,25 @@
"wlan_devices": "Urządzenia WLAN" "wlan_devices": "Urządzenia WLAN"
}, },
"plex": { "plex": {
"streams": "Active Streams", "streams": "Aktywne strumienie",
"movies": "Filmy", "movies": "Filmy",
"tv": "Seriale" "tv": "Seriale"
}, },
"glances": { "glances": {
"cpu": "CPU", "cpu": "Procesor",
"mem": "MEM", "mem": "Pamięć",
"wait": "Proszę czekać" "wait": "Proszę czekać"
}, },
"changedetectionio": { "changedetectionio": {
"diffsDetected": "Diffs Detected", "diffsDetected": "Wykryto różnic",
"totalObserved": "Total Observed" "totalObserved": "Obserwowanych ogółem"
}, },
"wmo": { "wmo": {
"77-day": "Snow Grains", "77-day": "Ziarnisty śnieg",
"0-day": "Słoneczny", "0-day": "Słoneczny",
"0-night": "Clear", "0-night": "Bezchmurny",
"1-day": "Mainly Sunny", "1-day": "Głównie słoneczny",
"1-night": "Mainly Clear", "1-night": "Głównie bezchmurny",
"2-day": "Częściowo pochmurnie", "2-day": "Częściowo pochmurnie",
"2-night": "Częściowo pochmurnie", "2-night": "Częściowo pochmurnie",
"3-day": "Pochmurnie", "3-day": "Pochmurnie",
@ -236,10 +238,10 @@
"53-night": "Mżawka", "53-night": "Mżawka",
"55-day": "Ciężka mżawka", "55-day": "Ciężka mżawka",
"55-night": "Ciężka mżawka", "55-night": "Ciężka mżawka",
"56-day": "Light Freezing Drizzle", "56-day": "Lekko chłodna mżawka",
"56-night": "Light Freezing Drizzle", "56-night": "Lekko chłodna mżawka",
"57-day": "Freezing Drizzle", "57-day": "Chłodna mżawka",
"57-night": "Freezing Drizzle", "57-night": "Chłodna mżawka",
"61-day": "Lekki deszcz", "61-day": "Lekki deszcz",
"61-night": "Lekki deszcz", "61-night": "Lekki deszcz",
"63-day": "Deszcz", "63-day": "Deszcz",
@ -256,7 +258,7 @@
"73-night": "Śnieg", "73-night": "Śnieg",
"75-day": "Ciężki śnieg", "75-day": "Ciężki śnieg",
"75-night": "Ciężki śnieg", "75-night": "Ciężki śnieg",
"77-night": "Snow Grains", "77-night": "Ziarnisty śnieg",
"80-day": "Lekkie opady", "80-day": "Lekkie opady",
"80-night": "Lekkie opady", "80-night": "Lekkie opady",
"81-day": "Opady", "81-day": "Opady",
@ -275,7 +277,7 @@
"99-night": "Burza z gradobiciem" "99-night": "Burza z gradobiciem"
}, },
"quicklaunch": { "quicklaunch": {
"bookmark": "Bookmark", "bookmark": "Zakładka",
"service": "Usługi" "service": "Usługi"
}, },
"homebridge": { "homebridge": {
@ -287,45 +289,49 @@
"child_bridges_status": "{{ok}}/{{total}}" "child_bridges_status": "{{ok}}/{{total}}"
}, },
"autobrr": { "autobrr": {
"approvedPushes": "Approved", "approvedPushes": "Zaakceptowane",
"rejectedPushes": "Rejected", "rejectedPushes": "Odrzucone",
"filters": "Filters", "filters": "Filtry",
"indexers": "Indexers" "indexers": "Indeksery"
}, },
"watchtower": { "watchtower": {
"containers_scanned": "Scanned", "containers_scanned": "Zeskanowane",
"containers_updated": "Updated", "containers_updated": "Zaktualizowane",
"containers_failed": "Failed" "containers_failed": "Niepowodzenie"
}, },
"tubearchivist": { "tubearchivist": {
"downloads": "Queue", "downloads": "Kolejka",
"videos": "Videos", "videos": "Pliki wideo",
"channels": "Channels", "channels": "Kanały",
"playlists": "Playlists" "playlists": "Playlisty"
}, },
"truenas": { "truenas": {
"load": "System Load", "load": "Obciążenie systemu",
"uptime": "Uptime", "uptime": "Czas działania",
"alerts": "Alerts", "alerts": "Ostrzeżenia",
"time": "{{value, number(style: unit; unitDisplay: long;)}}" "time": "{{value, number(style: unit; unitDisplay: long;)}}"
}, },
"navidrome": { "navidrome": {
"please_wait": "Please Wait", "please_wait": "Proszę czekać",
"nothing_streaming": "No Active Streams" "nothing_streaming": "Brak aktywnych strumieni"
}, },
"pyload": { "pyload": {
"speed": "Speed", "speed": "Prędkość",
"active": "Active", "active": "Aktywne",
"queue": "Queue", "queue": "Kolejka",
"total": "Total" "total": "Razem"
}, },
"gluetun": { "gluetun": {
"public_ip": "Public IP", "public_ip": "Adres publiczny",
"region": "Region", "region": "Region",
"country": "Country" "country": "Państwo"
}, },
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Kanały",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Błąd",
"ping": "Ping"
} }
} }

View File

@ -57,7 +57,9 @@
"tx": "Tx", "tx": "Tx",
"mem": "Mem", "mem": "Mem",
"cpu": "CPU", "cpu": "CPU",
"offline": "Desligado" "offline": "Desligado",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Reproduzindo", "playing": "Reproduzindo",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -23,7 +23,9 @@
"tx": "Tx", "tx": "Tx",
"mem": "Mem", "mem": "Mem",
"cpu": "CPU", "cpu": "CPU",
"offline": "Desligado" "offline": "Desligado",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "A reproduzir", "playing": "A reproduzir",
@ -338,5 +340,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -11,7 +11,9 @@
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Offline" "offline": "Offline",
"error": "Error",
"unknown": "Unknown"
}, },
"jellyseerr": { "jellyseerr": {
"approved": "Aprobate", "approved": "Aprobate",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -23,7 +23,9 @@
"tx": "Тx", "tx": "Тx",
"mem": "Память", "mem": "Память",
"cpu": "Процессор", "cpu": "Процессор",
"offline": "Не в сети" "offline": "Не в сети",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Воспроизведение", "playing": "Воспроизведение",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -45,7 +45,9 @@
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Offline" "offline": "Offline",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Playing", "playing": "Playing",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -26,7 +26,9 @@
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Offline" "offline": "Offline",
"error": "Error",
"unknown": "Unknown"
}, },
"search": { "search": {
"placeholder": "Sök…" "placeholder": "Sök…"
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -46,7 +46,9 @@
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "సీపియూ", "cpu": "సీపియూ",
"offline": "ఆఫ్‌లైన్" "offline": "ఆఫ్‌లైన్",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "ఆడుతున్నారు", "playing": "ఆడుతున్నారు",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -45,7 +45,9 @@
"tx": "Giden Veri", "tx": "Giden Veri",
"mem": "Bellek", "mem": "Bellek",
"cpu": "İşlemci", "cpu": "İşlemci",
"offline": "Çevrimdışı" "offline": "Çevrimdışı",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Oynatılıyor", "playing": "Oynatılıyor",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -23,7 +23,9 @@
"tx": "TX", "tx": "TX",
"mem": "BỘ NHỚ", "mem": "BỘ NHỚ",
"cpu": "CPU", "cpu": "CPU",
"offline": "Ngoại tuyến" "offline": "Ngoại tuyến",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Đang chơi", "playing": "Đang chơi",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -47,7 +47,9 @@
"tx": "發送", "tx": "發送",
"mem": "內存", "mem": "內存",
"cpu": "處理器", "cpu": "處理器",
"offline": "離線" "offline": "離線",
"error": "Error",
"unknown": "Unknown"
}, },
"nzbget": { "nzbget": {
"rate": "速度", "rate": "速度",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -23,7 +23,9 @@
"tx": "发送", "tx": "发送",
"mem": "内存", "mem": "内存",
"cpu": "处理器", "cpu": "处理器",
"offline": "离线" "offline": "离线",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "播放中", "playing": "播放中",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -19,7 +19,9 @@
"offline": "Offline", "offline": "Offline",
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "CPU" "cpu": "CPU",
"error": "Error",
"unknown": "Unknown"
}, },
"emby": { "emby": {
"playing": "Playing", "playing": "Playing",
@ -327,5 +329,9 @@
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Channels",
"hd": "HD" "hd": "HD"
},
"ping": {
"error": "Error",
"ping": "Ping"
} }
} }

View File

@ -3,6 +3,7 @@ import { useContext, useState } from "react";
import Status from "./status"; import Status from "./status";
import Widget from "./widget"; import Widget from "./widget";
import Ping from "./ping";
import Docker from "widgets/docker/component"; import Docker from "widgets/docker/component";
import { SettingsContext } from "utils/contexts/settings"; import { SettingsContext } from "utils/contexts/settings";
@ -30,7 +31,7 @@ export default function Item({ service }) {
<div <div
className={`${ className={`${
hasLink ? "cursor-pointer " : " " hasLink ? "cursor-pointer " : " "
}transition-all h-15 mb-3 p-1 rounded-md font-medium text-theme-700 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 hover:bg-theme-300/20 dark:bg-white/5 dark:hover:bg-white/10`} }transition-all h-15 mb-3 p-1 rounded-md font-medium text-theme-700 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 hover:bg-theme-300/20 dark:bg-white/5 dark:hover:bg-white/10 relative`}
> >
<div className="flex select-none"> <div className="flex select-none">
{service.icon && {service.icon &&
@ -70,17 +71,26 @@ export default function Item({ service }) {
</div> </div>
)} )}
<div className="absolute top-0 right-0 w-1/2 flex flex-row justify-end gap-2 mr-2">
{service.ping && (
<div className="flex-shrink-0 flex items-center justify-center cursor-pointer">
<Ping service={service} />
<span className="sr-only">Ping status</span>
</div>
)}
{service.container && ( {service.container && (
<button <button
type="button" type="button"
onClick={() => (statsOpen ? closeStats() : setStatsOpen(true))} onClick={() => (statsOpen ? closeStats() : setStatsOpen(true))}
className="flex-shrink-0 flex items-center justify-center w-12 cursor-pointer" className="flex-shrink-0 flex items-center justify-center cursor-pointer"
> >
<Status service={service} /> <Status service={service} />
<span className="sr-only">View container stats</span> <span className="sr-only">View container stats</span>
</button> </button>
)} )}
</div> </div>
</div>
{service.container && service.server && ( {service.container && service.server && (
<div <div

View File

@ -0,0 +1,44 @@
import { useTranslation } from "react-i18next";
import useSWR from "swr";
export default function Ping({ service }) {
const { t } = useTranslation();
const { data, error } = useSWR(`/api/ping?${new URLSearchParams({ping: service.ping}).toString()}`, {
refreshInterval: 30000
});
if (error) {
return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden">
<div className="text-[8px] font-bold text-rose-500 uppercase">{t("ping.error")}</div>
</div>
);
}
if (!data) {
return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden">
<div className="text-[8px] font-bold text-black/20 dark:text-white/40 uppercase">{t("ping.ping")}</div>
</div>
);
}
const statusText = `${service.ping}: HTTP status ${data.status}`;
if (data && data.status !== 200) {
return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={statusText}>
<div className="text-[8px] font-bold text-rose-500/80">{data.status}</div>
</div>
);
}
if (data && data.status === 200) {
return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={statusText}>
<div className="text-[8px] font-bold text-emerald-500/80">{t("common.ms", { value: data.latency, style: "unit", unit: "millisecond", unitDisplay: "narrow", maximumFractionDigits: 0 })}</div>
</div>
);
}
}

View File

@ -1,19 +1,36 @@
import { useTranslation } from "react-i18next";
import useSWR from "swr"; import useSWR from "swr";
export default function Status({ service }) { export default function Status({ service }) {
const { t } = useTranslation();
const { data, error } = useSWR(`/api/docker/status/${service.container}/${service.server || ""}`); const { data, error } = useSWR(`/api/docker/status/${service.container}/${service.server || ""}`);
if (error) { if (error) {
return <div className="w-3 h-3 bg-rose-300 dark:bg-rose-500 rounded-full" />; <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={data.status}>
<div className="text-[8px] font-bold text-rose-500/80 uppercase">{t("docker.error")}</div>
</div>
} }
if (data && data.status === "running") { if (data && data.status === "running") {
return <div className="w-3 h-3 bg-emerald-300 dark:bg-emerald-500 rounded-full" />; return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={data.status}>
<div className="text-[8px] font-bold text-emerald-500/80 uppercase">{data.status}</div>
</div>
);
} }
if (data && data.status === "not found") { if (data && (data.status === "not found" || data.status === "exited")) {
return <div className="h-2.5 w-2.5 bg-orange-400/50 dark:bg-yellow-200/40 -rotate-45" />; return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={data.status}>
<div className="text-[8px] font-bold text-orange-400/50 dark:text-orange-400/80 uppercase">{data.status}</div>
</div>
);
} }
return <div className="w-3 h-3 bg-black/20 dark:bg-white/40 rounded-full" />; return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden">
<div className="text-[8px] font-bold text-black/20 dark:text-white/40 uppercase">{t("docker.unknown")}</div>
</div>
);
} }

28
src/pages/api/ping.js Normal file
View File

@ -0,0 +1,28 @@
import { performance } from "perf_hooks";
import createLogger from "utils/logger";
import { httpProxy } from "utils/proxy/http";
const logger = createLogger("ping");
export default async function handler(req, res) {
const { ping: pingURL } = req.query;
if (!pingURL) {
logger.debug("No ping URL specified");
return res.status(400).send({
error: "No ping URL given",
});
}
const startTime = performance.now();
const [status] = await httpProxy(pingURL, {
method: "HEAD"
});
const endTime = performance.now();
return res.status(200).json({
status,
latency: endTime - startTime
});
}

View File

@ -4,10 +4,15 @@ import { format as utilFormat } from "node:util";
import winston from "winston"; import winston from "winston";
import checkAndCopyConfig, { getSettings } from "utils/config/config";
let winstonLogger; let winstonLogger;
function init() { function init() {
const configPath = join(process.cwd(), "config"); const configPath = join(process.cwd(), "config");
checkAndCopyConfig("settings.yaml");
const settings = getSettings();
const logpath = settings.logpath || configPath;
function combineMessageAndSplat() { function combineMessageAndSplat() {
return { return {
@ -57,7 +62,7 @@ function init() {
winston.format.timestamp(), winston.format.timestamp(),
winston.format.printf(messageFormatter) winston.format.printf(messageFormatter)
), ),
filename: `${configPath}/logs/homepage.log`, filename: `${logpath}/logs/homepage.log`,
handleExceptions: true, handleExceptions: true,
handleRejections: true, handleRejections: true,
}), }),

View File

@ -96,7 +96,7 @@ export async function httpProxy(url, params = {}) {
return [status, contentType, data, responseHeaders]; return [status, contentType, data, responseHeaders];
} }
catch (err) { catch (err) {
logger.error("Error calling %s//%s%s...", url.protocol, url.hostname, url.pathname); logger.error("Error calling %s//%s%s...", constructedUrl.protocol, constructedUrl.hostname, 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];
} }