mirror of
https://github.com/gethomepage/homepage.git
synced 2025-12-06 21:57:48 +01:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4a39299c5 | ||
|
|
7d2bfa2d84 | ||
|
|
c094bd3d83 | ||
|
|
69ee459e8a | ||
|
|
ed0527a3da | ||
|
|
04a1c68ba0 | ||
|
|
b74faea449 | ||
|
|
0c9b6480c5 | ||
|
|
6fbb3bfbb1 | ||
|
|
53355561a8 | ||
|
|
6e43194f71 | ||
|
|
a72a27a8b5 | ||
|
|
6c682cb648 | ||
|
|
e7587b8308 | ||
|
|
e663994c9b | ||
|
|
898fb88d86 | ||
|
|
6f5c2a8c1e |
134
README.md
134
README.md
@@ -6,71 +6,58 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<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>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="images/1.png" />
|
<img src="images/1.png?v=2" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="images/2.png" width="19%" />
|
<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>
|
||||||
<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://hosted.weblate.org/engage/homepage/"><img src="https://hosted.weblate.org/widgets/homepage/-/homepage/svg-badge.svg" alt="Weblate"></a>
|
<a href="https://hosted.weblate.org/engage/homepage/"><img src="https://hosted.weblate.org/widgets/homepage/-/homepage/svg-badge.svg" alt="Weblate"></a>
|
||||||
|
|
||||||
|
<a href="https://discord.gg/k4ruYNrudu"><img alt="Discord" src="https://img.shields.io/discord/1019316731635834932"></a>
|
||||||
|
|
||||||
|
<a href="https://paypal.me/phelpsben" title="Donate"><img alt="GitHub Sponsors" src="https://img.shields.io/github/sponsors/benphelps"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## Features
|
# Features
|
||||||
|
|
||||||
- **Fast!** The entire site is statically generated at build time, so you can expect instant load times
|
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.
|
||||||
- **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
|
|
||||||
|
|
||||||
## 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:
|
Using docker compose:
|
||||||
|
|
||||||
@@ -80,22 +67,31 @@ services:
|
|||||||
homepage:
|
homepage:
|
||||||
image: ghcr.io/benphelps/homepage:latest
|
image: ghcr.io/benphelps/homepage:latest
|
||||||
container_name: homepage
|
container_name: homepage
|
||||||
|
environment:
|
||||||
|
PUID: 1000 -- optional, your user id
|
||||||
|
PGID: 1000 -- optional, your group id
|
||||||
ports:
|
ports:
|
||||||
- 3000:3000
|
- 3000:3000
|
||||||
volumes:
|
volumes:
|
||||||
- /path/to/config:/app/config # Make sure your local config directory exists
|
- /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
|
- /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
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
```
|
```
|
||||||
|
|
||||||
or docker run:
|
or docker run:
|
||||||
|
|
||||||
```bash
|
```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:
|
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.
|
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
|
```bash
|
||||||
pnpm start
|
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
|
# Configuration
|
||||||
the specific configuration options.
|
|
||||||
|
|
||||||
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!):
|
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:
|
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 -->
|
If you have any questions, suggestions, or general issues, please start a discussion on the [Discussions](https://github.com/benphelps/homepage/discussions) page.
|
||||||
<!-- prettier-ignore-start -->
|
|
||||||
<!-- markdownlint-disable -->
|
|
||||||
|
|
||||||
<!-- markdownlint-restore -->
|
For bug reports, please open an issue on the [Issues](https://github.com/benphelps/homepage/issues) page.
|
||||||
<!-- prettier-ignore-end -->
|
|
||||||
|
|
||||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
## Contributing & Contributers
|
||||||
|
|
||||||
|
Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information.
|
||||||
|
|
||||||
|
Thanks to the over 200 contributors who have helped make this project what it is today!
|
||||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
|
||||||
[](#contributors)
|
|
||||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
|
||||||
|
|||||||
BIN
images/1.png
BIN
images/1.png
Binary file not shown.
|
Before Width: | Height: | Size: 345 KiB After Width: | Height: | Size: 734 KiB |
@@ -36,8 +36,8 @@ options:
|
|||||||
switchCurrentContext: false
|
switchCurrentContext: false
|
||||||
runtime:
|
runtime:
|
||||||
gpuRequest: ""
|
gpuRequest: ""
|
||||||
serversMemory: "1024Mi"
|
serversMemory: "1024MiB"
|
||||||
agentsMemory: "1024Mi"
|
agentsMemory: "1024MiB"
|
||||||
labels:
|
labels:
|
||||||
- label: foo=bar
|
- label: foo=bar
|
||||||
nodeFilters:
|
nodeFilters:
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
{
|
{
|
||||||
"widget": {
|
"widget": {
|
||||||
"missing_type": "Missend Widget Type: {{type}}",
|
"missing_type": "Missend Widget Type: {{type}}",
|
||||||
"api_error": "API Error",
|
"api_error": "API fout",
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
"information": "Informatie",
|
"information": "Informatie",
|
||||||
"url": "URL",
|
"url": "URL",
|
||||||
"raw_error": "Raw Fout",
|
"raw_error": "Raw Error",
|
||||||
"response_data": "Reactiegegevens"
|
"response_data": "Responsgegevens"
|
||||||
},
|
},
|
||||||
"resources": {
|
"resources": {
|
||||||
"total": "Totaal",
|
"total": "Totaal",
|
||||||
"free": "Vrij",
|
"free": "Vrij",
|
||||||
"used": "Gebruikt",
|
"used": "Gebruikt",
|
||||||
"load": "Laadt",
|
"load": "lading",
|
||||||
"cpu": "CPU",
|
"cpu": "CPU",
|
||||||
"mem": "MEM",
|
"mem": "GEH",
|
||||||
"days": "d",
|
"days": "d",
|
||||||
"hours": "h",
|
"hours": "h",
|
||||||
"temp": "TEMP",
|
"temp": "TEMP",
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
"offline": "Offline",
|
"offline": "Offline",
|
||||||
"error": "Fout",
|
"error": "Fout",
|
||||||
"unknown": "Onbekend",
|
"unknown": "Onbekend",
|
||||||
"running": "Running",
|
"running": "Lopend",
|
||||||
"starting": "Starten",
|
"starting": "Starten",
|
||||||
"unhealthy": "Ongezond",
|
"unhealthy": "Ongezond",
|
||||||
"not_found": "Niet Gevonden",
|
"not_found": "Niet Gevonden",
|
||||||
@@ -72,8 +72,8 @@
|
|||||||
"playing": "Afspelen",
|
"playing": "Afspelen",
|
||||||
"transcoding": "Transcodering",
|
"transcoding": "Transcodering",
|
||||||
"bitrate": "Bitsnelheid",
|
"bitrate": "Bitsnelheid",
|
||||||
"no_active": "Geen Actieve Streams",
|
"no_active": "Geen actieve streams",
|
||||||
"plex_connection_error": "Check Plex Connection"
|
"plex_connection_error": "Controleer Plex Connectie"
|
||||||
},
|
},
|
||||||
"rutorrent": {
|
"rutorrent": {
|
||||||
"active": "Actief",
|
"active": "Actief",
|
||||||
@@ -84,16 +84,16 @@
|
|||||||
"wanted": "Gezocht",
|
"wanted": "Gezocht",
|
||||||
"queued": "In de wachtrij",
|
"queued": "In de wachtrij",
|
||||||
"series": "Series",
|
"series": "Series",
|
||||||
"queue": "Queue",
|
"queue": "Rij",
|
||||||
"unknown": "Unknown"
|
"unknown": "Onbekend"
|
||||||
},
|
},
|
||||||
"radarr": {
|
"radarr": {
|
||||||
"movies": "Films",
|
"movies": "Films",
|
||||||
"wanted": "Gezocht",
|
"wanted": "Gezocht",
|
||||||
"queued": "In de wachtrij",
|
"queued": "In de wachtrij",
|
||||||
"missing": "Missend",
|
"missing": "Missend",
|
||||||
"queue": "Queue",
|
"queue": "Rij",
|
||||||
"unknown": "Unknown"
|
"unknown": "Onbekend"
|
||||||
},
|
},
|
||||||
"readarr": {
|
"readarr": {
|
||||||
"wanted": "Gezocht",
|
"wanted": "Gezocht",
|
||||||
@@ -114,7 +114,7 @@
|
|||||||
"queries": "Queries",
|
"queries": "Queries",
|
||||||
"blocked": "Geblokkeerd",
|
"blocked": "Geblokkeerd",
|
||||||
"gravity": "Gravity",
|
"gravity": "Gravity",
|
||||||
"blocked_percent": "Blocked %"
|
"blocked_percent": "Geblokkerde %"
|
||||||
},
|
},
|
||||||
"traefik": {
|
"traefik": {
|
||||||
"routers": "Routers",
|
"routers": "Routers",
|
||||||
@@ -135,15 +135,15 @@
|
|||||||
"sabnzbd": {
|
"sabnzbd": {
|
||||||
"rate": "Rate",
|
"rate": "Rate",
|
||||||
"queue": "Wachtrij",
|
"queue": "Wachtrij",
|
||||||
"timeleft": "Time Left"
|
"timeleft": "Tijd Over"
|
||||||
},
|
},
|
||||||
"nzbget": {
|
"nzbget": {
|
||||||
"rate": "Rate",
|
"rate": "Tarief",
|
||||||
"remaining": "Resterend",
|
"remaining": "Resterend",
|
||||||
"downloaded": "Gedownload"
|
"downloaded": "Gedownload"
|
||||||
},
|
},
|
||||||
"coinmarketcap": {
|
"coinmarketcap": {
|
||||||
"configure": "Configure one or more crypto currencies to track",
|
"configure": "Configureer een of meer crypto eenheiden om bij te houden",
|
||||||
"1hour": "1 Uur",
|
"1hour": "1 Uur",
|
||||||
"7days": "7 Dagen",
|
"7days": "7 Dagen",
|
||||||
"1day": "1 Dag",
|
"1day": "1 Dag",
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
},
|
},
|
||||||
"gotify": {
|
"gotify": {
|
||||||
"apps": "Applicaties",
|
"apps": "Applicaties",
|
||||||
"clients": "Clients",
|
"clients": "Cliënten",
|
||||||
"messages": "Berichten"
|
"messages": "Berichten"
|
||||||
},
|
},
|
||||||
"prowlarr": {
|
"prowlarr": {
|
||||||
@@ -164,7 +164,7 @@
|
|||||||
"transmission": {
|
"transmission": {
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Bloedzuiger",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
},
|
},
|
||||||
"jackett": {
|
"jackett": {
|
||||||
@@ -178,28 +178,28 @@
|
|||||||
"lidarr": {
|
"lidarr": {
|
||||||
"wanted": "Gezocht",
|
"wanted": "Gezocht",
|
||||||
"queued": "In de wachtrij",
|
"queued": "In de wachtrij",
|
||||||
"artists": "Artists"
|
"artists": "Artiesten"
|
||||||
},
|
},
|
||||||
"adguard": {
|
"adguard": {
|
||||||
"queries": "Queries",
|
"queries": "Queries",
|
||||||
"blocked": "Geblokkeerd",
|
"blocked": "Geblokkeerd",
|
||||||
"filtered": "Filtered",
|
"filtered": "Gefilterde",
|
||||||
"latency": "Latency"
|
"latency": "Latency"
|
||||||
},
|
},
|
||||||
"qbittorrent": {
|
"qbittorrent": {
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Bloedzuiger",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
},
|
},
|
||||||
"mastodon": {
|
"mastodon": {
|
||||||
"user_count": "Users",
|
"user_count": "Gebruikers",
|
||||||
"status_count": "Posts",
|
"status_count": "Posts",
|
||||||
"domain_count": "Domeinen"
|
"domain_count": "Domeinen"
|
||||||
},
|
},
|
||||||
"strelaysrv": {
|
"strelaysrv": {
|
||||||
"numActiveSessions": "Sessions",
|
"numActiveSessions": "Sessies",
|
||||||
"numConnections": "Connections",
|
"numConnections": "Connecties",
|
||||||
"dataRelayed": "Relayed",
|
"dataRelayed": "Relayed",
|
||||||
"transferRate": "Rate"
|
"transferRate": "Rate"
|
||||||
},
|
},
|
||||||
@@ -223,13 +223,13 @@
|
|||||||
"wlan_users": "WLAN Gebruikers",
|
"wlan_users": "WLAN Gebruikers",
|
||||||
"up": "UP",
|
"up": "UP",
|
||||||
"down": "DOWN",
|
"down": "DOWN",
|
||||||
"wait": "Wachten aub",
|
"wait": "Even geduld",
|
||||||
"lan": "LAN",
|
"lan": "LAN",
|
||||||
"wlan": "WLAN",
|
"wlan": "WLAN",
|
||||||
"devices": "Apparaten",
|
"devices": "Apparaten",
|
||||||
"lan_devices": "LAN Apparaten",
|
"lan_devices": "LAN Apparaten",
|
||||||
"wlan_devices": "WLAN Apparaten",
|
"wlan_devices": "WLAN Apparaten",
|
||||||
"empty_data": "Subsystem status onbekend"
|
"empty_data": "Subsysteem status onbekend"
|
||||||
},
|
},
|
||||||
"plex": {
|
"plex": {
|
||||||
"streams": "Actieve Streams",
|
"streams": "Actieve Streams",
|
||||||
@@ -396,7 +396,7 @@
|
|||||||
"deluge": {
|
"deluge": {
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Bloedzuiger",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
},
|
},
|
||||||
"flood": {
|
"flood": {
|
||||||
@@ -409,7 +409,7 @@
|
|||||||
"queue": "Wachtrij",
|
"queue": "Wachtrij",
|
||||||
"processed": "Processed",
|
"processed": "Processed",
|
||||||
"errored": "Errored",
|
"errored": "Errored",
|
||||||
"saved": "Saved"
|
"saved": "Opgeslagen"
|
||||||
},
|
},
|
||||||
"miniflux": {
|
"miniflux": {
|
||||||
"read": "Gelezen",
|
"read": "Gelezen",
|
||||||
@@ -424,16 +424,16 @@
|
|||||||
"bibitrate": "{{value, rate(bits: true; binary: true)}}"
|
"bibitrate": "{{value, rate(bits: true; binary: true)}}"
|
||||||
},
|
},
|
||||||
"omada": {
|
"omada": {
|
||||||
"connectedAp": "Connected APs",
|
"connectedAp": "Verbonden APs",
|
||||||
"activeUser": "Actieve apparaten",
|
"activeUser": "Actieve apparaten",
|
||||||
"alerts": "Meldingen",
|
"alerts": "Meldingen",
|
||||||
"connectedGateway": "Connected gateways",
|
"connectedGateway": "Verbonden gateways",
|
||||||
"connectedSwitches": "Connected switches"
|
"connectedSwitches": "Verbonden switches"
|
||||||
},
|
},
|
||||||
"downloadstation": {
|
"downloadstation": {
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Bloedzuiger",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
},
|
},
|
||||||
"mikrotik": {
|
"mikrotik": {
|
||||||
@@ -460,7 +460,7 @@
|
|||||||
"layers": "Layers"
|
"layers": "Layers"
|
||||||
},
|
},
|
||||||
"medusa": {
|
"medusa": {
|
||||||
"wanted": "Wanted",
|
"wanted": "Gewild",
|
||||||
"queued": "Queued",
|
"queued": "Queued",
|
||||||
"series": "Series"
|
"series": "Series"
|
||||||
},
|
},
|
||||||
@@ -589,13 +589,13 @@
|
|||||||
"switches_on": "Switches On"
|
"switches_on": "Switches On"
|
||||||
},
|
},
|
||||||
"freshrss": {
|
"freshrss": {
|
||||||
"subscriptions": "Subscriptions",
|
"subscriptions": "Abonnementen",
|
||||||
"unread": "Unread"
|
"unread": "Ongelezen"
|
||||||
},
|
},
|
||||||
"channelsdvrserver": {
|
"channelsdvrserver": {
|
||||||
"shows": "Shows",
|
"shows": "Shows",
|
||||||
"recordings": "Recordings",
|
"recordings": "Recordings",
|
||||||
"scheduled": "Scheduled",
|
"scheduled": "Geplanned",
|
||||||
"passes": "Passes"
|
"passes": "Passes"
|
||||||
},
|
},
|
||||||
"whatsupdocker": {
|
"whatsupdocker": {
|
||||||
@@ -604,25 +604,25 @@
|
|||||||
},
|
},
|
||||||
"tailscale": {
|
"tailscale": {
|
||||||
"address": "Address",
|
"address": "Address",
|
||||||
"expires": "Expires",
|
"expires": "Verloopt",
|
||||||
"never": "Never",
|
"never": "Nooit",
|
||||||
"last_seen": "Last Seen",
|
"last_seen": "Laatst Gezien",
|
||||||
"now": "Now",
|
"now": "Nu",
|
||||||
"years": "{{number}}y",
|
"years": "{{number}}y",
|
||||||
"weeks": "{{number}}w",
|
"weeks": "{{number}}w",
|
||||||
"days": "{{number}}d",
|
"days": "{{number}}d",
|
||||||
"hours": "{{number}}h",
|
"hours": "{{number}}h",
|
||||||
"minutes": "{{number}}m",
|
"minutes": "{{number}}m",
|
||||||
"seconds": "{{number}}s",
|
"seconds": "{{number}}s",
|
||||||
"ago": "{{value}} Ago"
|
"ago": "{{value}} Geleden"
|
||||||
},
|
},
|
||||||
"qnap": {
|
"qnap": {
|
||||||
"cpuUsage": "CPU Usage",
|
"cpuUsage": "CPU Verbruik",
|
||||||
"memUsage": "MEM Usage",
|
"memUsage": "MEM Gebruik",
|
||||||
"systemTempC": "System Temp",
|
"systemTempC": "Systeem Temperatuur",
|
||||||
"poolUsage": "Pool Usage",
|
"poolUsage": "Pool Gebruik",
|
||||||
"volumeUsage": "Volume Usage",
|
"volumeUsage": "Volume Usage",
|
||||||
"invalid": "Invalid"
|
"invalid": "ongeldig"
|
||||||
},
|
},
|
||||||
"pfsense": {
|
"pfsense": {
|
||||||
"load": "Load Avg",
|
"load": "Load Avg",
|
||||||
@@ -636,21 +636,21 @@
|
|||||||
},
|
},
|
||||||
"caddy": {
|
"caddy": {
|
||||||
"upstreams": "Upstreams",
|
"upstreams": "Upstreams",
|
||||||
"requests": "Current requests",
|
"requests": "Momentele verzoeken",
|
||||||
"requests_failed": "Failed requests"
|
"requests_failed": "Gefaalde verzoeken"
|
||||||
},
|
},
|
||||||
"evcc": {
|
"evcc": {
|
||||||
"pv_power": "Production",
|
"pv_power": "Productie",
|
||||||
"battery_soc": "Battery",
|
"battery_soc": "Battery",
|
||||||
"grid_power": "Grid",
|
"grid_power": "Grid",
|
||||||
"home_power": "Consumption",
|
"home_power": "Consumption",
|
||||||
"charge_power": "Charger",
|
"charge_power": "Oplader",
|
||||||
"watt_hour": "Wh"
|
"watt_hour": "Wh"
|
||||||
},
|
},
|
||||||
"pialert": {
|
"pialert": {
|
||||||
"total": "Total",
|
"total": "Total",
|
||||||
"connected": "Connected",
|
"connected": "Verbonden",
|
||||||
"new_devices": "New Devices",
|
"new_devices": "Nieuwe Apparaten",
|
||||||
"down_alerts": "Down Alerts"
|
"down_alerts": "Down Alerts"
|
||||||
},
|
},
|
||||||
"jdownloader": {
|
"jdownloader": {
|
||||||
|
|||||||
@@ -2,18 +2,18 @@
|
|||||||
"docker": {
|
"docker": {
|
||||||
"rx": "RX",
|
"rx": "RX",
|
||||||
"tx": "TX",
|
"tx": "TX",
|
||||||
"mem": "MEM",
|
"mem": "RAM",
|
||||||
"cpu": "CPU",
|
"cpu": "CPU",
|
||||||
"offline": "Offline",
|
"offline": "Offline",
|
||||||
"error": "Error",
|
"error": "Chyba",
|
||||||
"unknown": "Unknown",
|
"unknown": "Neznáme",
|
||||||
"running": "Running",
|
"running": "Beží",
|
||||||
"starting": "Starting",
|
"starting": "Spúšťa sa",
|
||||||
"unhealthy": "Unhealthy",
|
"unhealthy": "Nezdravý",
|
||||||
"not_found": "Not Found",
|
"not_found": "Nenájdené",
|
||||||
"exited": "Exited",
|
"exited": "Ukončené",
|
||||||
"partial": "Partial",
|
"partial": "Čiastočný",
|
||||||
"healthy": "Healthy"
|
"healthy": "Zdravý"
|
||||||
},
|
},
|
||||||
"rutorrent": {
|
"rutorrent": {
|
||||||
"active": "Active",
|
"active": "Active",
|
||||||
@@ -21,10 +21,10 @@
|
|||||||
"download": "Download"
|
"download": "Download"
|
||||||
},
|
},
|
||||||
"tdarr": {
|
"tdarr": {
|
||||||
"queue": "Queue",
|
"queue": "Fronta",
|
||||||
"processed": "Processed",
|
"processed": "Spracované",
|
||||||
"errored": "Errored",
|
"errored": "Chybné",
|
||||||
"saved": "Saved"
|
"saved": "Uložené"
|
||||||
},
|
},
|
||||||
"strelaysrv": {
|
"strelaysrv": {
|
||||||
"numActiveSessions": "Sessions",
|
"numActiveSessions": "Sessions",
|
||||||
@@ -144,74 +144,74 @@
|
|||||||
"bibitrate": "{{value, rate(bits: true; binary: true)}}"
|
"bibitrate": "{{value, rate(bits: true; binary: true)}}"
|
||||||
},
|
},
|
||||||
"widget": {
|
"widget": {
|
||||||
"api_error": "API Error",
|
"api_error": "Chyba API",
|
||||||
"missing_type": "Missing Widget Type: {{type}}",
|
"missing_type": "Chýba typ widgetu: {{type}}",
|
||||||
"information": "Information",
|
"information": "Informácia",
|
||||||
"status": "Status",
|
"status": "Stav",
|
||||||
"url": "URL",
|
"url": "URL",
|
||||||
"raw_error": "Raw Error",
|
"raw_error": "Nevyriešená chyba",
|
||||||
"response_data": "Response Data"
|
"response_data": "Dáta odpovede"
|
||||||
},
|
},
|
||||||
"weather": {
|
"weather": {
|
||||||
"current": "Current Location",
|
"current": "Aktuálna poloha",
|
||||||
"allow": "Click to allow",
|
"allow": "Klikni pre povolenie",
|
||||||
"updating": "Updating",
|
"updating": "Prebieha aktualizácia",
|
||||||
"wait": "Please wait"
|
"wait": "Počkajte prosím"
|
||||||
},
|
},
|
||||||
"search": {
|
"search": {
|
||||||
"placeholder": "Search…"
|
"placeholder": "Hľadať…"
|
||||||
},
|
},
|
||||||
"resources": {
|
"resources": {
|
||||||
"cpu": "CPU",
|
"cpu": "CPU",
|
||||||
"mem": "MEM",
|
"mem": "RAM",
|
||||||
"total": "Total",
|
"total": "Celkovo",
|
||||||
"free": "Free",
|
"free": "Voľné",
|
||||||
"used": "Used",
|
"used": "Využité",
|
||||||
"load": "Load",
|
"load": "Záťaž",
|
||||||
"temp": "TEMP",
|
"temp": "TEPLOTA",
|
||||||
"max": "Max",
|
"max": "Max.",
|
||||||
"uptime": "UP",
|
"uptime": "BEŽÍ",
|
||||||
"months": "mo",
|
"months": "mes.",
|
||||||
"days": "d",
|
"days": "d",
|
||||||
"hours": "h",
|
"hours": "h",
|
||||||
"minutes": "m"
|
"minutes": "m"
|
||||||
},
|
},
|
||||||
"unifi": {
|
"unifi": {
|
||||||
"users": "Users",
|
"users": "Používatelia",
|
||||||
"uptime": "System Uptime",
|
"uptime": "Doba prevádzky",
|
||||||
"days": "Days",
|
"days": "Dní",
|
||||||
"wan": "WAN",
|
"wan": "WAN",
|
||||||
"lan": "LAN",
|
"lan": "LAN",
|
||||||
"wlan": "WLAN",
|
"wlan": "WLAN",
|
||||||
"devices": "Devices",
|
"devices": "Zariadenia",
|
||||||
"lan_devices": "LAN Devices",
|
"lan_devices": "Zariadenia LAN",
|
||||||
"wlan_devices": "WLAN Devices",
|
"wlan_devices": "Zariadenia WLAN",
|
||||||
"lan_users": "LAN Users",
|
"lan_users": "Používatelia LAN",
|
||||||
"wlan_users": "WLAN Users",
|
"wlan_users": "Používatelia WLAN",
|
||||||
"up": "UP",
|
"up": "BEŽÍ",
|
||||||
"down": "DOWN",
|
"down": "NEBEŽÍ",
|
||||||
"wait": "Please wait",
|
"wait": "Počkajte prosím",
|
||||||
"empty_data": "Subsystem status unknown"
|
"empty_data": "Stav podsystému neznámy"
|
||||||
},
|
},
|
||||||
"ping": {
|
"ping": {
|
||||||
"error": "Error",
|
"error": "Chyba",
|
||||||
"ping": "Ping"
|
"ping": "Odozva"
|
||||||
},
|
},
|
||||||
"emby": {
|
"emby": {
|
||||||
"playing": "Playing",
|
"playing": "Prehrávané",
|
||||||
"transcoding": "Transcoding",
|
"transcoding": "Prekódovávané",
|
||||||
"bitrate": "Bitrate",
|
"bitrate": "Prenosová rýchlosť",
|
||||||
"no_active": "No Active Streams",
|
"no_active": "Žiadny aktívny stream",
|
||||||
"movies": "Movies",
|
"movies": "Filmy",
|
||||||
"series": "Series",
|
"series": "Seriály",
|
||||||
"episodes": "Episodes",
|
"episodes": "Epizódy",
|
||||||
"songs": "Songs"
|
"songs": "Skladby"
|
||||||
},
|
},
|
||||||
"flood": {
|
"flood": {
|
||||||
"download": "Download",
|
"download": "Sťahovanie",
|
||||||
"upload": "Upload",
|
"upload": "Odosielanie",
|
||||||
"leech": "Leech",
|
"leech": "Leechovanie",
|
||||||
"seed": "Seed"
|
"seed": "Seedovanie"
|
||||||
},
|
},
|
||||||
"changedetectionio": {
|
"changedetectionio": {
|
||||||
"totalObserved": "Total Observed",
|
"totalObserved": "Total Observed",
|
||||||
@@ -276,70 +276,70 @@
|
|||||||
"queued": "Queued",
|
"queued": "Queued",
|
||||||
"series": "Series",
|
"series": "Series",
|
||||||
"queue": "Queue",
|
"queue": "Queue",
|
||||||
"unknown": "Unknown"
|
"unknown": "Neznáme"
|
||||||
},
|
},
|
||||||
"radarr": {
|
"radarr": {
|
||||||
"wanted": "Wanted",
|
"wanted": "Chcené",
|
||||||
"missing": "Missing",
|
"missing": "Chýbajúce",
|
||||||
"queued": "Queued",
|
"queued": "Vo fronte",
|
||||||
"movies": "Movies",
|
"movies": "Filmy",
|
||||||
"queue": "Queue",
|
"queue": "Fronta",
|
||||||
"unknown": "Unknown"
|
"unknown": "Neznáme"
|
||||||
},
|
},
|
||||||
"lidarr": {
|
"lidarr": {
|
||||||
"wanted": "Wanted",
|
"wanted": "Chcené",
|
||||||
"queued": "Queued",
|
"queued": "Vo fronte",
|
||||||
"artists": "Artists"
|
"artists": "Interpreti"
|
||||||
},
|
},
|
||||||
"readarr": {
|
"readarr": {
|
||||||
"wanted": "Wanted",
|
"wanted": "Chcené",
|
||||||
"queued": "Queued",
|
"queued": "Vo fronte",
|
||||||
"books": "Books"
|
"books": "Knihy"
|
||||||
},
|
},
|
||||||
"bazarr": {
|
"bazarr": {
|
||||||
"missingEpisodes": "Missing Episodes",
|
"missingEpisodes": "Chýbajúce epizódy",
|
||||||
"missingMovies": "Missing Movies"
|
"missingMovies": "Chýbajúce filmy"
|
||||||
},
|
},
|
||||||
"ombi": {
|
"ombi": {
|
||||||
"pending": "Pending",
|
"pending": "Čakajúce",
|
||||||
"approved": "Approved",
|
"approved": "Schválené",
|
||||||
"available": "Available"
|
"available": "Dostupné"
|
||||||
},
|
},
|
||||||
"jellyseerr": {
|
"jellyseerr": {
|
||||||
"pending": "Pending",
|
"pending": "Čakajúce",
|
||||||
"approved": "Approved",
|
"approved": "Schválené",
|
||||||
"available": "Available"
|
"available": "Dostupné"
|
||||||
},
|
},
|
||||||
"overseerr": {
|
"overseerr": {
|
||||||
"pending": "Pending",
|
"pending": "Čakajúce",
|
||||||
"processing": "Processing",
|
"processing": "Spracovávané",
|
||||||
"approved": "Approved",
|
"approved": "Schválené",
|
||||||
"available": "Available"
|
"available": "Dostupné"
|
||||||
},
|
},
|
||||||
"pihole": {
|
"pihole": {
|
||||||
"queries": "Queries",
|
"queries": "Dopyty",
|
||||||
"blocked": "Blocked",
|
"blocked": "Zablokované",
|
||||||
"gravity": "Gravity",
|
"gravity": "Gravitácia",
|
||||||
"blocked_percent": "Blocked %"
|
"blocked_percent": "Blokované %"
|
||||||
},
|
},
|
||||||
"adguard": {
|
"adguard": {
|
||||||
"queries": "Queries",
|
"queries": "Dopyty",
|
||||||
"blocked": "Blocked",
|
"blocked": "Blokované",
|
||||||
"filtered": "Filtered",
|
"filtered": "Filtrované",
|
||||||
"latency": "Latency"
|
"latency": "Odozva"
|
||||||
},
|
},
|
||||||
"speedtest": {
|
"speedtest": {
|
||||||
"upload": "Upload",
|
"upload": "Odosielanie",
|
||||||
"download": "Download",
|
"download": "Sťahovanie",
|
||||||
"ping": "Ping"
|
"ping": "Ping"
|
||||||
},
|
},
|
||||||
"portainer": {
|
"portainer": {
|
||||||
"running": "Running",
|
"running": "Spustené",
|
||||||
"stopped": "Stopped",
|
"stopped": "Zastavené",
|
||||||
"total": "Total"
|
"total": "Celkovo"
|
||||||
},
|
},
|
||||||
"traefik": {
|
"traefik": {
|
||||||
"routers": "Routers",
|
"routers": "Routery",
|
||||||
"services": "Services",
|
"services": "Services",
|
||||||
"middleware": "Middleware"
|
"middleware": "Middleware"
|
||||||
},
|
},
|
||||||
@@ -589,8 +589,8 @@
|
|||||||
"switches_on": "Switches On"
|
"switches_on": "Switches On"
|
||||||
},
|
},
|
||||||
"freshrss": {
|
"freshrss": {
|
||||||
"subscriptions": "Subscriptions",
|
"subscriptions": "Odbery",
|
||||||
"unread": "Unread"
|
"unread": "Neprečítané"
|
||||||
},
|
},
|
||||||
"channelsdvrserver": {
|
"channelsdvrserver": {
|
||||||
"shows": "Shows",
|
"shows": "Shows",
|
||||||
@@ -603,18 +603,18 @@
|
|||||||
"updates": "Updates"
|
"updates": "Updates"
|
||||||
},
|
},
|
||||||
"tailscale": {
|
"tailscale": {
|
||||||
"address": "Address",
|
"address": "Adresa",
|
||||||
"years": "{{number}}y",
|
"years": "{{number}}r",
|
||||||
"expires": "Expires",
|
"expires": "Vyprší",
|
||||||
"never": "Never",
|
"never": "Nikdy",
|
||||||
"last_seen": "Last Seen",
|
"last_seen": "Naposledy videné",
|
||||||
"now": "Now",
|
"now": "Teraz",
|
||||||
"weeks": "{{number}}w",
|
"weeks": "{{number}}t",
|
||||||
"days": "{{number}}d",
|
"days": "{{number}}d",
|
||||||
"hours": "{{number}}h",
|
"hours": "{{number}}h",
|
||||||
"minutes": "{{number}}m",
|
"minutes": "{{number}}m",
|
||||||
"seconds": "{{number}}s",
|
"seconds": "{{number}}s",
|
||||||
"ago": "{{value}} Ago"
|
"ago": "Pred {{value}}"
|
||||||
},
|
},
|
||||||
"qnap": {
|
"qnap": {
|
||||||
"cpuUsage": "CPU Usage",
|
"cpuUsage": "CPU Usage",
|
||||||
@@ -635,23 +635,23 @@
|
|||||||
"wanIP": "WAN IP"
|
"wanIP": "WAN IP"
|
||||||
},
|
},
|
||||||
"caddy": {
|
"caddy": {
|
||||||
"upstreams": "Upstreams",
|
"upstreams": "Odosielanie dát",
|
||||||
"requests": "Current requests",
|
"requests": "Current requests",
|
||||||
"requests_failed": "Failed requests"
|
"requests_failed": "Failed requests"
|
||||||
},
|
},
|
||||||
"evcc": {
|
"evcc": {
|
||||||
"pv_power": "Production",
|
"pv_power": "Produkcia",
|
||||||
"battery_soc": "Battery",
|
"battery_soc": "Batéria",
|
||||||
"grid_power": "Grid",
|
"grid_power": "Mriežka",
|
||||||
"home_power": "Consumption",
|
"home_power": "Spotreba",
|
||||||
"charge_power": "Charger",
|
"charge_power": "Nabíjačka",
|
||||||
"watt_hour": "Wh"
|
"watt_hour": "Wh"
|
||||||
},
|
},
|
||||||
"pialert": {
|
"pialert": {
|
||||||
"total": "Total",
|
"total": "Celkovo",
|
||||||
"connected": "Connected",
|
"connected": "Pripojené",
|
||||||
"new_devices": "New Devices",
|
"new_devices": "Nové zariadenia",
|
||||||
"down_alerts": "Down Alerts"
|
"down_alerts": "Upozornenia o výpadkoch"
|
||||||
},
|
},
|
||||||
"jdownloader": {
|
"jdownloader": {
|
||||||
"downloadCount": "Queue Count",
|
"downloadCount": "Queue Count",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import classNames from "classnames";
|
|||||||
import { TabContext } from "utils/contexts/tab";
|
import { TabContext } from "utils/contexts/tab";
|
||||||
|
|
||||||
export function slugify(tabName) {
|
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 }) {
|
export default function Tab({ tab }) {
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ function Home({ initialSettings }) {
|
|||||||
const tabs = useMemo( () => [
|
const tabs = useMemo( () => [
|
||||||
...new Set(
|
...new Set(
|
||||||
Object.keys(settings.layout ?? {}).map(
|
Object.keys(settings.layout ?? {}).map(
|
||||||
(groupName) => settings.layout[groupName]?.tab
|
(groupName) => settings.layout[groupName]?.tab?.toString()
|
||||||
).filter(group => group)
|
).filter(group => group)
|
||||||
)
|
)
|
||||||
], [settings.layout]);
|
], [settings.layout]);
|
||||||
@@ -362,13 +362,7 @@ function Home({ initialSettings }) {
|
|||||||
/>
|
/>
|
||||||
</style>
|
</style>
|
||||||
<link rel="preload" href="/api/config/custom.js" as="fetch" crossOrigin="anonymous" />
|
<link rel="preload" href="/api/config/custom.js" as="fetch" crossOrigin="anonymous" />
|
||||||
<script data-name="custom.js">
|
<script data-name="custom.js" src="/api/config/custom.js" async />
|
||||||
<FileContent path="custom.js"
|
|
||||||
loadingValue="/* Loading custom JS... */"
|
|
||||||
errorValue="/* Failed to load custom JS... */"
|
|
||||||
emptyValue="/* No custom JS */"
|
|
||||||
/>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div className="relative container m-auto flex flex-col justify-start z-10 h-full">
|
<div className="relative container m-auto flex flex-col justify-start z-10 h-full">
|
||||||
<QuickLaunch
|
<QuickLaunch
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import path from "path";
|
|||||||
import yaml from "js-yaml";
|
import yaml from "js-yaml";
|
||||||
import Docker from "dockerode";
|
import Docker from "dockerode";
|
||||||
import * as shvl from "shvl";
|
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 createLogger from "utils/logger";
|
||||||
import checkAndCopyConfig, { CONF_DIR, substituteEnvironmentVars } from "utils/config/config";
|
import checkAndCopyConfig, { CONF_DIR, substituteEnvironmentVars } from "utils/config/config";
|
||||||
@@ -141,6 +141,26 @@ function getUrlFromIngress(ingress) {
|
|||||||
return `${urlSchema}://${urlHost}${urlPath}`;
|
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() {
|
export async function servicesFromKubernetes() {
|
||||||
const ANNOTATION_BASE = "gethomepage.dev";
|
const ANNOTATION_BASE = "gethomepage.dev";
|
||||||
const ANNOTATION_WIDGET_BASE = `${ANNOTATION_BASE}/widget.`;
|
const ANNOTATION_WIDGET_BASE = `${ANNOTATION_BASE}/widget.`;
|
||||||
@@ -164,11 +184,14 @@ export async function servicesFromKubernetes() {
|
|||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const traefikContainoExists = await checkCRD(kc, "ingressroutes.traefik.containo.us");
|
||||||
|
const traefikExists = await checkCRD(kc, "ingressroutes.traefik.io");
|
||||||
|
|
||||||
const traefikIngressListContaino = await crd
|
const traefikIngressListContaino = await crd
|
||||||
.listClusterCustomObject("traefik.containo.us", "v1alpha1", "ingressroutes")
|
.listClusterCustomObject("traefik.containo.us", "v1alpha1", "ingressroutes")
|
||||||
.then((response) => response.body)
|
.then((response) => response.body)
|
||||||
.catch(async (error) => {
|
.catch(async (error) => {
|
||||||
if (![403, 404].includes(error.statusCode)) {
|
if (traefikContainoExists) {
|
||||||
logger.error(
|
logger.error(
|
||||||
"Error getting traefik ingresses from traefik.containo.us: %d %s %s",
|
"Error getting traefik ingresses from traefik.containo.us: %d %s %s",
|
||||||
error.statusCode,
|
error.statusCode,
|
||||||
@@ -184,7 +207,7 @@ export async function servicesFromKubernetes() {
|
|||||||
.listClusterCustomObject("traefik.io", "v1alpha1", "ingressroutes")
|
.listClusterCustomObject("traefik.io", "v1alpha1", "ingressroutes")
|
||||||
.then((response) => response.body)
|
.then((response) => response.body)
|
||||||
.catch(async (error) => {
|
.catch(async (error) => {
|
||||||
if (![403, 404].includes(error.statusCode)) {
|
if (traefikExists) {
|
||||||
logger.error(
|
logger.error(
|
||||||
"Error getting traefik ingresses from traefik.io: %d %s %s",
|
"Error getting traefik ingresses from traefik.io: %d %s %s",
|
||||||
error.statusCode,
|
error.statusCode,
|
||||||
@@ -196,10 +219,10 @@ export async function servicesFromKubernetes() {
|
|||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
|
|
||||||
const traefikIngressList = [...traefikIngressListContaino, ...traefikIngressListIo];
|
const traefikIngressList = [...traefikIngressListContaino?.items ?? [], ...traefikIngressListIo?.items ?? []];
|
||||||
|
|
||||||
if (traefikIngressList?.items?.length > 0) {
|
if (traefikIngressList.length > 0) {
|
||||||
const traefikServices = traefikIngressList.items.filter(
|
const traefikServices = traefikIngressList.filter(
|
||||||
(ingress) => ingress.metadata.annotations && ingress.metadata.annotations[`${ANNOTATION_BASE}/href`]
|
(ingress) => ingress.metadata.annotations && ingress.metadata.annotations[`${ANNOTATION_BASE}/href`]
|
||||||
);
|
);
|
||||||
ingressList.items.push(...traefikServices);
|
ingressList.items.push(...traefikServices);
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ import Container from "components/services/widget/container";
|
|||||||
import Block from "components/services/widget/block";
|
import Block from "components/services/widget/block";
|
||||||
|
|
||||||
const passedReduce = (acc, e) => {
|
const passedReduce = (acc, e) => {
|
||||||
if (e.overallstatus === "GOOD") {
|
if (e.monitor && e.overallstatus === "GOOD") {
|
||||||
return acc + 1;
|
return acc + 1;
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
};
|
};
|
||||||
const failedReduce = (acc, e) => {
|
const failedReduce = (acc, e) => {
|
||||||
if (e.overallstatus !== "GOOD") {
|
if (e.monitor && e.overallstatus !== "GOOD") {
|
||||||
return acc + 1;
|
return acc + 1;
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
|
|||||||
Reference in New Issue
Block a user