diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/DISCUSSION_TEMPLATE/feature-requests.yml similarity index 85% rename from .github/ISSUE_TEMPLATE/feature_request.yml rename to .github/DISCUSSION_TEMPLATE/feature-requests.yml index 5ddcb12e..96e5ef2a 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/DISCUSSION_TEMPLATE/feature-requests.yml @@ -1,5 +1,3 @@ -name: Feature request -description: Suggest an idea for this project title: "[Feature Request] " labels: ["enhancement"] body: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..a2ae1dfb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,11 @@ +blank_issues_enabled: false +contact_links: + - name: 🤔 Questions and Help + url: https://github.com/benphelps/homepage/discussions + about: This issue tracker is for bugs only, not general support questions. Please refer to our Discussions. + - name: 💬 Chat + url: https://discord.gg/k4ruYNrudu + about: Want to discuss homepage with others? Check out our chat. + - name: 🚀 Feature Request + url: https://github.com/benphelps/homepage/discussions/new?category=feature-requests + about: Remember to search for existing feature requests and "up-vote" any you like diff --git a/Dockerfile b/Dockerfile index 1d9a4931..9fec35e7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,7 @@ COPY . . SHELL ["/bin/ash", "-xeo", "pipefail", "-c"] RUN npm run telemetry \ - && mkdir config && echo '---' > config/settings.yaml \ + && mkdir config \ && NEXT_PUBLIC_BUILDTIME=$BUILDTIME NEXT_PUBLIC_VERSION=$VERSION NEXT_PUBLIC_REVISION=$REVISION npm run build # Production image, copy all the files and run next diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index bf443461..c2858808 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -10,6 +10,8 @@ export PGID=${PGID:-0} # while also supporting the lscr.io /config directory [ ! -d "/app/config" ] && ln -s /config /app/config +export HOMEPAGE_BUILDTIME=$(date +%s) + # Set privileges for /app but only if pid 1 user is root and we are dropping privileges. # If container is run as an unprivileged user, it means owner already handled ownership setup on their own. # Running chown in that case (as non-root) will cause error diff --git a/package-lock.json b/package-lock.json index cacce469..0691562c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "minecraft-ping-js": "^1.0.2", "next": "^12.3.1", "next-i18next": "^12.0.1", - "osx-temperature-sensor": "^1.0.8", + "osx-temperature-sensor": "*", "pretty-bytes": "^6.0.0", "raw-body": "^2.5.1", "react": "^18.2.0", @@ -52,6 +52,9 @@ "tailwind-scrollbar": "^2.0.1", "tailwindcss": "^3.1.8", "typescript": "^4.8.3" + }, + "optionalDependencies": { + "osx-temperature-sensor": "^1.0.8" } }, "node_modules/@babel/runtime": { @@ -4034,6 +4037,7 @@ "resolved": "https://registry.npmjs.org/osx-temperature-sensor/-/osx-temperature-sensor-1.0.8.tgz", "integrity": "sha512-Gl3b+bn7+oDDnqPa+4v/cg3yg9lnE8ppS7ivL3opBZh4i7h99JNmkm6zWmo0m2a83UUJu+C9D7lGP0OS8IlehA==", "hasInstallScript": true, + "optional": true, "os": [ "darwin" ], diff --git a/package.json b/package.json index ee6e7af6..b46cea8d 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,6 @@ "minecraft-ping-js": "^1.0.2", "next": "^12.3.1", "next-i18next": "^12.0.1", - "osx-temperature-sensor": "^1.0.8", "pretty-bytes": "^6.0.0", "raw-body": "^2.5.1", "react": "^18.2.0", @@ -54,5 +53,8 @@ "tailwind-scrollbar": "^2.0.1", "tailwindcss": "^3.1.8", "typescript": "^4.8.3" + }, + "optionalDependencies": { + "osx-temperature-sensor": "^1.0.8" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ec4bc025..344998b0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,9 +40,6 @@ dependencies: next-i18next: specifier: ^12.0.1 version: 12.1.0(next@12.3.4)(react-dom@18.2.0)(react@18.2.0) - osx-temperature-sensor: - specifier: ^1.0.8 - version: 1.0.8 pretty-bytes: specifier: ^6.0.0 version: 6.1.0 @@ -80,6 +77,11 @@ dependencies: specifier: ^1.6.11 version: 1.6.11 +optionalDependencies: + osx-temperature-sensor: + specifier: ^1.0.8 + version: 1.0.8 + devDependencies: '@tailwindcss/forms': specifier: ^0.5.3 @@ -645,6 +647,7 @@ packages: /autoprefixer@10.4.14(postcss@8.4.21): resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} engines: {node: ^10 || ^12 || >=14} + hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: @@ -1221,6 +1224,7 @@ packages: /eslint-config-prettier@8.8.0(eslint@8.37.0): resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} + hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: @@ -2374,6 +2378,7 @@ packages: /next@12.3.4(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-VcyMJUtLZBGzLKo3oMxrEF0stxh8HwuW976pAzlHhI3t8qJ4SROjCrSh1T24bhrbjw55wfZXAbXPGwPt5FLRfQ==} engines: {node: '>=12.22.0'} + hasBin: true peerDependencies: fibers: '>= 3.1.0' node-sass: ^6.0.0 || ^7.0.0 @@ -2574,6 +2579,7 @@ packages: os: [darwin] requiresBuild: true dev: false + optional: true /p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} @@ -3229,6 +3235,7 @@ packages: /tailwindcss@3.3.0(postcss@8.4.21): resolution: {integrity: sha512-hOXlFx+YcklJ8kXiCAfk/FMyr4Pm9ck477G0m/us2344Vuj355IpoEDB5UmGAsSpTBmr+4ZhjzW04JuFXkb/fw==} engines: {node: '>=12.13.0'} + hasBin: true peerDependencies: postcss: ^8.0.9 dependencies: @@ -3450,6 +3457,7 @@ packages: /update-browserslist-db@1.0.10(browserslist@4.21.5): resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} + hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: diff --git a/public/locales/ca/common.json b/public/locales/ca/common.json index cf001534..0dc8e8e9 100644 --- a/public/locales/ca/common.json +++ b/public/locales/ca/common.json @@ -183,7 +183,7 @@ "qbittorrent": { "download": "Descàrrega", "upload": "Pujada", - "leech": "Company", + "leech": "Companys", "seed": "Llavors" }, "mastodon": { diff --git a/public/locales/el/common.json b/public/locales/el/common.json new file mode 100644 index 00000000..fa32d935 --- /dev/null +++ b/public/locales/el/common.json @@ -0,0 +1,566 @@ +{ + "resources": { + "used": "Used", + "load": "Load", + "cpu": "CPU", + "mem": "MEM", + "temp": "TEMP", + "total": "Total", + "free": "Free", + "max": "Max", + "uptime": "UP", + "months": "mo", + "days": "d", + "hours": "h", + "minutes": "m" + }, + "omada": { + "activeUser": "Active devices", + "alerts": "Alerts", + "connectedAp": "Connected APs", + "connectedGateway": "Connected gateways", + "connectedSwitches": "Connected switches" + }, + "wmo": { + "0-night": "Clear", + "65-day": "Heavy Rain", + "65-night": "Heavy Rain", + "0-day": "Sunny", + "1-day": "Mainly Sunny", + "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", + "66-day": "Freezing Rain", + "66-night": "Freezing Rain", + "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", + "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" + }, + "common": { + "bibyterate": "{{value, rate(bits: false; binary: true)}}", + "bibitrate": "{{value, rate(bits: true; binary: true)}}" + }, + "widget": { + "missing_type": "Missing Widget Type: {{type}}", + "api_error": "API Error", + "information": "Information", + "status": "Status", + "url": "URL", + "raw_error": "Raw Error", + "response_data": "Response Data" + }, + "weather": { + "current": "Current Location", + "allow": "Click to allow", + "updating": "Updating", + "wait": "Please wait" + }, + "search": { + "placeholder": "Search…" + }, + "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", + "empty_data": "Subsystem status unknown" + }, + "docker": { + "rx": "RX", + "tx": "TX", + "mem": "MEM", + "cpu": "CPU", + "running": "Running", + "offline": "Offline", + "error": "Error", + "unknown": "Unknown", + "healthy": "Healthy", + "exited": "Exited", + "starting": "Starting", + "partial": "Partial", + "unhealthy": "Unhealthy", + "not_found": "Not Found" + }, + "ping": { + "error": "Error", + "ping": "Ping" + }, + "emby": { + "playing": "Playing", + "transcoding": "Transcoding", + "bitrate": "Bitrate", + "no_active": "No Active Streams", + "movies": "Movies", + "series": "Series", + "episodes": "Episodes", + "songs": "Songs" + }, + "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" + }, + "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" + }, + "sonarr": { + "series": "Series", + "wanted": "Wanted", + "queued": "Queued" + }, + "downloadstation": { + "download": "Download", + "upload": "Upload", + "leech": "Leech", + "seed": "Seed" + }, + "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" + }, + "navidrome": { + "nothing_streaming": "No Active Streams", + "please_wait": "Please Wait" + }, + "npm": { + "enabled": "Enabled", + "disabled": "Disabled", + "total": "Total" + }, + "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" + }, + "strelaysrv": { + "numActiveSessions": "Sessions", + "numConnections": "Connections", + "dataRelayed": "Relayed", + "transferRate": "Rate" + }, + "jackett": { + "configured": "Configured", + "errored": "Errored" + }, + "mastodon": { + "user_count": "Users", + "status_count": "Posts", + "domain_count": "Domains" + }, + "medusa": { + "wanted": "Wanted", + "queued": "Queued", + "series": "Series" + }, + "minecraft": { + "players": "Players", + "version": "Version", + "down": "Offline", + "status": "Status", + "up": "Online" + }, + "miniflux": { + "read": "Read", + "unread": "Unread" + }, + "authentik": { + "users": "Users", + "loginsLast24H": "Logins (24h)", + "failedLoginsLast24H": "Failed Logins (24h)" + }, + "proxmox": { + "mem": "MEM", + "cpu": "CPU", + "lxc": "LXC", + "vms": "VMs" + }, + "glances": { + "cpu": "CPU", + "mem": "MEM", + "wait": "Please wait", + "temp": "TEMP", + "uptime": "UP", + "days": "d", + "hours": "h" + }, + "quicklaunch": { + "bookmark": "Bookmark", + "service": "Service", + "search": "Search", + "custom": "Custom", + "visit": "Visit", + "url": "URL" + }, + "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}}", + "up": "Up", + "pending": "Pending", + "down": "Down" + }, + "healthchecks": { + "new": "New", + "up": "Online", + "grace": "In Grace Period", + "down": "Offline", + "paused": "Paused", + "status": "Status", + "last_ping": "Last Ping", + "never": "No pings yet" + }, + "watchtower": { + "containers_scanned": "Scanned", + "containers_updated": "Updated", + "containers_failed": "Failed" + }, + "autobrr": { + "approvedPushes": "Approved", + "rejectedPushes": "Rejected", + "filters": "Filters", + "indexers": "Indexers" + }, + "tubearchivist": { + "downloads": "Queue", + "videos": "Videos", + "channels": "Channels", + "playlists": "Playlists" + }, + "truenas": { + "load": "System Load", + "uptime": "Uptime", + "alerts": "Alerts", + "time": "{{value, number(style: unit; unitDisplay: long;)}}" + }, + "pyload": { + "speed": "Speed", + "active": "Active", + "queue": "Queue", + "total": "Total" + }, + "gluetun": { + "public_ip": "Public IP", + "region": "Region", + "country": "Country" + }, + "hdhomerun": { + "channels": "Channels", + "hd": "HD" + }, + "scrutiny": { + "passed": "Passed", + "failed": "Failed", + "unknown": "Unknown" + }, + "paperlessngx": { + "inbox": "Inbox", + "total": "Total" + }, + "nextdns": { + "wait": "Please Wait", + "no_devices": "No Device Data Received" + }, + "mikrotik": { + "cpuLoad": "CPU Load", + "memoryUsed": "Memory Used", + "uptime": "Uptime", + "numberOfLeases": "Leases" + }, + "xteve": { + "streams_all": "All Streams", + "streams_active": "Active Streams", + "streams_xepg": "XEPG Channels" + }, + "opnsense": { + "cpu": "CPU Load", + "memory": "Active Memory", + "wanUpload": "WAN Upload", + "wanDownload": "WAN Download" + }, + "moonraker": { + "printer_state": "Printer State", + "print_status": "Print Status", + "print_progress": "Progress", + "layers": "Layers" + }, + "octoprint": { + "printer_state": "Status", + "temp_tool": "Tool temp", + "temp_bed": "Bed temp", + "job_completion": "Completion" + }, + "cloudflared": { + "origin_ip": "Origin IP", + "status": "Status" + }, + "proxmoxbackupserver": { + "datastore_usage": "Datastore", + "failed_tasks_24h": "Failed Tasks 24h", + "cpu_usage": "CPU", + "memory_usage": "Memory" + }, + "immich": { + "users": "Users", + "photos": "Photos", + "videos": "Videos", + "storage": "Storage" + }, + "uptimekuma": { + "up": "Sites Up", + "down": "Sites Down", + "uptime": "Uptime", + "incident": "Incident", + "m": "m" + }, + "komga": { + "libraries": "Libraries", + "series": "Series", + "books": "Books" + }, + "diskstation": { + "days": "Days", + "uptime": "Uptime", + "volumeAvailable": "Available" + }, + "mylar": { + "series": "Series", + "issues": "Issues", + "wanted": "Wanted" + }, + "photoprism": { + "albums": "Albums", + "photos": "Photos", + "videos": "Videos", + "people": "People" + }, + "fileflows": { + "processed": "Processed", + "queue": "Queue", + "processing": "Processing", + "time": "Time" + }, + "grafana": { + "dashboards": "Dashboards", + "datasources": "Data Sources", + "totalalerts": "Total Alerts", + "alertstriggered": "Alerts Triggered" + }, + "nextcloud": { + "cpuload": "Cpu Load", + "memoryusage": "Memory Usage", + "freespace": "Free Space", + "activeusers": "Active Users" + }, + "kopia": { + "status": "Status", + "size": "Size", + "lastrun": "Last Run", + "nextrun": "Next Run", + "failed": "Failed" + }, + "unmanic": { + "active_workers": "Active Workers", + "total_workers": "Total Workers", + "records_total": "Queue Length" + }, + "pterodactyl": { + "servers": "Servers", + "nodes": "Nodes" + }, + "prometheus": { + "targets_up": "Targets Up", + "targets_down": "Targets Down", + "targets_total": "Total Targets" + }, + "ghostfolio": { + "gross_percent_today": "Today", + "gross_percent_1y": "One year", + "gross_percent_max": "All time" + }, + "audiobookshelf": { + "podcasts": "Podcasts", + "books": "Books", + "podcastsDuration": "Duration", + "booksDuration": "Duration" + } +} diff --git a/public/locales/es/common.json b/public/locales/es/common.json index 827b6cc4..4ea0c934 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -19,7 +19,7 @@ "cpu": "CPU", "mem": "MEM", "temp": "TEMPORAL", - "max": "Máximo", + "max": "Máx.", "uptime": "ARRIBA", "months": "Meses", "days": "Días", @@ -118,7 +118,7 @@ "current": "Ubicación actual", "allow": "Clic para permitir", "updating": "Actualizando", - "wait": "Espere, por favor" + "wait": "Espera, por favor" }, "overseerr": { "pending": "Pendiente", @@ -183,7 +183,7 @@ "qbittorrent": { "download": "Bajada", "upload": "Subida", - "leech": "Depender", + "leech": "Compañeros", "seed": "Semillas" }, "mastodon": { @@ -228,7 +228,7 @@ "plex": { "streams": "Transmisiones activas", "movies": "Películas", - "tv": "Programas de TV" + "tv": "Series" }, "glances": { "cpu": "Procesador", @@ -425,8 +425,8 @@ "numberOfLeases": "Alquileres" }, "xteve": { - "streams_all": "Todas las corrientes", - "streams_active": "Corrientes activas", + "streams_all": "Todos los flujos", + "streams_active": "Flujos activos", "streams_xepg": "Canales XEPG" }, "opnsense": { @@ -448,8 +448,8 @@ }, "octoprint": { "temp_bed": "temperatura de la plataforma", - "printer_state": "Status", - "temp_tool": "Herramienta de temperatura", + "printer_state": "Estado", + "temp_tool": "Temperatura de herramienta", "job_completion": "Finalización" }, "cloudflared": { diff --git a/public/locales/fr/common.json b/public/locales/fr/common.json index eb9ca02a..7a30263d 100644 --- a/public/locales/fr/common.json +++ b/public/locales/fr/common.json @@ -24,7 +24,7 @@ "months": "mo", "days": "d", "hours": "h", - "minutes": "m" + "minutes": "mn" }, "docker": { "rx": "Rx", diff --git a/public/locales/pl/common.json b/public/locales/pl/common.json index 8468c580..8c332f3d 100644 --- a/public/locales/pl/common.json +++ b/public/locales/pl/common.json @@ -15,13 +15,13 @@ "free": "Wolne", "cpu": "CPU", "mem": "PAM", - "temp": "TEMP", + "temp": "TYMCZASOWE", "max": "Max", "uptime": "UP", - "months": "mo", - "days": "d", + "months": "misiąc", + "days": "dni", "hours": "h", - "minutes": "m" + "minutes": "minuty" }, "emby": { "no_active": "Brak aktywnych strumieni", @@ -79,7 +79,7 @@ "error": "Błąd", "unknown": "Nieznany", "running": "Działa", - "starting": "Starting", + "starting": "Startować", "unhealthy": "Unhealthy", "not_found": "Not Found", "exited": "Exited", diff --git a/src/components/services/group.jsx b/src/components/services/group.jsx index 13b745fd..7b7e2e87 100644 --- a/src/components/services/group.jsx +++ b/src/components/services/group.jsx @@ -8,7 +8,7 @@ export default function ServicesGroup({ services, layout }) {
diff --git a/src/components/widgets/resources/cputemp.jsx b/src/components/widgets/resources/cputemp.jsx index 92c684e5..571e6c8a 100644 --- a/src/components/widgets/resources/cputemp.jsx +++ b/src/components/widgets/resources/cputemp.jsx @@ -47,16 +47,14 @@ export default function CpuTemp({ expanded, units }) { ); } - let minTemp = 0; let mainTemp = data.cputemp.main; if (data.cputemp.cores?.length) { mainTemp = data.cputemp.cores.reduce((a, b) => a + b) / data.cputemp.cores.length; - minTemp = Math.min(...data.cputemp.cores); } const unit = units === "imperial" ? "fahrenheit" : "celsius"; mainTemp = (unit === "celsius") ? mainTemp : convertToFahrenheit(mainTemp); const maxTemp = (unit === "celsius") ? data.cputemp.max : convertToFahrenheit(data.cputemp.max); - const percent = Math.round(((mainTemp - minTemp) / (maxTemp - minTemp)) * 100); + const percent = Math.round((mainTemp / maxTemp) * 100); return (
diff --git a/src/pages/api/hash.js b/src/pages/api/hash.js index fac3ad05..96369134 100644 --- a/src/pages/api/hash.js +++ b/src/pages/api/hash.js @@ -19,8 +19,8 @@ export default async function handler(req, res) { return hash(readFileSync(configYaml, "utf8")); }); - // this ties hash to specific build which should force revaliation between versions - const buildTime = process.env.NEXT_PUBLIC_BUILDTIME?.length ? process.env.NEXT_PUBLIC_BUILDTIME : ''; + // set to date by docker entrypoint, will force revalidation between restarts/recreates + const buildTime = process.env.HOMEPAGE_BUILDTIME?.length ? process.env.HOMEPAGE_BUILDTIME : ''; const combinedHash = hash(hashes.join("") + buildTime); diff --git a/src/utils/config/config.js b/src/utils/config/config.js index 1644917e..f312560d 100644 --- a/src/utils/config/config.js +++ b/src/utils/config/config.js @@ -1,6 +1,6 @@ /* eslint-disable no-console */ import { join } from "path"; -import { existsSync, copyFile, readFileSync } from "fs"; +import { existsSync, readFileSync, copyFileSync } from "fs"; import cache from "memory-cache"; import yaml from "js-yaml"; @@ -13,13 +13,13 @@ export default function checkAndCopyConfig(config) { const configYaml = join(process.cwd(), "config", config); if (!existsSync(configYaml)) { const configSkeleton = join(process.cwd(), "src", "skeleton", config); - copyFile(configSkeleton, configYaml, (err) => { - if (err) { + try { + copyFileSync(configSkeleton, configYaml) + console.info("%s was copied to the config folder", config); + } catch (err) { console.error("error copying config", err); throw err; - } - console.info("%s was copied to the config folder", config); - }); + } return true; } diff --git a/src/utils/config/service-helpers.js b/src/utils/config/service-helpers.js index f739f05f..8795e8bf 100644 --- a/src/utils/config/service-helpers.js +++ b/src/utils/config/service-helpers.js @@ -4,7 +4,7 @@ import path from "path"; import yaml from "js-yaml"; import Docker from "dockerode"; import * as shvl from "shvl"; -import { NetworkingV1Api } from "@kubernetes/client-node"; +import { CustomObjectsApi, NetworkingV1Api } from "@kubernetes/client-node"; import createLogger from "utils/logger"; import checkAndCopyConfig, { substituteEnvironmentVars } from "utils/config/config"; @@ -145,6 +145,7 @@ export async function servicesFromKubernetes() { return []; } const networking = kc.makeApiClient(NetworkingV1Api); + const crd = kc.makeApiClient(CustomObjectsApi); const ingressList = await networking.listIngressForAllNamespaces(null, null, null, null) .then((response) => response.body) @@ -152,6 +153,20 @@ export async function servicesFromKubernetes() { logger.error("Error getting ingresses: %d %s %s", error.statusCode, error.body, error.response); return null; }); + + const traefikIngressList = await crd.listClusterCustomObject("traefik.containo.us", "v1alpha1", "ingressroutes") + .then((response) => response.body) + .catch((error) => { + logger.error("Error getting traefik ingresses: %d %s %s", error.statusCode, error.body, error.response); + return null; + }); + + if (traefikIngressList && traefikIngressList.items.length > 0) { + const traefikServices = traefikIngressList.items + .filter((ingress) => ingress.metadata.annotations && ingress.metadata.annotations[`${ANNOTATION_BASE}/href`]) + ingressList.items.push(...traefikServices); + } + if (!ingressList) { return []; } @@ -282,8 +297,8 @@ export function cleanServiceGroups(groups) { if (wan) cleanedService.widget.wan = wan; } if (type === "emby" || type === "jellyfin") { - if (enableBlocks) cleanedService.widget.enableBlocks = enableBlocks; - if (enableNowPlaying) cleanedService.widget.enableNowPlaying = enableNowPlaying; + if (enableBlocks !== undefined) cleanedService.widget.enableBlocks = enableBlocks; + if (enableNowPlaying !== undefined) cleanedService.widget.enableNowPlaying = enableNowPlaying; } if (type === "diskstation") { if (volume) cleanedService.widget.volume = volume; diff --git a/src/utils/proxy/use-widget-api.js b/src/utils/proxy/use-widget-api.js index f9235d78..52e986e1 100644 --- a/src/utils/proxy/use-widget-api.js +++ b/src/utils/proxy/use-widget-api.js @@ -7,7 +7,7 @@ export default function useWidgetAPI(widget, ...options) { if (options && options[1]?.refreshInterval) { config.refreshInterval = options[1].refreshInterval; } - const { data, error } = useSWR(formatProxyUrl(widget, ...options), config); + const { data, error, mutate } = useSWR(formatProxyUrl(widget, ...options), config); // make the data error the top-level error - return { data, error: data?.error ?? error } + return { data, error: data?.error ?? error, mutate } } diff --git a/src/utils/proxy/validate-widget-data.js b/src/utils/proxy/validate-widget-data.js index c498357d..57adc942 100644 --- a/src/utils/proxy/validate-widget-data.js +++ b/src/utils/proxy/validate-widget-data.js @@ -3,10 +3,14 @@ import widgets from "widgets/widgets"; export default function validateWidgetData(widget, endpoint, data) { let valid = true; let dataParsed; - try { - dataParsed = JSON.parse(data); - } catch (e) { - valid = false; + if (typeof data === 'object') { + dataParsed = data; + } else { + try { + dataParsed = JSON.parse(data); + } catch (e) { + valid = false; + } } if (dataParsed && Object.entries(dataParsed).length) { diff --git a/src/widgets/emby/component.jsx b/src/widgets/emby/component.jsx index 3f70a79d..0e0351ea 100644 --- a/src/widgets/emby/component.jsx +++ b/src/widgets/emby/component.jsx @@ -272,7 +272,7 @@ export default function Component({ service }) { ); } - if (playing.length === -1) + if (playing.length > 0) return ( <> {enableBlocks && } diff --git a/tailwind.config.js b/tailwind.config.js index b6e27a30..0d78a6c0 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -25,6 +25,10 @@ module.exports = { 900: "rgb(var(--color-900) / )", }, }, + screens: { + '3xl': '1800px', + // => @media (min-width: 1800px) { ... } + }, }, }, plugins: [tailwindForms, tailwindScrollbars],