Compare commits

...

17 Commits

Author SHA1 Message Date
shamoon
d4a39299c5 Fix k8s traefikingresslist detection (#2030) 2023-09-19 15:00:22 -07:00
shamoon
7d2bfa2d84 Update index.jsx 2023-09-19 14:10:19 -07:00
shamoon
c094bd3d83 Update service-helpers.js 2023-09-19 13:12:03 -07:00
Daniel Li
69ee459e8a Fix: SMART result of OMV should always from monitored devices (#2025) 2023-09-19 08:46:16 -07:00
shamoon
ed0527a3da Fix custom.js not working (#2023) 2023-09-18 21:41:31 -07:00
shamoon
04a1c68ba0 Fix k3d memory specification 2023-09-18 14:35:42 -07:00
Pysta
b74faea449 Translated using Weblate (Slovak)
Currently translated at 24.1% (129 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sk/
2023-09-18 14:23:36 +02:00
avb15621
0c9b6480c5 Translated using Weblate (Dutch)
Currently translated at 53.9% (288 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2023-09-18 14:23:35 +02:00
Roel van de Wiel
6fbb3bfbb1 Translated using Weblate (Dutch)
Currently translated at 53.9% (288 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2023-09-18 14:23:35 +02:00
A Warmerdam
53355561a8 Translated using Weblate (Dutch)
Currently translated at 53.9% (288 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2023-09-18 14:23:35 +02:00
Jan-Philipp Fischer
6e43194f71 Fix: Kubernetes discovery & Check for Custom Resource Definitions (#2003)
* Implement a CRD existence check

* test adding patch
2023-09-17 16:49:03 -07:00
shamoon
a72a27a8b5 Maybe handle k8s traefik ingress routes returns nothing 2023-09-17 10:05:45 -07:00
Ben Phelps
6c682cb648 Update README.md 2023-09-17 11:00:15 +03:00
Ben Phelps
e7587b8308 update readme image 2023-09-17 10:57:37 +03:00
shamoon
e663994c9b Allow tab name 0 2023-09-16 15:24:32 -07:00
shamoon
898fb88d86 Allow numbers in tab name (#2004) 2023-09-16 14:37:06 -07:00
Ben Phelps
6f5c2a8c1e update readme 2023-09-16 22:16:34 +03:00
9 changed files with 270 additions and 261 deletions

134
README.md
View File

@@ -6,71 +6,58 @@
</p>
<p align="center">
A modern <em>(fully static, fast)</em>, secure <em>(fully proxied)</em>, highly customizable application dashboard with integrations for more than 25 services and translations for over 15 languages. Easily configured via YAML files (or discovery via docker labels).
A modern, <em>fully static, fast</em>, secure <em>fully proxied</em>, highly customizable application dashboard with integrations for over 100 services and translations into multiple languages. Easily configured via YAML files or through docker label discovery.
</p>
<p align="center">
<img src="images/1.png" />
<img src="images/1.png?v=2" />
</p>
<p align="center">
<img src="images/2.png" width="19%" />
<img src="images/3.png" width="19%" />
<img src="images/4.png" width="19%" />
<img src="images/5.png" width="19%" />
<img src="images/6.png" width="19%" />
</p>
<p align="center">
<a href="https://discord.gg/k4ruYNrudu"><img src="https://img.shields.io/badge/Discord - Chat-blue?logo=discord&logoColor=white" /></a>
<a href="https://paypal.me/phelpsben" title="Donate"><img src="https://img.shields.io/badge/PayPal - Donate-blue?logo=paypal&logoColor=white" alt="Linkedin - phelpsben"></a>
</p>
<p align="center">
<a href="https://github.com/benphelps/homepage/actions/workflows/docker-publish.yml"><img src="https://github.com/benphelps/homepage/actions/workflows/docker-publish.yml/badge.svg" alt="Docker"></a>
<a href="https://github.com/benphelps/homepage/actions/workflows/docker-publish.yml"><img alt="GitHub Workflow Status (with event)" src="https://img.shields.io/github/actions/workflow/status/benphelps/homepage/docker-publish.yml"></a>
&nbsp;
<a href="https://hosted.weblate.org/engage/homepage/"><img src="https://hosted.weblate.org/widgets/homepage/-/homepage/svg-badge.svg" alt="Weblate"></a>
&nbsp;
<a href="https://discord.gg/k4ruYNrudu"><img alt="Discord" src="https://img.shields.io/discord/1019316731635834932"></a>
&nbsp;
<a href="https://paypal.me/phelpsben" title="Donate"><img alt="GitHub Sponsors" src="https://img.shields.io/github/sponsors/benphelps"></a>
</p>
## Features
# Features
- **Fast!** The entire site is statically generated at build time, so you can expect instant load times
- **Secure!** Every API request to backend services goes through a proxy server, so your API keys are never exposed to the frontend client.
- Images built for AMD64 (x86_64), ARM64, ARMv7 and ARMv6
- Supports all Raspberry Pi's, most SBCs & Apple Silicon
- Full i18n support with translations for Catalan, Chinese, Dutch, Finnish, French, German, Hebrew, Hungarian, Malay, Norwegian Bokmål, Polish, Portuguese, Portuguese (Brazil), Romanian, Russian, Spanish, Swedish and Yue
- Want to help translate? [Join the Weblate project](https://hosted.weblate.org/engage/homepage/)
- Service & Web Bookmarks
- Docker Integration
- Container status (Running / Stopped) & statistics (CPU, Memory, Network)
- Automatic service discovery (via labels)
- Service Integration
- Sonarr, Radarr, Readarr, Prowlarr, Bazarr, Lidarr, Emby, Jellyfin, Tautulli, Plex and more
- Ombi, Overseerr, Jellyseerr, Jackett, NZBGet, SABnzbd, ruTorrent, Transmission, qBittorrent and more
- Portainer, Traefik, Speedtest Tracker, PiHole, AdGuard Home, Nginx Proxy Manager, Gotify, Syncthing Relay Server, Authentik, Proxmox and more
- Information Providers
- Coin Market Cap, Mastodon and more
- Information & Utility Widgets
- System Stats (Disk, CPU, Memory)
- Weather via [OpenWeatherMap](https://openweathermap.org/) or [Open-Meteo](https://open-meteo.com/)
- Web Search Bar
- UniFi Console, Glances and more
- Instant "Quick-launch" search
- Customizable
- 21 theme colors with light and dark mode support
- Background image support
- Column and Row layout options
With features like quick search, bookmarks, weather support, a wide range of integrations and widgets, an elegant and modern design, and a focus on performance, Homepage is your ideal start to the day and a handy companion throughout it.
## Support & Suggestions
- **Fast** - The site is statically generated at build time for instant load times.
- **Secure** - All API requests to backend services are proxied, keeping your API keys hidden. Constantly reviewed for security by the community.
- **For Everyone** - Images built for AMD64, ARM64, ARMv7, and ARMv6.
- **Full i18n** - Support for over 40 languages.
- **Service & Web Bookmarks** - Add custom links to the homepage.
- **Docker Integration** - Container status and stats. Automatic service discovery via labels.
- **Service Integration** - Over 100 service integrations, including popular starr and self-hosted apps.
- **Information & Utility Widgets** - Weather, time, date, search, and more.
- **And much more...**
If you have any questions, suggestions, or general issues, please start a discussion on the [Discussions](https://github.com/benphelps/homepage/discussions) page.
## Docker Integration
For bug reports, please open an issue on the [Issues](https://github.com/benphelps/homepage/issues) page.
Homepage has built-in support for Docker, and can automatically discover and add services to the homepage based on labels. See the [Docker](https://gethomepage.dev/en/installation/docker/) page for more information.
## Getting Started
## Service Widgets
For configuration options, examples and more, [please check out the homepage site](http://gethomepage.dev).
Homepage also has support for over 100 3rd party services, including all popular starr apps, and most popular self-hosted apps. Some examples include: Radarr, Sonarr, Lidarr, Bazarr, Ombi, Tautulli, Plex, Jellyfin, Emby, Transmission, qBittorrent, Deluge, Jackett, NZBGet, SABnzbd, etc. As well as service integrations, Homepage also has a number of information providers, sourcing information from a variety of external 3rd party APIs. See the [Service](https://gethomepage.dev/en/configs/service-widgets/) page for more information.
### With Docker
## Information Widgets
Homepage has built-in support for a number of information providers, including weather, time, date, search, glances and more. System and status information presented at the top of the page. See the [Information Providers](https://gethomepage.dev/en/configs/widgets/) page for more information.
## Customization
Homepage is highly customizable, with support for custom themes, custom CSS & JS, custom layouts, formatting, localization and more. See the [Settings](https://gethomepage.dev/en/configs/settings/) page for more information.
# Getting Started
For configuration options, examples and more, [please check out the homepage documentation](http://gethomepage.dev).
## With Docker
Using docker compose:
@@ -80,22 +67,31 @@ services:
homepage:
image: ghcr.io/benphelps/homepage:latest
container_name: homepage
environment:
PUID: 1000 -- optional, your user id
PGID: 1000 -- optional, your group id
ports:
- 3000:3000
volumes:
- /path/to/config:/app/config # Make sure your local config directory exists
- /var/run/docker.sock:/var/run/docker.sock:ro # (optional) For docker integrations
# user: 1000:1000 optional, not compatibile with direct socket see https://gethomepage.dev/en/configs/docker/#using-socket-directly
- /var/run/docker.sock:/var/run/docker.sock:ro # optional, for docker integrations
restart: unless-stopped
```
or docker run:
```bash
docker run -p 3000:3000 -v /path/to/config:/app/config -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/benphelps/homepage:latest
docker run --name homepage \
-e PUID=1000 \
-e PGID=1000 \
-p 3000:3000 \
-v /path/to/config:/app/config \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
--restart unless-stopped \
ghcr.io/benphelps/homepage:latest
```
### With Node
## With Node
First, clone the repository:
@@ -112,22 +108,23 @@ pnpm build
If this is your first time starting, copy the `src/skeleton` directory to `config/` to populate initial example config files.
Finally, run the server:
Finally, run the server in production mode:
```bash
pnpm start
```
## Configuration
or development mode:
Configuration files will be generated and placed on the first request.
```bash
pnpm dev
```
Configuration is done in the /config directory using .yaml files. Refer to each config for
the specific configuration options.
# Configuration
You may also check [the homepage site](http://gethomepage.dev) for detailed configuration instructions, examples and more.
Please refere to the [homepage documentation](https://gethomepage.dev/) website for more information. Everything you need to know about configuring Homepage is there. Please read everything carefully before asking for help, as most questions are answered there or are simple YAML configuration issues.
## Development
# Development
Install NPM packages, this project uses [pnpm](https://pnpm.io/) (and so should you!):
@@ -145,19 +142,14 @@ Open [http://localhost:3000](http://localhost:3000) to start.
This is a [Next.js](https://nextjs.org/) application, see their documentation for more information:
## Contributors
# Support & Suggestions
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
If you have any questions, suggestions, or general issues, please start a discussion on the [Discussions](https://github.com/benphelps/homepage/discussions) page.
<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->
For bug reports, please open an issue on the [Issues](https://github.com/benphelps/homepage/issues) page.
<!-- ALL-CONTRIBUTORS-LIST:END -->
## Contributing & Contributers
Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information.
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
Thanks to the over 200 contributors who have helped make this project what it is today!

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 KiB

After

Width:  |  Height:  |  Size: 734 KiB

View File

@@ -36,8 +36,8 @@ options:
switchCurrentContext: false
runtime:
gpuRequest: ""
serversMemory: "1024Mi"
agentsMemory: "1024Mi"
serversMemory: "1024MiB"
agentsMemory: "1024MiB"
labels:
- label: foo=bar
nodeFilters:

View File

@@ -1,20 +1,20 @@
{
"widget": {
"missing_type": "Missend Widget Type: {{type}}",
"api_error": "API Error",
"api_error": "API fout",
"status": "Status",
"information": "Informatie",
"url": "URL",
"raw_error": "Raw Fout",
"response_data": "Reactiegegevens"
"raw_error": "Raw Error",
"response_data": "Responsgegevens"
},
"resources": {
"total": "Totaal",
"free": "Vrij",
"used": "Gebruikt",
"load": "Laadt",
"load": "lading",
"cpu": "CPU",
"mem": "MEM",
"mem": "GEH",
"days": "d",
"hours": "h",
"temp": "TEMP",
@@ -31,7 +31,7 @@
"offline": "Offline",
"error": "Fout",
"unknown": "Onbekend",
"running": "Running",
"running": "Lopend",
"starting": "Starten",
"unhealthy": "Ongezond",
"not_found": "Niet Gevonden",
@@ -72,8 +72,8 @@
"playing": "Afspelen",
"transcoding": "Transcodering",
"bitrate": "Bitsnelheid",
"no_active": "Geen Actieve Streams",
"plex_connection_error": "Check Plex Connection"
"no_active": "Geen actieve streams",
"plex_connection_error": "Controleer Plex Connectie"
},
"rutorrent": {
"active": "Actief",
@@ -84,16 +84,16 @@
"wanted": "Gezocht",
"queued": "In de wachtrij",
"series": "Series",
"queue": "Queue",
"unknown": "Unknown"
"queue": "Rij",
"unknown": "Onbekend"
},
"radarr": {
"movies": "Films",
"wanted": "Gezocht",
"queued": "In de wachtrij",
"missing": "Missend",
"queue": "Queue",
"unknown": "Unknown"
"queue": "Rij",
"unknown": "Onbekend"
},
"readarr": {
"wanted": "Gezocht",
@@ -114,7 +114,7 @@
"queries": "Queries",
"blocked": "Geblokkeerd",
"gravity": "Gravity",
"blocked_percent": "Blocked %"
"blocked_percent": "Geblokkerde %"
},
"traefik": {
"routers": "Routers",
@@ -135,15 +135,15 @@
"sabnzbd": {
"rate": "Rate",
"queue": "Wachtrij",
"timeleft": "Time Left"
"timeleft": "Tijd Over"
},
"nzbget": {
"rate": "Rate",
"rate": "Tarief",
"remaining": "Resterend",
"downloaded": "Gedownload"
},
"coinmarketcap": {
"configure": "Configure one or more crypto currencies to track",
"configure": "Configureer een of meer crypto eenheiden om bij te houden",
"1hour": "1 Uur",
"7days": "7 Dagen",
"1day": "1 Dag",
@@ -151,7 +151,7 @@
},
"gotify": {
"apps": "Applicaties",
"clients": "Clients",
"clients": "Cliënten",
"messages": "Berichten"
},
"prowlarr": {
@@ -164,7 +164,7 @@
"transmission": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"leech": "Bloedzuiger",
"seed": "Seed"
},
"jackett": {
@@ -178,28 +178,28 @@
"lidarr": {
"wanted": "Gezocht",
"queued": "In de wachtrij",
"artists": "Artists"
"artists": "Artiesten"
},
"adguard": {
"queries": "Queries",
"blocked": "Geblokkeerd",
"filtered": "Filtered",
"filtered": "Gefilterde",
"latency": "Latency"
},
"qbittorrent": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"leech": "Bloedzuiger",
"seed": "Seed"
},
"mastodon": {
"user_count": "Users",
"user_count": "Gebruikers",
"status_count": "Posts",
"domain_count": "Domeinen"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
"numConnections": "Connections",
"numActiveSessions": "Sessies",
"numConnections": "Connecties",
"dataRelayed": "Relayed",
"transferRate": "Rate"
},
@@ -223,13 +223,13 @@
"wlan_users": "WLAN Gebruikers",
"up": "UP",
"down": "DOWN",
"wait": "Wachten aub",
"wait": "Even geduld",
"lan": "LAN",
"wlan": "WLAN",
"devices": "Apparaten",
"lan_devices": "LAN Apparaten",
"wlan_devices": "WLAN Apparaten",
"empty_data": "Subsystem status onbekend"
"empty_data": "Subsysteem status onbekend"
},
"plex": {
"streams": "Actieve Streams",
@@ -396,7 +396,7 @@
"deluge": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"leech": "Bloedzuiger",
"seed": "Seed"
},
"flood": {
@@ -409,7 +409,7 @@
"queue": "Wachtrij",
"processed": "Processed",
"errored": "Errored",
"saved": "Saved"
"saved": "Opgeslagen"
},
"miniflux": {
"read": "Gelezen",
@@ -424,16 +424,16 @@
"bibitrate": "{{value, rate(bits: true; binary: true)}}"
},
"omada": {
"connectedAp": "Connected APs",
"connectedAp": "Verbonden APs",
"activeUser": "Actieve apparaten",
"alerts": "Meldingen",
"connectedGateway": "Connected gateways",
"connectedSwitches": "Connected switches"
"connectedGateway": "Verbonden gateways",
"connectedSwitches": "Verbonden switches"
},
"downloadstation": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"leech": "Bloedzuiger",
"seed": "Seed"
},
"mikrotik": {
@@ -460,7 +460,7 @@
"layers": "Layers"
},
"medusa": {
"wanted": "Wanted",
"wanted": "Gewild",
"queued": "Queued",
"series": "Series"
},
@@ -589,13 +589,13 @@
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
"subscriptions": "Abonnementen",
"unread": "Ongelezen"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Recordings",
"scheduled": "Scheduled",
"scheduled": "Geplanned",
"passes": "Passes"
},
"whatsupdocker": {
@@ -604,25 +604,25 @@
},
"tailscale": {
"address": "Address",
"expires": "Expires",
"never": "Never",
"last_seen": "Last Seen",
"now": "Now",
"expires": "Verloopt",
"never": "Nooit",
"last_seen": "Laatst Gezien",
"now": "Nu",
"years": "{{number}}y",
"weeks": "{{number}}w",
"days": "{{number}}d",
"hours": "{{number}}h",
"minutes": "{{number}}m",
"seconds": "{{number}}s",
"ago": "{{value}} Ago"
"ago": "{{value}} Geleden"
},
"qnap": {
"cpuUsage": "CPU Usage",
"memUsage": "MEM Usage",
"systemTempC": "System Temp",
"poolUsage": "Pool Usage",
"cpuUsage": "CPU Verbruik",
"memUsage": "MEM Gebruik",
"systemTempC": "Systeem Temperatuur",
"poolUsage": "Pool Gebruik",
"volumeUsage": "Volume Usage",
"invalid": "Invalid"
"invalid": "ongeldig"
},
"pfsense": {
"load": "Load Avg",
@@ -636,21 +636,21 @@
},
"caddy": {
"upstreams": "Upstreams",
"requests": "Current requests",
"requests_failed": "Failed requests"
"requests": "Momentele verzoeken",
"requests_failed": "Gefaalde verzoeken"
},
"evcc": {
"pv_power": "Production",
"pv_power": "Productie",
"battery_soc": "Battery",
"grid_power": "Grid",
"home_power": "Consumption",
"charge_power": "Charger",
"charge_power": "Oplader",
"watt_hour": "Wh"
},
"pialert": {
"total": "Total",
"connected": "Connected",
"new_devices": "New Devices",
"connected": "Verbonden",
"new_devices": "Nieuwe Apparaten",
"down_alerts": "Down Alerts"
},
"jdownloader": {

View File

@@ -2,18 +2,18 @@
"docker": {
"rx": "RX",
"tx": "TX",
"mem": "MEM",
"mem": "RAM",
"cpu": "CPU",
"offline": "Offline",
"error": "Error",
"unknown": "Unknown",
"running": "Running",
"starting": "Starting",
"unhealthy": "Unhealthy",
"not_found": "Not Found",
"exited": "Exited",
"partial": "Partial",
"healthy": "Healthy"
"error": "Chyba",
"unknown": "Neznáme",
"running": "Beží",
"starting": "Spúšťa sa",
"unhealthy": "Nezdravý",
"not_found": "Nenájdené",
"exited": "Ukončené",
"partial": "Čiastočný",
"healthy": "Zdravý"
},
"rutorrent": {
"active": "Active",
@@ -21,10 +21,10 @@
"download": "Download"
},
"tdarr": {
"queue": "Queue",
"processed": "Processed",
"errored": "Errored",
"saved": "Saved"
"queue": "Fronta",
"processed": "Spracované",
"errored": "Chybné",
"saved": "Uložené"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
@@ -144,74 +144,74 @@
"bibitrate": "{{value, rate(bits: true; binary: true)}}"
},
"widget": {
"api_error": "API Error",
"missing_type": "Missing Widget Type: {{type}}",
"information": "Information",
"status": "Status",
"api_error": "Chyba API",
"missing_type": "Chýba typ widgetu: {{type}}",
"information": "Informácia",
"status": "Stav",
"url": "URL",
"raw_error": "Raw Error",
"response_data": "Response Data"
"raw_error": "Nevyriešená chyba",
"response_data": "Dáta odpovede"
},
"weather": {
"current": "Current Location",
"allow": "Click to allow",
"updating": "Updating",
"wait": "Please wait"
"current": "Aktuálna poloha",
"allow": "Klikni pre povolenie",
"updating": "Prebieha aktualizácia",
"wait": "Počkajte prosím"
},
"search": {
"placeholder": "Search…"
"placeholder": "Hľadať…"
},
"resources": {
"cpu": "CPU",
"mem": "MEM",
"total": "Total",
"free": "Free",
"used": "Used",
"load": "Load",
"temp": "TEMP",
"max": "Max",
"uptime": "UP",
"months": "mo",
"mem": "RAM",
"total": "Celkovo",
"free": "Voľné",
"used": "Využité",
"load": "Záťaž",
"temp": "TEPLOTA",
"max": "Max.",
"uptime": "BEŽÍ",
"months": "mes.",
"days": "d",
"hours": "h",
"minutes": "m"
},
"unifi": {
"users": "Users",
"uptime": "System Uptime",
"days": "Days",
"users": "Používatelia",
"uptime": "Doba prevádzky",
"days": "D",
"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"
"devices": "Zariadenia",
"lan_devices": "Zariadenia LAN",
"wlan_devices": "Zariadenia WLAN",
"lan_users": "Používatelia LAN",
"wlan_users": "Používatelia WLAN",
"up": "BEŽÍ",
"down": "NEBEŽÍ",
"wait": "Počkajte prosím",
"empty_data": "Stav podsystému neznámy"
},
"ping": {
"error": "Error",
"ping": "Ping"
"error": "Chyba",
"ping": "Odozva"
},
"emby": {
"playing": "Playing",
"transcoding": "Transcoding",
"bitrate": "Bitrate",
"no_active": "No Active Streams",
"movies": "Movies",
"series": "Series",
"episodes": "Episodes",
"songs": "Songs"
"playing": "Prehrávané",
"transcoding": "Prekódovávané",
"bitrate": "Prenosová rýchlosť",
"no_active": "Žiadny aktívny stream",
"movies": "Filmy",
"series": "Seriály",
"episodes": "Epizódy",
"songs": "Skladby"
},
"flood": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
"download": "Sťahovanie",
"upload": "Odosielanie",
"leech": "Leechovanie",
"seed": "Seedovanie"
},
"changedetectionio": {
"totalObserved": "Total Observed",
@@ -276,70 +276,70 @@
"queued": "Queued",
"series": "Series",
"queue": "Queue",
"unknown": "Unknown"
"unknown": "Neznáme"
},
"radarr": {
"wanted": "Wanted",
"missing": "Missing",
"queued": "Queued",
"movies": "Movies",
"queue": "Queue",
"unknown": "Unknown"
"wanted": "Chcené",
"missing": "Chýbajúce",
"queued": "Vo fronte",
"movies": "Filmy",
"queue": "Fronta",
"unknown": "Neznáme"
},
"lidarr": {
"wanted": "Wanted",
"queued": "Queued",
"artists": "Artists"
"wanted": "Chcené",
"queued": "Vo fronte",
"artists": "Interpreti"
},
"readarr": {
"wanted": "Wanted",
"queued": "Queued",
"books": "Books"
"wanted": "Chcené",
"queued": "Vo fronte",
"books": "Knihy"
},
"bazarr": {
"missingEpisodes": "Missing Episodes",
"missingMovies": "Missing Movies"
"missingEpisodes": "Chýbajúce epizódy",
"missingMovies": "Chýbajúce filmy"
},
"ombi": {
"pending": "Pending",
"approved": "Approved",
"available": "Available"
"pending": "Čakajúce",
"approved": "Schválené",
"available": "Dostupné"
},
"jellyseerr": {
"pending": "Pending",
"approved": "Approved",
"available": "Available"
"pending": "Čakajúce",
"approved": "Schválené",
"available": "Dostupné"
},
"overseerr": {
"pending": "Pending",
"processing": "Processing",
"approved": "Approved",
"available": "Available"
"pending": "Čakajúce",
"processing": "Spracovávané",
"approved": "Schválené",
"available": "Dostupné"
},
"pihole": {
"queries": "Queries",
"blocked": "Blocked",
"gravity": "Gravity",
"blocked_percent": "Blocked %"
"queries": "Dopyty",
"blocked": "Zablokované",
"gravity": "Gravitácia",
"blocked_percent": "Blokované %"
},
"adguard": {
"queries": "Queries",
"blocked": "Blocked",
"filtered": "Filtered",
"latency": "Latency"
"queries": "Dopyty",
"blocked": "Blokované",
"filtered": "Filtrované",
"latency": "Odozva"
},
"speedtest": {
"upload": "Upload",
"download": "Download",
"upload": "Odosielanie",
"download": "Sťahovanie",
"ping": "Ping"
},
"portainer": {
"running": "Running",
"stopped": "Stopped",
"total": "Total"
"running": "Spustené",
"stopped": "Zastavené",
"total": "Celkovo"
},
"traefik": {
"routers": "Routers",
"routers": "Routery",
"services": "Services",
"middleware": "Middleware"
},
@@ -589,8 +589,8 @@
"switches_on": "Switches On"
},
"freshrss": {
"subscriptions": "Subscriptions",
"unread": "Unread"
"subscriptions": "Odbery",
"unread": "Neprečítané"
},
"channelsdvrserver": {
"shows": "Shows",
@@ -603,18 +603,18 @@
"updates": "Updates"
},
"tailscale": {
"address": "Address",
"years": "{{number}}y",
"expires": "Expires",
"never": "Never",
"last_seen": "Last Seen",
"now": "Now",
"weeks": "{{number}}w",
"address": "Adresa",
"years": "{{number}}r",
"expires": "Vyprší",
"never": "Nikdy",
"last_seen": "Naposledy videné",
"now": "Teraz",
"weeks": "{{number}}t",
"days": "{{number}}d",
"hours": "{{number}}h",
"minutes": "{{number}}m",
"seconds": "{{number}}s",
"ago": "{{value}} Ago"
"ago": "Pred {{value}}"
},
"qnap": {
"cpuUsage": "CPU Usage",
@@ -635,23 +635,23 @@
"wanIP": "WAN IP"
},
"caddy": {
"upstreams": "Upstreams",
"upstreams": "Odosielanie dát",
"requests": "Current requests",
"requests_failed": "Failed requests"
},
"evcc": {
"pv_power": "Production",
"battery_soc": "Battery",
"grid_power": "Grid",
"home_power": "Consumption",
"charge_power": "Charger",
"pv_power": "Produkcia",
"battery_soc": "Batéria",
"grid_power": "Mriežka",
"home_power": "Spotreba",
"charge_power": "Nabíjačka",
"watt_hour": "Wh"
},
"pialert": {
"total": "Total",
"connected": "Connected",
"new_devices": "New Devices",
"down_alerts": "Down Alerts"
"total": "Celkovo",
"connected": "Pripojené",
"new_devices": "Nové zariadenia",
"down_alerts": "Upozornenia o výpadkoch"
},
"jdownloader": {
"downloadCount": "Queue Count",

View File

@@ -4,7 +4,7 @@ import classNames from "classnames";
import { TabContext } from "utils/contexts/tab";
export function slugify(tabName) {
return tabName ? encodeURIComponent(tabName.replace(/\s+/g, '-').toLowerCase()) : ''
return tabName !== undefined ? encodeURIComponent(tabName.toString().replace(/\s+/g, '-').toLowerCase()) : ''
}
export default function Tab({ tab }) {

View File

@@ -239,7 +239,7 @@ function Home({ initialSettings }) {
const tabs = useMemo( () => [
...new Set(
Object.keys(settings.layout ?? {}).map(
(groupName) => settings.layout[groupName]?.tab
(groupName) => settings.layout[groupName]?.tab?.toString()
).filter(group => group)
)
], [settings.layout]);
@@ -362,13 +362,7 @@ function Home({ initialSettings }) {
/>
</style>
<link rel="preload" href="/api/config/custom.js" as="fetch" crossOrigin="anonymous" />
<script data-name="custom.js">
<FileContent path="custom.js"
loadingValue="/* Loading custom JS... */"
errorValue="/* Failed to load custom JS... */"
emptyValue="/* No custom JS */"
/>
</script>
<script data-name="custom.js" src="/api/config/custom.js" async />
<div className="relative container m-auto flex flex-col justify-start z-10 h-full">
<QuickLaunch

View File

@@ -4,7 +4,7 @@ import path from "path";
import yaml from "js-yaml";
import Docker from "dockerode";
import * as shvl from "shvl";
import { CustomObjectsApi, NetworkingV1Api } from "@kubernetes/client-node";
import { CustomObjectsApi, NetworkingV1Api, ApiextensionsV1Api } from "@kubernetes/client-node";
import createLogger from "utils/logger";
import checkAndCopyConfig, { CONF_DIR, substituteEnvironmentVars } from "utils/config/config";
@@ -141,6 +141,26 @@ function getUrlFromIngress(ingress) {
return `${urlSchema}://${urlHost}${urlPath}`;
}
export async function checkCRD(kc, name) {
const apiExtensions = kc.makeApiClient(ApiextensionsV1Api);
const exist = await apiExtensions
.readCustomResourceDefinitionStatus(name)
.then(() => true)
.catch(async (error) => {
if (error.statusCode === 403) {
logger.error(
"Error checking if CRD %s exists. Make sure to add the following permission to your RBAC: %d %s %s",
name,
error.statusCode,
error.body.message
);
}
return false
});
return exist
}
export async function servicesFromKubernetes() {
const ANNOTATION_BASE = "gethomepage.dev";
const ANNOTATION_WIDGET_BASE = `${ANNOTATION_BASE}/widget.`;
@@ -164,11 +184,14 @@ export async function servicesFromKubernetes() {
return null;
});
const traefikContainoExists = await checkCRD(kc, "ingressroutes.traefik.containo.us");
const traefikExists = await checkCRD(kc, "ingressroutes.traefik.io");
const traefikIngressListContaino = await crd
.listClusterCustomObject("traefik.containo.us", "v1alpha1", "ingressroutes")
.then((response) => response.body)
.catch(async (error) => {
if (![403, 404].includes(error.statusCode)) {
if (traefikContainoExists) {
logger.error(
"Error getting traefik ingresses from traefik.containo.us: %d %s %s",
error.statusCode,
@@ -184,7 +207,7 @@ export async function servicesFromKubernetes() {
.listClusterCustomObject("traefik.io", "v1alpha1", "ingressroutes")
.then((response) => response.body)
.catch(async (error) => {
if (![403, 404].includes(error.statusCode)) {
if (traefikExists) {
logger.error(
"Error getting traefik ingresses from traefik.io: %d %s %s",
error.statusCode,
@@ -196,10 +219,10 @@ export async function servicesFromKubernetes() {
return [];
});
const traefikIngressList = [...traefikIngressListContaino, ...traefikIngressListIo];
const traefikIngressList = [...traefikIngressListContaino?.items ?? [], ...traefikIngressListIo?.items ?? []];
if (traefikIngressList?.items?.length > 0) {
const traefikServices = traefikIngressList.items.filter(
if (traefikIngressList.length > 0) {
const traefikServices = traefikIngressList.filter(
(ingress) => ingress.metadata.annotations && ingress.metadata.annotations[`${ANNOTATION_BASE}/href`]
);
ingressList.items.push(...traefikServices);

View File

@@ -3,13 +3,13 @@ import Container from "components/services/widget/container";
import Block from "components/services/widget/block";
const passedReduce = (acc, e) => {
if (e.overallstatus === "GOOD") {
if (e.monitor && e.overallstatus === "GOOD") {
return acc + 1;
}
return acc;
};
const failedReduce = (acc, e) => {
if (e.overallstatus !== "GOOD") {
if (e.monitor && e.overallstatus !== "GOOD") {
return acc + 1;
}
return acc;