Merge branch 'main' into pr/301
This commit is contained in:
commit
f7fa14edff
30
.github/ISSUE_TEMPLATE/bug_report.md
vendored
30
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -1,30 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Create a report to help us improve
|
|
||||||
title: "[Bug] "
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Describe the bug**
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
|
|
||||||
**Expected behavior**
|
|
||||||
A clear and concise description of what you expected to happen.
|
|
||||||
|
|
||||||
**Screenshots**
|
|
||||||
If applicable, add screenshots to help explain your problem.
|
|
||||||
|
|
||||||
**Configuration**
|
|
||||||
If applicable,
|
|
||||||
```yaml
|
|
||||||
# Please provide your service, widget or otherwise related configuration here
|
|
||||||
```
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context about the problem here. This includes things like:
|
|
||||||
- Service version or API version
|
|
||||||
- Docker version
|
|
||||||
- Deployment method
|
|
||||||
- Sample YAML configurations
|
|
||||||
66
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
66
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
name: Bug report
|
||||||
|
description: Create a report to help us improve
|
||||||
|
title: "[Bug] "
|
||||||
|
labels: ["bug"]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Have a question? 👉 [Start a new discussion](https://github.com/benphelps/homepage/discussions/new) or [ask in chat](https://discord.gg/SaPGSzrEZC).
|
||||||
|
|
||||||
|
Before opening an issue, please double check:
|
||||||
|
|
||||||
|
- [The troubleshooting guide](https://gethomepage.dev/en/more/troubleshooting/).
|
||||||
|
- [The homepage documentation](https://gethomepage.dev/)
|
||||||
|
- [Existing issues](https://github.com/benphelps/homepage/search?q=&type=issues) and [discussions](https://github.com/benphelps/homepage/search?q=&type=discussions).
|
||||||
|
- type: textarea
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: A clear and concise description of what the bug is. If applicable, add screenshots to help explain your problem.
|
||||||
|
placeholder: |
|
||||||
|
Currently homepage does not work when...
|
||||||
|
|
||||||
|
[Screenshot if applicable]
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: reproduction
|
||||||
|
attributes:
|
||||||
|
label: Steps to reproduce
|
||||||
|
description: Steps to reproduce the behavior.
|
||||||
|
placeholder: |
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. See error
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: version
|
||||||
|
attributes:
|
||||||
|
label: homepage version
|
||||||
|
placeholder: e.g. v0.4.18 (4ea2798)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: dropdown
|
||||||
|
id: install-method
|
||||||
|
attributes:
|
||||||
|
label: Installation method
|
||||||
|
options:
|
||||||
|
- Docker
|
||||||
|
- Unraid
|
||||||
|
- Source
|
||||||
|
- Other (please describe above)
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: config
|
||||||
|
attributes:
|
||||||
|
label: Configuration
|
||||||
|
description: Please provide any relevant service, widget or otherwise related configuration here
|
||||||
|
render: yaml
|
||||||
|
- type: textarea
|
||||||
|
id: other
|
||||||
|
attributes:
|
||||||
|
label: Other
|
||||||
|
description: Any other relevant details. E.g. service version or API version, docker version, etc.
|
||||||
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
name: Feature request
|
|
||||||
about: Suggest an idea for this project
|
|
||||||
title: "[Feature Request] "
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Is your feature request related to a service? Please describe.**
|
|
||||||
A clear and concise description of what you would like to see from this service.
|
|
||||||
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
|
||||||
A clear and concise description of what the problem is. Ex. I would like it if [...]
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context or screenshots about the feature request here.
|
|
||||||
17
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
17
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
name: Feature request
|
||||||
|
description: Suggest an idea for this project
|
||||||
|
title: "[Feature Request] "
|
||||||
|
labels: ["enhancement"]
|
||||||
|
body:
|
||||||
|
- type: textarea
|
||||||
|
id: description
|
||||||
|
attributes:
|
||||||
|
label: Description
|
||||||
|
description: A clear and concise description of what you would like to see.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: other
|
||||||
|
attributes:
|
||||||
|
label: Other
|
||||||
|
description: Add any other context or information about the feature request here.
|
||||||
18
.github/workflows/docker-publish.yml
vendored
18
.github/workflows/docker-publish.yml
vendored
@ -43,7 +43,7 @@ jobs:
|
|||||||
if: github.event_name != 'pull_request'
|
if: github.event_name != 'pull_request'
|
||||||
uses: sigstore/cosign-installer@main
|
uses: sigstore/cosign-installer@main
|
||||||
with:
|
with:
|
||||||
cosign-release: 'v1.11.0' # optional
|
cosign-release: 'v1.13.1' # optional
|
||||||
|
|
||||||
# Setup QEMU
|
# Setup QEMU
|
||||||
# https://github.com/marketplace/actions/docker-setup-buildx#with-qemu
|
# https://github.com/marketplace/actions/docker-setup-buildx#with-qemu
|
||||||
@ -100,7 +100,7 @@ jobs:
|
|||||||
REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}
|
REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}
|
||||||
# https://github.com/docker/setup-qemu-action#about
|
# https://github.com/docker/setup-qemu-action#about
|
||||||
# platforms: linux/amd64,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6
|
# platforms: linux/amd64,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6
|
||||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6
|
||||||
cache-from: type=local,src=/tmp/.buildx-cache
|
cache-from: type=local,src=/tmp/.buildx-cache
|
||||||
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
|
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
|
||||||
|
|
||||||
@ -109,13 +109,13 @@ jobs:
|
|||||||
# repository is public to avoid leaking data. If you would like to publish
|
# repository is public to avoid leaking data. If you would like to publish
|
||||||
# transparency data even for private images, pass --force to cosign below.
|
# transparency data even for private images, pass --force to cosign below.
|
||||||
# https://github.com/sigstore/cosign
|
# https://github.com/sigstore/cosign
|
||||||
- name: Sign the published Docker image
|
# - name: Sign the published Docker image
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
# if: ${{ github.event_name != 'pull_request' }}
|
||||||
env:
|
# env:
|
||||||
COSIGN_EXPERIMENTAL: "true"
|
# COSIGN_EXPERIMENTAL: "true"
|
||||||
# This step uses the identity token to provision an ephemeral certificate
|
# # This step uses the identity token to provision an ephemeral certificate
|
||||||
# against the sigstore community Fulcio instance.
|
# # against the sigstore community Fulcio instance.
|
||||||
run: echo "${{ steps.meta.outputs.tags }}" | xargs -I {} cosign sign {}@${{ steps.build-and-push.outputs.digest }}
|
# run: echo "${{ steps.meta.outputs.tags }}" | xargs -I {} cosign sign {}@${{ steps.build-and-push.outputs.digest }}
|
||||||
|
|
||||||
# Temp fix
|
# Temp fix
|
||||||
# https://github.com/docker/build-push-action/issues/252
|
# https://github.com/docker/build-push-action/issues/252
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
# syntax = docker/dockerfile:latest
|
# syntax = docker/dockerfile:latest
|
||||||
|
|
||||||
# Install dependencies only when needed
|
# Install dependencies only when needed
|
||||||
FROM node:current-alpine AS deps
|
FROM docker.io/node:18-alpine AS deps
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ RUN --mount=type=cache,id=pnpm-store,target=/root/.local/share/pnpm/store pnpm f
|
|||||||
RUN --mount=type=cache,id=pnpm-store,target=/root/.local/share/pnpm/store pnpm install -r --offline
|
RUN --mount=type=cache,id=pnpm-store,target=/root/.local/share/pnpm/store pnpm install -r --offline
|
||||||
|
|
||||||
# Rebuild the source code only when needed
|
# Rebuild the source code only when needed
|
||||||
FROM node:current-alpine AS builder
|
FROM docker.io/node:18-alpine AS builder
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
ARG BUILDTIME
|
ARG BUILDTIME
|
||||||
@ -37,7 +37,7 @@ RUN <<EOF
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Production image, copy all the files and run next
|
# Production image, copy all the files and run next
|
||||||
FROM node:current-alpine AS runner
|
FROM docker.io/node:18-alpine AS runner
|
||||||
LABEL org.opencontainers.image.title "Homepage"
|
LABEL org.opencontainers.image.title "Homepage"
|
||||||
LABEL org.opencontainers.image.description "A self-hosted services landing page, with docker and service integrations."
|
LABEL org.opencontainers.image.description "A self-hosted services landing page, with docker and service integrations."
|
||||||
LABEL org.opencontainers.image.url="https://github.com/benphelps/homepage"
|
LABEL org.opencontainers.image.url="https://github.com/benphelps/homepage"
|
||||||
|
|||||||
@ -38,7 +38,7 @@
|
|||||||
- Images built for AMD64 (x86_64), ARM64, ARMv7 and ARMv6
|
- Images built for AMD64 (x86_64), ARM64, ARMv7 and ARMv6
|
||||||
- Supports all Raspberry Pi's, most SBCs & Apple Silicon
|
- Supports all Raspberry Pi's, most SBCs & Apple Silicon
|
||||||
- Full i18n support with automatic language detection
|
- Full i18n support with automatic language detection
|
||||||
- Translations for Catalan, Chinese, Dutch, Finnish, French, German, Hebrew, Hungarian, Norwegian Bokmål, Polish, Portuguese, Portuguese (Brazil), Romainian, Russian, Spanish, Swedish and Yue
|
- Translations for Catalan, Chinese, Dutch, Finnish, French, German, Hebrew, Hungarian, 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/)
|
- Want to help translate? [Join the Weblate project](https://hosted.weblate.org/engage/homepage/)
|
||||||
- Service & Web Bookmarks
|
- Service & Web Bookmarks
|
||||||
- Docker Integration
|
- Docker Integration
|
||||||
@ -67,7 +67,7 @@ If you have a more specific issue, please open an issue on the [Issues](https://
|
|||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
For configuration options, examples and more, [please check out the Wiki](https://github.com/benphelps/homepage/wiki).
|
For configuration options, examples and more, [please check out the homepage site](http://gethomepage.dev).
|
||||||
|
|
||||||
### With Docker
|
### With Docker
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ Configuration files will be genereted and placed on the first request.
|
|||||||
Configuration is done in the /config directory using .yaml files. Refer to each config for
|
Configuration is done in the /config directory using .yaml files. Refer to each config for
|
||||||
the specific configuration options.
|
the specific configuration options.
|
||||||
|
|
||||||
You may also check [the wiki](https://github.com/benphelps/homepage/wiki) for detailed configuration instructions, examples and more.
|
You may also check [the homepage site](http://gethomepage.dev) for detailed configuration instructions, examples and more.
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
|
|||||||
302
public/locales/ar/common.json
Normal file
302
public/locales/ar/common.json
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
{
|
||||||
|
"widget": {
|
||||||
|
"missing_type": "نوع القطعة مفقود: {{type}}",
|
||||||
|
"api_error": "API خطأ",
|
||||||
|
"status": "الحالة"
|
||||||
|
},
|
||||||
|
"weather": {
|
||||||
|
"current": "الموقع الحالي",
|
||||||
|
"allow": "اضغط للسماح",
|
||||||
|
"updating": "جاري التحديث",
|
||||||
|
"wait": "الرجاء الانتظار"
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
"placeholder": "بحث …"
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"cpu": "المعالج",
|
||||||
|
"total": "المجموع",
|
||||||
|
"free": "متاح",
|
||||||
|
"used": "مستخدم",
|
||||||
|
"load": "الضغط"
|
||||||
|
},
|
||||||
|
"unifi": {
|
||||||
|
"users": "المستخدمون",
|
||||||
|
"uptime": "مدة تشغيل النظام",
|
||||||
|
"days": "ايام",
|
||||||
|
"wan": "WAN",
|
||||||
|
"lan": "LAN",
|
||||||
|
"wlan": "WLAN",
|
||||||
|
"devices": "الاجهزة",
|
||||||
|
"lan_devices": "LAN اجهزة",
|
||||||
|
"wlan_devices": "WLAN احهزة",
|
||||||
|
"lan_users": "LAN مستخدمين",
|
||||||
|
"wlan_users": "WLAN مستخدمين",
|
||||||
|
"up": "اعلي",
|
||||||
|
"down": "اسفل",
|
||||||
|
"wait": "الرجاء الانتظار"
|
||||||
|
},
|
||||||
|
"wmo": {
|
||||||
|
"73-day": "Snow",
|
||||||
|
"0-day": "Sunny",
|
||||||
|
"0-night": "Clear",
|
||||||
|
"1-day": "Mainly Sunny",
|
||||||
|
"1-night": "Mainly Clear",
|
||||||
|
"2-day": "Partly Cloudy",
|
||||||
|
"2-night": "Partly Cloudy",
|
||||||
|
"3-day": "Cloudy",
|
||||||
|
"3-night": "Cloudy",
|
||||||
|
"45-day": "Foggy",
|
||||||
|
"45-night": "Foggy",
|
||||||
|
"48-day": "Foggy",
|
||||||
|
"48-night": "Foggy",
|
||||||
|
"51-day": "Light Drizzle",
|
||||||
|
"51-night": "Light Drizzle",
|
||||||
|
"53-day": "Drizzle",
|
||||||
|
"53-night": "Drizzle",
|
||||||
|
"55-day": "Heavy Drizzle",
|
||||||
|
"55-night": "Heavy Drizzle",
|
||||||
|
"56-day": "Light Freezing Drizzle",
|
||||||
|
"56-night": "Light Freezing Drizzle",
|
||||||
|
"57-day": "Freezing Drizzle",
|
||||||
|
"57-night": "Freezing Drizzle",
|
||||||
|
"61-day": "Light Rain",
|
||||||
|
"61-night": "Light Rain",
|
||||||
|
"63-day": "Rain",
|
||||||
|
"63-night": "Rain",
|
||||||
|
"65-day": "Heavy Rain",
|
||||||
|
"65-night": "Heavy Rain",
|
||||||
|
"66-day": "Freezing Rain",
|
||||||
|
"66-night": "Freezing Rain",
|
||||||
|
"67-day": "Freezing Rain",
|
||||||
|
"67-night": "Freezing Rain",
|
||||||
|
"71-day": "Light Snow",
|
||||||
|
"71-night": "Light Snow",
|
||||||
|
"73-night": "Snow",
|
||||||
|
"75-day": "Heavy Snow",
|
||||||
|
"75-night": "Heavy Snow",
|
||||||
|
"77-day": "Snow Grains",
|
||||||
|
"77-night": "Snow Grains",
|
||||||
|
"80-day": "Light Showers",
|
||||||
|
"80-night": "Light Showers",
|
||||||
|
"81-day": "Showers",
|
||||||
|
"81-night": "Showers",
|
||||||
|
"82-day": "Heavy Showers",
|
||||||
|
"82-night": "Heavy Showers",
|
||||||
|
"85-day": "Snow Showers",
|
||||||
|
"85-night": "Snow Showers",
|
||||||
|
"86-day": "Snow Showers",
|
||||||
|
"86-night": "Snow Showers",
|
||||||
|
"95-day": "Thunderstorm",
|
||||||
|
"95-night": "Thunderstorm",
|
||||||
|
"96-day": "Thunderstorm With Hail",
|
||||||
|
"96-night": "Thunderstorm With Hail",
|
||||||
|
"99-day": "Thunderstorm With Hail",
|
||||||
|
"99-night": "Thunderstorm With Hail"
|
||||||
|
},
|
||||||
|
"docker": {
|
||||||
|
"rx": "RX",
|
||||||
|
"tx": "TX",
|
||||||
|
"mem": "الرام",
|
||||||
|
"cpu": "المعالج",
|
||||||
|
"offline": "غير متصل"
|
||||||
|
},
|
||||||
|
"emby": {
|
||||||
|
"playing": "يعمل الان",
|
||||||
|
"transcoding": "التحويل",
|
||||||
|
"bitrate": "معدل البت",
|
||||||
|
"no_active": "No Active Streams"
|
||||||
|
},
|
||||||
|
"changedetectionio": {
|
||||||
|
"totalObserved": "Total Observed",
|
||||||
|
"diffsDetected": "Diffs Detected"
|
||||||
|
},
|
||||||
|
"tautulli": {
|
||||||
|
"playing": "Playing",
|
||||||
|
"transcoding": "Transcoding",
|
||||||
|
"bitrate": "Bitrate",
|
||||||
|
"no_active": "No Active Streams"
|
||||||
|
},
|
||||||
|
"nzbget": {
|
||||||
|
"rate": "Rate",
|
||||||
|
"remaining": "Remaining",
|
||||||
|
"downloaded": "Downloaded"
|
||||||
|
},
|
||||||
|
"plex": {
|
||||||
|
"streams": "Active Streams",
|
||||||
|
"movies": "Movies",
|
||||||
|
"tv": "TV Shows"
|
||||||
|
},
|
||||||
|
"sabnzbd": {
|
||||||
|
"rate": "Rate",
|
||||||
|
"queue": "Queue",
|
||||||
|
"timeleft": "Time Left"
|
||||||
|
},
|
||||||
|
"rutorrent": {
|
||||||
|
"active": "Active",
|
||||||
|
"upload": "Upload",
|
||||||
|
"download": "Download"
|
||||||
|
},
|
||||||
|
"transmission": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"qbittorrent": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"sonarr": {
|
||||||
|
"wanted": "Wanted",
|
||||||
|
"queued": "Queued",
|
||||||
|
"series": "Series"
|
||||||
|
},
|
||||||
|
"radarr": {
|
||||||
|
"wanted": "Wanted",
|
||||||
|
"missing": "Missing",
|
||||||
|
"queued": "Queued",
|
||||||
|
"movies": "Movies"
|
||||||
|
},
|
||||||
|
"lidarr": {
|
||||||
|
"wanted": "Wanted",
|
||||||
|
"queued": "Queued",
|
||||||
|
"albums": "Albums"
|
||||||
|
},
|
||||||
|
"readarr": {
|
||||||
|
"wanted": "Wanted",
|
||||||
|
"queued": "Queued",
|
||||||
|
"books": "Books"
|
||||||
|
},
|
||||||
|
"bazarr": {
|
||||||
|
"missingEpisodes": "Missing Episodes",
|
||||||
|
"missingMovies": "Missing Movies"
|
||||||
|
},
|
||||||
|
"ombi": {
|
||||||
|
"pending": "Pending",
|
||||||
|
"approved": "Approved",
|
||||||
|
"available": "Available"
|
||||||
|
},
|
||||||
|
"jellyseerr": {
|
||||||
|
"pending": "Pending",
|
||||||
|
"approved": "Approved",
|
||||||
|
"available": "Available"
|
||||||
|
},
|
||||||
|
"overseerr": {
|
||||||
|
"pending": "Pending",
|
||||||
|
"approved": "Approved",
|
||||||
|
"available": "Available"
|
||||||
|
},
|
||||||
|
"pihole": {
|
||||||
|
"queries": "Queries",
|
||||||
|
"blocked": "Blocked",
|
||||||
|
"gravity": "Gravity"
|
||||||
|
},
|
||||||
|
"adguard": {
|
||||||
|
"queries": "Queries",
|
||||||
|
"blocked": "Blocked",
|
||||||
|
"filtered": "Filtered",
|
||||||
|
"latency": "Latency"
|
||||||
|
},
|
||||||
|
"speedtest": {
|
||||||
|
"upload": "Upload",
|
||||||
|
"download": "Download",
|
||||||
|
"ping": "Ping"
|
||||||
|
},
|
||||||
|
"portainer": {
|
||||||
|
"running": "Running",
|
||||||
|
"stopped": "Stopped",
|
||||||
|
"total": "Total"
|
||||||
|
},
|
||||||
|
"traefik": {
|
||||||
|
"routers": "Routers",
|
||||||
|
"services": "Services",
|
||||||
|
"middleware": "Middleware"
|
||||||
|
},
|
||||||
|
"npm": {
|
||||||
|
"enabled": "Enabled",
|
||||||
|
"disabled": "Disabled",
|
||||||
|
"total": "Total"
|
||||||
|
},
|
||||||
|
"coinmarketcap": {
|
||||||
|
"configure": "Configure one or more crypto currencies to track",
|
||||||
|
"1hour": "1 Hour",
|
||||||
|
"1day": "1 Day",
|
||||||
|
"7days": "7 Days",
|
||||||
|
"30days": "30 Days"
|
||||||
|
},
|
||||||
|
"gotify": {
|
||||||
|
"apps": "Applications",
|
||||||
|
"clients": "Clients",
|
||||||
|
"messages": "Messages"
|
||||||
|
},
|
||||||
|
"prowlarr": {
|
||||||
|
"enableIndexers": "Indexers",
|
||||||
|
"numberOfGrabs": "Grabs",
|
||||||
|
"numberOfQueries": "Queries",
|
||||||
|
"numberOfFailGrabs": "Fail Grabs",
|
||||||
|
"numberOfFailQueries": "Fail Queries"
|
||||||
|
},
|
||||||
|
"jackett": {
|
||||||
|
"configured": "Configured",
|
||||||
|
"errored": "Errored"
|
||||||
|
},
|
||||||
|
"strelaysrv": {
|
||||||
|
"numActiveSessions": "Sessions",
|
||||||
|
"numConnections": "Connections",
|
||||||
|
"dataRelayed": "Relayed",
|
||||||
|
"transferRate": "Rate"
|
||||||
|
},
|
||||||
|
"mastodon": {
|
||||||
|
"user_count": "Users",
|
||||||
|
"status_count": "Posts",
|
||||||
|
"domain_count": "Domains"
|
||||||
|
},
|
||||||
|
"authentik": {
|
||||||
|
"users": "Users",
|
||||||
|
"loginsLast24H": "Logins (24h)",
|
||||||
|
"failedLoginsLast24H": "Failed Logins (24h)"
|
||||||
|
},
|
||||||
|
"proxmox": {
|
||||||
|
"mem": "MEM",
|
||||||
|
"cpu": "CPU",
|
||||||
|
"lxc": "LXC",
|
||||||
|
"vms": "VMs"
|
||||||
|
},
|
||||||
|
"glances": {
|
||||||
|
"cpu": "CPU",
|
||||||
|
"mem": "MEM",
|
||||||
|
"wait": "Please wait"
|
||||||
|
},
|
||||||
|
"quicklaunch": {
|
||||||
|
"bookmark": "Bookmark",
|
||||||
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers",
|
||||||
|
"approvedPushes": "Approved"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -284,5 +284,30 @@
|
|||||||
"96-night": "Thunderstorm With Hail",
|
"96-night": "Thunderstorm With Hail",
|
||||||
"99-day": "Thunderstorm With Hail",
|
"99-day": "Thunderstorm With Hail",
|
||||||
"99-night": "Thunderstorm With Hail"
|
"99-night": "Thunderstorm With Hail"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"watchtower":{
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -209,36 +209,36 @@
|
|||||||
"wait": "Espere por favor"
|
"wait": "Espere por favor"
|
||||||
},
|
},
|
||||||
"changedetectionio": {
|
"changedetectionio": {
|
||||||
"totalObserved": "Observados en Total",
|
"totalObserved": "Total Observados",
|
||||||
"diffsDetected": "Diffs Detected"
|
"diffsDetected": "Diferencias detectadas"
|
||||||
},
|
},
|
||||||
"wmo": {
|
"wmo": {
|
||||||
"48-night": "Niebla",
|
"48-night": "Niebla",
|
||||||
"51-day": "Light Drizzle",
|
"51-day": "Llovizna ligera",
|
||||||
"51-night": "Light Drizzle",
|
"51-night": "Llovizna ligera",
|
||||||
"2-day": "Parcialmente Nuboso",
|
"2-day": "Parcialmente nuboso",
|
||||||
"0-day": "Soleado",
|
"0-day": "Soleado",
|
||||||
"0-night": "Despejado",
|
"0-night": "Despejado",
|
||||||
"1-day": "Mayormente Soleado",
|
"1-day": "Mayormente soleado",
|
||||||
"1-night": "Mayormente Despejado",
|
"1-night": "Mayormente despejado",
|
||||||
"2-night": "Parcialmente Nuboso",
|
"2-night": "Parcialmente nuboso",
|
||||||
"3-day": "Nubaldo",
|
"3-day": "Nublado",
|
||||||
"3-night": "Nublado",
|
"3-night": "Nublado",
|
||||||
"45-day": "Niebla",
|
"45-day": "Niebla",
|
||||||
"45-night": "Niebla",
|
"45-night": "Niebla",
|
||||||
"48-day": "Niebla",
|
"48-day": "Niebla",
|
||||||
"53-day": "Drizzle",
|
"53-day": "Llovizna",
|
||||||
"53-night": "Drizzle",
|
"53-night": "Llovizna",
|
||||||
"55-day": "Heavy Drizzle",
|
"55-day": "Llovizna pesada",
|
||||||
"55-night": "Heavy Drizzle",
|
"55-night": "Llovizna pesada",
|
||||||
"56-day": "Light Freezing Drizzle",
|
"56-day": "Llovizna helada ligera",
|
||||||
"56-night": "Light Freezing Drizzle",
|
"56-night": "Llovizna helada ligera",
|
||||||
"57-day": "Freezing Drizzle",
|
"57-day": "Llovizna helada",
|
||||||
"57-night": "Freezing Drizzle",
|
"57-night": "Llovizna helada",
|
||||||
"61-day": "Light Rain",
|
"61-day": "Lluvia ligera",
|
||||||
"61-night": "Light Rain",
|
"61-night": "Lluvia ligera",
|
||||||
"67-day": "Granizo",
|
"67-day": "Granizo",
|
||||||
"63-day": "Rain",
|
"63-day": "Lluvia",
|
||||||
"63-night": "Lluvia",
|
"63-night": "Lluvia",
|
||||||
"65-day": "Chubascos",
|
"65-day": "Chubascos",
|
||||||
"65-night": "Chubascos",
|
"65-night": "Chubascos",
|
||||||
@ -260,18 +260,43 @@
|
|||||||
"82-day": "Chubascos",
|
"82-day": "Chubascos",
|
||||||
"82-night": "Chubascos",
|
"82-night": "Chubascos",
|
||||||
"85-day": "Chubascos",
|
"85-day": "Chubascos",
|
||||||
"85-night": "Snow Showers",
|
"85-night": "Lluvia de nieve",
|
||||||
"86-day": "Snow Showers",
|
"86-day": "Lluvia de nieve",
|
||||||
"86-night": "Snow Showers",
|
"86-night": "Lluvia de nieve",
|
||||||
"95-day": "Thunderstorm",
|
"95-day": "Tormenta",
|
||||||
"95-night": "Thunderstorm",
|
"95-night": "Tormenta",
|
||||||
"96-day": "Thunderstorm With Hail",
|
"96-day": "Tormenta con granizo",
|
||||||
"96-night": "Thunderstorm With Hail",
|
"96-night": "Tormenta con granizo",
|
||||||
"99-day": "Thunderstorm With Hail",
|
"99-day": "Tormenta con granizo",
|
||||||
"99-night": "Thunderstorm With Hail"
|
"99-night": "Tormenta con granizo"
|
||||||
},
|
},
|
||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Marcadores",
|
||||||
"service": "Service"
|
"service": "Servicio"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "Sistema",
|
||||||
|
"updates": "Actualizaciones",
|
||||||
|
"update_available": "Actualización disponible",
|
||||||
|
"up_to_date": "Actualizado",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Aprobado",
|
||||||
|
"rejectedPushes": "Rechazado",
|
||||||
|
"filters": "Filtros",
|
||||||
|
"indexers": "Indexadores"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Escaneado",
|
||||||
|
"containers_updated": "Actualizado",
|
||||||
|
"containers_failed": "Fallido"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Cola",
|
||||||
|
"videos": "Vídeos",
|
||||||
|
"channels": "Canales",
|
||||||
|
"playlists": "Listas de reproducción"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -271,7 +271,32 @@
|
|||||||
"0-day": "Ensoleillé"
|
"0-day": "Ensoleillé"
|
||||||
},
|
},
|
||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Signet",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "Système",
|
||||||
|
"updates": "Mises à jour",
|
||||||
|
"update_available": "Mise à jour disponible",
|
||||||
|
"up_to_date": "À jour",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approuvé",
|
||||||
|
"rejectedPushes": "Rejeté",
|
||||||
|
"filters": "Filtres",
|
||||||
|
"indexers": "Indexeur"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanné",
|
||||||
|
"containers_updated": "Mis à jour",
|
||||||
|
"containers_failed": "Échoué"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Vidéos",
|
||||||
|
"channels": "Chaînes",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -220,8 +220,8 @@
|
|||||||
"1-day": "Mainly Sunny",
|
"1-day": "Mainly Sunny",
|
||||||
"1-night": "Mainly Clear",
|
"1-night": "Mainly Clear",
|
||||||
"2-day": "Parzialmente Nuvoloso",
|
"2-day": "Parzialmente Nuvoloso",
|
||||||
"3-day": "Cloudy",
|
"3-day": "Nuvoloso",
|
||||||
"3-night": "Cloudy",
|
"3-night": "Nuvoloso",
|
||||||
"45-day": "Nebbioso",
|
"45-day": "Nebbioso",
|
||||||
"45-night": "Nebbioso",
|
"45-night": "Nebbioso",
|
||||||
"48-day": "Nebbioso",
|
"48-day": "Nebbioso",
|
||||||
@ -241,10 +241,10 @@
|
|||||||
"63-day": "Pioggia",
|
"63-day": "Pioggia",
|
||||||
"63-night": "Pioggia",
|
"63-night": "Pioggia",
|
||||||
"65-night": "Heavy Rain",
|
"65-night": "Heavy Rain",
|
||||||
"66-day": "Freezing Rain",
|
"66-day": "Grandine",
|
||||||
"66-night": "Freezing Rain",
|
"66-night": "Grandine",
|
||||||
"67-day": "Freezing Rain",
|
"67-day": "Grandine",
|
||||||
"67-night": "Freezing Rain",
|
"67-night": "Grandine",
|
||||||
"71-day": "Light Snow",
|
"71-day": "Light Snow",
|
||||||
"71-night": "Light Snow",
|
"71-night": "Light Snow",
|
||||||
"73-day": "Neve",
|
"73-day": "Neve",
|
||||||
@ -263,15 +263,40 @@
|
|||||||
"85-night": "Snow Showers",
|
"85-night": "Snow Showers",
|
||||||
"86-day": "Snow Showers",
|
"86-day": "Snow Showers",
|
||||||
"86-night": "Snow Showers",
|
"86-night": "Snow Showers",
|
||||||
"95-day": "Thunderstorm",
|
"95-day": "Temporale",
|
||||||
"95-night": "Thunderstorm",
|
"95-night": "Temporale",
|
||||||
"96-day": "Thunderstorm With Hail",
|
"96-day": "Temporale con grandine",
|
||||||
"96-night": "Thunderstorm With Hail",
|
"96-night": "Temporale con grandine",
|
||||||
"99-day": "Thunderstorm With Hail",
|
"99-day": "Temporale con grandine",
|
||||||
"99-night": "Thunderstorm With Hail"
|
"99-night": "Temporale con grandine"
|
||||||
},
|
},
|
||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Servizio"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -149,14 +149,14 @@
|
|||||||
"errored": "Błędne"
|
"errored": "Błędne"
|
||||||
},
|
},
|
||||||
"adguard": {
|
"adguard": {
|
||||||
"queries": "Queries",
|
"queries": "Zapytania",
|
||||||
"blocked": "Blocked",
|
"blocked": "Zablokowane",
|
||||||
"filtered": "Filtered",
|
"filtered": "Przefiltrowane",
|
||||||
"latency": "Latency"
|
"latency": "Opóźnienia"
|
||||||
},
|
},
|
||||||
"qbittorrent": {
|
"qbittorrent": {
|
||||||
"download": "Download",
|
"download": "Pobieranie",
|
||||||
"upload": "Upload",
|
"upload": "Wysyłanie",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
},
|
},
|
||||||
@ -187,26 +187,26 @@
|
|||||||
"uptime": "Czas pracy systemu",
|
"uptime": "Czas pracy systemu",
|
||||||
"days": "Dni",
|
"days": "Dni",
|
||||||
"wan": "WAN",
|
"wan": "WAN",
|
||||||
"lan_users": "LAN Users",
|
"lan_users": "Użytkownicy LAN",
|
||||||
"wlan_users": "WLAN Users",
|
"wlan_users": "Użytkownicy WLAN",
|
||||||
"up": "UP",
|
"up": "Wysyłanie",
|
||||||
"down": "DOWN",
|
"down": "Pobieranie",
|
||||||
"wait": "Please wait",
|
"wait": "Proszę czekać",
|
||||||
"lan": "LAN",
|
"lan": "LAN",
|
||||||
"wlan": "WLAN",
|
"wlan": "WLAN",
|
||||||
"devices": "Devices",
|
"devices": "Urządzenia",
|
||||||
"lan_devices": "LAN Devices",
|
"lan_devices": "Urządzenia LAN",
|
||||||
"wlan_devices": "WLAN Devices"
|
"wlan_devices": "Urządzenia WLAN"
|
||||||
},
|
},
|
||||||
"plex": {
|
"plex": {
|
||||||
"streams": "Active Streams",
|
"streams": "Active Streams",
|
||||||
"movies": "Movies",
|
"movies": "Filmy",
|
||||||
"tv": "TV Shows"
|
"tv": "Seriale"
|
||||||
},
|
},
|
||||||
"glances": {
|
"glances": {
|
||||||
"cpu": "CPU",
|
"cpu": "CPU",
|
||||||
"mem": "MEM",
|
"mem": "MEM",
|
||||||
"wait": "Please wait"
|
"wait": "Proszę czekać"
|
||||||
},
|
},
|
||||||
"changedetectionio": {
|
"changedetectionio": {
|
||||||
"diffsDetected": "Diffs Detected",
|
"diffsDetected": "Diffs Detected",
|
||||||
@ -218,60 +218,85 @@
|
|||||||
"0-night": "Clear",
|
"0-night": "Clear",
|
||||||
"1-day": "Mainly Sunny",
|
"1-day": "Mainly Sunny",
|
||||||
"1-night": "Mainly Clear",
|
"1-night": "Mainly Clear",
|
||||||
"2-day": "Partly Cloudy",
|
"2-day": "Częściowo pochmurnie",
|
||||||
"2-night": "Partly Cloudy",
|
"2-night": "Częściowo pochmurnie",
|
||||||
"3-day": "Cloudy",
|
"3-day": "Pochmurnie",
|
||||||
"3-night": "Cloudy",
|
"3-night": "Pochmurnie",
|
||||||
"45-day": "Foggy",
|
"45-day": "Mgliście",
|
||||||
"45-night": "Foggy",
|
"45-night": "Mgliście",
|
||||||
"48-day": "Foggy",
|
"48-day": "Mgliście",
|
||||||
"48-night": "Foggy",
|
"48-night": "Mgliście",
|
||||||
"51-day": "Light Drizzle",
|
"51-day": "Lekka mżawka",
|
||||||
"51-night": "Light Drizzle",
|
"51-night": "Lekka mżawka",
|
||||||
"53-day": "Drizzle",
|
"53-day": "Mżawka",
|
||||||
"53-night": "Drizzle",
|
"53-night": "Mżawka",
|
||||||
"55-day": "Heavy Drizzle",
|
"55-day": "Ciężka mżawka",
|
||||||
"55-night": "Heavy Drizzle",
|
"55-night": "Ciężka mżawka",
|
||||||
"56-day": "Light Freezing Drizzle",
|
"56-day": "Light Freezing Drizzle",
|
||||||
"56-night": "Light Freezing Drizzle",
|
"56-night": "Light Freezing Drizzle",
|
||||||
"57-day": "Freezing Drizzle",
|
"57-day": "Freezing Drizzle",
|
||||||
"57-night": "Freezing Drizzle",
|
"57-night": "Freezing Drizzle",
|
||||||
"61-day": "Light Rain",
|
"61-day": "Lekki deszcz",
|
||||||
"61-night": "Light Rain",
|
"61-night": "Lekki deszcz",
|
||||||
"63-day": "Rain",
|
"63-day": "Deszcz",
|
||||||
"63-night": "Rain",
|
"63-night": "Deszcz",
|
||||||
"65-day": "Heavy Rain",
|
"65-day": "Ciężki deszcz",
|
||||||
"65-night": "Heavy Rain",
|
"65-night": "Ciężki deszcz",
|
||||||
"66-day": "Freezing Rain",
|
"66-day": "Mroźny deszcz",
|
||||||
"66-night": "Freezing Rain",
|
"66-night": "Mroźny deszcz",
|
||||||
"67-day": "Freezing Rain",
|
"67-day": "Mroźny deszcz",
|
||||||
"67-night": "Freezing Rain",
|
"67-night": "Mroźny deszcz",
|
||||||
"71-day": "Light Snow",
|
"71-day": "Lekki śnieg",
|
||||||
"71-night": "Light Snow",
|
"71-night": "Lekki śnieg",
|
||||||
"73-day": "Snow",
|
"73-day": "Śnieg",
|
||||||
"73-night": "Snow",
|
"73-night": "Śnieg",
|
||||||
"75-day": "Heavy Snow",
|
"75-day": "Ciężki śnieg",
|
||||||
"75-night": "Heavy Snow",
|
"75-night": "Ciężki śnieg",
|
||||||
"77-night": "Snow Grains",
|
"77-night": "Snow Grains",
|
||||||
"80-day": "Light Showers",
|
"80-day": "Lekkie opady",
|
||||||
"80-night": "Light Showers",
|
"80-night": "Lekkie opady",
|
||||||
"81-day": "Showers",
|
"81-day": "Opady",
|
||||||
"81-night": "Showers",
|
"81-night": "Opady",
|
||||||
"82-day": "Heavy Showers",
|
"82-day": "Ciężkie opady",
|
||||||
"82-night": "Heavy Showers",
|
"82-night": "Ciężkie opady",
|
||||||
"85-day": "Snow Showers",
|
"85-day": "Opady śniegu",
|
||||||
"85-night": "Snow Showers",
|
"85-night": "Opady śniegu",
|
||||||
"86-day": "Snow Showers",
|
"86-day": "Opady śniegu",
|
||||||
"86-night": "Snow Showers",
|
"86-night": "Opady śniegu",
|
||||||
"95-day": "Thunderstorm",
|
"95-day": "Burze z piorunami",
|
||||||
"95-night": "Thunderstorm",
|
"95-night": "Burze z piorunami",
|
||||||
"96-day": "Thunderstorm With Hail",
|
"96-day": "Burza z gradobiciem",
|
||||||
"96-night": "Thunderstorm With Hail",
|
"96-night": "Burza z gradobiciem",
|
||||||
"99-day": "Thunderstorm With Hail",
|
"99-day": "Burza z gradobiciem",
|
||||||
"99-night": "Thunderstorm With Hail"
|
"99-night": "Burza z gradobiciem"
|
||||||
},
|
},
|
||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Usługi"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Aktualizacje",
|
||||||
|
"update_available": "Dostępna aktualizacja",
|
||||||
|
"up_to_date": "Aktualny",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -284,5 +284,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}",
|
||||||
|
"child_bridges": "Child Bridges"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -209,69 +209,94 @@
|
|||||||
"wait": "దయచేసి వేచి ఉండండి"
|
"wait": "దయచేసి వేచి ఉండండి"
|
||||||
},
|
},
|
||||||
"changedetectionio": {
|
"changedetectionio": {
|
||||||
"totalObserved": "Total Observed",
|
"totalObserved": "మొత్తం గమనించబడింది",
|
||||||
"diffsDetected": "Diffs Detected"
|
"diffsDetected": "తేడాలు గుర్తించబడ్డాయి"
|
||||||
},
|
},
|
||||||
"wmo": {
|
"wmo": {
|
||||||
"0-day": "Sunny",
|
"0-day": "సన్నీ",
|
||||||
"0-night": "Clear",
|
"0-night": "స్పష్టమైన",
|
||||||
"57-night": "Freezing Drizzle",
|
"57-night": "గడ్డకట్టే చినుకులు",
|
||||||
"73-day": "Snow",
|
"73-day": "మంచు",
|
||||||
"73-night": "Snow",
|
"73-night": "మంచు",
|
||||||
"75-day": "Heavy Snow",
|
"75-day": "భారీ మంచు",
|
||||||
"75-night": "Heavy Snow",
|
"75-night": "భారీ మంచు",
|
||||||
"77-day": "Snow Grains",
|
"77-day": "మంచు గింజలు",
|
||||||
"77-night": "Snow Grains",
|
"77-night": "మంచు గింజలు",
|
||||||
"80-day": "Light Showers",
|
"80-day": "తేలికపాటి జల్లులు",
|
||||||
"80-night": "Light Showers",
|
"80-night": "తేలికపాటి జల్లులు",
|
||||||
"81-day": "Showers",
|
"81-day": "జల్లులు",
|
||||||
"81-night": "Showers",
|
"81-night": "జల్లులు",
|
||||||
"82-day": "Heavy Showers",
|
"82-day": "భారీ వర్షాలు",
|
||||||
"82-night": "Heavy Showers",
|
"82-night": "భారీ వర్షాలు",
|
||||||
"85-day": "Snow Showers",
|
"85-day": "మంచు జల్లులు",
|
||||||
"85-night": "Snow Showers",
|
"85-night": "మంచు జల్లులు",
|
||||||
"1-day": "Mainly Sunny",
|
"1-day": "ప్రధానంగా ఎండ",
|
||||||
"1-night": "Mainly Clear",
|
"1-night": "ప్రధానంగా స్పష్టంగా",
|
||||||
"2-day": "Partly Cloudy",
|
"2-day": "పాక్షికంగా మేఘావృతమై ఉంటుంది",
|
||||||
"2-night": "Partly Cloudy",
|
"2-night": "పాక్షికంగా మేఘావృతమై ఉంటుంది",
|
||||||
"3-day": "Cloudy",
|
"3-day": "మేఘావృతం",
|
||||||
"3-night": "Cloudy",
|
"3-night": "మేఘావృతం",
|
||||||
"45-day": "Foggy",
|
"45-day": "పొగమంచు",
|
||||||
"45-night": "Foggy",
|
"45-night": "పొగమంచు",
|
||||||
"48-day": "Foggy",
|
"48-day": "పొగమంచు",
|
||||||
"48-night": "Foggy",
|
"48-night": "పొగమంచు",
|
||||||
"51-day": "Light Drizzle",
|
"51-day": "తేలికపాటి చినుకులు",
|
||||||
"51-night": "Light Drizzle",
|
"51-night": "తేలికపాటి చినుకులు",
|
||||||
"53-day": "Drizzle",
|
"53-day": "చినుకులు",
|
||||||
"53-night": "Drizzle",
|
"53-night": "చినుకులు",
|
||||||
"55-day": "Heavy Drizzle",
|
"55-day": "భారీ చినుకులు",
|
||||||
"55-night": "Heavy Drizzle",
|
"55-night": "భారీ చినుకులు",
|
||||||
"56-day": "Light Freezing Drizzle",
|
"56-day": "తేలికపాటి గడ్డకట్టే చినుకులు",
|
||||||
"56-night": "Light Freezing Drizzle",
|
"56-night": "తేలికపాటి గడ్డకట్టే చినుకులు",
|
||||||
"57-day": "Freezing Drizzle",
|
"57-day": "గడ్డకట్టే చినుకులు",
|
||||||
"61-day": "Light Rain",
|
"61-day": "తేలికపాటి వర్షం",
|
||||||
"61-night": "Light Rain",
|
"61-night": "తేలికపాటి వర్షం",
|
||||||
"63-day": "Rain",
|
"63-day": "వర్షం",
|
||||||
"63-night": "Rain",
|
"63-night": "వర్షం",
|
||||||
"65-day": "Heavy Rain",
|
"65-day": "భారీవర్షం",
|
||||||
"65-night": "Heavy Rain",
|
"65-night": "భారీవర్షం",
|
||||||
"66-day": "Freezing Rain",
|
"66-day": "గడ్డకట్టే వర్షం",
|
||||||
"66-night": "Freezing Rain",
|
"66-night": "గడ్డకట్టే వర్షం",
|
||||||
"67-day": "Freezing Rain",
|
"67-day": "గడ్డకట్టే వర్షం",
|
||||||
"67-night": "Freezing Rain",
|
"67-night": "గడ్డకట్టే వర్షం",
|
||||||
"71-day": "Light Snow",
|
"71-day": "తేలికపాటి మంచు",
|
||||||
"71-night": "Light Snow",
|
"71-night": "తేలికపాటి మంచు",
|
||||||
"86-day": "Snow Showers",
|
"86-day": "మంచు జల్లులు",
|
||||||
"86-night": "Snow Showers",
|
"86-night": "మంచు జల్లులు",
|
||||||
"95-day": "Thunderstorm",
|
"95-day": "ఉరుము",
|
||||||
"95-night": "Thunderstorm",
|
"95-night": "ఉరుము",
|
||||||
"96-day": "Thunderstorm With Hail",
|
"96-day": "వడగళ్లతో కూడిన ఉరుములతో కూడిన వర్షం",
|
||||||
"96-night": "Thunderstorm With Hail",
|
"96-night": "వడగళ్లతో కూడిన ఉరుములతో కూడిన వర్షం",
|
||||||
"99-day": "Thunderstorm With Hail",
|
"99-day": "వడగళ్లతో కూడిన ఉరుములతో కూడిన వర్షం",
|
||||||
"99-night": "Thunderstorm With Hail"
|
"99-night": "వడగళ్లతో కూడిన ఉరుములతో కూడిన వర్షం"
|
||||||
},
|
},
|
||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "బుక్మార్క్",
|
||||||
"service": "Service"
|
"service": "సేవ"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "వ్యవస్థ",
|
||||||
|
"updates": "నవీకరణలు",
|
||||||
|
"update_available": "అందుబాటులో నవీకరణ",
|
||||||
|
"up_to_date": "తాజాగా",
|
||||||
|
"child_bridges": "పిల్ల వంతెనలు",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"rejectedPushes": "తిరస్కరించారు",
|
||||||
|
"approvedPushes": "ఆమోదించబడింది",
|
||||||
|
"filters": "ఫిల్టర్లు",
|
||||||
|
"indexers": "సూచికలు"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "స్కాన్ చేశారు",
|
||||||
|
"containers_updated": "నవీకరించబడింది",
|
||||||
|
"containers_failed": "విఫలమయ్యారు"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -273,5 +273,30 @@
|
|||||||
"quicklaunch": {
|
"quicklaunch": {
|
||||||
"bookmark": "Bookmark",
|
"bookmark": "Bookmark",
|
||||||
"service": "Service"
|
"service": "Service"
|
||||||
|
},
|
||||||
|
"homebridge": {
|
||||||
|
"available_update": "System",
|
||||||
|
"updates": "Updates",
|
||||||
|
"update_available": "Update Available",
|
||||||
|
"up_to_date": "Up to Date",
|
||||||
|
"child_bridges": "Child Bridges",
|
||||||
|
"child_bridges_status": "{{ok}}/{{total}}"
|
||||||
|
},
|
||||||
|
"autobrr": {
|
||||||
|
"approvedPushes": "Approved",
|
||||||
|
"rejectedPushes": "Rejected",
|
||||||
|
"filters": "Filters",
|
||||||
|
"indexers": "Indexers"
|
||||||
|
},
|
||||||
|
"watchtower": {
|
||||||
|
"containers_scanned": "Scanned",
|
||||||
|
"containers_updated": "Updated",
|
||||||
|
"containers_failed": "Failed"
|
||||||
|
},
|
||||||
|
"tubearchivist": {
|
||||||
|
"downloads": "Queue",
|
||||||
|
"videos": "Videos",
|
||||||
|
"channels": "Channels",
|
||||||
|
"playlists": "Playlists"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,10 +27,12 @@ export default function DateTime({ options }) {
|
|||||||
const dateFormat = new Intl.DateTimeFormat(i18n.language, { ...format });
|
const dateFormat = new Intl.DateTimeFormat(i18n.language, { ...format });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-row items-center grow justify-end">
|
<div className="flex flex-col justify-center first:ml-0 ml-4">
|
||||||
<span className={`text-theme-800 dark:text-theme-200 ${textSizes[textSize || "lg"]}`}>
|
<div className="flex flex-row items-center grow justify-end">
|
||||||
{dateFormat.format(date)}
|
<span className={`text-theme-800 dark:text-theme-200 ${textSizes[textSize || "lg"]}`}>
|
||||||
</span>
|
{dateFormat.format(date)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable react/jsx-props-no-spreading */
|
/* eslint-disable react/jsx-props-no-spreading */
|
||||||
import { SWRConfig } from "swr";
|
import { SWRConfig } from "swr";
|
||||||
import { appWithTranslation } from "next-i18next";
|
import { appWithTranslation } from "next-i18next";
|
||||||
|
import Head from "next/head";
|
||||||
|
|
||||||
import "styles/globals.css";
|
import "styles/globals.css";
|
||||||
import "styles/theme.css";
|
import "styles/theme.css";
|
||||||
@ -18,6 +19,10 @@ function MyApp({ Component, pageProps }) {
|
|||||||
fetcher: (resource, init) => fetch(resource, init).then((res) => res.json()),
|
fetcher: (resource, init) => fetch(resource, init).then((res) => res.json()),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<Head>
|
||||||
|
{/* https://nextjs.org/docs/messages/no-document-viewport-meta */}
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||||
|
</Head>
|
||||||
<ColorProvider>
|
<ColorProvider>
|
||||||
<ThemeProvider>
|
<ThemeProvider>
|
||||||
<SettingsProvider>
|
<SettingsProvider>
|
||||||
|
|||||||
@ -9,7 +9,6 @@ export default function Document() {
|
|||||||
content="A highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations."
|
content="A highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations."
|
||||||
/>
|
/>
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png?v=4" />
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png?v=4" />
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png?v=4" />
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png?v=4" />
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png?v=4" />
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png?v=4" />
|
||||||
|
|||||||
@ -35,7 +35,7 @@ const Version = dynamic(() => import("components/version"), {
|
|||||||
ssr: false,
|
ssr: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const rightAlignedWidgets = ["weatherapi", "openweathermap", "weather", "search", "datetime"];
|
const rightAlignedWidgets = ["weatherapi", "openweathermap", "weather", "openmeteo", "search", "datetime"];
|
||||||
|
|
||||||
export async function getStaticProps() {
|
export async function getStaticProps() {
|
||||||
let logger;
|
let logger;
|
||||||
@ -272,7 +272,7 @@ function Home({ initialSettings }) {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{bookmarks && (
|
{bookmarks && (
|
||||||
<div className="grow flex flex-wrap pt-0 p-4 sm:p-8">
|
<div className="grow flex flex-wrap pt-0 p-4 sm:p-8 gap-x-2">
|
||||||
{bookmarks.map((group) => (
|
{bookmarks.map((group) => (
|
||||||
<BookmarksGroup key={group.name} group={group} />
|
<BookmarksGroup key={group.name} group={group} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
# For configuration options and examples, please see:
|
# For configuration options and examples, please see:
|
||||||
# https://github.com/benphelps/homepage/wiki/Bookmarks
|
# https://gethomepage.dev/en/configs/bookmarks
|
||||||
|
|
||||||
- Developer:
|
- Developer:
|
||||||
- Github:
|
- Github:
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
# For configuration options and examples, please see:
|
# For configuration options and examples, please see:
|
||||||
# https://github.com/benphelps/homepage/wiki/Docker-Integration
|
# https://gethomepage.dev/en/configs/docker/
|
||||||
|
|
||||||
# my-docker:
|
# my-docker:
|
||||||
# host: 127.0.0.1
|
# host: 127.0.0.1
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
# For configuration options and examples, please see:
|
# For configuration options and examples, please see:
|
||||||
# https://github.com/benphelps/homepage/wiki/Services
|
# https://gethomepage.dev/en/configs/services
|
||||||
|
|
||||||
- My First Group:
|
- My First Group:
|
||||||
- My First Service:
|
- My First Service:
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
# For configuration options and examples, please see:
|
# For configuration options and examples, please see:
|
||||||
# https://github.com/benphelps/homepage/wiki/Settings
|
# https://gethomepage.dev/en/configs/settings
|
||||||
|
|
||||||
providers:
|
providers:
|
||||||
openweathermap: openweathermapapikey
|
openweathermap: openweathermapapikey
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
# For configuration options and examples, please see:
|
# For configuration options and examples, please see:
|
||||||
# https://github.com/benphelps/homepage/wiki/Information-Widgets
|
# https://gethomepage.dev/en/configs/widgets
|
||||||
|
|
||||||
- resources:
|
- resources:
|
||||||
cpu: true
|
cpu: true
|
||||||
|
|||||||
@ -31,6 +31,10 @@ export default async function credentialedProxyHandler(req, res) {
|
|||||||
headers.Authorization = `Bearer ${widget.key}`;
|
headers.Authorization = `Bearer ${widget.key}`;
|
||||||
} else if (widget.type === "proxmox") {
|
} else if (widget.type === "proxmox") {
|
||||||
headers.Authorization = `PVEAPIToken=${widget.username}=${widget.password}`;
|
headers.Authorization = `PVEAPIToken=${widget.username}=${widget.password}`;
|
||||||
|
} else if (widget.type === "autobrr") {
|
||||||
|
headers["X-API-Token"] = `${widget.key}`;
|
||||||
|
} else if (widget.type === "tubearchivist") {
|
||||||
|
headers.Authorization = `Token ${widget.key}`;
|
||||||
} else {
|
} else {
|
||||||
headers["X-API-Key"] = `${widget.key}`;
|
headers["X-API-Key"] = `${widget.key}`;
|
||||||
}
|
}
|
||||||
|
|||||||
39
src/widgets/autobrr/component.jsx
Normal file
39
src/widgets/autobrr/component.jsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { useTranslation } from "next-i18next";
|
||||||
|
|
||||||
|
import Container from "components/services/widget/container";
|
||||||
|
import Block from "components/services/widget/block";
|
||||||
|
import useWidgetAPI from "utils/proxy/use-widget-api";
|
||||||
|
|
||||||
|
export default function Component({ service }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { widget } = service;
|
||||||
|
|
||||||
|
const { data: statsData, error: statsError } = useWidgetAPI(widget, "stats");
|
||||||
|
const { data: filtersData, error: filtersError } = useWidgetAPI(widget, "filters");
|
||||||
|
const { data: indexersData, error: indexersError } = useWidgetAPI(widget, "indexers");
|
||||||
|
|
||||||
|
if (statsError || filtersError || indexersError) {
|
||||||
|
return <Container error={t("widget.api_error")} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!statsData || !filtersData || !indexersData) {
|
||||||
|
return (
|
||||||
|
<Container service={service}>
|
||||||
|
<Block label="autobrr.approvedPushes" />
|
||||||
|
<Block label="autobrr.rejectedPushes" />
|
||||||
|
<Block label="autobrr.filters" />
|
||||||
|
<Block label="autobrr.indexers" />
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container service={service}>
|
||||||
|
<Block label="autobrr.approvedPushes" value={t("common.number", { value: statsData.push_approved_count })} />
|
||||||
|
<Block label="autobrr.rejectedPushes" value={t("common.number", { value: statsData.push_rejected_count })} />
|
||||||
|
<Block label="autobrr.filters" value={t("common.number", { value: filtersData.length })} />
|
||||||
|
<Block label="autobrr.indexers" value={t("common.number", { value: indexersData.length })} />
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
20
src/widgets/autobrr/widget.js
Normal file
20
src/widgets/autobrr/widget.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
|
||||||
|
|
||||||
|
const widget = {
|
||||||
|
api: "{url}/api/{endpoint}",
|
||||||
|
proxyHandler: credentialedProxyHandler,
|
||||||
|
|
||||||
|
mappings: {
|
||||||
|
stats: {
|
||||||
|
endpoint: "release/stats",
|
||||||
|
},
|
||||||
|
filters: {
|
||||||
|
endpoint: "filters",
|
||||||
|
},
|
||||||
|
indexers: {
|
||||||
|
endpoint: "release/indexers",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default widget;
|
||||||
@ -3,12 +3,14 @@ import dynamic from "next/dynamic";
|
|||||||
const components = {
|
const components = {
|
||||||
adguard: dynamic(() => import("./adguard/component")),
|
adguard: dynamic(() => import("./adguard/component")),
|
||||||
authentik: dynamic(() => import("./authentik/component")),
|
authentik: dynamic(() => import("./authentik/component")),
|
||||||
|
autobrr: dynamic(() => import("./autobrr/component")),
|
||||||
bazarr: dynamic(() => import("./bazarr/component")),
|
bazarr: dynamic(() => import("./bazarr/component")),
|
||||||
changedetectionio: dynamic(() => import("./changedetectionio/component")),
|
changedetectionio: dynamic(() => import("./changedetectionio/component")),
|
||||||
coinmarketcap: dynamic(() => import("./coinmarketcap/component")),
|
coinmarketcap: dynamic(() => import("./coinmarketcap/component")),
|
||||||
docker: dynamic(() => import("./docker/component")),
|
docker: dynamic(() => import("./docker/component")),
|
||||||
emby: dynamic(() => import("./emby/component")),
|
emby: dynamic(() => import("./emby/component")),
|
||||||
gotify: dynamic(() => import("./gotify/component")),
|
gotify: dynamic(() => import("./gotify/component")),
|
||||||
|
homebridge: dynamic(() => import("./homebridge/component")),
|
||||||
jackett: dynamic(() => import("./jackett/component")),
|
jackett: dynamic(() => import("./jackett/component")),
|
||||||
jellyfin: dynamic(() => import("./emby/component")),
|
jellyfin: dynamic(() => import("./emby/component")),
|
||||||
jellyseerr: dynamic(() => import("./jellyseerr/component")),
|
jellyseerr: dynamic(() => import("./jellyseerr/component")),
|
||||||
@ -34,7 +36,9 @@ const components = {
|
|||||||
tautulli: dynamic(() => import("./tautulli/component")),
|
tautulli: dynamic(() => import("./tautulli/component")),
|
||||||
traefik: dynamic(() => import("./traefik/component")),
|
traefik: dynamic(() => import("./traefik/component")),
|
||||||
transmission: dynamic(() => import("./transmission/component")),
|
transmission: dynamic(() => import("./transmission/component")),
|
||||||
|
tubearchivist: dynamic(() => import("./tubearchivist/component")),
|
||||||
unifi: dynamic(() => import("./unifi/component")),
|
unifi: dynamic(() => import("./unifi/component")),
|
||||||
|
watchtower: dynamic(() => import("./watchtower/component")),
|
||||||
};
|
};
|
||||||
|
|
||||||
export default components;
|
export default components;
|
||||||
|
|||||||
@ -10,7 +10,7 @@ const widget = {
|
|||||||
},
|
},
|
||||||
PlayControl: {
|
PlayControl: {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
enpoint: "Sessions/{sessionId}/Playing/{command}",
|
endpoint: "Sessions/{sessionId}/Playing/{command}",
|
||||||
segments: ["sessionId", "command"],
|
segments: ["sessionId", "command"],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
51
src/widgets/homebridge/component.jsx
Normal file
51
src/widgets/homebridge/component.jsx
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import { useTranslation } from "next-i18next";
|
||||||
|
|
||||||
|
import Container from "components/services/widget/container";
|
||||||
|
import Block from "components/services/widget/block";
|
||||||
|
import useWidgetAPI from "utils/proxy/use-widget-api";
|
||||||
|
|
||||||
|
export default function Component({ service }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { widget } = service;
|
||||||
|
|
||||||
|
const { data: homebridgeData, error: homebridgeError } = useWidgetAPI(widget, "info");
|
||||||
|
|
||||||
|
if (homebridgeError || homebridgeData?.error) {
|
||||||
|
return <Container error={t("widget.api_error")} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!homebridgeData) {
|
||||||
|
return (
|
||||||
|
<Container service={service}>
|
||||||
|
<Block label="widget.status" />
|
||||||
|
<Block label="homebridge.updates" />
|
||||||
|
<Block label="homebridge.child_bridges" />
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container service={service}>
|
||||||
|
<Block
|
||||||
|
label="widget.status"
|
||||||
|
value={`${homebridgeData.status[0].toUpperCase()}${homebridgeData.status.substr(1)}`}
|
||||||
|
/>
|
||||||
|
<Block
|
||||||
|
label="homebridge.updates"
|
||||||
|
value={
|
||||||
|
(homebridgeData.updateAvailable || homebridgeData.plugins?.updatesAvailable)
|
||||||
|
? t("homebridge.update_available")
|
||||||
|
: t("homebridge.up_to_date")}
|
||||||
|
/>
|
||||||
|
{homebridgeData?.childBridges?.total > 0 &&
|
||||||
|
<Block
|
||||||
|
label="homebridge.child_bridges"
|
||||||
|
value={t("homebridge.child_bridges_status", {
|
||||||
|
total: homebridgeData.childBridges.total,
|
||||||
|
ok: homebridgeData.childBridges.running
|
||||||
|
})}
|
||||||
|
/>}
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
106
src/widgets/homebridge/proxy.js
Normal file
106
src/widgets/homebridge/proxy.js
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
import cache from "memory-cache";
|
||||||
|
|
||||||
|
import { httpProxy } from "utils/proxy/http";
|
||||||
|
import { formatApiCall } from "utils/proxy/api-helpers";
|
||||||
|
import getServiceWidget from "utils/config/service-helpers";
|
||||||
|
import createLogger from "utils/logger";
|
||||||
|
import widgets from "widgets/widgets";
|
||||||
|
|
||||||
|
const proxyName = "homebridgeProxyHandler";
|
||||||
|
const sessionTokenCacheKey = `${proxyName}__sessionToken`;
|
||||||
|
const logger = createLogger(proxyName);
|
||||||
|
|
||||||
|
async function login(widget) {
|
||||||
|
const endpoint = "auth/login";
|
||||||
|
const api = widgets?.[widget.type]?.api
|
||||||
|
const loginUrl = new URL(formatApiCall(api, { endpoint, ...widget }));
|
||||||
|
const loginBody = { username: widget.username, password: widget.password };
|
||||||
|
const headers = { "Content-Type": "application/json" };
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
const [status, contentType, data, responseHeaders] = await httpProxy(loginUrl, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(loginBody),
|
||||||
|
headers,
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { access_token: accessToken, expires_in: expiresIn } = JSON.parse(data.toString());
|
||||||
|
|
||||||
|
cache.put(sessionTokenCacheKey, accessToken, (expiresIn * 1000) - 5 * 60 * 1000); // expiresIn (s) - 5m
|
||||||
|
return { accessToken };
|
||||||
|
} catch (e) {
|
||||||
|
logger.error("Unable to login to Homebridge API: %s", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { accessToken: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function apiCall(widget, endpoint) {
|
||||||
|
const headers = {
|
||||||
|
"content-type": "application/json",
|
||||||
|
"Authorization": `Bearer ${cache.get(sessionTokenCacheKey)}`,
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget }));
|
||||||
|
const method = "GET";
|
||||||
|
|
||||||
|
let [status, contentType, data, responseHeaders] = await httpProxy(url, {
|
||||||
|
method,
|
||||||
|
headers,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (status === 401) {
|
||||||
|
logger.debug("Homebridge API rejected the request, attempting to obtain new session token");
|
||||||
|
const { accessToken } = login(widget);
|
||||||
|
headers.Authorization = `Bearer ${accessToken}`;
|
||||||
|
|
||||||
|
// retry the request, now with the new session token
|
||||||
|
[status, contentType, data, responseHeaders] = await httpProxy(url, {
|
||||||
|
method,
|
||||||
|
headers,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status !== 200) {
|
||||||
|
logger.error("Error getting data from Homebridge: %d. Data: %s", status, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { status, contentType, data: JSON.parse(data.toString()), responseHeaders };
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function homebridgeProxyHandler(req, res) {
|
||||||
|
const { group, service } = req.query;
|
||||||
|
|
||||||
|
if (!group || !service) {
|
||||||
|
logger.debug("Invalid or missing service '%s' or group '%s'", service, group);
|
||||||
|
return res.status(400).json({ error: "Invalid proxy service type" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const widget = await getServiceWidget(group, service);
|
||||||
|
|
||||||
|
if (!widget) {
|
||||||
|
logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group);
|
||||||
|
return res.status(400).json({ error: "Invalid proxy service type" });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cache.get(sessionTokenCacheKey)) {
|
||||||
|
await login(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data: statusData } = await apiCall(widget, "status/homebridge");
|
||||||
|
const { data: versionData } = await apiCall(widget, "status/homebridge-version");
|
||||||
|
const { data: childBridgeData } = await apiCall(widget, "status/homebridge/child-bridges");
|
||||||
|
const { data: pluginsData } = await apiCall(widget, "plugins");
|
||||||
|
|
||||||
|
return res.status(200).send({
|
||||||
|
status: statusData?.status,
|
||||||
|
updateAvailable: versionData?.updateAvailable,
|
||||||
|
plugins: {
|
||||||
|
updatesAvailable: pluginsData?.filter(p => p.updateAvailable).length,
|
||||||
|
},
|
||||||
|
childBridges: {
|
||||||
|
running: childBridgeData?.filter(cb => cb.status === "ok").length,
|
||||||
|
total: childBridgeData?.length
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
14
src/widgets/homebridge/widget.js
Normal file
14
src/widgets/homebridge/widget.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import homebridgeProxyHandler from "./proxy";
|
||||||
|
|
||||||
|
const widget = {
|
||||||
|
api: "{url}/api/{endpoint}",
|
||||||
|
proxyHandler: homebridgeProxyHandler,
|
||||||
|
|
||||||
|
mappings: {
|
||||||
|
info: {
|
||||||
|
endpoint: "/",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default widget;
|
||||||
40
src/widgets/tubearchivist/component.jsx
Normal file
40
src/widgets/tubearchivist/component.jsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { useTranslation } from "next-i18next";
|
||||||
|
|
||||||
|
import Container from "components/services/widget/container";
|
||||||
|
import Block from "components/services/widget/block";
|
||||||
|
import useWidgetAPI from "utils/proxy/use-widget-api";
|
||||||
|
|
||||||
|
export default function Component({ service }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { widget } = service;
|
||||||
|
|
||||||
|
const { data: downloadsData, error: downloadsError } = useWidgetAPI(widget, "downloads");
|
||||||
|
const { data: videosData, error: videosError } = useWidgetAPI(widget, "videos");
|
||||||
|
const { data: channelsData, error: channelsError } = useWidgetAPI(widget, "channels");
|
||||||
|
const { data: playlistsData, error: playlistsError } = useWidgetAPI(widget, "playlists");
|
||||||
|
|
||||||
|
if (downloadsError || videosError || channelsError || playlistsError) {
|
||||||
|
return <Container error={t("widget.api_error")} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!downloadsData || !videosData || !channelsData || !playlistsData) {
|
||||||
|
return (
|
||||||
|
<Container service={service}>
|
||||||
|
<Block label="tubearchivist.downloads" />
|
||||||
|
<Block label="tubearchivist.videos" />
|
||||||
|
<Block label="tubearchivist.channels" />
|
||||||
|
<Block label="tubearchivist.playlists" />
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container service={service}>
|
||||||
|
<Block label="tubearchivist.downloads" value={t("common.number", { value: downloadsData?.paginate?.total_hits })} />
|
||||||
|
<Block label="tubearchivist.videos" value={t("common.number", { value: videosData?.paginate?.total_hits })} />
|
||||||
|
<Block label="tubearchivist.channels" value={t("common.number", { value: channelsData?.paginate?.total_hits })} />
|
||||||
|
<Block label="tubearchivist.playlists" value={t("common.number", { value: playlistsData?.paginate?.total_hits })} />
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
23
src/widgets/tubearchivist/widget.js
Normal file
23
src/widgets/tubearchivist/widget.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
|
||||||
|
|
||||||
|
const widget = {
|
||||||
|
api: "{url}/api/{endpoint}",
|
||||||
|
proxyHandler: credentialedProxyHandler,
|
||||||
|
|
||||||
|
mappings: {
|
||||||
|
downloads: {
|
||||||
|
endpoint: "download",
|
||||||
|
},
|
||||||
|
videos: {
|
||||||
|
endpoint: "video",
|
||||||
|
},
|
||||||
|
channels: {
|
||||||
|
endpoint: "channel",
|
||||||
|
},
|
||||||
|
playlists: {
|
||||||
|
endpoint: "playlist",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default widget;
|
||||||
36
src/widgets/watchtower/component.jsx
Normal file
36
src/widgets/watchtower/component.jsx
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { useTranslation } from "next-i18next";
|
||||||
|
|
||||||
|
import Container from "components/services/widget/container";
|
||||||
|
import Block from "components/services/widget/block";
|
||||||
|
import useWidgetAPI from "utils/proxy/use-widget-api";
|
||||||
|
|
||||||
|
|
||||||
|
export default function Component({ service }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { widget } = service;
|
||||||
|
|
||||||
|
const { data: watchData, error: watchError } = useWidgetAPI(widget, "watchtower");
|
||||||
|
|
||||||
|
if (watchError || !watchData) {
|
||||||
|
return <Container error={t("widget.api_error")} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!watchData) {
|
||||||
|
return (
|
||||||
|
<Container service={service}>
|
||||||
|
<Block label="watchtower.containers_scanned " />
|
||||||
|
<Block label="watchtower.containers_updated" />
|
||||||
|
<Block label="watchtower.containers_failed" />
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container service={service}>
|
||||||
|
<Block label="watchtower.containers_scanned" value={t("common.number", { value: watchData.watchtower_containers_scanned })} />
|
||||||
|
<Block label="watchtower.containers_updated" value={t("common.number", { value: watchData.watchtower_containers_updated })} />
|
||||||
|
<Block label="watchtower.containers_failed" value={t("common.number", { value: watchData.watchtower_containers_failed })} />
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
48
src/widgets/watchtower/proxy.js
Normal file
48
src/widgets/watchtower/proxy.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { httpProxy } from "utils/proxy/http";
|
||||||
|
import { formatApiCall } from "utils/proxy/api-helpers";
|
||||||
|
import getServiceWidget from "utils/config/service-helpers";
|
||||||
|
import createLogger from "utils/logger";
|
||||||
|
import widgets from "widgets/widgets";
|
||||||
|
|
||||||
|
const proxyName = "watchtowerProxyHandler";
|
||||||
|
const logger = createLogger(proxyName);
|
||||||
|
|
||||||
|
export default async function watchtowerProxyHandler(req, res) {
|
||||||
|
const { group, service, endpoint } = req.query;
|
||||||
|
|
||||||
|
if (!group || !service) {
|
||||||
|
logger.debug("Invalid or missing service '%s' or group '%s'", service, group);
|
||||||
|
return res.status(400).json({ error: "Invalid proxy service type" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const widget = await getServiceWidget(group, service);
|
||||||
|
|
||||||
|
if (!widget) {
|
||||||
|
logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group);
|
||||||
|
return res.status(400).json({ error: "Invalid proxy service type" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget }));
|
||||||
|
|
||||||
|
const [status, contentType, data] = await httpProxy(url, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${widget.key}`,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (status !== 200 || !data) {
|
||||||
|
logger.error("Error getting data from WatchTower: %d. Data: %s", status, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
const cleanData = data.toString().split("\n").filter(s => s.startsWith("watchtower"))
|
||||||
|
const jsonRes = {}
|
||||||
|
|
||||||
|
cleanData.map(e => e.split(" ")).forEach(strArray => {
|
||||||
|
const [key, value] = strArray
|
||||||
|
jsonRes[key] = value
|
||||||
|
})
|
||||||
|
|
||||||
|
if (contentType) res.setHeader("Content-Type", contentType);
|
||||||
|
return res.status(status).send(jsonRes);
|
||||||
|
}
|
||||||
14
src/widgets/watchtower/widget.js
Normal file
14
src/widgets/watchtower/widget.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import watchtowerProxyHandler from "./proxy";
|
||||||
|
|
||||||
|
const widget = {
|
||||||
|
api: "{url}/{endpoint}",
|
||||||
|
proxyHandler: watchtowerProxyHandler,
|
||||||
|
|
||||||
|
mappings: {
|
||||||
|
"watchtower": {
|
||||||
|
endpoint: "v1/metrics",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default widget;
|
||||||
@ -1,10 +1,12 @@
|
|||||||
import adguard from "./adguard/widget";
|
import adguard from "./adguard/widget";
|
||||||
import authentik from "./authentik/widget";
|
import authentik from "./authentik/widget";
|
||||||
|
import autobrr from "./autobrr/widget";
|
||||||
import bazarr from "./bazarr/widget";
|
import bazarr from "./bazarr/widget";
|
||||||
import changedetectionio from "./changedetectionio/widget";
|
import changedetectionio from "./changedetectionio/widget";
|
||||||
import coinmarketcap from "./coinmarketcap/widget";
|
import coinmarketcap from "./coinmarketcap/widget";
|
||||||
import emby from "./emby/widget";
|
import emby from "./emby/widget";
|
||||||
import gotify from "./gotify/widget";
|
import gotify from "./gotify/widget";
|
||||||
|
import homebridge from "./homebridge/widget";
|
||||||
import jackett from "./jackett/widget";
|
import jackett from "./jackett/widget";
|
||||||
import jellyseerr from "./jellyseerr/widget";
|
import jellyseerr from "./jellyseerr/widget";
|
||||||
import lidarr from "./lidarr/widget";
|
import lidarr from "./lidarr/widget";
|
||||||
@ -29,16 +31,20 @@ import strelaysrv from "./strelaysrv/widget";
|
|||||||
import tautulli from "./tautulli/widget";
|
import tautulli from "./tautulli/widget";
|
||||||
import traefik from "./traefik/widget";
|
import traefik from "./traefik/widget";
|
||||||
import transmission from "./transmission/widget";
|
import transmission from "./transmission/widget";
|
||||||
|
import tubearchivist from "./tubearchivist/widget";
|
||||||
import unifi from "./unifi/widget";
|
import unifi from "./unifi/widget";
|
||||||
|
import watchtower from './watchtower/widget'
|
||||||
|
|
||||||
const widgets = {
|
const widgets = {
|
||||||
adguard,
|
adguard,
|
||||||
authentik,
|
authentik,
|
||||||
|
autobrr,
|
||||||
bazarr,
|
bazarr,
|
||||||
changedetectionio,
|
changedetectionio,
|
||||||
coinmarketcap,
|
coinmarketcap,
|
||||||
emby,
|
emby,
|
||||||
gotify,
|
gotify,
|
||||||
|
homebridge,
|
||||||
jackett,
|
jackett,
|
||||||
jellyfin: emby,
|
jellyfin: emby,
|
||||||
jellyseerr,
|
jellyseerr,
|
||||||
@ -64,8 +70,10 @@ const widgets = {
|
|||||||
tautulli,
|
tautulli,
|
||||||
traefik,
|
traefik,
|
||||||
transmission,
|
transmission,
|
||||||
|
tubearchivist,
|
||||||
unifi,
|
unifi,
|
||||||
unifi_console: unifi,
|
unifi_console: unifi,
|
||||||
|
watchtower,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default widgets;
|
export default widgets;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user