diff --git a/README.md b/README.md index ec2e1e682..e19252aee 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ services: - 3000:3000 volumes: - /path/to/config:/app/config # Make sure your local config directory exists - - /var/run/docker.sock:/var/run/docker.sock # (optional) For docker integrations + - /var/run/docker.sock:/var/run/docker.sock:ro # (optional) For docker integrations ``` or docker run: diff --git a/public/locales/hr/common.json b/public/locales/hr/common.json index b555aa0b0..68a0b21a6 100644 --- a/public/locales/hr/common.json +++ b/public/locales/hr/common.json @@ -347,61 +347,61 @@ "deluge": { "download": "Preuzimanje", "upload": "Prijenos", - "leech": "Leech", - "seed": "Seed" + "leech": "Korištenje tuđeg sadržaja", + "seed": "Prenošenje preuzetog sadržaja" }, "flood": { "download": "Preuzimanje", "upload": "Prijenos", - "leech": "Leech", - "seed": "Seed" + "leech": "Korištenje tuđeg sadržaja", + "seed": "Prenošenje preuzetog sadržaja" }, "tdarr": { - "queue": "Queue", - "processed": "Processed", - "errored": "Errored", - "saved": "Saved" + "queue": "Red čekanja", + "processed": "Obrađeno", + "errored": "S greškom", + "saved": "Spremljeno" }, "miniflux": { - "read": "Read", - "unread": "Unread" + "read": "Pročitano", + "unread": "Nepročitano" }, "nextdns": { - "wait": "Please Wait", - "no_devices": "No Device Data Received" + "wait": "Pričekaj", + "no_devices": "Podaci o uređaju nisu primljeni" }, "common": { "bibyterate": "{{value, rate(bits: false; binary: true)}}", "bibitrate": "{{value, rate(bits: true; binary: true)}}" }, "omada": { - "connectedAp": "Connected APs", - "activeUser": "Active devices", - "alerts": "Alerts", - "connectedGateway": "Connected gateways", - "connectedSwitches": "Connected switches" + "connectedAp": "Povezani AP-ovi", + "activeUser": "Aktivni uređaji", + "alerts": "Upozorenja", + "connectedGateway": "Povezani pristupi", + "connectedSwitches": "Povezani prekidači" }, "downloadstation": { - "download": "Download", - "upload": "Upload", - "leech": "Leech", - "seed": "Seed" + "download": "Preuzimanje", + "upload": "Prijenos", + "leech": "Korištenje tuđeg sadržaja", + "seed": "Prenošenje preuzetog sadržaja" }, "mikrotik": { "cpuLoad": "CPU Load", - "memoryUsed": "Memory Used", + "memoryUsed": "Korištena memorija", "uptime": "Uptime", "numberOfLeases": "Leases" }, "xteve": { - "streams_all": "All Streams", - "streams_active": "Active Streams", - "streams_xepg": "XEPG Channels" + "streams_all": "Svi prijenosi", + "streams_active": "Aktivni prijenosi", + "streams_xepg": "XEPG kanali" }, "opnsense": { "cpu": "CPU Load", - "memory": "Active Memory", - "wanUpload": "WAN Upload", - "wanDownload": "WAN Download" + "memory": "Aktivna memorija", + "wanUpload": "WAN prijenos", + "wanDownload": "WAN preuzimanje" } } diff --git a/public/locales/ja/common.json b/public/locales/ja/common.json new file mode 100644 index 000000000..11913e363 --- /dev/null +++ b/public/locales/ja/common.json @@ -0,0 +1,407 @@ +{ + "navidrome": { + "nothing_streaming": "No Active Streams", + "please_wait": "Please Wait" + }, + "npm": { + "total": "Total", + "enabled": "Enabled", + "disabled": "Disabled" + }, + "strelaysrv": { + "numActiveSessions": "Sessions", + "numConnections": "Connections", + "dataRelayed": "Relayed", + "transferRate": "Rate" + }, + "glances": { + "mem": "MEM", + "cpu": "CPU", + "wait": "Please wait" + }, + "autobrr": { + "filters": "Filters", + "indexers": "Indexers", + "approvedPushes": "Approved", + "rejectedPushes": "Rejected" + }, + "gluetun": { + "region": "Region", + "country": "Country", + "public_ip": "Public IP" + }, + "common": { + "bibyterate": "{{value, rate(bits: false; binary: true)}}", + "bibitrate": "{{value, rate(bits: true; binary: true)}}" + }, + "widget": { + "api_error": "APIエラー", + "information": "情報", + "missing_type": "見つからないウィジェットタイプ: {{type}}", + "status": "ステータス", + "url": "URL", + "raw_error": "生のエラー", + "response_data": "レスポンスデータ" + }, + "weather": { + "current": "Current Location", + "allow": "Click to allow", + "updating": "Updating", + "wait": "Please wait" + }, + "search": { + "placeholder": "Search…" + }, + "resources": { + "cpu": "CPU", + "total": "Total", + "free": "Free", + "used": "Used", + "load": "Load" + }, + "unifi": { + "users": "Users", + "uptime": "System Uptime", + "days": "Days", + "wan": "WAN", + "lan": "LAN", + "wlan": "WLAN", + "devices": "Devices", + "lan_devices": "LAN Devices", + "wlan_devices": "WLAN Devices", + "lan_users": "LAN Users", + "wlan_users": "WLAN Users", + "up": "UP", + "down": "DOWN", + "wait": "Please wait" + }, + "docker": { + "rx": "RX", + "tx": "TX", + "mem": "MEM", + "cpu": "CPU", + "offline": "Offline", + "error": "Error", + "unknown": "Unknown" + }, + "ping": { + "error": "Error", + "ping": "Ping" + }, + "emby": { + "playing": "Playing", + "transcoding": "Transcoding", + "bitrate": "Bitrate", + "no_active": "No Active Streams" + }, + "flood": { + "download": "Download", + "upload": "Upload", + "leech": "Leech", + "seed": "Seed" + }, + "changedetectionio": { + "totalObserved": "Total Observed", + "diffsDetected": "Diffs Detected" + }, + "tautulli": { + "playing": "Playing", + "transcoding": "Transcoding", + "bitrate": "Bitrate", + "no_active": "No Active Streams" + }, + "omada": { + "connectedAp": "Connected APs", + "activeUser": "Active devices", + "alerts": "Alerts", + "connectedGateway": "Connected gateways", + "connectedSwitches": "Connected switches" + }, + "nzbget": { + "rate": "Rate", + "remaining": "Remaining", + "downloaded": "Downloaded" + }, + "plex": { + "streams": "Active Streams", + "movies": "Movies", + "tv": "TV Shows" + }, + "sabnzbd": { + "rate": "Rate", + "queue": "Queue", + "timeleft": "Time Left" + }, + "rutorrent": { + "active": "Active", + "upload": "Upload", + "download": "Download" + }, + "transmission": { + "download": "Download", + "upload": "Upload", + "leech": "Leech", + "seed": "Seed" + }, + "qbittorrent": { + "download": "Download", + "upload": "Upload", + "leech": "Leech", + "seed": "Seed" + }, + "deluge": { + "download": "Download", + "upload": "Upload", + "leech": "Leech", + "seed": "Seed" + }, + "downloadstation": { + "download": "Download", + "upload": "Upload", + "leech": "Leech", + "seed": "Seed" + }, + "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" + }, + "jellyseerr": { + "pending": "Pending", + "approved": "Approved", + "available": "Available" + }, + "overseerr": { + "pending": "Pending", + "processing": "Processing", + "approved": "Approved", + "available": "Available" + }, + "pihole": { + "queries": "Queries", + "blocked": "Blocked", + "gravity": "Gravity" + }, + "adguard": { + "queries": "Queries", + "blocked": "Blocked", + "filtered": "Filtered", + "latency": "Latency" + }, + "speedtest": { + "upload": "Upload", + "download": "Download", + "ping": "Ping" + }, + "portainer": { + "running": "Running", + "stopped": "Stopped", + "total": "Total" + }, + "tdarr": { + "queue": "Queue", + "processed": "Processed", + "errored": "Errored", + "saved": "Saved" + }, + "traefik": { + "routers": "Routers", + "services": "Services", + "middleware": "Middleware" + }, + "coinmarketcap": { + "configure": "Configure one or more crypto currencies to track", + "1hour": "1 Hour", + "1day": "1 Day", + "7days": "7 Days", + "30days": "30 Days" + }, + "gotify": { + "apps": "Applications", + "clients": "Clients", + "messages": "Messages" + }, + "prowlarr": { + "enableIndexers": "Indexers", + "numberOfGrabs": "Grabs", + "numberOfQueries": "Queries", + "numberOfFailGrabs": "Fail Grabs", + "numberOfFailQueries": "Fail Queries" + }, + "jackett": { + "configured": "Configured", + "errored": "Errored" + }, + "mastodon": { + "user_count": "Users", + "status_count": "Posts", + "domain_count": "Domains" + }, + "miniflux": { + "read": "Read", + "unread": "Unread" + }, + "authentik": { + "users": "Users", + "loginsLast24H": "Logins (24h)", + "failedLoginsLast24H": "Failed Logins (24h)" + }, + "proxmox": { + "mem": "MEM", + "cpu": "CPU", + "lxc": "LXC", + "vms": "VMs" + }, + "quicklaunch": { + "bookmark": "Bookmark", + "service": "Service" + }, + "wmo": { + "0-day": "Sunny", + "1-day": "Mainly Sunny", + "0-night": "Clear", + "1-night": "Mainly Clear", + "2-day": "Partly Cloudy", + "2-night": "Partly Cloudy", + "3-day": "Cloudy", + "3-night": "Cloudy", + "45-day": "Foggy", + "45-night": "Foggy", + "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", + "57-night": "Freezing Drizzle", + "61-day": "Light Rain", + "61-night": "Light Rain", + "63-day": "Rain", + "63-night": "Rain", + "67-night": "Freezing Rain", + "71-day": "Light Snow", + "65-day": "Heavy Rain", + "65-night": "Heavy Rain", + "66-day": "Freezing Rain", + "66-night": "Freezing Rain", + "67-day": "Freezing Rain", + "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", + "80-night": "Light Showers", + "81-day": "Showers", + "81-night": "Showers", + "82-day": "Heavy Showers", + "82-night": "Heavy Showers", + "85-day": "Snow Showers", + "85-night": "Snow Showers", + "86-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": { + "available_update": "System", + "updates": "Updates", + "update_available": "Update Available", + "up_to_date": "Up to Date", + "child_bridges": "Child Bridges", + "child_bridges_status": "{{ok}}/{{total}}" + }, + "watchtower": { + "containers_scanned": "Scanned", + "containers_updated": "Updated", + "containers_failed": "Failed" + }, + "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" + }, + "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" + }, + "opnsense": { + "cpu": "CPU Load", + "memory": "Active Memory", + "wanUpload": "WAN Upload", + "wanDownload": "WAN Download" + } +} diff --git a/public/locales/pt/common.json b/public/locales/pt/common.json index 92a388707..f3cd28f51 100644 --- a/public/locales/pt/common.json +++ b/public/locales/pt/common.json @@ -1,6 +1,6 @@ { "widget": { - "missing_type": "Widget ausente: {{type}}", + "missing_type": "Tipo de Widget ausente: {{type}}", "api_error": "Erro da API", "status": "Estado", "information": "Informação", @@ -14,8 +14,8 @@ "resources": { "total": "Total", "free": "Livre", - "used": "Usado", - "load": "Carregar", + "used": "Utilizado", + "load": "Carga", "cpu": "CPU" }, "docker": { @@ -53,7 +53,7 @@ "wanted": "Desejado", "queued": "Fila", "movies": "Filmes", - "missing": "Missing" + "missing": "Faltando" }, "readarr": { "wanted": "Desejados", @@ -111,14 +111,14 @@ "weather": { "current": "Localização atual", "allow": "Clicar para permitir", - "updating": "A atualizar", + "updating": "Atualizando", "wait": "Por favor aguarde" }, "overseerr": { "pending": "Pendente", "approved": "Aprovado", "available": "Disponível", - "processing": "Processing" + "processing": "Processando" }, "sabnzbd": { "rate": "Taxa", @@ -192,9 +192,9 @@ "transferRate": "Taxa" }, "authentik": { - "loginsLast24H": "Logins (24h)", - "failedLoginsLast24H": "Failed Logins (24h)", - "users": "Users" + "loginsLast24H": "Inícios de sessão (24h)", + "failedLoginsLast24H": "Inícios de sessão falhados (24h)", + "users": "Utilizadores" }, "proxmox": { "mem": "MEM", @@ -204,13 +204,13 @@ }, "unifi": { "users": "Utilizadores", - "uptime": "Tempo de Atividade do Sistema", + "uptime": "Sistema Ativo", "days": "Dias", "wan": "WAN", "lan_users": "Utilizadores LAN", "wlan_users": "Utilizadores WLAN", - "up": "Ligados", - "down": "Desligados", + "up": "Ligado", + "down": "Desligado", "wait": "Por favor, aguarde", "lan": "LAN", "wlan": "WLAN", @@ -241,7 +241,7 @@ "2-night": "Parcialmente nublado", "3-day": "Nublado", "3-night": "Nublado", - "99-night": "Thunderstorm With Hail", + "99-night": "Trovoada com granizo", "45-day": "Nevoeiro", "45-night": "Nevoeiro", "48-day": "Nevoeiro", @@ -257,160 +257,160 @@ "57-day": "Freezing Drizzle", "57-night": "Freezing Drizzle", "66-day": "Freezing Rain", - "61-day": "Light Rain", - "61-night": "Light Rain", - "63-day": "Rain", - "63-night": "Rain", - "65-day": "Heavy Rain", + "61-day": "Chuva fraca", + "61-night": "Chuva fraca", + "63-day": "Chuva", + "63-night": "Chuva", + "65-day": "Chuva forte", "66-night": "Freezing Rain", - "65-night": "Heavy Rain", + "65-night": "Chuva forte", "67-day": "Freezing 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", + "71-day": "Neve fraca", + "71-night": "Neve fraca", + "73-day": "Neve", + "73-night": "Neve", + "75-day": "Neve forte", + "75-night": "Neve forte", "77-day": "Snow Grains", "77-night": "Snow Grains", - "80-day": "Light Showers", - "80-night": "Light Showers", - "81-day": "Showers", - "81-night": "Showers", - "82-day": "Heavy Showers", - "82-night": "Heavy Showers", + "80-day": "Neve fraca", + "80-night": "Chuviscos ligeiros", + "81-day": "Chuviscos", + "81-night": "Chuviscos", + "82-day": "Chuviscos fortes", + "82-night": "Chuviscos fortes", "85-day": "Snow Showers", "85-night": "Snow Showers", "86-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" + "95-day": "Trovoada", + "95-night": "Trovoada", + "96-day": "Trovoada com granizo", + "96-night": "Trovoada com granizo", + "99-day": "Trovoada com granizo" }, "quicklaunch": { "bookmark": "Marcador", "service": "Serviço" }, "homebridge": { - "available_update": "System", - "updates": "Updates", - "update_available": "Update Available", - "up_to_date": "Up to Date", + "available_update": "Sistema", + "updates": "Atualizações", + "update_available": "Atualização disponível", + "up_to_date": "Atualizado", "child_bridges": "Child Bridges", "child_bridges_status": "{{ok}}/{{total}}" }, "autobrr": { - "approvedPushes": "Approved", - "rejectedPushes": "Rejected", - "filters": "Filters", - "indexers": "Indexers" + "approvedPushes": "Aprovado", + "rejectedPushes": "Rejeitado", + "filters": "Filtros", + "indexers": "Indexadores" }, "watchtower": { - "containers_scanned": "Scanned", - "containers_updated": "Updated", - "containers_failed": "Failed" + "containers_scanned": "Verificado", + "containers_updated": "Atualizado", + "containers_failed": "Falhou" }, "tubearchivist": { - "downloads": "Queue", - "videos": "Videos", - "channels": "Channels", - "playlists": "Playlists" + "downloads": "Fila", + "videos": "Vídeos", + "channels": "Canais", + "playlists": "Listas" }, "truenas": { - "load": "System Load", - "uptime": "Uptime", - "alerts": "Alerts", + "load": "Carga do sistema", + "uptime": "Ligado", + "alerts": "Alertas", "time": "{{value, number(style: unit; unitDisplay: long;)}}" }, "navidrome": { - "nothing_streaming": "No Active Streams", - "please_wait": "Please Wait" + "nothing_streaming": "Sem streams ativos", + "please_wait": "Por favor aguarde" }, "pyload": { - "queue": "Queue", + "queue": "Fila", "total": "Total", - "speed": "Speed", - "active": "Active" + "speed": "Velocidade", + "active": "Ativo" }, "gluetun": { - "region": "Region", - "country": "Country", - "public_ip": "Public IP" + "region": "Região", + "country": "País", + "public_ip": "IP público" }, "hdhomerun": { - "channels": "Channels", + "channels": "Canais", "hd": "HD" }, "ping": { "error": "Erro", - "ping": "Ping" + "ping": "Tempo de resposta" }, "scrutiny": { - "passed": "Passed", - "failed": "Failed", - "unknown": "Unknown" + "passed": "Aprovado", + "failed": "Falhou", + "unknown": "Desconhecido" }, "paperlessngx": { - "inbox": "Inbox", + "inbox": "Caixa de entrada", "total": "Total" }, "deluge": { - "download": "Download", - "upload": "Upload", + "download": "Descarregar", + "upload": "Enviar", "leech": "Leech", - "seed": "Seed" + "seed": "Semente" }, "flood": { "download": "Descarregar", "upload": "Carregar", "leech": "Leech", - "seed": "Seed" + "seed": "Semente" }, "tdarr": { - "queue": "Queue", - "processed": "Processed", - "errored": "Errored", - "saved": "Saved" + "queue": "Fila", + "processed": "Processado", + "errored": "Erro", + "saved": "Guardado" }, "miniflux": { - "read": "Read", - "unread": "Unread" + "read": "Lido", + "unread": "Não lido" }, "nextdns": { - "wait": "Please Wait", - "no_devices": "No Device Data Received" + "wait": "Aguarde", + "no_devices": "Nenhum dado do dispositivo recebido" }, "omada": { - "connectedAp": "Connected APs", - "activeUser": "Active devices", - "alerts": "Alerts", - "connectedGateway": "Connected gateways", - "connectedSwitches": "Connected switches" + "connectedAp": "APs Ligados", + "activeUser": "Dispositivos activos", + "alerts": "Alertas", + "connectedGateway": "Gateways ligados", + "connectedSwitches": "Switches ligados" }, "downloadstation": { - "download": "Download", - "upload": "Upload", + "download": "Descarregar", + "upload": "Enviar", "leech": "Leech", - "seed": "Seed" + "seed": "Semente" }, "mikrotik": { - "cpuLoad": "CPU Load", - "memoryUsed": "Memory Used", - "uptime": "Uptime", + "cpuLoad": "Carga do CPU", + "memoryUsed": "Memória Utilizada", + "uptime": "Ativo", "numberOfLeases": "Leases" }, "xteve": { - "streams_all": "All Streams", - "streams_active": "Active Streams", - "streams_xepg": "XEPG Channels" + "streams_all": "Todos os Streams", + "streams_active": "Streams ativos", + "streams_xepg": "Canais XEPG" }, "opnsense": { - "cpu": "CPU Load", - "memory": "Active Memory", - "wanUpload": "WAN Upload", - "wanDownload": "WAN Download" + "cpu": "Carga do CPU", + "memory": "Memória Ativa", + "wanUpload": "Envio WAN", + "wanDownload": "WAN Descarga" } } diff --git a/public/locales/zh-Hant/common.json b/public/locales/zh-Hant/common.json index fd00cccda..7aec083ac 100644 --- a/public/locales/zh-Hant/common.json +++ b/public/locales/zh-Hant/common.json @@ -1,116 +1,116 @@ { "widget": { - "missing_type": "Missing Widget Type: {{type}}", - "api_error": "API Error", - "status": "Status", - "information": "Information", + "missing_type": "遺失的小工具類型: {{type}}", + "api_error": "API錯誤", + "status": "狀態", + "information": "資訊", "url": "URL", "raw_error": "Raw Error", "response_data": "Response Data" }, "weather": { - "current": "Current Location", - "allow": "Click to allow", - "updating": "Updating", - "wait": "Please wait" + "current": "目前位置", + "allow": "點擊以允許", + "updating": "更新中", + "wait": "請稍後" }, "docker": { - "rx": "RX", - "offline": "Offline", - "tx": "TX", - "mem": "MEM", - "cpu": "CPU", - "error": "Error", - "unknown": "Unknown" + "rx": "接收", + "offline": "離線", + "tx": "發送", + "mem": "記憶體", + "cpu": "處理器", + "error": "錯誤", + "unknown": "未知的" }, "emby": { - "playing": "Playing", - "transcoding": "Transcoding", - "bitrate": "Bitrate", - "no_active": "No Active Streams" + "playing": "正在播放", + "transcoding": "轉碼", + "bitrate": "位元率", + "no_active": "暫無撥放" }, "tautulli": { - "playing": "Playing", - "transcoding": "Transcoding", - "bitrate": "Bitrate", - "no_active": "No Active Streams" + "playing": "正在播放", + "transcoding": "轉碼", + "bitrate": "位元率", + "no_active": "暫無撥放" }, "jellyseerr": { - "pending": "Pending", - "approved": "Approved", - "available": "Available" + "pending": "待定", + "approved": "已接受", + "available": "可用的" }, "search": { - "placeholder": "Search…" + "placeholder": "搜尋…" }, "resources": { - "total": "Total", - "free": "Free", - "used": "Used", - "load": "Load", + "total": "全部", + "free": "剩餘", + "used": "已使用", + "load": "負載", "cpu": "CPU" }, "nzbget": { - "rate": "Rate", - "remaining": "Remaining", - "downloaded": "Downloaded" + "rate": "速率", + "remaining": "剩餘", + "downloaded": "已下載" }, "sabnzbd": { - "rate": "Rate", - "queue": "Queue", - "timeleft": "Time Left" + "rate": "速率", + "queue": "佇列", + "timeleft": "剩餘時間" }, "rutorrent": { "active": "Active", - "upload": "Upload", - "download": "Download" + "upload": "上傳", + "download": "下載" }, "radarr": { - "movies": "Movies", - "wanted": "Wanted", - "queued": "Queued", - "missing": "Missing" + "movies": "電影", + "wanted": "欲觀看", + "queued": "已加入佇列", + "missing": "遺失" }, "sonarr": { - "wanted": "Wanted", - "queued": "Queued", - "series": "Series" + "wanted": "欲觀看", + "queued": "已加入佇列", + "series": "系列" }, "readarr": { - "wanted": "Wanted", - "queued": "Queued", - "books": "Books" + "wanted": "欲觀看", + "queued": "已加入佇列", + "books": "書籍" }, "ombi": { - "pending": "Pending", - "approved": "Approved", - "available": "Available" + "pending": "待定", + "approved": "已接受", + "available": "可用的" }, "overseerr": { - "pending": "Pending", - "approved": "Approved", - "available": "Available", - "processing": "Processing" + "pending": "待定", + "approved": "已接受", + "available": "可用的", + "processing": "處理中" }, "pihole": { - "queries": "Queries", - "blocked": "Blocked", + "queries": "查詢", + "blocked": "已阻擋", "gravity": "Gravity" }, "speedtest": { - "upload": "Upload", - "download": "Download", + "upload": "上行", + "download": "下行", "ping": "Ping" }, "portainer": { - "running": "Running", - "stopped": "Stopped", - "total": "Total" + "running": "運行中", + "stopped": "已停止", + "total": "總數" }, "traefik": { - "routers": "Routers", - "services": "Services", - "middleware": "Middleware" + "routers": "路由器", + "services": "服務", + "middleware": "中介軟體" }, "gotify": { "clients": "Clients", @@ -118,8 +118,8 @@ "messages": "Messages" }, "npm": { - "enabled": "Enabled", - "disabled": "Disabled", + "enabled": "已啟用", + "disabled": "已停用", "total": "Total" }, "coinmarketcap": { @@ -137,8 +137,8 @@ "numberOfFailQueries": "Fail Queries" }, "transmission": { - "download": "Download", - "upload": "Upload", + "download": "下載", + "upload": "上傳", "leech": "Leech", "seed": "Seed" }, @@ -147,23 +147,23 @@ "errored": "Errored" }, "bazarr": { - "missingEpisodes": "Missing Episodes", - "missingMovies": "Missing Movies" + "missingEpisodes": "缺失的劇集", + "missingMovies": "缺失的電影" }, "lidarr": { - "wanted": "Wanted", - "queued": "Queued", - "albums": "Albums" + "wanted": "欲觀看", + "queued": "已加入佇列", + "albums": "專輯" }, "adguard": { - "queries": "Queries", - "blocked": "Blocked", - "filtered": "Filtered", - "latency": "Latency" + "queries": "查詢", + "blocked": "已阻擋", + "filtered": "已過濾", + "latency": "延遲" }, "qbittorrent": { - "download": "Download", - "upload": "Upload", + "download": "下載", + "upload": "上傳", "leech": "Leech", "seed": "Seed" }, @@ -190,25 +190,25 @@ "vms": "VMs" }, "unifi": { - "users": "Users", - "uptime": "System Uptime", - "days": "Days", + "users": "使用者", + "uptime": "系統運行時間", + "days": "天", "wan": "WAN", - "lan_users": "LAN Users", - "wlan_users": "WLAN Users", + "lan_users": "LAN使用者", + "wlan_users": "WLAN使用者", "up": "UP", "down": "DOWN", - "wait": "Please wait", + "wait": "請稍後", "lan": "LAN", "wlan": "WLAN", - "devices": "Devices", - "lan_devices": "LAN Devices", - "wlan_devices": "WLAN Devices" + "devices": "設備", + "lan_devices": "LAN設備", + "wlan_devices": "WLAN設備" }, "plex": { - "streams": "Active Streams", - "movies": "Movies", - "tv": "TV Shows" + "streams": "正在串流", + "movies": "電影", + "tv": "影集" }, "glances": { "cpu": "CPU", @@ -313,8 +313,8 @@ "time": "{{value, number(style: unit; unitDisplay: long;)}}" }, "navidrome": { - "nothing_streaming": "No Active Streams", - "please_wait": "Please Wait" + "nothing_streaming": "暫無撥放", + "please_wait": "請稍後" }, "pyload": { "speed": "Speed", @@ -332,7 +332,7 @@ "hd": "HD" }, "ping": { - "error": "Error", + "error": "錯誤", "ping": "Ping" }, "scrutiny": { @@ -345,22 +345,22 @@ "total": "Total" }, "deluge": { - "download": "Download", - "upload": "Upload", + "download": "下載", + "upload": "上傳", "leech": "Leech", "seed": "Seed" }, "flood": { - "download": "Download", - "upload": "Upload", + "download": "下載", + "upload": "上傳", "leech": "Leech", "seed": "Seed" }, "tdarr": { - "queue": "Queue", - "processed": "Processed", - "errored": "Errored", - "saved": "Saved" + "queue": "佇列", + "processed": "已處理", + "errored": "錯誤", + "saved": "已儲存" }, "miniflux": { "read": "Read", @@ -375,15 +375,15 @@ "bibitrate": "{{value, rate(bits: true; binary: true)}}" }, "omada": { - "connectedAp": "Connected APs", - "activeUser": "Active devices", - "alerts": "Alerts", - "connectedGateway": "Connected gateways", - "connectedSwitches": "Connected switches" + "connectedAp": "已連接的存取點", + "activeUser": "在線裝置", + "alerts": "警示", + "connectedGateway": "已連接的閘道", + "connectedSwitches": "已連接的交換器" }, "downloadstation": { - "download": "Download", - "upload": "Upload", + "download": "下載", + "upload": "上傳", "leech": "Leech", "seed": "Seed" }, diff --git a/src/components/widgets/datetime/datetime.jsx b/src/components/widgets/datetime/datetime.jsx index 88b25e2d9..869834736 100644 --- a/src/components/widgets/datetime/datetime.jsx +++ b/src/components/widgets/datetime/datetime.jsx @@ -13,22 +13,23 @@ const textSizes = { }; export default function DateTime({ options }) { - const { text_size: textSize, format } = options; + const { text_size: textSize, locale, format } = options; const { i18n } = useTranslation(); const [date, setDate] = useState(""); + const dateLocale = locale ?? i18n.language; useEffect(() => { - const dateFormat = new Intl.DateTimeFormat(i18n.language, { ...format }); + const dateFormat = new Intl.DateTimeFormat(dateLocale, { ...format }); const interval = setInterval(() => { setDate(dateFormat.format(new Date())); }, 1000); return () => clearInterval(interval); - }, [date, setDate, i18n.language, format]); + }, [date, setDate, dateLocale, format]); return (
- + {date}
diff --git a/src/utils/proxy/handlers/credentialed.js b/src/utils/proxy/handlers/credentialed.js index 5d34264df..10ca2b9c3 100644 --- a/src/utils/proxy/handlers/credentialed.js +++ b/src/utils/proxy/handlers/credentialed.js @@ -30,6 +30,8 @@ export default async function credentialedProxyHandler(req, res, map) { headers["X-gotify-Key"] = `${widget.key}`; } else if (widget.type === "authentik") { headers.Authorization = `Bearer ${widget.key}`; + } else if (widget.type === "truenas") { + headers.Authorization = `Bearer ${widget.key}`; } else if (widget.type === "proxmox") { headers.Authorization = `PVEAPIToken=${widget.username}=${widget.password}`; } else if (widget.type === "autobrr") { diff --git a/src/utils/proxy/use-widget-api.js b/src/utils/proxy/use-widget-api.js index 05eb220ec..f9235d787 100644 --- a/src/utils/proxy/use-widget-api.js +++ b/src/utils/proxy/use-widget-api.js @@ -4,8 +4,8 @@ import { formatProxyUrl } from "./api-helpers"; export default function useWidgetAPI(widget, ...options) { const config = {}; - if (options?.refreshInterval) { - config.refreshInterval = options.refreshInterval; + if (options && options[1]?.refreshInterval) { + config.refreshInterval = options[1].refreshInterval; } const { data, error } = useSWR(formatProxyUrl(widget, ...options), config); // make the data error the top-level error diff --git a/src/widgets/downloadstation/proxy.js b/src/widgets/downloadstation/proxy.js index dc76a3cb9..73a6a259e 100644 --- a/src/widgets/downloadstation/proxy.js +++ b/src/widgets/downloadstation/proxy.js @@ -5,10 +5,8 @@ import widgets from "widgets/widgets"; import getServiceWidget from "utils/config/service-helpers"; const logger = createLogger("downloadstationProxyHandler"); -const authApi = "{url}/webapi/auth.cgi?api=SYNO.API.Auth&version=2&method=login&account={username}&passwd={password}&session=DownloadStation&format=cookie" -async function login(widget) { - const loginUrl = formatApiCall(authApi, widget); +async function login(loginUrl) { const [status, contentType, data] = await httpProxy(loginUrl); if (status !== 200) { return [status, contentType, data]; @@ -56,8 +54,28 @@ export default async function downloadstationProxyHandler(req, res) { const json = JSON.parse(data.toString()); if (json?.success !== true) { - logger.debug("Logging in to DownloadStation"); - [status, contentType, data] = await login(widget); + logger.debug("Attempting login to DownloadStation"); + + const apiInfoUrl = formatApiCall("{url}/webapi/query.cgi?api=SYNO.API.Info&version=1&method=query", widget); + let path = "entry.cgi"; + let maxVersion = 7; + [status, contentType, data] = await httpProxy(apiInfoUrl); + if (status === 200) { + try { + const apiAuthInfo = JSON.parse(data.toString()).data['SYNO.API.Auth']; + if (apiAuthInfo) { + path = apiAuthInfo.path; + maxVersion = apiAuthInfo.maxVersion; + logger.debug(`Deteceted Downloadstation auth API path: ${path} and maxVersion: ${maxVersion}`); + } + } catch { + logger.debug(`Error ${status} obtaining DownloadStation API info`); + } + } + + const authApi = `{url}/webapi/${path}?api=SYNO.API.Auth&version=${maxVersion}&method=login&account={username}&passwd={password}&session=DownloadStation&format=cookie` + const loginUrl = formatApiCall(authApi, widget); + [status, contentType, data] = await login(loginUrl); if (status !== 200) { return res.status(status).end(data) } diff --git a/src/widgets/truenas/widget.js b/src/widgets/truenas/widget.js index 4c479e9f3..3139019bc 100644 --- a/src/widgets/truenas/widget.js +++ b/src/widgets/truenas/widget.js @@ -1,9 +1,31 @@ import { jsonArrayFilter } from "utils/proxy/api-helpers"; +import credentialedProxyHandler from "utils/proxy/handlers/credentialed"; import genericProxyHandler from "utils/proxy/handlers/generic"; +import getServiceWidget from "utils/config/service-helpers"; const widget = { api: "{url}/api/v2.0/{endpoint}", - proxyHandler: genericProxyHandler, + proxyHandler: async (req, res, map) => { // choose proxy handler based on widget settings + const { group, service } = req.query; + + if (group && service) { + const widgetOpts = await getServiceWidget(group, service); + let handler; + if (widgetOpts.username && widgetOpts.password) { + handler = genericProxyHandler; + } else if (widgetOpts.key) { + handler = credentialedProxyHandler; + } + + if (handler) { + return handler(req, res, map); + } + + return res.status(500).json({ error: "Username / password or API key required" }); + } + + return res.status(500).json({ error: "Error parsing widget request" }); + }, mappings: { alerts: {