mirror of
https://github.com/gethomepage/homepage.git
synced 2025-12-05 21:47:48 +01:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 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>
|
||||
|
||||
<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>
|
||||
|
||||
## 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 -->
|
||||
[](#contributors)
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
Thanks to the over 200 contributors who have helped make this project what it is today!
|
||||
|
||||
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
|
||||
runtime:
|
||||
gpuRequest: ""
|
||||
serversMemory: "1024Mi"
|
||||
agentsMemory: "1024Mi"
|
||||
serversMemory: "1024MiB"
|
||||
agentsMemory: "1024MiB"
|
||||
labels:
|
||||
- label: foo=bar
|
||||
nodeFilters:
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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": "Dní",
|
||||
"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",
|
||||
|
||||
@@ -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 }) {
|
||||
|
||||
@@ -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="{true}" />
|
||||
|
||||
<div className="relative container m-auto flex flex-col justify-start z-10 h-full">
|
||||
<QuickLaunch
|
||||
|
||||
@@ -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)
|
||||
.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,
|
||||
@@ -182,9 +205,9 @@ export async function servicesFromKubernetes() {
|
||||
|
||||
const traefikIngressListIo = await crd
|
||||
.listClusterCustomObject("traefik.io", "v1alpha1", "ingressroutes")
|
||||
.then((response) => response.body)
|
||||
.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,9 +219,9 @@ export async function servicesFromKubernetes() {
|
||||
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(
|
||||
(ingress) => ingress.metadata.annotations && ingress.metadata.annotations[`${ANNOTATION_BASE}/href`]
|
||||
);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user