Merge branch 'develop'

pull/2563/head
sct 3 years ago
commit f7dc6256ba
No known key found for this signature in database
GPG Key ID: 845B4E54293A6F5E

@ -539,6 +539,87 @@
"contributions": [
"code"
]
},
{
"login": "sootylunatic",
"name": "sootylunatic",
"avatar_url": "https://avatars.githubusercontent.com/u/36486087?v=4",
"profile": "https://github.com/sootylunatic",
"contributions": [
"translation"
]
},
{
"login": "JoKerIsCraZy",
"name": "JoKerIsCraZy",
"avatar_url": "https://avatars.githubusercontent.com/u/47474211?v=4",
"profile": "https://github.com/JoKerIsCraZy",
"contributions": [
"translation"
]
},
{
"login": "GoByeBye",
"name": "Daddie0",
"avatar_url": "https://avatars.githubusercontent.com/u/33762262?v=4",
"profile": "https://daddie.dev",
"contributions": [
"translation"
]
},
{
"login": "Simoneu01",
"name": "Simone",
"avatar_url": "https://avatars.githubusercontent.com/u/43807696?v=4",
"profile": "http://ungaro.me",
"contributions": [
"translation"
]
},
{
"login": "adan89lion",
"name": "Seohyun Joo",
"avatar_url": "https://avatars.githubusercontent.com/u/6585644?v=4",
"profile": "https://github.com/adan89lion",
"contributions": [
"translation"
]
},
{
"login": "ty4ko",
"name": "Sergey",
"avatar_url": "https://avatars.githubusercontent.com/u/21213535?v=4",
"profile": "https://github.com/ty4ko",
"contributions": [
"translation"
]
},
{
"login": "skafte1990",
"name": "Shaaft",
"avatar_url": "https://avatars.githubusercontent.com/u/31465453?v=4",
"profile": "https://github.com/skafte1990",
"contributions": [
"translation"
]
},
{
"login": "sr093906",
"name": "sr093906",
"avatar_url": "https://avatars.githubusercontent.com/u/8369201?v=4",
"profile": "https://github.com/sr093906",
"contributions": [
"translation"
]
},
{
"login": "Nackophilz",
"name": "Nackophilz",
"avatar_url": "https://avatars.githubusercontent.com/u/61667226?v=4",
"profile": "https://github.com/Nackophilz",
"contributions": [
"translation"
]
}
],
"badgeTemplate": "<a href=\"#contributors-\"><img alt=\"All Contributors\" src=\"https://img.shields.io/badge/all_contributors-<%= contributors.length %>-orange.svg\"/></a>",

12
.github/CODEOWNERS vendored

@ -1,12 +1,14 @@
# Global code ownership
* @sct
* @sct
# Documentation
docs/ @TheCatLady @samwiseg0
/.all-contributorsrc @TheCatLady @samwiseg0 @danshilm
/*.md @TheCatLady @samwiseg0 @danshilm
/docs/ @TheCatLady @samwiseg0 @danshilm
# Snap-related files
.github/workflows/snap.yaml @samwiseg0
snap/ @samwiseg0
/.github/workflows/snap.yaml @samwiseg0
/snap/ @samwiseg0
# i18n locale files
src/i18n/locale/ @sct @TheCatLady
/src/i18n/locale/ @sct @TheCatLady

@ -0,0 +1,91 @@
name: 🐛 Bug Report
description: Report a problem
labels: ['type:bug', 'awaiting-triage']
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
Please note that we use GitHub issues exclusively for bug reports and feature requests. For support requests, please use our other support channels to get help.
- type: textarea
id: description
attributes:
label: Description
description: Please provide a clear and concise description of the bug or issue.
validations:
required: true
- type: input
id: version
attributes:
label: Version
description: What version of Overseerr are you running? (You can find this in Settings → About → Version.)
validations:
required: true
- type: textarea
id: repro-steps
attributes:
label: Steps to Reproduce
description: Please tell us how we can reproduce the undesired behavior.
placeholder: |
1. Go to [...]
2. Click on [...]
3. Scroll down to [...]
4. See error in [...]
validations:
required: true
- type: textarea
id: screenshots
attributes:
label: Screenshots
description: If applicable, please provide screenshots depicting the problem.
- type: textarea
id: logs
attributes:
label: Logs
description: Please copy and paste any relevant log output. (This will be automatically formatted into code, so no need for backticks.)
render: shell
- type: dropdown
id: platform
attributes:
label: Platform
options:
- desktop
- smartphone
- tablet
validations:
required: true
- type: input
id: device
attributes:
label: Device
description: e.g., iPhone X, Surface Pro, Samsung Galaxy Tab
validations:
required: true
- type: input
id: os
attributes:
label: Operating System
description: e.g., iOS 8.1, Windows 10, Android 11
validations:
required: true
- type: input
id: browser
attributes:
label: Browser
description: e.g., Chrome, Safari, Edge, Firefox
validations:
required: true
- type: textarea
id: additional-context
attributes:
label: Additional Context
description: Please provide any additional information that may be relevant or helpful.
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/sct/overseerr/blob/develop/CODE_OF_CONDUCT.md)
options:
- label: I agree to follow Overseerr's Code of Conduct
required: true

@ -1,45 +0,0 @@
---
name: Bug report
about: Submit a report to help us improve
title: ''
labels: 'awaiting-triage, type:bug'
assignees: ''
---
#### Description
Please provide a clear and concise description of the bug or issue.
#### Version
What version of Overseerr are you running? (You can find this in Settings → About → Version.)
#### Steps to Reproduce
Please tell us how we can reproduce the undesired behavior.
1. Go to [...]
2. Click on [...]
3. Scroll down to [...]
4. See error in [...]
#### Expected Behavior
Please provide a clear and concise description of what you expected to happen.
#### Screenshots
If applicable, please provide screenshots depicting the problem.
#### Device
What device were you using when you encountered this issue? Please provide this information to help us reproduce and investigate the bug.
- **Platform:** [e.g., desktop, smartphone, tablet]
- **Device:** [e.g., iPhone X, Surface Pro, Samsung Galaxy Tab]
- **OS:** [e.g., iOS 8.1, Windows 10, Android 11]
- **Browser:** [e.g., Chrome, Safari, Edge, Firefox]
#### Additional Context
Please provide any additional information that may be relevant or helpful.

@ -1,8 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Support via Discord
- name: 💬 Support via Discord
url: https://discord.gg/overseerr
about: Chat with users and devs on support and setup related topics.
- name: Support via GitHub Discussions
about: Chat with other users and the Overseerr dev team
- name: 💬 Support via GitHub Discussions
url: https://github.com/sct/overseerr/discussions
about: Ask questions and discuss with other community members

@ -0,0 +1,37 @@
name: ✨ Feature Request
description: Suggest an idea
labels: ['type:enhancement', 'awaiting-triage']
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this feature request!
Please note that we use GitHub issues exclusively for bug reports and feature requests. For support requests, please use our other support channels to get help.
- type: textarea
id: description
attributes:
label: Description
description: Is your feature request related to a problem? If so, please provide a clear and concise description of the problem; e.g., "I'm always frustrated when [...]."
validations:
required: true
- type: textarea
id: desired-behavior
attributes:
label: Desired Behavior
description: Provide a clear and concise description of what you want to happen.
validations:
required: true
- type: textarea
id: additional-context
attributes:
label: Additional Context
description: Provide any additional information or screenshots that may be relevant or helpful.
- type: checkboxes
id: terms
attributes:
label: Code of Conduct
description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/sct/overseerr/blob/develop/CODE_OF_CONDUCT.md)
options:
- label: I agree to follow Overseerr's Code of Conduct
required: true

@ -1,19 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: 'awaiting-triage, type:enhancement'
assignees: ''
---
#### Description
Is your feature request related to a problem? If so, please provide a clear and concise description of the problem. E.g., "I'm always frustrated when [...]."
#### Desired Behavior
Provide a clear and concise description of what you want to happen.
#### Additional Context
Provide any additional information or screenshots that may be relevant or helpful.

@ -12,7 +12,7 @@ jobs:
test:
name: Lint & Test Build
runs-on: ubuntu-20.04
container: node:14.17-alpine
container: node:14.18-alpine
steps:
- name: Checkout
uses: actions/checkout@v2.3.4

@ -1,19 +0,0 @@
name: 'Invalid Template'
on:
issues:
types: [labeled, unlabeled, reopened]
jobs:
support:
runs-on: ubuntu-20.04
steps:
- uses: dessant/support-requests@v2.0.1
with:
github-token: ${{ github.token }}
support-label: 'invalid:template-incomplete'
issue-comment: >
:wave: @{issue-author}, please follow the template provided.
close-issue: true
lock-issue: true
issue-lock-reason: 'resolved'

@ -9,7 +9,7 @@ jobs:
test:
name: Lint & Test Build
runs-on: ubuntu-20.04
container: node:14.17-alpine
container: node:14.18-alpine
steps:
- name: Checkout
uses: actions/checkout@v2.3.4

@ -20,7 +20,7 @@ jobs:
name: Lint & Test Build
needs: jobs
runs-on: ubuntu-20.04
container: node:14.17-alpine
container: node:14.18-alpine
steps:
- name: Checkout
uses: actions/checkout@v2.3.4

@ -1,4 +1,4 @@
FROM node:14.17-alpine AS BUILD_IMAGE
FROM node:14.18-alpine AS BUILD_IMAGE
WORKDIR /app
@ -31,7 +31,7 @@ RUN touch config/DOCKER
RUN echo "{\"commitTag\": \"${COMMIT_TAG}\"}" > committag.json
FROM node:14.17-alpine
FROM node:14.18-alpine
WORKDIR /app

@ -1,4 +1,4 @@
FROM node:14.17-alpine
FROM node:14.18-alpine
COPY . /app
WORKDIR /app

@ -12,7 +12,7 @@
<a href="https://lgtm.com/projects/g/sct/overseerr/context:javascript"><img alt="Language grade: JavaScript" src="https://img.shields.io/lgtm/grade/javascript/g/sct/overseerr.svg?logo=lgtm&logoWidth=18"/></a>
<a href="https://github.com/sct/overseerr/blob/develop/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/sct/overseerr"></a>
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
<a href="#contributors-"><img alt="All Contributors" src="https://img.shields.io/badge/all_contributors-58-orange.svg"/></a>
<a href="#contributors-"><img alt="All Contributors" src="https://img.shields.io/badge/all_contributors-67-orange.svg"/></a>
<!-- ALL-CONTRIBUTORS-BADGE:END -->
</p>
@ -149,6 +149,17 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<tr>
<td align="center"><a href="https://github.com/tangentThought"><img src="https://avatars.githubusercontent.com/u/25516090?v=4?s=100" width="100px;" alt=""/><br /><sub><b>tangentThought</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=tangentThought" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/nicospz"><img src="https://avatars.githubusercontent.com/u/31373060?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nicolás Espinoza</b></sub></a><br /><a href="https://github.com/sct/overseerr/commits?author=nicospz" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/sootylunatic"><img src="https://avatars.githubusercontent.com/u/36486087?v=4?s=100" width="100px;" alt=""/><br /><sub><b>sootylunatic</b></sub></a><br /><a href="#translation-sootylunatic" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/JoKerIsCraZy"><img src="https://avatars.githubusercontent.com/u/47474211?v=4?s=100" width="100px;" alt=""/><br /><sub><b>JoKerIsCraZy</b></sub></a><br /><a href="#translation-JoKerIsCraZy" title="Translation">🌍</a></td>
<td align="center"><a href="https://daddie.dev"><img src="https://avatars.githubusercontent.com/u/33762262?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Daddie0</b></sub></a><br /><a href="#translation-GoByeBye" title="Translation">🌍</a></td>
<td align="center"><a href="http://ungaro.me"><img src="https://avatars.githubusercontent.com/u/43807696?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Simone</b></sub></a><br /><a href="#translation-Simoneu01" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/adan89lion"><img src="https://avatars.githubusercontent.com/u/6585644?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Seohyun Joo</b></sub></a><br /><a href="#translation-adan89lion" title="Translation">🌍</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/ty4ko"><img src="https://avatars.githubusercontent.com/u/21213535?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sergey</b></sub></a><br /><a href="#translation-ty4ko" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/skafte1990"><img src="https://avatars.githubusercontent.com/u/31465453?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Shaaft</b></sub></a><br /><a href="#translation-skafte1990" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/sr093906"><img src="https://avatars.githubusercontent.com/u/8369201?v=4?s=100" width="100px;" alt=""/><br /><sub><b>sr093906</b></sub></a><br /><a href="#translation-sr093906" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/Nackophilz"><img src="https://avatars.githubusercontent.com/u/61667226?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nackophilz</b></sub></a><br /><a href="#translation-Nackophilz" title="Translation">🌍</a></td>
</tr>
</table>

@ -145,8 +145,7 @@ location ^~ /overseerr {
sub_filter '/android-' '/$app/android-';
sub_filter '/apple-' '/$app/apple-';
sub_filter '/favicon' '/$app/favicon';
sub_filter '/logo_full.svg' '/$app/logo_full.svg';
sub_filter '/logo_stacked.svg' '/$app/logo_stacked.svg';
sub_filter '/logo_' '/$app/logo_';
sub_filter '/site.webmanifest' '/$app/site.webmanifest';
}
```

@ -8,6 +8,7 @@ We do not officially support these third-party integrations. If you run into any
- [Heimdall](https://github.com/linuxserver/Heimdall), an application dashboard and launcher
- [LunaSea](https://docs.lunasea.app/modules/overseerr), a self-hosted controller for mobile and macOS
- [Requestrr](https://github.com/darkalfx/requestrr/wiki/Configuring-Overseerr), a Discord chatbot
- [Doplarr](https://github.com/kiranshila/Doplarr), a Discord request bot
- [ha-overseerr](https://github.com/vaparr/ha-overseerr), a custom Home Assistant component
- [OverCLIrr](https://github.com/WillFantom/OverCLIrr), a command-line tool
- [Overseerr Exporter](https://github.com/WillFantom/overseerr-exporter), a Prometheus exporter

@ -10,8 +10,18 @@ After running Overseerr for the first time, configure it by visiting the web UI
## Docker
{% hint style="warning" %}
Be sure to replace `/path/to/appdata/config` in the below examples with a valid host directory path. If this volume mount is not configured correctly, your Overseerr settings/data will not be persisted when the container is recreated (e.g., when updating the image or rebooting your machine).
The `TZ` environment variable value should also be set to the [TZ database name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) of your time zone!
{% endhint %}
{% tabs %}
{% tab title="Basic" %}
{% tab title="Docker CLI" %}
For details on the Docker CLI, please [review the official `docker run` documentation](https://docs.docker.com/engine/reference/run/).
**Installation:**
```bash
docker run -d \
@ -24,11 +34,41 @@ docker run -d \
sctx/overseerr
```
To run the container as a specific user/group, you may optionally add `--user=[ user | user:group | uid | uid:gid | user:gid | uid:group ]` to the above command.
**Updating:**
Stop and remove the existing container:
```bash
docker stop overseerr && docker rm overseerr
```
Pull the latest image:
```bash
docker pull sctx/overseerr
```
Finally, run the container with the same parameters originally used to create the container:
```bash
docker run -d ...
```
{% hint style="info" %}
You may alternatively use a third-party updating mechanism, such as [Watchtower](https://github.com/containrrr/watchtower) or [Ouroboros](https://github.com/pyouroboros/ouroboros), to keep Overseerr up-to-date automatically.
{% endhint %}
{% endtab %}
{% tab title="Compose" %}
{% tab title="Docker Compose" %}
For details on how to use Docker Compose, please [review the official Compose documentation](https://docs.docker.com/compose/reference/).
**docker-compose.yml:**
**Installation:**
Define the `overseerr` service in your `docker-compose.yml` as follows:
```yaml
---
@ -48,47 +88,29 @@ services:
restart: unless-stopped
```
{% endtab %}
{% tab title="UID/GID" %}
Then, start all services defined in the your Compose file:
```text
docker run -d \
--name overseerr \
--user=[ user | user:group | uid | uid:gid | user:gid | uid:group ] \
-e LOG_LEVEL=debug \
-e TZ=Asia/Tokyo \
-p 5055:5055 \
-v /path/to/appdata/config:/app/config \
--restart unless-stopped \
sctx/overseerr
```bash
docker-compose up -d
```
{% endtab %}
**Updating:**
{% tab title="Manual Update" %}
Pull the latest image:
```bash
# Stop the Overseerr container
docker stop overseerr
# Remove the Overseerr container
docker rm overseerr
docker-compose pull overseerr
```
# Pull the latest update
docker pull sctx/overseerr
Then, restart all services defined in the Compose file:
# Run the Overseerr container with the same parameters as before
docker run -d ...
```bash
docker-compose up -d
```
{% endtab %}
{% endtabs %}
{% hint style="info" %}
Use a 3rd party updating mechanism such as [Watchtower](https://github.com/containrrr/watchtower) or [Ouroboros](https://github.com/pyouroboros/ouroboros) to keep Overseerr up-to-date automatically.
{% endhint %}
## Unraid
1. Ensure you have the **Community Applications** plugin installed.
@ -144,29 +166,24 @@ The [Overseerr snap](https://snapcraft.io/overseerr) is the only officially supp
Currently, the listening port cannot be changed, so port `5055` will need to be available on your host. To install `snapd`, please refer to the [Snapcraft documentation](https://snapcraft.io/docs/installing-snapd).
{% endhint %}
**To install:**
**Installation:**
```
sudo snap install overseerr
```
{% hint style="danger" %}
To install the development build, add the `--edge` argument to the above command (i.e., `sudo snap install overseerr --edge`). However, note that this version can break any moment. Be prepared to troubleshoot any issues that arise!
{% endhint %}
**Updating:**
Snap will keep Overseerr up-to-date automatically. You can force a refresh by using the following command.
```
```bash
sudo snap refresh
```
**To install the development build:**
```
sudo snap install overseerr --edge
```
{% hint style="danger" %}
This version can break any moment. Be prepared to troubleshoot any issues that arise!
{% endhint %}
## Third-Party
{% tabs %}

@ -119,3 +119,9 @@ Language profile support for Sonarr was added in [v1.20.0](https://github.com/sc
### I am getting "Username and Password not accepted" when attempting to send email notifications via Gmail!
If you have 2-Step Verification enabled on your account, you will need to create an [app password](https://support.google.com/mail/answer/185833).
### The logo image in email notifications is broken!
This may be an issue with how you are proxying your Overseerr instance. A good first troubleshooting step is to verify that the [`Content-Security-Policy` HTTP header](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) being set by your proxy (if any) is configured appropriately to allow external embedding of the image.
For Gmail users, another possible issue is that Google's image URL proxy is being blocked from fetching the image. If using Cloudflare, overzealous firewall rules could be the culprit.

3
next-env.d.ts vendored

@ -1,3 +1,6 @@
/// <reference types="next" />
/// <reference types="next/types/global" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.

@ -1278,6 +1278,27 @@ components:
allowSelfSigned:
type: boolean
example: false
Job:
type: object
properties:
id:
type: string
example: job-name
type:
type: string
enum: [process, command]
interval:
type: string
enum: [short, long, fixed]
name:
type: string
example: A Job Name
nextExecutionTime:
type: string
example: '2020-09-02T05:02:23.000Z'
running:
type: boolean
example: false
PersonDetail:
type: object
properties:
@ -2214,23 +2235,7 @@ paths:
schema:
type: array
items:
type: object
properties:
id:
type: string
example: job-name
name:
type: string
example: A Job Name
type:
type: string
enum: [process, command]
nextExecutionTime:
type: string
example: '2020-09-02T05:02:23.000Z'
running:
type: boolean
example: false
$ref: '#/components/schemas/Job'
/settings/jobs/{jobId}/run:
post:
summary: Invoke a specific job
@ -2249,23 +2254,7 @@ paths:
content:
application/json:
schema:
type: object
properties:
id:
type: string
example: job-name
type:
type: string
enum: [process, command]
name:
type: string
example: A Job Name
nextExecutionTime:
type: string
example: '2020-09-02T05:02:23.000Z'
running:
type: boolean
example: false
$ref: '#/components/schemas/Job'
/settings/jobs/{jobId}/cancel:
post:
summary: Cancel a specific job
@ -2284,23 +2273,36 @@ paths:
content:
application/json:
schema:
type: object
properties:
id:
type: string
example: job-name
type:
type: string
enum: [process, command]
name:
type: string
example: A Job Name
nextExecutionTime:
type: string
example: '2020-09-02T05:02:23.000Z'
running:
type: boolean
example: false
$ref: '#/components/schemas/Job'
/settings/jobs/{jobId}/schedule:
post:
summary: Modify job schedule
description: Re-registers the job with the schedule specified. Will return the job in JSON format.
tags:
- settings
parameters:
- in: path
name: jobId
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
schedule:
type: string
example: '0 */5 * * * *'
responses:
'200':
description: Rescheduled job
content:
application/json:
schema:
$ref: '#/components/schemas/Job'
/settings/cache:
get:
summary: Get a list of active caches
@ -2398,7 +2400,7 @@ paths:
example: Server ready on port 5055
timestamp:
type: string
example: 2020-12-15T16:20:00.069Z
example: '2020-12-15T16:20:00.069Z'
/settings/notifications/email:
get:
summary: Get email notification settings
@ -5165,6 +5167,22 @@ paths:
name:
type: string
example: Drama
/backdrops:
get:
summary: Get backdrops of trending items
description: Returns a list of backdrop image paths in a JSON array.
security: []
tags:
- tmdb
responses:
'200':
description: Results
content:
application/json:
schema:
type: array
items:
type: string
security:
- cookieAuth: []

@ -10,40 +10,40 @@
"lint": "eslint \"./server/**/*.{ts,tsx}\" \"./src/**/*.{ts,tsx}\"",
"start": "NODE_ENV=production node dist/index.js",
"i18n:extract": "extract-messages -l=en -o src/i18n/locale -d en --flat true --overwriteDefault true \"./src/**/!(*.test).{ts,tsx}\"",
"migration:generate": "ts-node --project server/tsconfig.json ./node_modules/.bin/typeorm migration:generate",
"migration:create": "ts-node --project server/tsconfig.json ./node_modules/.bin/typeorm migration:create",
"migration:run": "ts-node --project server/tsconfig.json ./node_modules/.bin/typeorm migration:run",
"migration:generate": "ts-node --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:generate",
"migration:create": "ts-node --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:create",
"migration:run": "ts-node --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:run",
"format": "prettier --write ."
},
"license": "MIT",
"dependencies": {
"@headlessui/react": "^1.3.0",
"@heroicons/react": "^1.0.1",
"@headlessui/react": "^1.4.1",
"@heroicons/react": "^1.0.4",
"@supercharge/request-ip": "^1.1.2",
"@svgr/webpack": "^5.5.0",
"@tanem/react-nprogress": "^3.0.70",
"@tanem/react-nprogress": "^3.0.79",
"ace-builds": "^1.4.12",
"axios": "^0.21.1",
"axios": "^0.21.4",
"bcrypt": "^5.0.1",
"bowser": "^2.11.0",
"connect-typeorm": "^1.1.4",
"cookie-parser": "^1.4.5",
"copy-to-clipboard": "^3.3.1",
"country-flag-icons": "^1.2.10",
"country-flag-icons": "^1.4.10",
"csurf": "^1.11.0",
"email-templates": "^8.0.7",
"email-templates": "^8.0.8",
"express": "^4.17.1",
"express-openapi-validator": "^4.12.14",
"express-rate-limit": "^5.2.6",
"express-openapi-validator": "^4.13.1",
"express-rate-limit": "^5.3.0",
"express-session": "^1.17.2",
"formik": "^2.2.9",
"gravatar-url": "3.1.0",
"intl": "^1.2.5",
"lodash": "^4.17.21",
"next": "11.0.1",
"next": "11.1.2",
"node-cache": "^5.1.2",
"node-schedule": "^2.0.0",
"nodemailer": "^6.6.2",
"nodemailer": "^6.6.3",
"openpgp": "^5.0.0-3",
"plex-api": "^5.3.1",
"pug": "^3.0.2",
@ -51,12 +51,12 @@
"react-ace": "^9.3.0",
"react-animate-height": "^2.0.23",
"react-dom": "17.0.2",
"react-intersection-observer": "^8.32.0",
"react-intl": "5.20.3",
"react-intersection-observer": "^8.32.1",
"react-intl": "5.20.10",
"react-markdown": "^6.0.2",
"react-select": "^4.3.1",
"react-spring": "^9.2.3",
"react-toast-notifications": "^2.4.4",
"react-spring": "^9.2.4",
"react-toast-notifications": "^2.5.1",
"react-transition-group": "^4.4.2",
"react-truncate-markup": "^5.1.0",
"react-use-clipboard": "1.0.7",
@ -65,8 +65,8 @@
"sqlite3": "^5.0.2",
"swagger-ui-express": "^4.1.6",
"swr": "^0.5.6",
"typeorm": "0.2.32",
"web-push": "^3.4.4",
"typeorm": "0.2.37",
"web-push": "^3.4.5",
"winston": "^3.3.3",
"winston-daily-rotate-file": "^4.5.5",
"xml2js": "^0.4.23",
@ -74,66 +74,66 @@
"yup": "^0.32.9"
},
"devDependencies": {
"@babel/cli": "^7.14.5",
"@commitlint/cli": "^12.1.4",
"@commitlint/config-conventional": "^12.1.4",
"@babel/cli": "^7.15.7",
"@commitlint/cli": "^13.1.0",
"@commitlint/config-conventional": "^13.1.0",
"@semantic-release/changelog": "^5.0.1",
"@semantic-release/commit-analyzer": "^8.0.1",
"@semantic-release/commit-analyzer": "^9.0.1",
"@semantic-release/exec": "^5.0.0",
"@semantic-release/git": "^9.0.0",
"@semantic-release/git": "^9.0.1",
"@tailwindcss/aspect-ratio": "^0.2.1",
"@tailwindcss/forms": "^0.3.3",
"@tailwindcss/typography": "^0.4.1",
"@types/bcrypt": "^5.0.0",
"@types/cookie-parser": "^1.4.2",
"@types/country-flag-icons": "^1.2.0",
"@types/csurf": "^1.11.1",
"@types/email-templates": "^8.0.3",
"@types/express": "^4.17.12",
"@types/express-rate-limit": "^5.1.2",
"@types/csurf": "^1.11.2",
"@types/email-templates": "^8.0.4",
"@types/express": "^4.17.13",
"@types/express-rate-limit": "^5.1.3",
"@types/express-session": "^1.17.3",
"@types/lodash": "^4.14.170",
"@types/lodash": "^4.14.173",
"@types/node": "^15.6.1",
"@types/node-schedule": "^1.3.1",
"@types/nodemailer": "^6.4.2",
"@types/react": "^17.0.11",
"@types/react-dom": "^17.0.8",
"@types/react-select": "^4.0.15",
"@types/node-schedule": "^1.3.2",
"@types/nodemailer": "^6.4.4",
"@types/react": "^17.0.22",
"@types/react-dom": "^17.0.9",
"@types/react-select": "^4.0.17",
"@types/react-toast-notifications": "^2.4.1",
"@types/react-transition-group": "^4.4.1",
"@types/secure-random-password": "^0.2.0",
"@types/swagger-ui-express": "^4.1.2",
"@types/web-push": "^3.3.1",
"@types/xml2js": "^0.4.8",
"@types/react-transition-group": "^4.4.3",
"@types/secure-random-password": "^0.2.1",
"@types/swagger-ui-express": "^4.1.3",
"@types/web-push": "^3.3.2",
"@types/xml2js": "^0.4.9",
"@types/yamljs": "^0.2.31",
"@types/yup": "^0.29.11",
"@typescript-eslint/eslint-plugin": "^4.28.0",
"@typescript-eslint/parser": "^4.28.0",
"autoprefixer": "^10.2.6",
"@types/yup": "^0.29.13",
"@typescript-eslint/eslint-plugin": "^4.31.1",
"@typescript-eslint/parser": "^4.31.1",
"autoprefixer": "^10.3.4",
"babel-plugin-react-intl": "^8.2.25",
"babel-plugin-react-intl-auto": "^3.3.0",
"commitizen": "^4.2.4",
"copyfiles": "^2.4.1",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^7.29.0",
"eslint-config-next": "^11.0.1",
"eslint": "^7.32.0",
"eslint-config-next": "^11.1.2",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-formatjs": "^2.16.1",
"eslint-plugin-formatjs": "^2.17.6",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.25.3",
"eslint-plugin-react-hooks": "^4.2.0",
"extract-react-intl-messages": "^4.1.1",
"husky": "4.3.8",
"lint-staged": "^11.0.0",
"nodemon": "^2.0.7",
"postcss": "^8.3.5",
"prettier": "^2.3.1",
"semantic-release": "^17.4.4",
"lint-staged": "^11.1.2",
"nodemon": "^2.0.12",
"postcss": "^8.3.6",
"prettier": "^2.4.1",
"semantic-release": "^18.0.0",
"semantic-release-docker-buildx": "^1.0.1",
"tailwindcss": "^2.2.2",
"ts-node": "^10.0.0",
"typescript": "^4.3.4"
"tailwindcss": "^2.2.15",
"ts-node": "^10.2.1",
"typescript": "^4.4.3"
},
"resolutions": {
"sqlite3/node-gyp": "^5.1.0"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 407 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 384 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 421 KiB

@ -1,5 +1,5 @@
import NodePlexAPI from 'plex-api';
import { getSettings, PlexSettings } from '../lib/settings';
import { getSettings, Library, PlexSettings } from '../lib/settings';
export interface PlexLibraryItem {
ratingKey: string;
@ -11,11 +11,16 @@ export interface PlexLibraryItem {
grandparentGuid?: string;
addedAt: number;
updatedAt: number;
Guid?: {
id: string;
}[];
type: 'movie' | 'show' | 'season' | 'episode';
Media: Media[];
}
interface PlexLibraryResponse {
MediaContainer: {
totalSize: number;
Metadata: PlexLibraryItem[];
};
}
@ -137,12 +142,50 @@ class PlexAPI {
return response.MediaContainer.Directory;
}
public async getLibraryContents(id: string): Promise<PlexLibraryItem[]> {
const response = await this.plexClient.query<PlexLibraryResponse>(
`/library/sections/${id}/all`
);
public async syncLibraries(): Promise<void> {
const settings = getSettings();
const libraries = await this.getLibraries();
const newLibraries: Library[] = libraries
// Remove libraries that are not movie or show
.filter((library) => library.type === 'movie' || library.type === 'show')
// Remove libraries that do not have a metadata agent set (usually personal video libraries)
.filter((library) => library.agent !== 'com.plexapp.agents.none')
.map((library) => {
const existing = settings.plex.libraries.find(
(l) => l.id === library.key && l.name === library.title
);
return {
id: library.key,
name: library.title,
enabled: existing?.enabled ?? false,
type: library.type,
lastScan: existing?.lastScan,
};
});
settings.plex.libraries = newLibraries;
settings.save();
}
public async getLibraryContents(
id: string,
{ offset = 0, size = 50 }: { offset?: number; size?: number } = {}
): Promise<{ totalSize: number; items: PlexLibraryItem[] }> {
const response = await this.plexClient.query<PlexLibraryResponse>({
uri: `/library/sections/${id}/all?includeGuids=1`,
extraHeaders: {
'X-Plex-Container-Start': `${offset}`,
'X-Plex-Container-Size': `${size}`,
},
});
return response.MediaContainer.Metadata ?? [];
return {
totalSize: response.MediaContainer.totalSize,
items: response.MediaContainer.Metadata ?? [],
};
}
public async getMetadata(
@ -166,10 +209,17 @@ class PlexAPI {
return response.MediaContainer.Metadata;
}
public async getRecentlyAdded(id: string): Promise<PlexLibraryItem[]> {
const response = await this.plexClient.query<PlexLibraryResponse>(
`/library/sections/${id}/recentlyAdded`
);
public async getRecentlyAdded(
id: string,
options: { addedAt: number } = {
addedAt: Date.now() - 1000 * 60 * 60,
}
): Promise<PlexLibraryItem[]> {
const response = await this.plexClient.query<PlexLibraryResponse>({
uri: `/library/sections/${id}/all?sort=addedAt%3Adesc&addedAt>>=${Math.floor(
options.addedAt / 1000
)}`,
});
return response.MediaContainer.Metadata;
}

@ -2,6 +2,35 @@ import cacheManager, { AvailableCacheIds } from '../../lib/cache';
import { DVRSettings } from '../../lib/settings';
import ExternalAPI from '../externalapi';
export interface SystemStatus {
version: string;
buildTime: Date;
isDebug: boolean;
isProduction: boolean;
isAdmin: boolean;
isUserInteractive: boolean;
startupPath: string;
appData: string;
osName: string;
osVersion: string;
isNetCore: boolean;
isMono: boolean;
isLinux: boolean;
isOsx: boolean;
isWindows: boolean;
isDocker: boolean;
mode: string;
branch: string;
authentication: string;
sqliteVersion: string;
migrationVersion: number;
urlBase: string;
runtimeVersion: string;
runtimeName: string;
startTime: Date;
packageUpdateMechanism: string;
}
export interface RootFolder {
id: number;
path: string;
@ -81,6 +110,18 @@ class ServarrBase<QueueItemAppendT> extends ExternalAPI {
this.apiName = apiName;
}
public getSystemStatus = async (): Promise<SystemStatus> => {
try {
const response = await this.axios.get<SystemStatus>('/system/status');
return response.data;
} catch (e) {
throw new Error(
`[${this.apiName}] Failed to retrieve system status: ${e.message}`
);
}
};
public getProfiles = async (): Promise<QualityProfile[]> => {
try {
const data = await this.getRolling<QualityProfile[]>(

@ -178,6 +178,7 @@ export class User {
password: password,
applicationUrl,
applicationTitle,
recipientName: this.username,
},
});
} catch (e) {
@ -214,6 +215,8 @@ export class User {
resetPasswordLink,
applicationUrl,
applicationTitle,
recipientName: this.displayName,
recipientEmail: this.email,
},
});
} catch (e) {

@ -10,7 +10,9 @@ import path from 'path';
import swaggerUi from 'swagger-ui-express';
import { createConnection, getRepository } from 'typeorm';
import YAML from 'yamljs';
import PlexAPI from './api/plexapi';
import { Session } from './entity/Session';
import { User } from './entity/User';
import { startJobs } from './job/schedule';
import notificationManager from './lib/notifications';
import DiscordAgent from './lib/notifications/agents/discord';
@ -49,6 +51,26 @@ app
// Load Settings
const settings = getSettings().load();
// Migrate library types
if (
settings.plex.libraries.length > 1 &&
!settings.plex.libraries[0].type
) {
const userRepository = getRepository(User);
const admin = await userRepository.findOne({
select: ['id', 'plexToken'],
order: { id: 'ASC' },
});
if (admin) {
const plexapi = new PlexAPI({ plexToken: admin.plexToken });
await plexapi.syncLibraries();
logger.info('Migrating libraries to include media type', {
label: 'Settings',
});
}
}
// Register Notification Agents
notificationManager.registerAgents([
new DiscordAgent(),

@ -1,15 +1,17 @@
import schedule from 'node-schedule';
import logger from '../logger';
import downloadTracker from '../lib/downloadtracker';
import { plexFullScanner, plexRecentScanner } from '../lib/scanners/plex';
import { radarrScanner } from '../lib/scanners/radarr';
import { sonarrScanner } from '../lib/scanners/sonarr';
import { getSettings, JobId } from '../lib/settings';
import logger from '../logger';
interface ScheduledJob {
id: string;
id: JobId;
job: schedule.Job;
name: string;
type: 'process' | 'command';
interval: 'short' | 'long' | 'fixed';
running?: () => boolean;
cancelFn?: () => void;
}
@ -17,12 +19,15 @@ interface ScheduledJob {
export const scheduledJobs: ScheduledJob[] = [];
export const startJobs = (): void => {
const jobs = getSettings().jobs;
// Run recently added plex scan every 5 minutes
scheduledJobs.push({
id: 'plex-recently-added-scan',
name: 'Plex Recently Added Scan',
type: 'process',
job: schedule.scheduleJob('0 */5 * * * *', () => {
interval: 'short',
job: schedule.scheduleJob(jobs['plex-recently-added-scan'].schedule, () => {
logger.info('Starting scheduled job: Plex Recently Added Scan', {
label: 'Jobs',
});
@ -37,7 +42,8 @@ export const startJobs = (): void => {
id: 'plex-full-scan',
name: 'Plex Full Library Scan',
type: 'process',
job: schedule.scheduleJob('0 0 3 * * *', () => {
interval: 'long',
job: schedule.scheduleJob(jobs['plex-full-scan'].schedule, () => {
logger.info('Starting scheduled job: Plex Full Library Scan', {
label: 'Jobs',
});
@ -52,7 +58,8 @@ export const startJobs = (): void => {
id: 'radarr-scan',
name: 'Radarr Scan',
type: 'process',
job: schedule.scheduleJob('0 0 4 * * *', () => {
interval: 'long',
job: schedule.scheduleJob(jobs['radarr-scan'].schedule, () => {
logger.info('Starting scheduled job: Radarr Scan', { label: 'Jobs' });
radarrScanner.run();
}),
@ -65,7 +72,8 @@ export const startJobs = (): void => {
id: 'sonarr-scan',
name: 'Sonarr Scan',
type: 'process',
job: schedule.scheduleJob('0 30 4 * * *', () => {
interval: 'long',
job: schedule.scheduleJob(jobs['sonarr-scan'].schedule, () => {
logger.info('Starting scheduled job: Sonarr Scan', { label: 'Jobs' });
sonarrScanner.run();
}),
@ -73,23 +81,27 @@ export const startJobs = (): void => {
cancelFn: () => sonarrScanner.cancel(),
});
// Run download sync
// Run download sync every minute
scheduledJobs.push({
id: 'download-sync',
name: 'Download Sync',
type: 'command',
job: schedule.scheduleJob('0 * * * * *', () => {
logger.debug('Starting scheduled job: Download Sync', { label: 'Jobs' });
interval: 'fixed',
job: schedule.scheduleJob(jobs['download-sync'].schedule, () => {
logger.debug('Starting scheduled job: Download Sync', {
label: 'Jobs',
});
downloadTracker.updateDownloads();
}),
});
// Reset download sync
// Reset download sync everyday at 01:00 am
scheduledJobs.push({
id: 'download-sync-reset',
name: 'Download Sync Reset',
type: 'command',
job: schedule.scheduleJob('0 0 1 * * *', () => {
interval: 'long',
job: schedule.scheduleJob(jobs['download-sync-reset'].schedule, () => {
logger.info('Starting scheduled job: Download Sync Reset', {
label: 'Jobs',
});

@ -1,6 +1,12 @@
import NodeCache from 'node-cache';
export type AvailableCacheIds = 'tmdb' | 'radarr' | 'sonarr' | 'rt' | 'github';
export type AvailableCacheIds =
| 'tmdb'
| 'radarr'
| 'sonarr'
| 'rt'
| 'github'
| 'plexguid';
const DEFAULT_TTL = 300;
const DEFAULT_CHECK_PERIOD = 120;
@ -48,6 +54,10 @@ class CacheManager {
stdTtl: 21600,
checkPeriod: 60 * 30,
}),
plexguid: new Cache('plexguid', 'Plex GUID Cache', {
stdTtl: 86400 * 7, // 1 week cache
checkPeriod: 60 * 30,
}),
};
public getCache(id: AvailableCacheIds): Cache {

@ -46,7 +46,8 @@ class EmailAgent
private buildMessage(
type: Notification,
payload: NotificationPayload,
toEmail: string
recipientEmail: string,
recipientName?: string
): EmailOptions | undefined {
const { applicationUrl, applicationTitle } = getSettings().main;
@ -54,12 +55,14 @@ class EmailAgent
return {
template: path.join(__dirname, '../../../templates/email/test-email'),
message: {
to: toEmail,
to: recipientEmail,
},
locals: {
body: payload.message,
applicationUrl,
applicationTitle,
recipientName,
recipientEmail,
},
};
}
@ -127,7 +130,7 @@ class EmailAgent
'../../../templates/email/media-request'
),
message: {
to: toEmail,
to: recipientEmail,
},
locals: {
requestType,
@ -143,6 +146,8 @@ class EmailAgent
: undefined,
applicationUrl,
applicationTitle,
recipientName,
recipientEmail,
},
};
}
@ -179,7 +184,12 @@ class EmailAgent
payload.notifyUser.settings?.pgpKey
);
await email.send(
this.buildMessage(type, payload, payload.notifyUser.email)
this.buildMessage(
type,
payload,
payload.notifyUser.email,
payload.notifyUser.displayName
)
);
} catch (e) {
logger.error('Error sending email notification', {
@ -228,7 +238,9 @@ class EmailAgent
this.getSettings(),
user.settings?.pgpKey
);
await email.send(this.buildMessage(type, payload, user.email));
await email.send(
this.buildMessage(type, payload, user.email, user.displayName)
);
} catch (e) {
logger.error('Error sending email notification', {
label: 'Notifications',

@ -55,6 +55,7 @@ class BaseScanner<T> {
private updateRate;
protected progress = 0;
protected items: T[] = [];
protected totalSize?: number = 0;
protected scannerName: string;
protected enable4kMovie = false;
protected enable4kShow = false;
@ -609,6 +610,14 @@ class BaseScanner<T> {
): void {
logger[level](message, { label: this.scannerName, ...optional });
}
get protectedUpdateRate(): number {
return this.updateRate;
}
get protectedBundleSize(): number {
return this.bundleSize;
}
}
export default BaseScanner;

@ -4,6 +4,7 @@ import animeList from '../../../api/animelist';
import PlexAPI, { PlexLibraryItem, PlexMetadata } from '../../../api/plexapi';
import { TmdbTvDetails } from '../../../api/themoviedb/interfaces';
import { User } from '../../../entity/User';
import cacheManager from '../../cache';
import { getSettings, Library } from '../../settings';
import BaseScanner, {
MediaIds,
@ -38,7 +39,7 @@ class PlexScanner
private isRecentOnly = false;
public constructor(isRecentOnly = false) {
super('Plex Scan');
super('Plex Scan', { bundleSize: 50 });
this.isRecentOnly = isRecentOnly;
}
@ -46,7 +47,7 @@ class PlexScanner
return {
running: this.running,
progress: this.progress,
total: this.items.length,
total: this.totalSize ?? 0,
currentLibrary: this.currentLibrary,
libraries: this.libraries,
};
@ -82,10 +83,17 @@ class PlexScanner
this.currentLibrary = library;
this.log(
`Beginning to process recently added for library: ${library.name}`,
'info'
'info',
{ lastScan: library.lastScan }
);
const libraryItems = await this.plexClient.getRecentlyAdded(
library.id
library.id,
library.lastScan
? {
// We remove 10 minutes from the last scan as a buffer
addedAt: library.lastScan - 1000 * 60 * 10,
}
: undefined
);
// Bundle items up by rating keys
@ -104,13 +112,26 @@ class PlexScanner
});
await this.loop(this.processItem.bind(this), { sessionId });
// After run completes, update last scan time
const newLibraries = settings.plex.libraries.map((lib) => {
if (lib.id === library.id) {
return {
...lib,
lastScan: Date.now(),
};
}
return lib;
});
settings.plex.libraries = newLibraries;
settings.save();
}
} else {
for (const library of this.libraries) {
this.currentLibrary = library;
this.log(`Beginning to process library: ${library.name}`, 'info');
this.items = await this.plexClient.getLibraryContents(library.id);
await this.loop(this.processItem.bind(this), { sessionId });
await this.paginateLibrary(library, { sessionId });
}
}
this.log(
@ -126,6 +147,52 @@ class PlexScanner
}
}
private async paginateLibrary(
library: Library,
{ start = 0, sessionId }: { start?: number; sessionId: string }
) {
if (!this.running) {
throw new Error('Sync was aborted.');
}
if (this.sessionId !== sessionId) {
throw new Error('New session was started. Old session aborted.');
}
const response = await this.plexClient.getLibraryContents(library.id, {
size: this.protectedBundleSize,
offset: start,
});
this.progress = start;
this.totalSize = response.totalSize;
if (response.items.length === 0) {
return;
}
await Promise.all(
response.items.map(async (item) => {
await this.processItem(item);
})
);
if (response.items.length < this.protectedBundleSize) {
return;
}
await new Promise<void>((resolve, reject) =>
setTimeout(() => {
this.paginateLibrary(library, {
start: start + this.protectedBundleSize,
sessionId,
})
.then(() => resolve())
.catch((e) => reject(new Error(e.message)));
}, this.protectedUpdateRate)
);
}
private async processItem(plexitem: PlexLibraryItem) {
try {
if (plexitem.type === 'movie') {
@ -147,9 +214,8 @@ class PlexScanner
private async processPlexMovie(plexitem: PlexLibraryItem) {
const mediaIds = await this.getMediaIds(plexitem);
const metadata = await this.plexClient.getMetadata(plexitem.ratingKey);
const has4k = metadata.Media.some(
const has4k = plexitem.Media.some(
(media) => media.videoResolution === '4k'
);
@ -263,10 +329,25 @@ class PlexScanner
}
private async getMediaIds(plexitem: PlexLibraryItem): Promise<MediaIds> {
const mediaIds: Partial<MediaIds> = {};
let mediaIds: Partial<MediaIds> = {};
// Check if item is using new plex movie/tv agent
if (plexitem.guid.match(plexRegex)) {
const metadata = await this.plexClient.getMetadata(plexitem.ratingKey);
const guidCache = cacheManager.getCache('plexguid');
const cachedGuids = guidCache.data.get<MediaIds>(plexitem.ratingKey);
if (cachedGuids) {
this.log('GUIDs are cached. Skipping metadata request.', 'debug', {
mediaIds: cachedGuids,
title: plexitem.title,
});
mediaIds = cachedGuids;
}
const metadata =
plexitem.Guid && plexitem.Guid.length > 0
? plexitem
: await this.plexClient.getMetadata(plexitem.ratingKey);
// If there is no Guid field at all, then we bail
if (!metadata.Guid) {
@ -295,6 +376,10 @@ class PlexScanner
});
mediaIds.tmdbId = tmdbMovie.id;
}
// Cache GUIDs
guidCache.data.set(plexitem.ratingKey, mediaIds);
// Check if the agent is IMDb
} else if (plexitem.guid.match(imdbRegex)) {
const imdbMatch = plexitem.guid.match(imdbRegex);

@ -9,6 +9,8 @@ export interface Library {
id: string;
name: string;
enabled: boolean;
type: 'show' | 'movie';
lastScan?: number;
}
export interface Region {
@ -213,6 +215,18 @@ interface NotificationSettings {
agents: NotificationAgents;
}
interface JobSettings {
schedule: string;
}
export type JobId =
| 'plex-recently-added-scan'
| 'plex-full-scan'
| 'radarr-scan'
| 'sonarr-scan'
| 'download-sync'
| 'download-sync-reset';
interface AllSettings {
clientId: string;
vapidPublic: string;
@ -223,6 +237,7 @@ interface AllSettings {
sonarr: SonarrSettings[];
public: PublicSettings;
notifications: NotificationSettings;
jobs: Record<JobId, JobSettings>;
}
const SETTINGS_PATH = process.env.CONFIG_DIRECTORY
@ -344,6 +359,26 @@ class Settings {
},
},
},
jobs: {
'plex-recently-added-scan': {
schedule: '0 */5 * * * *',
},
'plex-full-scan': {
schedule: '0 0 3 * * *',
},
'radarr-scan': {
schedule: '0 0 4 * * *',
},
'sonarr-scan': {
schedule: '0 30 4 * * *',
},
'download-sync': {
schedule: '0 * * * * *',
},
'download-sync-reset': {
schedule: '0 0 1 * * *',
},
},
};
if (initialSettings) {
this.data = merge(this.data, initialSettings);
@ -426,6 +461,14 @@ class Settings {
this.data.notifications = data;
}
get jobs(): Record<JobId, JobSettings> {
return this.data.jobs;
}
set jobs(data: Record<JobId, JobSettings>) {
this.data.jobs = data;
}
get clientId(): string {
if (!this.data.clientId) {
this.data.clientId = randomUUID();

@ -12,7 +12,7 @@ import { mapMovieResult, mapPersonResult, mapTvResult } from '../models/Search';
import { mapNetwork } from '../models/Tv';
import { isMovie, isPerson } from '../utils/typeHelpers';
const createTmdbWithRegionLanaguage = (user?: User): TheMovieDb => {
export const createTmdbWithRegionLanguage = (user?: User): TheMovieDb => {
const settings = getSettings();
const region =
@ -38,7 +38,7 @@ const createTmdbWithRegionLanaguage = (user?: User): TheMovieDb => {
const discoverRoutes = Router();
discoverRoutes.get('/movies', async (req, res) => {
const tmdb = createTmdbWithRegionLanaguage(req.user);
const tmdb = createTmdbWithRegionLanguage(req.user);
const data = await tmdb.getDiscoverMovies({
page: Number(req.query.page),
@ -69,7 +69,7 @@ discoverRoutes.get('/movies', async (req, res) => {
discoverRoutes.get<{ language: string }>(
'/movies/language/:language',
async (req, res, next) => {
const tmdb = createTmdbWithRegionLanaguage(req.user);
const tmdb = createTmdbWithRegionLanguage(req.user);
const languages = await tmdb.getLanguages();
@ -112,7 +112,7 @@ discoverRoutes.get<{ language: string }>(
discoverRoutes.get<{ genreId: string }>(
'/movies/genre/:genreId',
async (req, res, next) => {
const tmdb = createTmdbWithRegionLanaguage(req.user);
const tmdb = createTmdbWithRegionLanguage(req.user);
const genres = await tmdb.getMovieGenres({
language: req.locale ?? (req.query.language as string),
@ -194,7 +194,7 @@ discoverRoutes.get<{ studioId: string }>(
);
discoverRoutes.get('/movies/upcoming', async (req, res) => {
const tmdb = createTmdbWithRegionLanaguage(req.user);
const tmdb = createTmdbWithRegionLanguage(req.user);
const now = new Date();
const offset = now.getTimezoneOffset();
@ -228,7 +228,7 @@ discoverRoutes.get('/movies/upcoming', async (req, res) => {
});
discoverRoutes.get('/tv', async (req, res) => {
const tmdb = createTmdbWithRegionLanaguage(req.user);
const tmdb = createTmdbWithRegionLanguage(req.user);
const data = await tmdb.getDiscoverTv({
page: Number(req.query.page),
@ -259,7 +259,7 @@ discoverRoutes.get('/tv', async (req, res) => {
discoverRoutes.get<{ language: string }>(
'/tv/language/:language',
async (req, res, next) => {
const tmdb = createTmdbWithRegionLanaguage(req.user);
const tmdb = createTmdbWithRegionLanguage(req.user);
const languages = await tmdb.getLanguages();
@ -301,7 +301,7 @@ discoverRoutes.get<{ language: string }>(
discoverRoutes.get<{ genreId: string }>(
'/tv/genre/:genreId',
async (req, res, next) => {
const tmdb = createTmdbWithRegionLanaguage(req.user);
const tmdb = createTmdbWithRegionLanguage(req.user);
const genres = await tmdb.getTvGenres({
language: req.locale ?? (req.query.language as string),
@ -382,7 +382,7 @@ discoverRoutes.get<{ networkId: string }>(
);
discoverRoutes.get('/tv/upcoming', async (req, res) => {
const tmdb = createTmdbWithRegionLanaguage(req.user);
const tmdb = createTmdbWithRegionLanguage(req.user);
const now = new Date();
const offset = now.getTimezoneOffset();
@ -416,7 +416,7 @@ discoverRoutes.get('/tv/upcoming', async (req, res) => {
});
discoverRoutes.get('/trending', async (req, res) => {
const tmdb = createTmdbWithRegionLanaguage(req.user);
const tmdb = createTmdbWithRegionLanguage(req.user);
const data = await tmdb.getAllTrending({
page: Number(req.query.page),

@ -1,6 +1,7 @@
import { Router } from 'express';
import GithubAPI from '../api/github';
import TheMovieDb from '../api/themoviedb';
import { TmdbMovieResult, TmdbTvResult } from '../api/themoviedb/interfaces';
import { StatusResponse } from '../interfaces/api/settingsInterfaces';
import { Permission } from '../lib/permissions';
import { getSettings } from '../lib/settings';
@ -9,9 +10,10 @@ import { mapProductionCompany } from '../models/Movie';
import { mapNetwork } from '../models/Tv';
import { appDataPath, appDataStatus } from '../utils/appDataVolume';
import { getAppVersion, getCommitTag } from '../utils/appVersion';
import { isPerson } from '../utils/typeHelpers';
import authRoutes from './auth';
import collectionRoutes from './collection';
import discoverRoutes from './discover';
import discoverRoutes, { createTmdbWithRegionLanguage } from './discover';
import mediaRoutes from './media';
import movieRoutes from './movie';
import personRoutes from './person';
@ -160,6 +162,28 @@ router.get('/genres/tv', isAuthenticated(), async (req, res) => {
return res.status(200).json(genres);
});
router.get('/backdrops', async (req, res) => {
const tmdb = createTmdbWithRegionLanguage();
const data = (
await tmdb.getAllTrending({
page: 1,
timeWindow: 'week',
})
).results.filter((result) => !isPerson(result)) as (
| TmdbMovieResult
| TmdbTvResult
)[];
return res
.status(200)
.json(
data
.map((result) => result.backdrop_path)
.filter((backdropPath) => !!backdropPath)
);
});
router.get('/', (_req, res) => {
return res.status(200).json({
api: 'Overseerr API',

@ -2,6 +2,7 @@ import { Router } from 'express';
import rateLimit from 'express-rate-limit';
import fs from 'fs';
import { merge, omit } from 'lodash';
import { rescheduleJob } from 'node-schedule';
import path from 'path';
import { getRepository } from 'typeorm';
import { URL } from 'url';
@ -20,7 +21,7 @@ import { scheduledJobs } from '../../job/schedule';
import cacheManager, { AvailableCacheIds } from '../../lib/cache';
import { Permission } from '../../lib/permissions';
import { plexFullScanner } from '../../lib/scanners/plex';
import { getSettings, Library, MainSettings } from '../../lib/settings';
import { getSettings, MainSettings } from '../../lib/settings';
import logger from '../../logger';
import { isAuthenticated } from '../../middleware/auth';
import { getAppVersion } from '../../utils/appVersion';
@ -49,7 +50,7 @@ settingsRoutes.get('/main', (req, res, next) => {
const settings = getSettings();
if (!req.user) {
return next({ status: 500, message: 'User missing from request' });
return next({ status: 400, message: 'User missing from request' });
}
res.status(200).json(filteredMainSettings(req.user, settings.main));
@ -197,26 +198,7 @@ settingsRoutes.get('/plex/library', async (req, res) => {
});
const plexapi = new PlexAPI({ plexToken: admin.plexToken });
const libraries = await plexapi.getLibraries();
const newLibraries: Library[] = libraries
// Remove libraries that are not movie or show
.filter((library) => library.type === 'movie' || library.type === 'show')
// Remove libraries that do not have a metadata agent set (usually personal video libraries)
.filter((library) => library.agent !== 'com.plexapp.agents.none')
.map((library) => {
const existing = settings.plex.libraries.find(
(l) => l.id === library.key && l.name === library.title
);
return {
id: library.key,
name: library.title,
enabled: existing?.enabled ?? false,
};
});
settings.plex.libraries = newLibraries;
await plexapi.syncLibraries();
}
const enabledLibraries = req.query.enable
@ -329,6 +311,7 @@ settingsRoutes.get('/jobs', (_req, res) => {
id: job.id,
name: job.name,
type: job.type,
interval: job.interval,
nextExecutionTime: job.job.nextInvocation(),
running: job.running ? job.running() : false,
}))
@ -348,6 +331,7 @@ settingsRoutes.post<{ jobId: string }>('/jobs/:jobId/run', (req, res, next) => {
id: scheduledJob.id,
name: scheduledJob.name,
type: scheduledJob.type,
interval: scheduledJob.interval,
nextExecutionTime: scheduledJob.job.nextInvocation(),
running: scheduledJob.running ? scheduledJob.running() : false,
});
@ -372,12 +356,45 @@ settingsRoutes.post<{ jobId: string }>(
id: scheduledJob.id,
name: scheduledJob.name,
type: scheduledJob.type,
interval: scheduledJob.interval,
nextExecutionTime: scheduledJob.job.nextInvocation(),
running: scheduledJob.running ? scheduledJob.running() : false,
});
}
);
settingsRoutes.post<{ jobId: string }>(
'/jobs/:jobId/schedule',
(req, res, next) => {
const scheduledJob = scheduledJobs.find(
(job) => job.id === req.params.jobId
);
if (!scheduledJob) {
return next({ status: 404, message: 'Job not found' });
}
const result = rescheduleJob(scheduledJob.job, req.body.schedule);
const settings = getSettings();
if (result) {
settings.jobs[scheduledJob.id].schedule = req.body.schedule;
settings.save();
return res.status(200).json({
id: scheduledJob.id,
name: scheduledJob.name,
type: scheduledJob.type,
interval: scheduledJob.interval,
nextExecutionTime: scheduledJob.job.nextInvocation(),
running: scheduledJob.running ? scheduledJob.running() : false,
});
} else {
return next({ status: 400, message: 'Invalid job schedule' });
}
}
);
settingsRoutes.get('/cache', (req, res) => {
const caches = cacheManager.getAllCaches();

@ -46,6 +46,7 @@ radarrRoutes.post<
url: RadarrAPI.buildUrl(req.body, '/api/v3'),
});
const { urlBase } = await radarr.getSystemStatus();
const profiles = await radarr.getProfiles();
const folders = await radarr.getRootFolders();
const tags = await radarr.getTags();
@ -57,6 +58,10 @@ radarrRoutes.post<
path: folder.path,
})),
tags,
urlBase:
req.body.baseUrl && req.body.baseUrl !== '/'
? req.body.baseUrl
: urlBase,
});
} catch (e) {
logger.error('Failed to test Radarr', {

@ -42,6 +42,7 @@ sonarrRoutes.post('/test', async (req, res, next) => {
url: SonarrAPI.buildUrl(req.body, '/api/v3'),
});
const { urlBase } = await sonarr.getSystemStatus();
const profiles = await sonarr.getProfiles();
const folders = await sonarr.getRootFolders();
const languageProfiles = await sonarr.getLanguageProfiles();
@ -55,6 +56,10 @@ sonarrRoutes.post('/test', async (req, res, next) => {
})),
languageProfiles,
tags,
urlBase:
req.body.baseUrl && req.body.baseUrl !== '/'
? req.body.baseUrl
: urlBase,
});
} catch (e) {
logger.error('Failed to test Sonarr', {

@ -109,7 +109,7 @@ router.post(
const user = new User({
avatar: body.avatar ?? avatar,
username: body.username ?? body.email,
username: body.username,
email: body.email,
password: body.password,
permissions: settings.main.defaultPermissions,
@ -194,14 +194,11 @@ router.use('/:id/settings', userSettingsRoutes);
router.get<{ id: string }, UserRequestsResponse>(
'/:id/requests',
async (req, res, next) => {
const userRepository = getRepository(User);
const requestRepository = getRepository(MediaRequest);
const pageSize = req.query.take ? Number(req.query.take) : 20;
const skip = req.query.skip ? Number(req.query.skip) : 0;
try {
const user = await userRepository.findOne({
const user = await getRepository(User).findOne({
where: { id: Number(req.params.id) },
});
@ -209,12 +206,32 @@ router.get<{ id: string }, UserRequestsResponse>(
return next({ status: 404, message: 'User not found.' });
}
const [requests, requestCount] = await requestRepository.findAndCount({
where: { requestedBy: user },
order: { id: 'DESC' },
take: pageSize,
skip,
});
if (
user.id !== req.user?.id &&
!req.user?.hasPermission(
[Permission.MANAGE_REQUESTS, Permission.REQUEST_VIEW],
{ type: 'or' }
)
) {
return next({
status: 403,
message: "You do not have permission to view this user's requests.",
});
}
const [requests, requestCount] = await getRepository(MediaRequest)
.createQueryBuilder('request')
.leftJoinAndSelect('request.media', 'media')
.leftJoinAndSelect('request.seasons', 'seasons')
.leftJoinAndSelect('request.modifiedBy', 'modifiedBy')
.leftJoinAndSelect('request.requestedBy', 'requestedBy')
.andWhere('requestedBy.id = :id', {
id: user.id,
})
.orderBy('request.id', 'DESC')
.take(pageSize)
.skip(skip)
.getManyAndCount();
return res.status(200).json({
pageInfo: {

@ -144,7 +144,7 @@ export class MediaSubscriber implements EntitySubscriberInterface {
event.entity.mediaType === MediaType.MOVIE &&
event.entity.status === MediaStatus.AVAILABLE
) {
this.notifyAvailableMovie(event.entity, event.databaseEntity);
this.notifyAvailableMovie(event.entity as Media, event.databaseEntity);
}
if (
@ -152,21 +152,21 @@ export class MediaSubscriber implements EntitySubscriberInterface {
(event.entity.status === MediaStatus.AVAILABLE ||
event.entity.status === MediaStatus.PARTIALLY_AVAILABLE)
) {
this.notifyAvailableSeries(event.entity, event.databaseEntity);
this.notifyAvailableSeries(event.entity as Media, event.databaseEntity);
}
if (
event.entity.status === MediaStatus.AVAILABLE &&
event.databaseEntity.status === MediaStatus.PENDING
) {
this.updateChildRequestStatus(event.entity, false);
this.updateChildRequestStatus(event.entity as Media, false);
}
if (
event.entity.status4k === MediaStatus.AVAILABLE &&
event.databaseEntity.status4k === MediaStatus.PENDING
) {
this.updateChildRequestStatus(event.entity, true);
this.updateChildRequestStatus(event.entity as Media, true);
}
}
}

@ -6,25 +6,6 @@ head
meta(name='viewport' content='width=device-width, initial-scale=1')
meta(name='format-detection' content='telephone=no, date=no, address=no, email=no')
link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')
//if mso
xml
o:officedocumentsettings
o:pixelsperinch 96
style.
td,
th,
div,
p,
a,
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Segoe UI', sans-serif;
mso-line-height-rule: exactly;
}
style.
.title:hover * {
text-decoration: underline;
@ -35,28 +16,35 @@ head
width: 100% !important;
}
}
div(style='display: block; background-color: #111827;')
table(style='margin: 0 auto; font-family: Inter, Arial, Sans-Serif; color: #fff; font-size: 16px; width: 26rem;')
div(style='display: block; background-color: #111827; padding: 2.5rem 0;')
table(style='margin: 0 auto; font-family: Inter, Arial, sans-serif; color: #fff; font-size: 16px; width: 26rem;')
tr
td(style="text-align: center;")
a(href=applicationUrl)
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; padding: 1rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;')
if applicationUrl
a(href=applicationUrl style='margin: 0 1rem;')
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;')
else
div(style='margin: 0 1rem 2.5rem; font-size: 3em; font-weight: 700;')
| #{applicationTitle}
if recipientName !== recipientEmail
tr
td(style='text-align: center;')
div(style='margin: 1rem 0 0; font-size: 1.25em;')
| Hi, #{recipientName.replace(/\.|@/g, ((x) => x + '\ufeff'))}!
tr
td(style='text-align: center;')
div(style='margin: 0rem 1rem 1rem; font-size: 1.25em;')
span
| An account has been created for you at #{applicationTitle}.
div(style='margin: 1rem 0 0; font-size: 1.25em;')
| An account has been created for you at #{applicationTitle}.
tr
td(style='text-align: center;')
div(style='margin: 1rem 1rem 1rem; font-size: 1.25em;')
span
| Your new password is:
div(style='margin: 0rem 1rem 1rem; font-size: 1.25em;')
span
div(style='margin: 1rem 0 0; font-size: 1.25em;')
| Your password is:
div(style='font-size: 1.25em; font-weight: 500; line-height: 2.25em;')
span(style='padding: 0.5rem; font-weight: 500; border: 1px solid rgb(100,100,100); font-family: monospace;')
| #{password}
if applicationUrl
tr
td
a(href=applicationUrl style='display: block; margin: 1.5rem 3rem 2.5rem 3rem; text-decoration: none; font-size: 1.0em; line-height: 2.25em;')
span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255, 255, 255, 0.2);')
a(href=applicationUrl style='display: block; margin: 1.5rem 3rem 0; text-decoration: none; font-size: 1.0em; line-height: 2.25em;')
span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255,255,255,0.2);')
| Open #{applicationTitle}

@ -6,25 +6,6 @@ head
meta(name='viewport' content='width=device-width, initial-scale=1')
meta(name='format-detection' content='telephone=no, date=no, address=no, email=no')
link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')
//if mso
xml
o:officedocumentsettings
o:pixelsperinch 96
style.
td,
th,
div,
p,
a,
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Segoe UI', sans-serif;
mso-line-height-rule: exactly;
}
style.
.title:hover * {
text-decoration: underline;
@ -35,31 +16,38 @@ head
width: 100% !important;
}
}
div(style='display: block; background-color: #111827;')
table(style='margin: 0 auto; font-family: Inter, Arial, Sans-Serif; color: #fff; font-size: 16px; width: 26rem;')
div(style='display: block; background-color: #111827; padding: 2.5rem 0;')
table(style='margin: 0 auto; font-family: Inter, Arial, sans-serif; color: #fff; font-size: 16px; width: 26rem;')
tr
td(style="text-align: center;")
a(href=applicationUrl)
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; padding: 1rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;')
if applicationUrl
a(href=applicationUrl style='margin: 0 1rem;')
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;')
else
div(style='margin: 0 1rem 2.5rem; font-size: 3em; font-weight: 700;')
| #{applicationTitle}
if recipientName !== recipientEmail
tr
td(style='text-align: center;')
div(style='margin: 1rem 0 0; font-size: 1.25em;')
| Hi, #{recipientName.replace(/\.|@/g, ((x) => x + '\ufeff'))}!
tr
td(style='text-align: center;')
div(style='margin: 0rem 1rem 1rem; font-size: 1.25em;')
span
| #{body}
div(style='margin: 1rem 0 0; font-size: 1.25em;')
| #{body}
tr
td
div(style='box-sizing: border-box; margin: 0; width: 100%; color: #fff; border-radius: .75rem; padding: 1rem; border: 1px solid rgba(100, 100, 100, 1); background: linear-gradient(135deg, rgba(17, 24, 39, 0.47) 0%, rgb(17, 24, 39) 75%), url(' + imageUrl + ') center 25%/cover')
div(style='box-sizing: border-box; margin: 1.5rem 0 0; width: 100%; color: #fff; border-radius: .75rem; padding: 1rem; border: 1px solid rgb(100,100,100); background: linear-gradient(135deg, rgba(17,24,39,0.47) 0%, rgb(17,24,39) 75%), url(' + imageUrl + ') center 25%/cover')
table(style='color: #fff; width: 100%;')
tr
td(style='vertical-align: top;')
a(href=actionUrl style='display: block; max-width: 20rem; color: #fff; font-weight: 700; text-decoration: none; margin: 0 1rem 0.25rem 0; font-size: 1.3em; line-height: 1.25em; margin-bottom: 5px;' class='title')
span
| #{mediaName}
| #{mediaName}
div(style='overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #d1d5db; font-size: .975em; line-height: 1.45em; padding-top: .25rem; padding-bottom: .25rem;')
span(style='display: block;')
b(style='color: #9ca3af; font-weight: 700;')
| Requested By&nbsp;
| #{requestedBy}
| #{requestedBy.replace(/\.|@/g, ((x) => x + '\ufeff'))}
each extra in mediaExtra
span(style='display: block;')
b(style='color: #9ca3af; font-weight: 700;')
@ -76,6 +64,6 @@ div(style='display: block; background-color: #111827;')
if actionUrl
tr
td
a(href=actionUrl style='display: block; margin: 1.5rem 3rem 2.5rem 3rem; text-decoration: none; font-size: 1.0em; line-height: 2.25em;')
span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255, 255, 255, 0.2);')
a(href=actionUrl style='display: block; margin: 1.5rem 3rem 0; text-decoration: none; font-size: 1.0em; line-height: 2.25em;')
span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255,255,255,0.2);')
| Open in #{applicationTitle}

@ -6,25 +6,6 @@ head
meta(name='viewport' content='width=device-width, initial-scale=1')
meta(name='format-detection' content='telephone=no, date=no, address=no, email=no')
link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')
//if mso
xml
o:officedocumentsettings
o:pixelsperinch 96
style.
td,
th,
div,
p,
a,
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Segoe UI', sans-serif;
mso-line-height-rule: exactly;
}
style.
.title:hover * {
text-decoration: underline;
@ -35,25 +16,35 @@ head
width: 100% !important;
}
}
div(style='display: block; background-color: #111827;')
table(style='margin: 0 auto; font-family: Inter, Arial, Sans-Serif; color: #fff; font-size: 16px; width: 26rem;')
div(style='display: block; background-color: #111827; padding: 2.5rem 0;')
table(style='margin: 0 auto; font-family: Inter, Arial, sans-serif; color: #fff; font-size: 16px; width: 26rem;')
tr
td(style="text-align: center;")
a(href=applicationUrl)
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; padding: 1rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;')
if applicationUrl
a(href=applicationUrl style='margin: 0 1rem;')
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;')
else
div(style='margin: 0 1rem 2.5rem; font-size: 3em; font-weight: 700;')
| #{applicationTitle}
if recipientName !== recipientEmail
tr
td(style='text-align: center;')
div(style='margin: 1rem 0 0; font-size: 1.25em;')
| Hi, #{recipientName.replace(/\.|@/g, ((x) => x + '\ufeff'))}!
tr
td(style='text-align: center;')
div(style='margin: 0rem 1rem 1rem; font-size: 1.25em;')
span
| Your #{applicationTitle} account password was requested to be reset. Click below to reset your password.
if resetPasswordLink
tr
td
a(href=resetPasswordLink style='display: block; margin: 1.5rem 3rem 2.5rem 3rem; text-decoration: none; font-size: 1.0em; line-height: 2.25em;')
span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255, 255, 255, 0.2);')
| Reset Password
div(style='margin: 1rem 0 0; font-size: 1.25em;')
| A request has been received to change the password for your #{applicationTitle} account.
tr
td
a(href=resetPasswordLink style='display: block; margin: 1.5rem 3rem; text-decoration: none; font-size: 1.0em; line-height: 2.25em;')
span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255,255,255,0.2);')
| Reset Password
tr
td(style='text-align: center;')
div(style='margin: 1rem 0 0; font-size: 1.25em;')
| The above link will expire in 24 hours.
tr
td(style='text-align: center;')
div(style='margin: 1rem; font-size: .85em;')
span
| If you did not request that your password be reset, you can safely ignore this email.
div(style='margin: 1rem 1rem 0; font-size: 1.25em;')
| If you did not initiate this request, you may safely disregard this message.

@ -6,25 +6,6 @@ head
meta(name='viewport' content='width=device-width, initial-scale=1')
meta(name='format-detection' content='telephone=no, date=no, address=no, email=no')
link(href='https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap' rel='stylesheet' media='screen')
//if mso
xml
o:officedocumentsettings
o:pixelsperinch 96
style.
td,
th,
div,
p,
a,
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Segoe UI', sans-serif;
mso-line-height-rule: exactly;
}
style.
.title:hover * {
text-decoration: underline;
@ -35,20 +16,28 @@ head
width: 100% !important;
}
}
div(style='display: block; background-color: #111827;')
table(style='margin: 0 auto; font-family: Inter, Arial, Sans-Serif; color: #fff; font-size: 16px; width: 26rem;')
div(style='display: block; background-color: #111827; padding: 2.5rem 0;')
table(style='margin: 0 auto; font-family: Inter, Arial, sans-serif; color: #fff; font-size: 16px; width: 26rem;')
tr
td(style="text-align: center;")
a(href=applicationUrl)
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; padding: 1rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;')
if applicationUrl
a(href=applicationUrl style='margin: 0 1rem;')
img(src=applicationUrl +'/logo_full.png' style='width: 26rem; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast;')
else
div(style='margin: 0 1rem 2.5rem; font-size: 3em; font-weight: 700;')
| #{applicationTitle}
if recipientName !== recipientEmail
tr
td(style='text-align: center;')
div(style='margin: 1rem 0 0; font-size: 1.25em;')
| Hi, #{recipientName.replace(/\.|@/g, ((x) => x + '\ufeff'))}!
tr
td(style='text-align: center;')
div(style='margin: 0rem 1rem 1rem; font-size: 1.25em;')
span
| #{body}
div(style='margin: 1rem 0 0; font-size: 1.25em;')
| #{body}
if applicationUrl
tr
td
a(href=applicationUrl style='display: block; margin: 1.5rem 3rem 2.5rem 3rem; text-decoration: none; font-size: 1.0em; line-height: 2.25em;')
span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255, 255, 255, 0.2);')
a(href=applicationUrl style='display: block; margin: 1.5rem 3rem 0; text-decoration: none; font-size: 1.0em; line-height: 2.25em;')
span(style='padding: 0.2rem; font-weight: 500; text-align: center; border-radius: 10px; background-color: rgb(99,102,241); color: #fff; display: block; border: 1px solid rgba(255,255,255,0.2);')
| Open #{applicationTitle}

@ -21,6 +21,13 @@ declare module 'plex-api' {
requestOptions?: Record<string, string | number>;
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
query: <T extends Record<string, any>>(endpoint: string) => Promise<T>;
query: <T extends Record<string, any>>(
endpoint:
| string
| {
uri: string;
extraHeaders?: Record<string, string | number>;
}
) => Promise<T>;
}
}

@ -11,7 +11,7 @@ confinement: strict
parts:
overseerr:
plugin: nodejs
nodejs-version: '14.17.0'
nodejs-version: '14.18.1'
nodejs-package-manager: 'yarn'
nodejs-yarn-version: v1.22.10
build-packages:

@ -3,36 +3,64 @@ import React from 'react';
interface BadgeProps {
badgeType?: 'default' | 'primary' | 'danger' | 'warning' | 'success';
className?: string;
url?: string;
}
const Badge: React.FC<BadgeProps> = ({
badgeType = 'default',
className,
url,
children,
}) => {
const badgeStyle = [
'px-2 inline-flex text-xs leading-5 font-semibold rounded-full cursor-default',
'px-2 inline-flex text-xs leading-5 font-semibold rounded-full',
];
if (url) {
badgeStyle.push('transition cursor-pointer');
} else {
badgeStyle.push('cursor-default');
}
switch (badgeType) {
case 'danger':
badgeStyle.push('bg-red-600 text-red-100');
if (url) {
badgeStyle.push('hover:bg-red-500');
}
break;
case 'warning':
badgeStyle.push('bg-yellow-500 text-yellow-100');
if (url) {
badgeStyle.push('hover:bg-yellow-400');
}
break;
case 'success':
badgeStyle.push('bg-green-500 text-green-100');
if (url) {
badgeStyle.push('hover:bg-green-400');
}
break;
default:
badgeStyle.push('bg-indigo-500 text-indigo-100');
if (url) {
badgeStyle.push('hover:bg-indigo-400');
}
}
if (className) {
badgeStyle.push(className);
}
return <span className={badgeStyle.join(' ')}>{children}</span>;
if (url) {
return (
<a href={url} target="_blank" rel="noopener noreferrer">
<span className={badgeStyle.join(' ')}>{children}</span>
</a>
);
} else {
return <span className={badgeStyle.join(' ')}>{children}</span>;
}
};
export default Badge;

@ -128,16 +128,16 @@ const Modal: React.FC<ModalProps> = ({
/>
</div>
)}
<div className="relative sm:flex sm:items-center">
<div className="relative overflow-x-hidden sm:flex sm:items-center">
{iconSvg && <div className="modal-icon">{iconSvg}</div>}
<div
className={`mt-3 text-center sm:mt-0 sm:text-left ${
className={`mt-3 text-center sm:mt-0 sm:text-left truncate text-white ${
iconSvg ? 'sm:ml-4' : 'sm:mb-4'
}`}
>
{title && (
<span
className="text-lg font-bold leading-6 text-white"
className="text-lg font-bold leading-6 truncate"
id="modal-headline"
>
{title}

@ -38,6 +38,12 @@ const networks: Network[] = [
'https://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/4KAy34EHvRM25Ih8wb82AuGU7zJ.png',
url: '/discover/tv/network/2552',
},
{
name: 'Hulu',
image:
'https://image.tmdb.org/t/p/w780_filter(duotone,ffffff,bababa)/pqUTCleNUiTLAVlelGxUgWn1ELh.png',
url: '/discover/tv/network/453',
},
{
name: 'HBO',
image:

@ -3,6 +3,7 @@ import axios from 'axios';
import { useRouter } from 'next/dist/client/router';
import React, { useEffect, useState } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import useSWR from 'swr';
import useSettings from '../../hooks/useSettings';
import { useUser } from '../../hooks/useUser';
import Accordion from '../Common/Accordion';
@ -60,19 +61,21 @@ const Login: React.FC = () => {
}
}, [user, router]);
const { data: backdrops } = useSWR<string[]>('/api/v1/backdrops', {
refreshInterval: 0,
refreshWhenHidden: false,
revalidateOnFocus: false,
});
return (
<div className="relative flex flex-col min-h-screen bg-gray-900 py-14">
<PageTitle title={intl.formatMessage(messages.signin)} />
<ImageFader
forceOptimize
backgroundImages={[
'/images/rotate1.jpg',
'/images/rotate2.jpg',
'/images/rotate3.jpg',
'/images/rotate4.jpg',
'/images/rotate5.jpg',
'/images/rotate6.jpg',
]}
backgroundImages={
backdrops?.map(
(backdrop) => `https://www.themoviedb.org/t/p/original${backdrop}`
) ?? []
}
/>
<div className="absolute z-50 top-4 right-4">
<LanguagePicker />

@ -1,8 +1,10 @@
import {
ArrowCircleRightIcon,
CloudIcon,
CogIcon,
FilmIcon,
PlayIcon,
TicketIcon,
} from '@heroicons/react/outline';
import {
CheckCircleIcon,
@ -12,6 +14,7 @@ import {
ExternalLinkIcon,
} from '@heroicons/react/solid';
import axios from 'axios';
import { uniqBy } from 'lodash';
import Link from 'next/link';
import { useRouter } from 'next/router';
import React, { useMemo, useState } from 'react';
@ -49,7 +52,8 @@ import StatusBadge from '../StatusBadge';
const messages = defineMessages({
originaltitle: 'Original Title',
releasedate: 'Release Date',
releasedate:
'{releaseCount, plural, one {Release Date} other {Release Dates}}',
revenue: 'Revenue',
budget: 'Budget',
watchtrailer: 'Watch Trailer',
@ -179,20 +183,29 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
: settings.currentSettings.region
? settings.currentSettings.region
: 'US';
const releases = data.releases.results.find(
(r) => r.iso_3166_1 === region
)?.release_dates;
// Release date types:
// 1. Premiere
// 2. Theatrical (limited)
// 3. Theatrical
// 4. Digital
// 5. Physical
// 6. TV
const filteredReleases = uniqBy(
releases?.filter((r) => r.type > 2 && r.type < 6),
'type'
);
const movieAttributes: React.ReactNode[] = [];
if (
data.releases.results.length &&
(data.releases.results.find((r) => r.iso_3166_1 === region)
?.release_dates[0].certification ||
data.releases.results[0].release_dates[0].certification)
) {
const certification = releases?.find((r) => r.certification)?.certification;
if (certification) {
movieAttributes.push(
<span className="p-0.5 py-0 border rounded-md">
{data.releases.results.find((r) => r.iso_3166_1 === region)
?.release_dates[0].certification ||
data.releases.results[0].release_dates[0].certification}
</span>
<span className="p-0.5 py-0 border rounded-md">{certification}</span>
);
}
@ -407,6 +420,11 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
status={data.mediaInfo?.status}
inProgress={(data.mediaInfo?.downloadStatus ?? []).length > 0}
plexUrl={data.mediaInfo?.plexUrl}
serviceUrl={
hasPermission(Permission.ADMIN)
? data.mediaInfo?.serviceUrl
: undefined
}
/>
{settings.currentSettings.movie4kEnabled &&
hasPermission(
@ -421,7 +439,12 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
inProgress={
(data.mediaInfo?.downloadStatus4k ?? []).length > 0
}
plexUrl4k={data.mediaInfo?.plexUrl4k}
plexUrl={data.mediaInfo?.plexUrl4k}
serviceUrl={
hasPermission(Permission.ADMIN)
? data.mediaInfo?.serviceUrl4k
: undefined
}
/>
)}
</div>
@ -577,17 +600,66 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
<span>{intl.formatMessage(globalMessages.status)}</span>
<span className="media-fact-value">{data.status}</span>
</div>
{data.releaseDate && (
{filteredReleases && filteredReleases.length > 0 ? (
<div className="media-fact">
<span>{intl.formatMessage(messages.releasedate)}</span>
<span className="media-fact-value">
{intl.formatDate(data.releaseDate, {
year: 'numeric',
month: 'long',
day: 'numeric',
<span>
{intl.formatMessage(messages.releasedate, {
releaseCount: filteredReleases.length,
})}
</span>
<span className="media-fact-value">
{filteredReleases.map((r, i) => (
<span
className="flex items-center justify-end"
key={`release-date-${i}`}
>
{r.type === 3 ? (
// Theatrical
<TicketIcon className="w-4 h-4" />
) : r.type === 4 ? (
// Digital
<CloudIcon className="w-4 h-4" />
) : (
// Physical
<svg
className="w-4 h-4"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="m12 2c-5.5242 0-10 4.4758-10 10 0 5.5242 4.4758 10 10 10 5.5242 0 10-4.4758 10-10 0-5.5242-4.4758-10-10-10zm0 18.065c-4.4476 0-8.0645-3.6169-8.0645-8.0645 0-4.4476 3.6169-8.0645 8.0645-8.0645 4.4476 0 8.0645 3.6169 8.0645 8.0645 0 4.4476-3.6169 8.0645-8.0645 8.0645zm0-14.516c-3.5565 0-6.4516 2.8952-6.4516 6.4516h1.2903c0-2.8468 2.3145-5.1613 5.1613-5.1613zm0 2.9032c-1.9597 0-3.5484 1.5887-3.5484 3.5484s1.5887 3.5484 3.5484 3.5484 3.5484-1.5887 3.5484-3.5484-1.5887-3.5484-3.5484-3.5484zm0 4.8387c-0.71371 0-1.2903-0.57661-1.2903-1.2903s0.57661-1.2903 1.2903-1.2903 1.2903 0.57661 1.2903 1.2903-0.57661 1.2903-1.2903 1.2903z"
fill="currentColor"
/>
</svg>
)}
<span className="ml-1.5">
{intl.formatDate(r.release_date, {
year: 'numeric',
month: 'long',
day: 'numeric',
})}
</span>
</span>
))}
</span>
</div>
) : (
data.releaseDate && (
<div className="media-fact">
<span>
{intl.formatMessage(messages.releasedate, {
releaseCount: 1,
})}
</span>
<span className="media-fact-value">
{intl.formatDate(data.releaseDate, {
year: 'numeric',
month: 'long',
day: 'numeric',
})}
</span>
</div>
)
)}
{data.revenue > 0 && (
<div className="media-fact">

@ -292,8 +292,18 @@ const RequestCard: React.FC<RequestCardProps> = ({ request, onTitleData }) => {
).length > 0
}
is4k={requestData.is4k}
plexUrl={requestData.media.plexUrl}
plexUrl4k={requestData.media.plexUrl4k}
plexUrl={
requestData.is4k
? requestData.media.plexUrl4k
: requestData.media.plexUrl
}
serviceUrl={
hasPermission(Permission.ADMIN)
? requestData.is4k
? requestData.media.serviceUrl4k
: requestData.media.serviceUrl
: undefined
}
/>
)}
</div>

@ -294,8 +294,18 @@ const RequestItem: React.FC<RequestItemProps> = ({
).length > 0
}
is4k={requestData.is4k}
plexUrl={requestData.media.plexUrl}
plexUrl4k={requestData.media.plexUrl4k}
plexUrl={
requestData.is4k
? requestData.media.plexUrl4k
: requestData.media.plexUrl
}
serviceUrl={
hasPermission(Permission.ADMIN)
? requestData.is4k
? requestData.media.serviceUrl4k
: requestData.media.serviceUrl
: undefined
}
/>
)}
</div>

@ -150,21 +150,21 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
const defaultProfile = serverData.profiles.find(
(profile) =>
profile.id ===
(isAnime
(isAnime && serverData.server.activeAnimeProfileId
? serverData.server.activeAnimeProfileId
: serverData.server.activeProfileId)
);
const defaultFolder = serverData.rootFolders.find(
(folder) =>
folder.path ===
(isAnime
(isAnime && serverData.server.activeAnimeDirectory
? serverData.server.activeAnimeDirectory
: serverData.server.activeDirectory)
);
const defaultLanguage = serverData.languageProfiles?.find(
(language) =>
language.id ===
(isAnime
(isAnime && serverData.server.activeAnimeLanguageProfileId
? serverData.server.activeAnimeLanguageProfileId
: serverData.server.activeLanguageProfileId)
);
@ -172,10 +172,15 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
? serverData.server.activeAnimeTags
: serverData.server.activeTags;
const applyOverrides =
defaultOverrides &&
((defaultOverrides.server === null && serverData.server.isDefault) ||
defaultOverrides.server === serverData.server.id);
if (
defaultProfile &&
defaultProfile.id !== selectedProfile &&
(!defaultOverrides || defaultOverrides.profile === null)
(!applyOverrides || defaultOverrides.profile === null)
) {
setSelectedProfile(defaultProfile.id);
}
@ -183,7 +188,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
if (
defaultFolder &&
defaultFolder.path !== selectedFolder &&
(!defaultOverrides || defaultOverrides.folder === null)
(!applyOverrides || !defaultOverrides.folder)
) {
setSelectedFolder(defaultFolder.path ?? '');
}
@ -191,7 +196,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
if (
defaultLanguage &&
defaultLanguage.id !== selectedLanguage &&
(!defaultOverrides || defaultOverrides.language === null)
(!applyOverrides || defaultOverrides.language === null)
) {
setSelectedLanguage(defaultLanguage.id);
}
@ -199,7 +204,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
if (
defaultTags &&
!isEqual(defaultTags, selectedTags) &&
(!defaultOverrides || defaultOverrides.tags === null)
(!applyOverrides || defaultOverrides.tags === null)
) {
setSelectedTags(defaultTags);
}
@ -215,7 +220,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
setSelectedProfile(defaultOverrides.profile);
}
if (defaultOverrides && defaultOverrides.folder != null) {
if (defaultOverrides && defaultOverrides.folder) {
setSelectedFolder(defaultOverrides.folder);
}
@ -241,7 +246,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
profile: selectedProfile !== -1 ? selectedProfile : undefined,
server: selectedServer ?? undefined,
user: selectedUser ?? undefined,
language: selectedLanguage ?? undefined,
language: selectedLanguage !== -1 ? selectedLanguage : undefined,
tags: selectedTags,
});
}

@ -48,13 +48,6 @@ const NotificationsDiscord: React.FC = () => {
otherwise: Yup.string().nullable(),
})
.url(intl.formatMessage(messages.validationUrl)),
types: Yup.number().when('enabled', {
is: true,
then: Yup.number()
.nullable()
.moreThan(0, intl.formatMessage(messages.validationTypes)),
otherwise: Yup.number().nullable(),
}),
});
if (!data && !error) {
@ -238,8 +231,8 @@ const NotificationsDiscord: React.FC = () => {
}
}}
error={
errors.types && touched.types
? (errors.types as string)
values.enabled && !values.types && touched.types
? intl.formatMessage(messages.validationTypes)
: undefined
}
/>
@ -266,7 +259,12 @@ const NotificationsDiscord: React.FC = () => {
<Button
buttonType="primary"
type="submit"
disabled={isSubmitting || !isValid || isTesting}
disabled={
isSubmitting ||
!isValid ||
isTesting ||
(values.enabled && !values.types)
}
>
<SaveIcon />
<span>

@ -45,13 +45,6 @@ const NotificationsLunaSea: React.FC = () => {
otherwise: Yup.string().nullable(),
})
.url(intl.formatMessage(messages.validationWebhookUrl)),
types: Yup.number().when('enabled', {
is: true,
then: Yup.number()
.nullable()
.moreThan(0, intl.formatMessage(messages.validationTypes)),
otherwise: Yup.number().nullable(),
}),
});
if (!data && !error) {
@ -217,8 +210,8 @@ const NotificationsLunaSea: React.FC = () => {
}
}}
error={
errors.types && touched.types
? (errors.types as string)
values.enabled && !values.types && touched.types
? intl.formatMessage(messages.validationTypes)
: undefined
}
/>
@ -245,7 +238,12 @@ const NotificationsLunaSea: React.FC = () => {
<Button
buttonType="primary"
type="submit"
disabled={isSubmitting || !isValid || isTesting}
disabled={
isSubmitting ||
!isValid ||
isTesting ||
(values.enabled && !values.types)
}
>
<SaveIcon />
<span>

@ -43,13 +43,6 @@ const NotificationsPushbullet: React.FC = () => {
.required(intl.formatMessage(messages.validationAccessTokenRequired)),
otherwise: Yup.string().nullable(),
}),
types: Yup.number().when('enabled', {
is: true,
then: Yup.number()
.nullable()
.moreThan(0, intl.formatMessage(messages.validationTypes)),
otherwise: Yup.number().nullable(),
}),
});
if (!data && !error) {
@ -197,8 +190,8 @@ const NotificationsPushbullet: React.FC = () => {
}
}}
error={
errors.types && touched.types
? (errors.types as string)
values.enabled && !values.types && touched.types
? intl.formatMessage(messages.validationTypes)
: undefined
}
/>
@ -225,7 +218,12 @@ const NotificationsPushbullet: React.FC = () => {
<Button
buttonType="primary"
type="submit"
disabled={isSubmitting || !isValid || isTesting}
disabled={
isSubmitting ||
!isValid ||
isTesting ||
(values.enabled && !values.types)
}
>
<SaveIcon />
<span>

@ -62,13 +62,6 @@ const NotificationsPushover: React.FC = () => {
/^[a-z\d]{30}$/i,
intl.formatMessage(messages.validationUserTokenRequired)
),
types: Yup.number().when('enabled', {
is: true,
then: Yup.number()
.nullable()
.moreThan(0, intl.formatMessage(messages.validationTypes)),
otherwise: Yup.number().nullable(),
}),
});
if (!data && !error) {
@ -243,8 +236,8 @@ const NotificationsPushover: React.FC = () => {
}
}}
error={
errors.types && touched.types
? (errors.types as string)
values.enabled && !values.types && touched.types
? intl.formatMessage(messages.validationTypes)
: undefined
}
/>
@ -271,7 +264,12 @@ const NotificationsPushover: React.FC = () => {
<Button
buttonType="primary"
type="submit"
disabled={isSubmitting || !isValid || isTesting}
disabled={
isSubmitting ||
!isValid ||
isTesting ||
(values.enabled && !values.types)
}
>
<SaveIcon />
<span>

@ -43,13 +43,6 @@ const NotificationsSlack: React.FC = () => {
otherwise: Yup.string().nullable(),
})
.url(intl.formatMessage(messages.validationWebhookUrl)),
types: Yup.number().when('enabled', {
is: true,
then: Yup.number()
.nullable()
.moreThan(0, intl.formatMessage(messages.validationTypes)),
otherwise: Yup.number().nullable(),
}),
});
if (!data && !error) {
@ -195,8 +188,8 @@ const NotificationsSlack: React.FC = () => {
}
}}
error={
errors.types && touched.types
? (errors.types as string)
values.enabled && !values.types && touched.types
? intl.formatMessage(messages.validationTypes)
: undefined
}
/>
@ -223,7 +216,12 @@ const NotificationsSlack: React.FC = () => {
<Button
buttonType="primary"
type="submit"
disabled={isSubmitting || !isValid || isTesting}
disabled={
isSubmitting ||
!isValid ||
isTesting ||
(values.enabled && !values.types)
}
>
<SaveIcon />
<span>

@ -101,13 +101,6 @@ const NotificationsWebhook: React.FC = () => {
}
}
),
types: Yup.number().when('enabled', {
is: true,
then: Yup.number()
.nullable()
.moreThan(0, intl.formatMessage(messages.validationTypes)),
otherwise: Yup.number().nullable(),
}),
});
if (!data && !error) {
@ -312,8 +305,8 @@ const NotificationsWebhook: React.FC = () => {
}
}}
error={
errors.types && touched.types
? (errors.types as string)
values.enabled && !values.types && touched.types
? intl.formatMessage(messages.validationTypes)
: undefined
}
/>
@ -340,7 +333,12 @@ const NotificationsWebhook: React.FC = () => {
<Button
buttonType="primary"
type="submit"
disabled={isSubmitting || !isValid || isTesting}
disabled={
isSubmitting ||
!isValid ||
isTesting ||
(values.enabled && !values.types)
}
>
<SaveIcon />
<span>

@ -82,6 +82,7 @@ interface TestResponse {
id: number;
label: string;
}[];
urlBase?: string;
}
interface RadarrModalProps {
@ -317,6 +318,9 @@ const RadarrModal: React.FC<RadarrModalProps> = ({
port: values.port,
useSsl: values.ssl,
});
if (!values.baseUrl || values.baseUrl === '/') {
setFieldValue('baseUrl', testResponse.urlBase);
}
}
}}
secondaryDisabled={

@ -4,7 +4,6 @@ import { defineMessages, FormattedRelativeTime, useIntl } from 'react-intl';
import ReactMarkdown from 'react-markdown';
import useSWR from 'swr';
import globalMessages from '../../../../i18n/globalMessages';
import Alert from '../../../Common/Alert';
import Badge from '../../../Common/Badge';
import Button from '../../../Common/Button';
import LoadingSpinner from '../../../Common/LoadingSpinner';
@ -13,14 +12,12 @@ import Transition from '../../../Transition';
const messages = defineMessages({
releases: 'Releases',
releasedataMissing: 'Release data unavailable. Is GitHub down?',
versionChangelog: 'Version Changelog',
releasedataMissing: 'Release data is currently unavailable.',
versionChangelog: '{version} Changelog',
viewongithub: 'View on GitHub',
latestversion: 'Latest',
currentversion: 'Current Version',
currentversion: 'Current',
viewchangelog: 'View Changelog',
runningDevelopMessage:
'The latest changes to the <code>develop</code> branch of Overseerr are not shown below. Please see the commit history for this branch on <GithubLink>GitHub</GithubLink> for details.',
});
const REPO_RELEASE_API =
@ -58,8 +55,9 @@ const Release: React.FC<ReleaseProps> = ({
}) => {
const intl = useIntl();
const [isModalOpen, setModalOpen] = useState(false);
return (
<div className="flex flex-col px-4 py-2 bg-gray-800 rounded-md sm:flex-row">
<div className="flex flex-col w-full px-4 py-2 space-y-3 bg-gray-800 rounded-md shadow-md sm:space-y-0 sm:space-x-3 sm:flex-row ring-1 ring-gray-700">
<Transition
enter="opacity-0 transition duration-300"
enterFrom="opacity-0"
@ -72,7 +70,9 @@ const Release: React.FC<ReleaseProps> = ({
<Modal
onCancel={() => setModalOpen(false)}
iconSvg={<DocumentTextIcon />}
title={intl.formatMessage(messages.versionChangelog)}
title={intl.formatMessage(messages.versionChangelog, {
version: release.name,
})}
cancelText={intl.formatMessage(globalMessages.close)}
okText={intl.formatMessage(messages.viewongithub)}
onOk={() => {
@ -84,38 +84,34 @@ const Release: React.FC<ReleaseProps> = ({
</div>
</Modal>
</Transition>
<div className="flex items-center justify-center mb-4 sm:mb-0 sm:justify-start">
<span className="mt-1 mr-2 text-xs">
<FormattedRelativeTime
value={Math.floor(
(new Date(release.created_at).getTime() - Date.now()) / 1000
)}
updateIntervalInSeconds={1}
numeric="auto"
/>
<div className="flex items-center justify-center flex-grow w-full space-x-2 truncate sm:justify-start">
<span className="text-lg font-bold truncate">
<span className="mr-2 text-xs font-normal whitespace-nowrap">
<FormattedRelativeTime
value={Math.floor(
(new Date(release.created_at).getTime() - Date.now()) / 1000
)}
updateIntervalInSeconds={1}
numeric="auto"
/>
</span>
{release.name}
</span>
<span className="text-lg font-bold">{release.name}</span>
{isLatest && (
<span className="ml-2 -mt-1">
<Badge badgeType="primary">
{intl.formatMessage(messages.latestversion)}
</Badge>
</span>
<Badge badgeType="success">
{intl.formatMessage(messages.latestversion)}
</Badge>
)}
{release.name.includes(currentVersion) && (
<span className="ml-2 -mt-1">
<Badge badgeType="success">
{intl.formatMessage(messages.currentversion)}
</Badge>
</span>
<Badge badgeType="primary">
{intl.formatMessage(messages.currentversion)}
</Badge>
)}
</div>
<div className="flex-1 text-center sm:text-right">
<Button buttonType="primary" onClick={() => setModalOpen(true)}>
<DocumentTextIcon />
<span>{intl.formatMessage(messages.viewchangelog)}</span>
</Button>
</div>
<Button buttonType="primary" onClick={() => setModalOpen(true)}>
<DocumentTextIcon />
<span>{intl.formatMessage(messages.viewchangelog)}</span>
</Button>
</div>
);
};
@ -143,31 +139,10 @@ const Releases: React.FC<ReleasesProps> = ({ currentVersion }) => {
return (
<div>
<h3 className="heading">{intl.formatMessage(messages.releases)}</h3>
<div className="section">
{currentVersion.startsWith('develop-') && (
<Alert
title={intl.formatMessage(messages.runningDevelopMessage, {
code: function code(msg) {
return <code className="bg-opacity-50">{msg}</code>;
},
GithubLink: function GithubLink(msg) {
return (
<a
href="https://github.com/sct/overseerr"
target="_blank"
rel="noreferrer"
className="text-yellow-100 underline transition duration-300 hover:text-white"
>
{msg}
</a>
);
},
})}
/>
)}
{data?.map((release, index) => {
<div className="space-y-3 section">
{data.map((release, index) => {
return (
<div key={`release-${release.id}`} className="mb-2">
<div key={`release-${release.id}`}>
<Release
release={release}
currentVersion={currentVersion}

@ -8,6 +8,7 @@ import {
} from '../../../../server/interfaces/api/settingsInterfaces';
import globalMessages from '../../../i18n/globalMessages';
import Error from '../../../pages/_error';
import Alert from '../../Common/Alert';
import Badge from '../../Common/Badge';
import List from '../../Common/List';
import LoadingSpinner from '../../Common/LoadingSpinner';
@ -16,7 +17,7 @@ import Releases from './Releases';
const messages = defineMessages({
about: 'About',
overseerrinformation: 'Overseerr Information',
overseerrinformation: 'About Overseerr',
version: 'Version',
totalmedia: 'Total Media',
totalrequests: 'Total Requests',
@ -31,6 +32,8 @@ const messages = defineMessages({
uptodate: 'Up to Date',
betawarning:
'This is BETA software. Features may be broken and/or unstable. Please report any issues on GitHub!',
runningDevelop:
'You are running the <code>develop</code> branch of Overseerr, which is only recommended for those contributing to development or assisting with bleeding-edge testing.',
});
const SettingsAbout: React.FC = () => {
@ -81,22 +84,58 @@ const SettingsAbout: React.FC = () => {
</div>
<div className="section">
<List title={intl.formatMessage(messages.overseerrinformation)}>
{data.version.startsWith('develop-') && (
<Alert
title={intl.formatMessage(messages.runningDevelop, {
code: function code(msg) {
return <code className="bg-opacity-50">{msg}</code>;
},
})}
/>
)}
<List.Item
title={intl.formatMessage(messages.version)}
className="truncate"
className="flex flex-row items-center truncate"
>
<code>{data.version.replace('develop-', '')}</code>
{status?.updateAvailable ? (
<Badge badgeType="warning" className="ml-2">
{intl.formatMessage(messages.outofdate)}
</Badge>
) : (
status?.commitTag !== 'local' && (
<Badge badgeType="success" className="ml-2">
{intl.formatMessage(messages.uptodate)}
</Badge>
)
)}
<code className="truncate">
{data.version.replace('develop-', '')}
</code>
{status?.commitTag !== 'local' &&
(status?.updateAvailable ? (
<a
href={
data.version.startsWith('develop-')
? `https://github.com/sct/overseerr/compare/${status.commitTag}...develop`
: 'https://github.com/sct/overseerr/releases'
}
target="_blank"
rel="noopener noreferrer"
>
<Badge
badgeType="warning"
className="ml-2 transition !cursor-pointer hover:bg-yellow-400"
>
{intl.formatMessage(messages.outofdate)}
</Badge>
</a>
) : (
<a
href={
data.version.startsWith('develop-')
? 'https://github.com/sct/overseerr/commits/develop'
: 'https://github.com/sct/overseerr/releases'
}
target="_blank"
rel="noopener noreferrer"
>
<Badge
badgeType="success"
className="ml-2 transition !cursor-pointer hover:bg-green-400"
>
{intl.formatMessage(messages.uptodate)}
</Badge>
</a>
))}
</List.Item>
<List.Item title={intl.formatMessage(messages.totalmedia)}>
{intl.formatNumber(data.totalMediaItems)}
@ -118,7 +157,7 @@ const SettingsAbout: React.FC = () => {
href="https://docs.overseerr.dev"
target="_blank"
rel="noreferrer"
className="text-indigo-500 hover:underline"
className="text-indigo-500 transition duration-300 hover:underline"
>
https://docs.overseerr.dev
</a>
@ -128,7 +167,7 @@ const SettingsAbout: React.FC = () => {
href="https://github.com/sct/overseerr/discussions"
target="_blank"
rel="noreferrer"
className="text-indigo-500 hover:underline"
className="text-indigo-500 transition duration-300 hover:underline"
>
https://github.com/sct/overseerr/discussions
</a>
@ -138,7 +177,7 @@ const SettingsAbout: React.FC = () => {
href="https://discord.gg/overseerr"
target="_blank"
rel="noreferrer"
className="text-indigo-500 hover:underline"
className="text-indigo-500 transition duration-300 hover:underline"
>
https://discord.gg/overseerr
</a>
@ -154,7 +193,7 @@ const SettingsAbout: React.FC = () => {
href="https://github.com/sponsors/sct"
target="_blank"
rel="noreferrer"
className="text-indigo-500 hover:underline"
className="text-indigo-500 transition duration-300 hover:underline"
>
https://github.com/sponsors/sct
</a>
@ -167,7 +206,7 @@ const SettingsAbout: React.FC = () => {
href="https://patreon.com/overseerr"
target="_blank"
rel="noreferrer"
className="text-indigo-500 hover:underline"
className="text-indigo-500 transition duration-300 hover:underline"
>
https://patreon.com/overseerr
</a>

@ -1,6 +1,7 @@
import { PlayIcon, StopIcon, TrashIcon } from '@heroicons/react/outline';
import { PencilIcon } from '@heroicons/react/solid';
import axios from 'axios';
import React from 'react';
import React, { useState } from 'react';
import {
defineMessages,
FormattedRelativeTime,
@ -10,14 +11,17 @@ import {
import { useToasts } from 'react-toast-notifications';
import useSWR from 'swr';
import { CacheItem } from '../../../../server/interfaces/api/settingsInterfaces';
import { JobId } from '../../../../server/lib/settings';
import Spinner from '../../../assets/spinner.svg';
import globalMessages from '../../../i18n/globalMessages';
import { formatBytes } from '../../../utils/numberHelpers';
import Badge from '../../Common/Badge';
import Button from '../../Common/Button';
import LoadingSpinner from '../../Common/LoadingSpinner';
import Modal from '../../Common/Modal';
import PageTitle from '../../Common/PageTitle';
import Table from '../../Common/Table';
import Transition from '../../Transition';
const messages: { [messageName: string]: MessageDescriptor } = defineMessages({
jobsandcache: 'Jobs & Cache',
@ -51,12 +55,21 @@ const messages: { [messageName: string]: MessageDescriptor } = defineMessages({
'sonarr-scan': 'Sonarr Scan',
'download-sync': 'Download Sync',
'download-sync-reset': 'Download Sync Reset',
editJobSchedule: 'Modify Job',
jobScheduleEditSaved: 'Job edited successfully!',
jobScheduleEditFailed: 'Something went wrong while saving the job.',
editJobSchedulePrompt: 'Frequency',
editJobScheduleSelectorHours:
'Every {jobScheduleHours, plural, one {hour} other {{jobScheduleHours} hours}}',
editJobScheduleSelectorMinutes:
'Every {jobScheduleMinutes, plural, one {minute} other {{jobScheduleMinutes} minutes}}',
});
interface Job {
id: string;
id: JobId;
name: string;
type: 'process' | 'command';
interval: 'short' | 'long' | 'fixed';
nextExecutionTime: string;
running: boolean;
}
@ -74,6 +87,16 @@ const SettingsJobs: React.FC = () => {
}
);
const [jobEditModal, setJobEditModal] = useState<{
isOpen: boolean;
job?: Job;
}>({
isOpen: false,
});
const [isSaving, setIsSaving] = useState(false);
const [jobScheduleMinutes, setJobScheduleMinutes] = useState(5);
const [jobScheduleHours, setJobScheduleHours] = useState(1);
if (!data && !error) {
return <LoadingSpinner />;
}
@ -118,6 +141,42 @@ const SettingsJobs: React.FC = () => {
cacheRevalidate();
};
const scheduleJob = async () => {
const jobScheduleCron = ['0', '0', '*', '*', '*', '*'];
try {
if (jobEditModal.job?.interval === 'short') {
jobScheduleCron[1] = `*/${jobScheduleMinutes}`;
} else if (jobEditModal.job?.interval === 'long') {
jobScheduleCron[2] = `*/${jobScheduleHours}`;
} else {
// jobs with interval: fixed should not be editable
throw new Error();
}
setIsSaving(true);
await axios.post(
`/api/v1/settings/jobs/${jobEditModal.job?.id}/schedule`,
{
schedule: jobScheduleCron.join(' '),
}
);
addToast(intl.formatMessage(messages.jobScheduleEditSaved), {
appearance: 'success',
autoDismiss: true,
});
setJobEditModal({ isOpen: false });
revalidate();
} catch (e) {
addToast(intl.formatMessage(messages.jobScheduleEditFailed), {
appearance: 'error',
autoDismiss: true,
});
} finally {
setIsSaving(false);
}
};
return (
<>
<PageTitle
@ -126,6 +185,82 @@ const SettingsJobs: React.FC = () => {
intl.formatMessage(globalMessages.settings),
]}
/>
<Transition
enter="opacity-0 transition duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="opacity-100 transition duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
show={jobEditModal.isOpen}
>
<Modal
title={intl.formatMessage(messages.editJobSchedule)}
okText={
isSaving
? intl.formatMessage(globalMessages.saving)
: intl.formatMessage(globalMessages.save)
}
iconSvg={<PencilIcon />}
onCancel={() => setJobEditModal({ isOpen: false })}
okDisabled={isSaving}
onOk={() => scheduleJob()}
>
<div className="section">
<form>
<div className="pb-6 form-row">
<label htmlFor="jobSchedule" className="text-label">
{intl.formatMessage(messages.editJobSchedulePrompt)}
</label>
<div className="form-input">
{jobEditModal.job?.interval === 'short' ? (
<select
name="jobScheduleMinutes"
className="inline"
value={jobScheduleMinutes}
onChange={(e) =>
setJobScheduleMinutes(Number(e.target.value))
}
>
{[5, 10, 15, 20, 30, 60].map((v) => (
<option value={v} key={`jobScheduleMinutes-${v}`}>
{intl.formatMessage(
messages.editJobScheduleSelectorMinutes,
{
jobScheduleMinutes: v,
}
)}
</option>
))}
</select>
) : (
<select
name="jobScheduleHours"
className="inline"
value={jobScheduleHours}
onChange={(e) =>
setJobScheduleHours(Number(e.target.value))
}
>
{[1, 2, 3, 4, 6, 8, 12, 24, 48, 72].map((v) => (
<option value={v} key={`jobScheduleHours-${v}`}>
{intl.formatMessage(
messages.editJobScheduleSelectorHours,
{
jobScheduleHours: v,
}
)}
</option>
))}
</select>
)}
</div>
</div>
</form>
</div>
</Modal>
</Transition>
<div className="mb-6">
<h3 className="heading">{intl.formatMessage(messages.jobs)}</h3>
<p className="description">
@ -179,6 +314,18 @@ const SettingsJobs: React.FC = () => {
</div>
</Table.TD>
<Table.TD alignText="right">
{job.interval !== 'fixed' && (
<Button
className="mr-2"
buttonType="warning"
onClick={() =>
setJobEditModal({ isOpen: true, job: job })
}
>
<PencilIcon />
{intl.formatMessage(globalMessages.edit)}
</Button>
)}
{job.running ? (
<Button buttonType="danger" onClick={() => cancelJob(job)}>
<StopIcon />

@ -92,6 +92,7 @@ interface TestResponse {
id: number;
label: string;
}[];
urlBase?: string;
}
interface SonarrModalProps {
@ -348,6 +349,9 @@ const SonarrModal: React.FC<SonarrModalProps> = ({
port: values.port,
useSsl: values.ssl,
});
if (!values.baseUrl || values.baseUrl === '/') {
setFieldValue('baseUrl', testResponse.urlBase);
}
}
}}
secondaryDisabled={

@ -6,6 +6,7 @@ import globalMessages from '../../i18n/globalMessages';
import Badge from '../Common/Badge';
const messages = defineMessages({
status: '{status}',
status4k: '4K {status}',
});
@ -14,7 +15,7 @@ interface StatusBadgeProps {
is4k?: boolean;
inProgress?: boolean;
plexUrl?: string;
plexUrl4k?: string;
serviceUrl?: string;
}
const StatusBadge: React.FC<StatusBadgeProps> = ({
@ -22,158 +23,64 @@ const StatusBadge: React.FC<StatusBadgeProps> = ({
is4k = false,
inProgress = false,
plexUrl,
plexUrl4k,
serviceUrl,
}) => {
const intl = useIntl();
if (is4k) {
switch (status) {
case MediaStatus.AVAILABLE:
if (plexUrl4k) {
return (
<a href={plexUrl4k} target="_blank" rel="noopener noreferrer">
<Badge
badgeType="success"
className="transition !cursor-pointer hover:bg-green-400"
>
{intl.formatMessage(messages.status4k, {
status: intl.formatMessage(globalMessages.available),
})}
</Badge>
</a>
);
}
return (
<Badge badgeType="success">
{intl.formatMessage(messages.status4k, {
status: intl.formatMessage(globalMessages.available),
})}
</Badge>
);
case MediaStatus.PARTIALLY_AVAILABLE:
if (plexUrl4k) {
return (
<a href={plexUrl4k} target="_blank" rel="noopener noreferrer">
<Badge
badgeType="success"
className="transition !cursor-pointer hover:bg-green-400"
>
{intl.formatMessage(messages.status4k, {
status: intl.formatMessage(globalMessages.partiallyavailable),
})}
</Badge>
</a>
);
}
return (
<Badge badgeType="success">
{intl.formatMessage(messages.status4k, {
status: intl.formatMessage(globalMessages.partiallyavailable),
})}
</Badge>
);
case MediaStatus.PROCESSING:
return (
<Badge badgeType="primary">
<div className="flex items-center">
<span>
{intl.formatMessage(messages.status4k, {
status: inProgress
? intl.formatMessage(globalMessages.processing)
: intl.formatMessage(globalMessages.requested),
})}
</span>
{inProgress && <Spinner className="w-3 h-3 ml-1" />}
</div>
</Badge>
);
case MediaStatus.PENDING:
return (
<Badge badgeType="warning">
{intl.formatMessage(messages.status4k, {
status: intl.formatMessage(globalMessages.pending),
})}
</Badge>
);
default:
return null;
}
}
switch (status) {
case MediaStatus.AVAILABLE:
if (plexUrl) {
return (
<a href={plexUrl} target="_blank" rel="noopener noreferrer">
<Badge
badgeType="success"
className="transition !cursor-pointer hover:bg-green-400"
>
<div className="flex items-center">
<span>{intl.formatMessage(globalMessages.available)}</span>
{inProgress && <Spinner className="w-3 h-3 ml-1" />}
</div>
</Badge>
</a>
);
}
return (
<Badge badgeType="success">
<Badge badgeType="success" url={plexUrl}>
<div className="flex items-center">
<span>{intl.formatMessage(globalMessages.available)}</span>
<span>
{intl.formatMessage(is4k ? messages.status4k : messages.status, {
status: intl.formatMessage(globalMessages.available),
})}
</span>
{inProgress && <Spinner className="w-3 h-3 ml-1" />}
</div>
</Badge>
);
case MediaStatus.PARTIALLY_AVAILABLE:
if (plexUrl) {
return (
<a href={plexUrl} target="_blank" rel="noopener noreferrer">
<Badge
badgeType="success"
className="transition !cursor-pointer hover:bg-green-400"
>
<div className="flex items-center">
<span>
{intl.formatMessage(globalMessages.partiallyavailable)}
</span>
{inProgress && <Spinner className="w-3 h-3 ml-1" />}
</div>
</Badge>
</a>
);
}
case MediaStatus.PARTIALLY_AVAILABLE:
return (
<Badge badgeType="success">
<Badge badgeType="success" url={plexUrl}>
<div className="flex items-center">
<span>{intl.formatMessage(globalMessages.partiallyavailable)}</span>
<span>
{intl.formatMessage(is4k ? messages.status4k : messages.status, {
status: intl.formatMessage(globalMessages.partiallyavailable),
})}
</span>
{inProgress && <Spinner className="w-3 h-3 ml-1" />}
</div>
</Badge>
);
case MediaStatus.PROCESSING:
return (
<Badge badgeType="primary">
<Badge badgeType="primary" url={serviceUrl}>
<div className="flex items-center">
<span>
{inProgress
? intl.formatMessage(globalMessages.processing)
: intl.formatMessage(globalMessages.requested)}
{intl.formatMessage(is4k ? messages.status4k : messages.status, {
status: inProgress
? intl.formatMessage(globalMessages.processing)
: intl.formatMessage(globalMessages.requested),
})}
</span>
{inProgress && <Spinner className="w-3 h-3 ml-1" />}
</div>
</Badge>
);
case MediaStatus.PENDING:
return (
<Badge badgeType="warning">
{intl.formatMessage(globalMessages.pending)}
{intl.formatMessage(is4k ? messages.status4k : messages.status, {
status: intl.formatMessage(globalMessages.pending),
})}
</Badge>
);
default:
return null;
}

@ -177,17 +177,12 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
: 'US';
const seriesAttributes: React.ReactNode[] = [];
if (
data.contentRatings.results.length &&
data.contentRatings.results.find(
(r) => r.iso_3166_1 === region || data.contentRatings.results[0].rating
)
) {
const contentRating = data.contentRatings.results.find(
(r) => r.iso_3166_1 === region
)?.rating;
if (contentRating) {
seriesAttributes.push(
<span className="p-0.5 py-0 border rounded-md">
{data.contentRatings.results.find((r) => r.iso_3166_1 === region)
?.rating || data.contentRatings.results[0].rating}
</span>
<span className="p-0.5 py-0 border rounded-md">{contentRating}</span>
);
}
@ -435,6 +430,11 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
status={data.mediaInfo?.status}
inProgress={(data.mediaInfo?.downloadStatus ?? []).length > 0}
plexUrl={data.mediaInfo?.plexUrl}
serviceUrl={
hasPermission(Permission.ADMIN)
? data.mediaInfo?.serviceUrl
: undefined
}
/>
{settings.currentSettings.series4kEnabled &&
hasPermission([Permission.REQUEST_4K, Permission.REQUEST_4K_TV], {
@ -446,7 +446,12 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
inProgress={
(data.mediaInfo?.downloadStatus4k ?? []).length > 0
}
plexUrl4k={data.mediaInfo?.plexUrl4k}
plexUrl={data.mediaInfo?.plexUrl4k}
serviceUrl={
hasPermission(Permission.ADMIN)
? data.mediaInfo?.serviceUrl4k
: undefined
}
/>
)}
</div>

@ -2,6 +2,8 @@ import React, { ReactNode } from 'react';
export type AvailableLocale =
| 'ca'
| 'cs'
| 'da'
| 'de'
| 'en'
| 'el'
@ -30,6 +32,14 @@ export const availableLanguages: AvailableLanguageObject = {
code: 'ca',
display: 'Català',
},
cs: {
code: 'cs',
display: 'Čeština',
},
da: {
code: 'da',
display: 'Dansk',
},
de: {
code: 'de',
display: 'Deutsch',

@ -666,7 +666,6 @@
"components.Settings.Notifications.smtpHost": "Amfitrió SMTP",
"components.Settings.Notifications.emailsettingsfailed": "No s'ha pogut desar la configuració de les notificacions per correu electrònic.",
"components.Settings.RadarrModal.apiKey": "Clau API",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "Els últims canvis a la branca <code>develop</code> de Overseerr no es mostren a continuació. Vegeu l'historial de pujades d'aquesta branca a <GithubLink>GitHub</GithubLink> per a més detalls.",
"components.Settings.SettingsAbout.Releases.releases": "Versions",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "La informació de la versió no està disponible. GitHub està fora de línia?",
"components.Settings.SettingsAbout.Releases.latestversion": "Última versió",
@ -879,5 +878,6 @@
"components.NotificationTypeSelector.usermediaAutoApprovedDescription": "Rep notificacions quan altres usuaris envien sol·licituds de mitjans nous que saprovin automàticament.",
"components.MovieDetails.showmore": "Mostra més",
"components.MovieDetails.showless": "Mostra menys",
"components.Layout.LanguagePicker.displaylanguage": "Idioma de visualització"
"components.Layout.LanguagePicker.displaylanguage": "Idioma de visualització",
"components.StatusBadge.status": "{status}"
}

@ -0,0 +1,442 @@
{
"components.Settings.notificationsettings": "Nastavení oznámení",
"components.Settings.locale": "Jazyk zobrazení",
"components.Settings.generalsettings": "Obecná nastavení",
"components.Settings.enablessl": "Použít SSL",
"components.Settings.default4k": "Výchozí 4K",
"components.Settings.cancelscan": "Zrušit skenování",
"components.Settings.apikey": "API klíč",
"components.Settings.activeProfile": "Aktivní profil",
"components.Settings.SonarrModal.syncEnabled": "Povolit skenování",
"components.Settings.SonarrModal.ssl": "Použít SSL",
"components.Settings.SonarrModal.servername": "Název serveru",
"components.Settings.SonarrModal.server4k": "4K server",
"components.Settings.SonarrModal.selecttags": "Vyberte značky",
"components.Settings.SonarrModal.seasonfolders": "Složky pro série",
"components.Settings.SonarrModal.rootfolder": "Kořenový adresář",
"components.Settings.SonarrModal.qualityprofile": "Profil kvality",
"components.Settings.SonarrModal.notagoptions": "Žádné značky.",
"components.Settings.SonarrModal.loadingTags": "Načítání značek…",
"components.Settings.SonarrModal.languageprofile": "Jazykový profil",
"components.Settings.SonarrModal.externalUrl": "Externí URL",
"components.Settings.SonarrModal.defaultserver": "Výchozí server",
"components.Settings.SonarrModal.apiKey": "API klíč",
"components.Settings.SonarrModal.animeTags": "Anime značky",
"components.Settings.SonarrModal.add": "Přidat server",
"components.Settings.SettingsUsers.userSettings": "Uživatelské nastavení",
"components.Settings.SettingsUsers.defaultPermissions": "Výchozí oprávnění",
"components.Settings.SettingsJobsCache.unknownJob": "Neznámá úloha",
"components.Settings.SettingsJobsCache.sonarr-scan": "Sonarr Sken",
"components.Settings.SettingsJobsCache.runnow": "Spustit nyní",
"components.Settings.SettingsJobsCache.radarr-scan": "Radarr Sken",
"components.Settings.SettingsJobsCache.jobstarted": "{jobname} zahájeno.",
"components.Settings.SettingsJobsCache.jobname": "Název úlohy",
"components.Settings.SettingsJobsCache.jobcancelled": "{jobname} zrušeno.",
"components.Settings.SettingsJobsCache.flushcache": "Vyprázdnit mezipaměť",
"components.Settings.SettingsJobsCache.canceljob": "Zrušit úlohu",
"components.Settings.SettingsJobsCache.cachevsize": "Velikost hodnoty",
"components.Settings.SettingsJobsCache.cachename": "Název mezipaměti",
"components.Settings.SettingsAbout.totalrequests": "Celkový počet žádostí",
"components.Settings.SettingsAbout.totalmedia": "Celkový počet médií",
"components.Settings.SettingsAbout.timezone": "Časové pásmo",
"components.Settings.SettingsAbout.supportoverseerr": "Podpořte Overseerr",
"components.Settings.SettingsAbout.overseerrinformation": "Overseerr Informace",
"components.Settings.SettingsAbout.githubdiscussions": "Diskuze na GitHubu",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Zobrazit seznam změn",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Seznam změn",
"components.Settings.SettingsAbout.Releases.currentversion": "Aktuální verze",
"components.Settings.RadarrModal.syncEnabled": "Povolit skenování",
"components.Settings.RadarrModal.ssl": "Použít SSL",
"components.Settings.RadarrModal.servername": "Název serveru",
"components.Settings.RadarrModal.server4k": "4K server",
"components.Settings.RadarrModal.selecttags": "Vyberte značky",
"components.Settings.RadarrModal.rootfolder": "Kořenový adresář",
"components.Settings.RadarrModal.qualityprofile": "Profil kvality",
"components.Settings.RadarrModal.notagoptions": "Žádné značky.",
"components.Settings.RadarrModal.minimumAvailability": "Minimální dostupnost",
"components.Settings.RadarrModal.loadingTags": "Načítání značek…",
"components.Settings.RadarrModal.externalUrl": "Externí URL",
"components.Settings.RadarrModal.defaultserver": "Výchozí server",
"components.Settings.RadarrModal.apiKey": "API klíč",
"components.Settings.RadarrModal.add": "Přidat server",
"components.Settings.Notifications.webhookUrl": "Webhook URL",
"components.Settings.Notifications.smtpPort": "SMTP Port",
"components.Settings.Notifications.smtpHost": "SMTP Host",
"components.Settings.Notifications.senderName": "Jméno odesílatele",
"components.Settings.Notifications.sendSilently": "Odeslat potichu",
"components.Settings.Notifications.pgpPassword": "PGP heslo",
"components.Settings.Notifications.encryption": "Metoda šifrování",
"components.Settings.Notifications.emailsender": "Adresa odesílatele",
"components.Settings.Notifications.chatId": "ID chatu",
"components.Settings.Notifications.botUsername": "Jméno bota",
"components.Settings.Notifications.authUser": "SMTP uživatelské jméno",
"components.Settings.Notifications.authPass": "SMTP Heslo",
"components.Settings.Notifications.agentenabled": "Povolit agenta",
"components.Settings.Notifications.NotificationsWebhook.webhookUrl": "Webhook URL",
"components.Settings.Notifications.NotificationsWebhook.customJson": "JSON Payload",
"components.Settings.Notifications.NotificationsWebhook.authheader": "Autorizační hlavička",
"components.Settings.Notifications.NotificationsWebhook.agentenabled": "Povolit agenta",
"components.Settings.Notifications.NotificationsWebPush.agentenabled": "Povolit agenta",
"components.Settings.Notifications.NotificationsSlack.webhookUrl": "Webhook URL",
"components.Settings.Notifications.NotificationsSlack.agentenabled": "Povolit agenta",
"components.Settings.Notifications.NotificationsPushover.agentenabled": "Povolit agenta",
"components.Settings.Notifications.NotificationsPushbullet.agentEnabled": "Povolit agenta",
"components.Settings.Notifications.NotificationsPushbullet.accessToken": "Přístupový token",
"components.Settings.Notifications.NotificationsLunaSea.webhookUrl": "Webhook URL",
"components.Settings.Notifications.NotificationsLunaSea.profileName": "Jméno profilu",
"components.Settings.Notifications.NotificationsLunaSea.agentenabled": "Povolit agenta",
"components.Search.searchresults": "Výsledek vyhledávání",
"components.ResetPassword.passwordreset": "Obnovení hesla",
"components.ResetPassword.email": "E-mailová adresa",
"components.ResetPassword.confirmpassword": "Potvrďte heslo",
"components.RequestModal.selectseason": "Vyberte série",
"components.RequestModal.seasonnumber": "{number} Série",
"components.RequestModal.requesttitle": "Zažádat o {title}",
"components.RequestModal.edit": "Upravit žádost",
"components.RequestModal.cancel": "Zrušit žádost",
"components.RequestModal.autoapproval": "Automatické schválení",
"components.RequestModal.alreadyrequested": "Již vyžádáno",
"components.RequestModal.AdvancedRequester.selecttags": "Vybrat značky",
"components.RequestModal.AdvancedRequester.rootfolder": "Kořenový adresář",
"components.RequestModal.AdvancedRequester.requestas": "Zažádat jako",
"components.RequestModal.AdvancedRequester.qualityprofile": "Profil kvality",
"components.RequestModal.AdvancedRequester.notagoptions": "Žádné značky.",
"components.RequestModal.AdvancedRequester.languageprofile": "Jazykový profil",
"components.RequestModal.AdvancedRequester.folder": "{path} ({space})",
"components.RequestModal.AdvancedRequester.destinationserver": "Cílový server",
"components.RequestModal.AdvancedRequester.default": "{name} (výchozí)",
"components.RequestList.sortModified": "Naposledy změněno",
"components.RequestList.sortAdded": "Datum žádosti",
"components.RequestList.RequestItem.editrequest": "Upravit žádost",
"components.RequestList.RequestItem.deleterequest": "Odstranit žádost",
"components.RequestList.RequestItem.cancelRequest": "Zrušit žádost",
"components.RequestCard.deleterequest": "Odstranit žádost",
"components.RequestButton.viewrequest": "Zobrazit žádost",
"components.RequestButton.requestmore": "Vyžádat více",
"components.RequestButton.declinerequest": "Odmítnout žádost",
"components.RequestButton.approverequest": "Schválit žádost",
"components.RequestBlock.server": "Cílový server",
"components.RequestBlock.rootfolder": "Kořenový adresář",
"components.RequestBlock.requestoverrides": "Přepsání požadavku",
"components.RequestBlock.profilechanged": "Profil kvality",
"components.RegionSelector.regionServerDefault": "Výchozí ({region})",
"components.RegionSelector.regionDefault": "Všechny regiony",
"components.PlexLoginButton.signinwithplex": "Přihlásit se",
"components.PlexLoginButton.signingin": "Přihlašování…",
"components.PersonDetails.birthdate": "Narozen {birthdate}",
"components.PersonDetails.ascharacter": "jako {character}",
"components.PermissionEdit.viewrequests": "Zobrazit žádosti",
"components.PermissionEdit.users": "Spravovat uživatele",
"components.PermissionEdit.settings": "Spravovat nastavení",
"components.PermissionEdit.requestTv": "Žádat seriály",
"components.PermissionEdit.requestMovies": "Žádat filmy",
"components.PermissionEdit.request4k": "Žádosti ve 4K",
"components.PermissionEdit.managerequests": "Spravovat žádosti",
"components.PermissionEdit.autoapproveSeries": "Automaticky schvalovat seriály",
"components.PermissionEdit.autoapproveMovies": "Automaticky schvalovat filmy",
"components.UserProfile.UserSettings.UserNotificationSettings.notifications": "Oznámení",
"components.UserProfile.UserSettings.UserNotificationSettings.email": "E-mail",
"components.UserProfile.UserSettings.UserGeneralSettings.user": "Uživatel",
"components.UserProfile.UserSettings.UserGeneralSettings.role": "Role",
"components.UserProfile.UserSettings.UserGeneralSettings.owner": "Vlastník",
"components.UserProfile.UserSettings.UserGeneralSettings.general": "Obecné",
"components.UserProfile.UserSettings.UserGeneralSettings.admin": "Admin",
"components.UserList.users": "Uživatelé",
"components.UserList.user": "Uživatel",
"components.UserList.totalrequests": "Žádosti",
"components.UserList.role": "Role",
"components.UserList.password": "Heslo",
"components.UserList.owner": "Vlastník",
"components.UserList.lastupdated": "Aktualizováno",
"components.UserList.creating": "Vytváření…",
"components.UserList.created": "Vytvořeno",
"components.UserList.create": "Vytvořit",
"components.UserList.admin": "Admin",
"components.UserList.accounttype": "Typ",
"components.TvDetails.recommendations": "Doporučení",
"components.TvDetails.overview": "Přehled",
"components.TvDetails.manageModalRequests": "Žádosti",
"components.TvDetails.cast": "Obsazení",
"components.TvDetails.anime": "Anime",
"components.StatusChacker.reloadOverseerr": "Znovu načíst",
"components.Setup.tip": "Tip",
"components.Setup.setup": "Konfigurace",
"components.Setup.finishing": "Dokončování…",
"components.Setup.continue": "Pokračovat",
"components.Settings.webhook": "Webhook",
"components.Settings.ssl": "SSL",
"components.Settings.services": "Služby",
"components.Settings.serverpreset": "Server",
"components.Settings.serverSecure": "zabezpečené",
"components.Settings.serverRemote": "vzdálený",
"components.Settings.serverLocal": "místní",
"components.Settings.scanning": "Synchronizace…",
"components.Settings.port": "Port",
"components.Settings.plex": "Plex",
"components.Settings.notifications": "Oznámení",
"components.Settings.menuUsers": "Uživatelé",
"components.Settings.menuServices": "Služby",
"components.Settings.menuPlexSettings": "Plex",
"components.Settings.menuNotifications": "Oznámení",
"components.Settings.menuLogs": "Záznamy",
"components.Settings.menuGeneralSettings": "Obecné",
"components.Settings.menuAbout": "O aplikaci",
"components.Settings.mediaTypeSeries": "seriál",
"components.Settings.mediaTypeMovie": "film",
"components.Settings.is4k": "4K",
"components.Settings.general": "Obecné",
"components.Settings.email": "E-mail",
"components.Settings.default": "Výchozí",
"components.Settings.address": "Adresy",
"components.Settings.SonarrModal.tags": "Značky",
"components.Settings.SonarrModal.port": "Port",
"components.Settings.SettingsUsers.users": "Uživatelé",
"components.Settings.SettingsLogs.time": "Časová značka",
"components.Settings.SettingsLogs.resumeLogs": "Pokračovat",
"components.Settings.SettingsLogs.pauseLogs": "Pauza",
"components.Settings.SettingsLogs.message": "Zpráva",
"components.Settings.SettingsLogs.logs": "Záznamy",
"components.Settings.SettingsLogs.level": "Závažnost",
"components.Settings.SettingsLogs.label": "Štítek",
"components.Settings.SettingsLogs.filterWarn": "Varování",
"components.Settings.SettingsLogs.filterInfo": "Informace",
"components.Settings.SettingsLogs.filterError": "Chyba",
"components.Settings.SettingsLogs.filterDebug": "Ladění",
"components.Settings.SettingsJobsCache.process": "Proces",
"components.Settings.SettingsJobsCache.jobtype": "Typ",
"components.Settings.SettingsJobsCache.jobs": "Úkoly",
"components.Settings.SettingsJobsCache.command": "Příkaz",
"components.Settings.SettingsJobsCache.cachehits": "Úspěchy",
"components.Settings.SettingsJobsCache.cache": "Mezipaměť",
"components.Settings.SettingsAbout.version": "Verze",
"components.Settings.SettingsAbout.preferredmethod": "Preferované",
"components.Settings.SettingsAbout.documentation": "Dokumentace",
"components.Settings.SettingsAbout.about": "O aplikaci",
"components.Settings.SettingsAbout.Releases.releases": "Verze",
"components.Settings.SettingsAbout.Releases.latestversion": "Nejnovější",
"components.Settings.RadarrModal.tags": "Značky",
"components.Settings.RadarrModal.port": "Port",
"components.Settings.Notifications.encryptionNone": "Žádné",
"components.Search.search": "Vyhledat",
"components.ResetPassword.password": "Heslo",
"components.RequestModal.season": "Série",
"components.RequestModal.extras": "Extra",
"components.RequestModal.QuotaDisplay.season": "série",
"components.RequestModal.QuotaDisplay.movie": "film",
"components.RequestModal.AdvancedRequester.tags": "Značky",
"components.RequestModal.AdvancedRequester.advancedoptions": "Pokročilé",
"components.RequestList.requests": "Žádosti",
"components.RequestList.RequestItem.requesteddate": "Zažádáno",
"components.RequestList.RequestItem.requested": "Zažádáno",
"components.RequestList.RequestItem.modified": "Upraveno",
"components.QuotaSelector.unlimited": "Neomezené",
"components.PersonDetails.crewmember": "Další profese",
"components.PersonDetails.appearsin": "Vystoupení",
"components.PermissionEdit.request": "Zažádat",
"components.PermissionEdit.autoapprove4kSeries": "Automatické schválení 4K seriálů",
"components.NotificationTypeSelector.usermediaapprovedDescription": "Získat upozornění na schválení vašich žádostí o média.",
"components.NotificationTypeSelector.usermediaAutoApprovedDescription": "Získat upozornění, když ostatní uživatelé zadají nové požadavky na média, která jsou automaticky schválena.",
"components.NotificationTypeSelector.mediarequestedDescription": "Odeslat oznámení, když uživatelé zažádají o média vyžadující schválení.",
"components.MovieDetails.streamingproviders": "Aktuálně streamovatelné zde",
"pages.serviceunavailable": "Služba není k dispozici",
"pages.returnHome": "Vrátit se domů",
"pages.pagenotfound": "Stránka nebyla nalezena",
"pages.oops": "Jejda",
"pages.internalservererror": "Interní chyba serveru",
"pages.errormessagewithcode": "{statusCode} - {error}",
"i18n.view": "Zobrazit",
"i18n.usersettings": "Uživatelské nastavení",
"i18n.unavailable": "Nedostupné",
"i18n.tvshows": "Seriály",
"i18n.tvshow": "Seriál",
"i18n.testing": "Testuji…",
"i18n.test": "Otestovat",
"i18n.status": "Stav",
"i18n.showingresults": "Zobrazuji <strong>{from}</strong> do <strong>{to}</strong> <strong>{total}</strong> výsledky",
"i18n.settings": "Nastavení",
"i18n.saving": "Ukládání…",
"i18n.save": "Uložit změny",
"i18n.retrying": "Opakování…",
"i18n.retry": "Opakovat",
"i18n.resultsperpage": "Zobrazit {pageSize} výsledků na stránku",
"i18n.requesting": "Zažádáno…",
"i18n.requested": "Zažádáno",
"i18n.request4k": "Zažádat ve 4K",
"i18n.request": "Zažádat",
"i18n.processing": "Zpracovává se",
"i18n.previous": "Předchozí",
"i18n.pending": "Čekající",
"i18n.partiallyavailable": "Částečně k dispozici",
"i18n.notrequested": "Nebylo zažádáno",
"i18n.noresults": "Žádné výsledky.",
"i18n.next": "Další",
"i18n.movies": "Filmy",
"i18n.movie": "Film",
"i18n.loading": "Načítání…",
"i18n.failed": "Selhalo",
"i18n.experimental": "Experimentální",
"i18n.edit": "Upravit",
"i18n.delimitedlist": "{a}, {b}",
"i18n.deleting": "Odstraňování…",
"i18n.delete": "Odstranit",
"i18n.declined": "Odmítnuto",
"i18n.decline": "Odmítnout",
"i18n.close": "Zavřít",
"i18n.canceling": "Rušení…",
"i18n.cancel": "Zrušit",
"i18n.back": "Zpět",
"i18n.available": "K dispozici",
"i18n.areyousure": "Jste si jistý?",
"i18n.approved": "Schváleno",
"i18n.approve": "Schválit",
"i18n.all": "Vše",
"i18n.advanced": "Pokročilé",
"components.UserProfile.unlimited": "Neomezené",
"components.UserProfile.totalrequests": "Celkový počet žádostí",
"components.UserProfile.seriesrequest": "Seriál zažádán",
"components.UserProfile.requestsperdays": "Zbývá {limit}",
"components.UserProfile.recentrequests": "Nedávné žádosti",
"components.UserProfile.norequests": "Žádné žádosti.",
"components.UserProfile.UserSettings.menuPermissions": "Oprávnění",
"components.UserProfile.UserSettings.menuNotifications": "Oznámení",
"components.UserProfile.UserSettings.menuGeneralSettings": "Obecné",
"components.UserProfile.UserSettings.menuChangePass": "Heslo",
"components.UserProfile.UserSettings.UserPermissions.unauthorizedDescription": "Vlastní oprávnění nelze upravovat.",
"components.UserProfile.UserSettings.UserPermissions.toastSettingsSuccess": "Oprávnění byla úspěšně uložena!",
"components.UserProfile.UserSettings.UserPermissions.toastSettingsFailure": "Při ukládání nastavení se něco pokazilo.",
"components.UserProfile.UserSettings.UserPermissions.permissions": "Oprávnění",
"components.UserProfile.UserSettings.UserPasswordChange.validationNewPasswordLength": "Heslo je příliš krátké; mělo by mít minimálně 8 znaků",
"components.UserProfile.UserSettings.UserPasswordChange.validationNewPassword": "Musíte zadat nové heslo",
"components.UserProfile.UserSettings.UserPasswordChange.validationCurrentPassword": "Musíte zadat své aktuální heslo",
"components.UserProfile.UserSettings.UserPasswordChange.validationConfirmPasswordSame": "Hesla se musí shodovat",
"components.UserProfile.UserSettings.UserPasswordChange.validationConfirmPassword": "Musíte potvrdit nové heslo",
"components.UserProfile.UserSettings.UserPasswordChange.toastSettingsSuccess": "Heslo úspěšně uloženo!",
"components.UserProfile.UserSettings.UserPasswordChange.toastSettingsFailureVerifyCurrent": "Při ukládání hesla se něco pokazilo. Bylo vaše aktuální heslo zadáno správně?",
"components.UserProfile.UserSettings.UserPasswordChange.toastSettingsFailure": "Při ukládání hesla se něco pokazilo.",
"components.UserProfile.UserSettings.UserPasswordChange.password": "Heslo",
"pages.somethingwentwrong": "Něco se pokazilo",
"components.PermissionEdit.autoapprove4kMovies": "Automatické schvalování 4K filmů",
"components.PermissionEdit.autoapprove4k": "Automatické schválení 4K",
"components.PermissionEdit.autoapprove": "Automatické schválení",
"components.PermissionEdit.advancedrequest": "Pokročilé žádosti",
"components.PermissionEdit.admin": "Admin",
"components.NotificationTypeSelector.notificationTypes": "Typy oznámení",
"components.NotificationTypeSelector.mediarequested": "Médium zažádáno",
"components.NotificationTypeSelector.mediafailedDescription": "Odeslat oznámení, když se nepodaří přidat požadavky na média do Radarru nebo Sonarru.",
"components.NotificationTypeSelector.mediafailed": "Médium selhalo",
"components.NotificationTypeSelector.mediadeclinedDescription": "Odeslat oznámení, pokud jsou požadavky na média odmítnuty.",
"components.NotificationTypeSelector.mediadeclined": "Médium odmítnuto",
"components.NotificationTypeSelector.mediaavailableDescription": "Odeslat oznámení, jakmile budou k dispozici žádosti o média.",
"components.NotificationTypeSelector.mediaavailable": "Médium je k dispozici",
"components.NotificationTypeSelector.mediaapprovedDescription": "Odeslat oznámení, když jsou požadavky na média ručně schváleny.",
"components.NotificationTypeSelector.mediaapproved": "Médium schváleno",
"components.NotificationTypeSelector.mediaAutoApprovedDescription": "Odeslat oznámení, když uživatelé zadají nové požadavky na média, která jsou automaticky schválena.",
"components.NotificationTypeSelector.mediaAutoApproved": "Médium automaticky schváleno",
"components.MovieDetails.watchtrailer": "Sledovat trailer",
"components.MovieDetails.viewfullcrew": "Zobrazit kompletní štáb",
"components.MovieDetails.similar": "Podobné tituly",
"components.MovieDetails.showmore": "Zobrazit více",
"components.MovieDetails.showless": "Zobrazit méně",
"components.MovieDetails.runtime": "{minutes} minut",
"components.MovieDetails.revenue": "Výnos",
"components.MovieDetails.releasedate": "Datum vydání",
"components.MovieDetails.recommendations": "Doporučení",
"components.MovieDetails.playonplex": "Přehrát v Plexu",
"components.MovieDetails.play4konplex": "Přehrát v Plexu ve 4K",
"components.MovieDetails.overviewunavailable": "Přehled není k dispozici.",
"components.MovieDetails.overview": "Přehled",
"components.MovieDetails.originaltitle": "Původní název",
"components.MovieDetails.originallanguage": "Původní jazyk",
"components.MovieDetails.openradarr4k": "Otevřít film ve 4K Radarru",
"components.MovieDetails.openradarr": "Otevřít film v Radarru",
"components.MovieDetails.markavailable": "Označit jako dostupné",
"components.MovieDetails.mark4kavailable": "Označit jako dostupné ve 4K",
"components.MovieDetails.manageModalTitle": "Spravovat film",
"components.MovieDetails.manageModalRequests": "Žádosti",
"components.MovieDetails.manageModalNoRequests": "Žádné žádosti.",
"components.MovieDetails.manageModalClearMediaWarning": "* Tímto nevratně odstraníte všechna data pro tento film, včetně všech požadavků. Pokud tato položka v knihovně Plex existuje, budou informace o médiu znovu vytvořeny při příštím skenování.",
"components.MovieDetails.manageModalClearMedia": "Vymazat data médií",
"components.MovieDetails.downloadstatus": "Stav stahování",
"components.MovieDetails.cast": "Obsazení",
"components.MovieDetails.budget": "Rozpočet",
"components.MovieDetails.MovieCast.fullcast": "Kompletní obsazení",
"components.MovieDetails.MovieCrew.fullcrew": "Kompletní štáb",
"components.MediaSlider.ShowMoreCard.seemore": "Zobrazit více",
"components.Login.validationpasswordrequired": "Musíte zadat heslo",
"components.Login.validationemailrequired": "Musíte zadat platnou e-mailovou adresu",
"components.Login.signinwithplex": "Použijte svůj Plex účet",
"components.Login.signinwithoverseerr": "Použijte svůj {applicationTitle} účet",
"components.Login.signinheader": "Pro pokračování se přihlaste",
"components.Login.signingin": "Přihlašování…",
"components.Login.signin": "Přihlásit se",
"components.Login.password": "Heslo",
"components.Login.loginerror": "Při pokusu o přihlášení se něco pokazilo.",
"components.Login.forgotpassword": "Zapomenuté heslo?",
"components.Login.email": "E-mailová adresa",
"components.Layout.VersionStatus.streamstable": "Overseerr Stabilní",
"components.Layout.VersionStatus.streamdevelop": "Overseerr Vývoj",
"components.Layout.VersionStatus.outofdate": "Zastaralý",
"components.Layout.UserDropdown.signout": "Odhlásit se",
"components.Layout.UserDropdown.settings": "Nastavení",
"components.Layout.UserDropdown.myprofile": "Profil",
"components.Layout.Sidebar.users": "Uživatelé",
"components.Layout.Sidebar.settings": "Nastavení",
"components.Layout.Sidebar.requests": "Žádosti",
"components.Layout.Sidebar.dashboard": "Objevit",
"components.Layout.SearchInput.searchPlaceholder": "Vyhledat Filmy a Seriály",
"components.Layout.LanguagePicker.displaylanguage": "Jazyk zobrazení",
"components.LanguageSelector.originalLanguageDefault": "Všechny jazyky",
"components.LanguageSelector.languageServerDefault": "Výchozí ({language})",
"components.DownloadBlock.estimatedtime": "Odhadovaný {time}",
"components.Discover.upcomingtv": "Nadcházející Seriály",
"components.Discover.upcomingmovies": "Nadcházející filmy",
"components.Discover.upcoming": "Nadcházející filmy",
"components.Discover.trending": "Populární",
"components.Discover.recentrequests": "Nedávné žádosti",
"components.Discover.recentlyAdded": "Nedávno přidané",
"components.Discover.populartv": "Populární Seriály",
"components.Discover.discovertv": "Populární Seriály",
"components.Discover.DiscoverTvLanguage.languageSeries": "{language} Seriály",
"components.Discover.DiscoverTvGenre.genreSeries": "{genre} Seriály",
"components.Discover.DiscoverNetwork.networkSeries": "{network} Seriály",
"components.Discover.popularmovies": "Populární filmy",
"components.Discover.noRequests": "Žádné požadavky.",
"components.Discover.discovermovies": "Populární filmy",
"components.Discover.discover": "Objevte",
"components.Discover.TvGenreSlider.tvgenres": "Žánry seriálů",
"components.Discover.TvGenreList.seriesgenres": "Žánry seriálů",
"components.Discover.StudioSlider.studios": "Studia",
"components.Discover.NetworkSlider.networks": "TV sítě",
"components.Discover.MovieGenreSlider.moviegenres": "Filmové žánry",
"components.Discover.MovieGenreList.moviegenres": "Filmové žánry",
"components.CollectionDetails.numberofmovies": "{count} Filmů",
"components.AppDataWarning.dockerVolumeMissingDescription": "Připojení svazku <code>{appDataPath}</code> nebylo správně nakonfigurováno. Všechna data budou vymazána při zastavení nebo opětovném spuštění kontejneru.",
"components.CollectionDetails.requestSuccess": "<strong> {title} </strong> úspěšně požádáno!",
"components.Discover.DiscoverStudio.studioMovies": "{studio} Filmy",
"components.Discover.DiscoverMovieLanguage.languageMovies": "{language} Filmy",
"components.Discover.DiscoverMovieGenre.genreMovies": "{genre} Filmy",
"components.CollectionDetails.requestswillbecreated4k": "Pro následující tituly budou vytvořeny požadavky ve 4K:",
"components.CollectionDetails.requestswillbecreated": "Pro následující tituly budou vytvořeny požadavky:",
"components.CollectionDetails.requestcollection4k": "Požádat o kolekci ve 4K",
"components.CollectionDetails.requestcollection": "Požádat o kolekci",
"components.CollectionDetails.overview": "Přehled",
"components.Settings.SettingsJobsCache.cachemisses": "Neúspěchy",
"components.NotificationTypeSelector.usermediadeclinedDescription": "Dostat oznámení o odmítnutí vašich požadavků na média.",
"components.NotificationTypeSelector.usermediaavailableDescription": "Dostat oznámení, jakmile budou k dispozici žádosti o média.",
"components.Layout.VersionStatus.commitsbehind": "{commitsBehind} {commitsBehind, plural, one {commit} other {commits}} za",
"components.Setup.configureplex": "Konfigurovat Plex",
"components.Settings.serverpresetRefreshing": "Načítání serverů…",
"components.Settings.applicationTitle": "Název aplikace",
"components.Settings.originallanguage": "Jazyk pro vyhledávání",
"components.Settings.plexsettings": "Nastavení Plexu",
"components.Settings.scan": "Synchronizovat knihovny",
"components.Settings.plexlibraries": "Plex knihovny",
"components.Settings.applicationurl": "Adresa URL aplikace",
"components.Settings.notrunning": "Není spuštěno",
"components.Settings.radarrsettings": "Nastavení Radarru",
"components.Settings.region": "Region pro vyhledávání",
"components.Settings.startscan": "Spustit skenování",
"components.Settings.serverpresetManualMessage": "Manuální konfigurace",
"components.Settings.sonarrsettings": "Nastavení Sonarru",
"components.StatusBadge.status": "{status}"
}

@ -0,0 +1,52 @@
{
"components.CollectionDetails.requestSuccess": "Dit ønske er accepteret!",
"components.Discover.discovermovies": "Populære Film",
"components.MediaSlider.ShowMoreCard.seemore": "Se Mere",
"components.Login.validationpasswordrequired": "Angiv et kodeord",
"components.Login.validationemailrequired": "Angiv en gyldig email adresse",
"components.Login.signinwithplex": "Brug din Plex Konto",
"components.Login.signinheader": "Log ind for at forsætte",
"components.Login.signingin": "Logger ind…",
"components.Login.signin": "Log ind",
"components.Login.password": "Kodeord",
"components.Login.loginerror": "Noget gik galt, i dit forsøg på at logge ind.",
"components.Login.forgotpassword": "Glemt kodeord?",
"components.Login.email": "Email Adresse",
"components.Layout.VersionStatus.streamdevelop": "Overseerr Udvikler",
"components.Layout.VersionStatus.outofdate": "Forældet",
"components.Layout.UserDropdown.signout": "Log ud",
"components.Layout.UserDropdown.settings": "Indstillinger",
"components.Layout.UserDropdown.myprofile": "Profil",
"components.Layout.Sidebar.users": "Brugere",
"components.Layout.Sidebar.settings": "Indstillinger",
"components.Layout.Sidebar.requests": "Ønsker",
"components.Layout.Sidebar.dashboard": "Udforsk",
"components.Layout.SearchInput.searchPlaceholder": "Søg Film & Serier",
"components.Layout.LanguagePicker.displaylanguage": "Vis Sprog",
"components.LanguageSelector.originalLanguageDefault": "Alle Sprog",
"components.LanguageSelector.languageServerDefault": "Standard ({sprog})",
"components.Discover.upcomingtv": "Kommende Serier",
"components.Discover.upcomingmovies": "Kommende Film",
"components.Discover.upcoming": "Kommende Film",
"components.Discover.trending": "Aktuelle",
"components.Discover.recentrequests": "Seneste Ønsker",
"components.Discover.recentlyAdded": "Nyligt tilføjet",
"components.Discover.populartv": "Populære Serier",
"components.Discover.popularmovies": "Populære Film",
"components.Discover.noRequests": "Ingen ønsker.",
"components.Discover.discovertv": "Populære Serier",
"components.Discover.discover": "Udforsk",
"components.Discover.TvGenreSlider.tvgenres": "Serie Genre",
"components.Discover.TvGenreList.seriesgenres": "Serie Genre",
"components.Discover.NetworkSlider.networks": "Netværk",
"components.Discover.MovieGenreSlider.moviegenres": "Film Genre",
"components.Discover.MovieGenreList.moviegenres": "Film Genre",
"components.Discover.DiscoverStudio.studioMovies": "{studio} Film",
"components.Discover.DiscoverNetwork.networkSeries": "{netværk} Serier",
"components.Discover.DiscoverMovieLanguage.languageMovies": "{sprog} Film",
"components.Discover.DiscoverMovieGenre.genreMovies": "{genre} Film",
"components.CollectionDetails.requestcollection4k": "Ønskesamling i 4k",
"components.CollectionDetails.requestcollection": "Ønskesamling",
"components.CollectionDetails.overview": "Overblik",
"components.StatusBadge.status": "{status}"
}

@ -25,7 +25,7 @@
"components.MovieDetails.overview": "Übersicht",
"components.MovieDetails.overviewunavailable": "Übersicht nicht verfügbar.",
"components.MovieDetails.recommendations": "Empfehlungen",
"components.MovieDetails.releasedate": "Erscheinungsdatum",
"components.MovieDetails.releasedate": "{releaseCount, plural, one {Erscheinungsdatum} other {Erscheinungsdaten}}",
"components.MovieDetails.revenue": "Einnahmen",
"components.MovieDetails.runtime": "{minutes} Minuten",
"components.MovieDetails.similar": "Ähnliche Titel",
@ -229,7 +229,6 @@
"components.Settings.SettingsAbout.Releases.viewongithub": "Auf GitHub anzeigen",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Änderungsprotokoll anzeigen",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Änderungsprotokoll",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "Die neuesten Änderungen am <code>Entwicklungszweig</code> von Overseerr werden unten nicht angezeigt. Weitere Informationen findest du im Commit-Verlauf für diesen Zweig auf <GithubLink>GitHub</GithubLink>.",
"components.Settings.SettingsAbout.Releases.releases": "Veröffentlichungen",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Informationen der Version nicht verfügbar. Ist GitHub offline?",
"components.Settings.SettingsAbout.Releases.latestversion": "Neuste",
@ -879,5 +878,8 @@
"components.Layout.LanguagePicker.displaylanguage": "Sprache darstellen",
"components.Settings.SettingsAbout.betawarning": "Dies ist eine BETA Software. Einige Funktionen könnten nicht funktionieren oder nicht stabil funktionieren. Bitte auf GitHub alle Fehler melden!",
"components.MovieDetails.showless": "Weniger Anzeigen",
"components.MovieDetails.showmore": "Mehr Anzeigen"
"components.MovieDetails.showmore": "Mehr Anzeigen",
"components.MovieDetails.streamingproviders": "Streamt derzeit auf",
"components.TvDetails.streamingproviders": "Streamt derzeit auf",
"components.StatusBadge.status": "{status}"
}

@ -406,7 +406,6 @@
"components.Settings.SettingsJobsCache.cacheDescription": "Το Overseerr αποθηκεύει προσωρινά αιτήματα σε εξωτερικά τελικά σημεία API για τη βελτιστοποίηση της απόδοσης και την αποφυγή περιττών κλήσεων API.",
"components.Settings.SettingsJobsCache.cache": "Κρυφή μνήμη",
"components.Settings.SettingsAbout.version": "Έκδοση",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "Οι τελευταίες αλλαγές στο <code>develop</code> branch του Overseerr δεν φαίνονται παρακάτω. Παρακαλώ ανάτρεξε στο ιστορικό δευσμεύσεων του branch στο <GithubLink>GitHub</GithubLink> για λεπτομέρειες.",
"components.Settings.SettingsAbout.Releases.releases": "Εκδόσεις",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Οι εκδόσεις λογισμικού δεν είναι διαθέσιμες. Μήπως έχει πέσει το GitHub;",
"components.Settings.SettingsAbout.Releases.latestversion": "Πιο πρόσφατη",
@ -854,5 +853,6 @@
"i18n.test": "Δοκιμή",
"i18n.status": "Κατάσταση",
"i18n.showingresults": "Εμφάνιση <strong>{from}</strong> έως <strong>{to}</strong> από <strong>{total}</strong> αποτελέσματα",
"components.Settings.SettingsAbout.betawarning": "Αυτό είναι λογισμικό BETA. Οι λειτουργίες ενδέχεται να είναι σπασμένες ή/και ασταθείς. Παρακαλώ αναφέρετε τυχόν προβλήματα με το GitHub!"
"components.Settings.SettingsAbout.betawarning": "Αυτό είναι λογισμικό BETA. Οι λειτουργίες ενδέχεται να είναι σπασμένες ή/και ασταθείς. Παρακαλώ αναφέρετε τυχόν προβλήματα με το GitHub!",
"components.StatusBadge.status": "{status}"
}

@ -80,7 +80,7 @@
"components.MovieDetails.play4konplex": "Play in 4K on Plex",
"components.MovieDetails.playonplex": "Play on Plex",
"components.MovieDetails.recommendations": "Recommendations",
"components.MovieDetails.releasedate": "Release Date",
"components.MovieDetails.releasedate": "{releaseCount, plural, one {Release Date} other {Release Dates}}",
"components.MovieDetails.revenue": "Revenue",
"components.MovieDetails.runtime": "{minutes} minutes",
"components.MovieDetails.showless": "Show Less",
@ -426,12 +426,11 @@
"components.Settings.RadarrModal.validationPortRequired": "You must provide a valid port number",
"components.Settings.RadarrModal.validationProfileRequired": "You must select a quality profile",
"components.Settings.RadarrModal.validationRootFolderRequired": "You must select a root folder",
"components.Settings.SettingsAbout.Releases.currentversion": "Current Version",
"components.Settings.SettingsAbout.Releases.currentversion": "Current",
"components.Settings.SettingsAbout.Releases.latestversion": "Latest",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Release data unavailable. Is GitHub down?",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Release data is currently unavailable.",
"components.Settings.SettingsAbout.Releases.releases": "Releases",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "The latest changes to the <code>develop</code> branch of Overseerr are not shown below. Please see the commit history for this branch on <GithubLink>GitHub</GithubLink> for details.",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Version Changelog",
"components.Settings.SettingsAbout.Releases.versionChangelog": "{version} Changelog",
"components.Settings.SettingsAbout.Releases.viewchangelog": "View Changelog",
"components.Settings.SettingsAbout.Releases.viewongithub": "View on GitHub",
"components.Settings.SettingsAbout.about": "About",
@ -441,8 +440,9 @@
"components.Settings.SettingsAbout.githubdiscussions": "GitHub Discussions",
"components.Settings.SettingsAbout.helppaycoffee": "Help Pay for Coffee",
"components.Settings.SettingsAbout.outofdate": "Out of Date",
"components.Settings.SettingsAbout.overseerrinformation": "Overseerr Information",
"components.Settings.SettingsAbout.overseerrinformation": "About Overseerr",
"components.Settings.SettingsAbout.preferredmethod": "Preferred",
"components.Settings.SettingsAbout.runningDevelop": "You are running the <code>develop</code> branch of Overseerr, which is only recommended for those contributing to development or assisting with bleeding-edge testing.",
"components.Settings.SettingsAbout.supportoverseerr": "Support Overseerr",
"components.Settings.SettingsAbout.timezone": "Time Zone",
"components.Settings.SettingsAbout.totalmedia": "Total Media",
@ -462,7 +462,13 @@
"components.Settings.SettingsJobsCache.command": "Command",
"components.Settings.SettingsJobsCache.download-sync": "Download Sync",
"components.Settings.SettingsJobsCache.download-sync-reset": "Download Sync Reset",
"components.Settings.SettingsJobsCache.editJobSchedule": "Modify Job",
"components.Settings.SettingsJobsCache.editJobSchedulePrompt": "Frequency",
"components.Settings.SettingsJobsCache.editJobScheduleSelectorHours": "Every {jobScheduleHours, plural, one {hour} other {{jobScheduleHours} hours}}",
"components.Settings.SettingsJobsCache.editJobScheduleSelectorMinutes": "Every {jobScheduleMinutes, plural, one {minute} other {{jobScheduleMinutes} minutes}}",
"components.Settings.SettingsJobsCache.flushcache": "Flush Cache",
"components.Settings.SettingsJobsCache.jobScheduleEditFailed": "Something went wrong while saving the job.",
"components.Settings.SettingsJobsCache.jobScheduleEditSaved": "Job edited successfully!",
"components.Settings.SettingsJobsCache.jobcancelled": "{jobname} canceled.",
"components.Settings.SettingsJobsCache.jobname": "Job Name",
"components.Settings.SettingsJobsCache.jobs": "Jobs",
@ -667,6 +673,7 @@
"components.Setup.signinMessage": "Get started by signing in with your Plex account",
"components.Setup.tip": "Tip",
"components.Setup.welcome": "Welcome to Overseerr",
"components.StatusBadge.status": "{status}",
"components.StatusBadge.status4k": "4K {status}",
"components.StatusChacker.newversionDescription": "Overseerr has been updated! Please click the button below to reload the page.",
"components.StatusChacker.newversionavailable": "Application Update",

@ -1,5 +1,5 @@
{
"components.Settings.SonarrModal.ssl": "Habilitar SSL",
"components.Settings.SonarrModal.ssl": "Usar SSL",
"components.Settings.SonarrModal.servername": "Nombre del Servidor",
"components.Settings.SonarrModal.server4k": "Servidor 4K",
"components.Settings.SonarrModal.selectRootFolder": "Selecciona la carpeta raíz",
@ -29,7 +29,7 @@
"components.Settings.RadarrModal.validationApiKeyRequired": "Debes proporcionar la clave API",
"components.Settings.RadarrModal.toastRadarrTestSuccess": "¡Conexión con Radarr establecida con éxito!",
"components.Settings.RadarrModal.toastRadarrTestFailure": "Error al connectar al Radarr.",
"components.Settings.RadarrModal.ssl": "Habilitar SSL",
"components.Settings.RadarrModal.ssl": "Usar SSL",
"components.Settings.RadarrModal.servername": "Nombre del Servidor",
"components.Settings.RadarrModal.server4k": "Servidor 4K",
"components.Settings.RadarrModal.selectRootFolder": "Selecciona la carpeta raíz",
@ -82,7 +82,7 @@
"components.MovieDetails.similar": "Títulos Similares",
"components.MovieDetails.runtime": "{minutes} minutos",
"components.MovieDetails.revenue": "Recaudado",
"components.MovieDetails.releasedate": "Fecha de Lanzamiento",
"components.MovieDetails.releasedate": "{releaseCount, plural, one {Fecha} other {Fechas}} de Lanzamiento",
"components.MovieDetails.cast": "Reparto",
"components.MovieDetails.MovieCast.fullcast": "Reparto Completo",
"components.MovieDetails.recommendations": "Recomendaciones",
@ -138,10 +138,10 @@
"i18n.approve": "Aprobar",
"components.UserList.userlist": "Lista de usuarios",
"components.UserList.user": "Usuario",
"components.UserList.totalrequests": "Solicitudes totales",
"components.UserList.totalrequests": "Solicitudes",
"components.UserList.role": "Rol",
"components.UserList.plexuser": "Usuario de Plex",
"components.UserList.lastupdated": "Última actualización",
"components.UserList.lastupdated": "Actualizado",
"components.UserList.created": "Creado",
"components.UserList.admin": "Administrador",
"components.TvDetails.similar": "Series Similares",
@ -228,7 +228,6 @@
"components.Settings.SettingsAbout.Releases.viewongithub": "Ver en GitHub",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Ver registro de cambios",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Cambios de la versión",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "Los últimos cambios de la rama de <code>desarrollo</code> de Overserr no se muestran a continuación. Por favor, consulta la historia de subidas de esta rama en <GithubLink>GitHub </GithubLink> para obtener los detalles.",
"components.Settings.SettingsAbout.Releases.releases": "Versiones",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Información de la versión no disponible. ¿GitHub está caído?",
"components.Settings.SettingsAbout.Releases.latestversion": "Última Versión",
@ -259,33 +258,33 @@
"components.Settings.Notifications.NotificationsSlack.agentenabled": "Habilitar Agente",
"components.RequestList.RequestItem.failedretry": "Algo salió mal al reintentar la solicitud.",
"components.MovieDetails.watchtrailer": "Ver Trailer",
"components.NotificationTypeSelector.mediarequestedDescription": "Envía una notificación cuando se solicitan medios que requieren ser aprobados.",
"components.NotificationTypeSelector.mediarequestedDescription": "Envía notificaciones cuando los usuarios soliciten contenidos que requieran ser aprobados.",
"components.StatusChacker.reloadOverseerr": "Recargar",
"components.StatusChacker.newversionavailable": "Actualización de Aplicación",
"components.StatusChacker.newversionDescription": "¡Overseerr se ha actualizado!Haga clic en el botón de abajo para volver a cargar la aplicación.",
"components.Settings.SettingsAbout.documentation": "Documentación",
"components.Settings.Notifications.validationChatIdRequired": "Debes proporcionar un ID de chat válido",
"components.Settings.Notifications.validationBotAPIRequired": "Debes proporcionar un token de autenticación del bot",
"components.Settings.Notifications.validationBotAPIRequired": "Debes proporcionar un token de autorización del bot",
"components.Settings.Notifications.telegramsettingssaved": "¡Se han guardado los ajustes de notificación de Telegram con éxito!",
"components.Settings.Notifications.telegramsettingsfailed": "La configuración de notificaciones de Telegram no se pudo guardar.",
"components.Settings.Notifications.senderName": "Nombre del remitente",
"components.Settings.Notifications.chatId": "ID de chat",
"components.Settings.Notifications.botAPI": "Token de Autenticación del Bot",
"components.Settings.Notifications.botAPI": "Token de Autorización del Bot",
"components.NotificationTypeSelector.mediarequested": "Contenido Solicitado",
"components.NotificationTypeSelector.mediafailedDescription": "Envía una notificación cuando los medios no se agregan a los servicios (Radarr / Sonarr).",
"components.NotificationTypeSelector.mediafailedDescription": "Envía notificaciones cuando los contenidos solicitados fallen al agregarse a Radarr o Sonarr.",
"components.NotificationTypeSelector.mediafailed": "Contenido Fallido",
"components.NotificationTypeSelector.mediaavailableDescription": "Envía una notificación cuando los medios solicitados están disponibles.",
"components.NotificationTypeSelector.mediaavailableDescription": "Envía notificaciones cuando las peticiones realizadas están disponibles.",
"components.NotificationTypeSelector.mediaavailable": "Contenido Disponible",
"components.NotificationTypeSelector.mediaapprovedDescription": "Envía una notificación cuando los medios pedidos son aprobados manualmente.",
"components.NotificationTypeSelector.mediaapprovedDescription": "Envía notificaciones cuando los medios solicitados son aprobados manualmente.",
"components.NotificationTypeSelector.mediaapproved": "Contenido Aprobado",
"i18n.request": "Solicitar",
"components.Settings.Notifications.NotificationsPushover.validationUserTokenRequired": "Debes proporcionar una clave de usuario válida",
"components.Settings.Notifications.NotificationsPushover.validationUserTokenRequired": "Debes proporcionar una clave de usuario o grupo válida",
"components.Settings.Notifications.NotificationsPushover.validationAccessTokenRequired": "Debes proporcionar un token de aplicación válido",
"components.Settings.Notifications.NotificationsPushover.userToken": "Clave de usuario o grupo",
"components.Settings.Notifications.NotificationsPushover.pushoversettingssaved": "¡Se han guardado los ajustes de notificación de Pushover!",
"components.Settings.Notifications.NotificationsPushover.pushoversettingsfailed": "No se pudo guardar la configuración de notificaciones de Pushover.",
"components.Settings.Notifications.NotificationsPushover.agentenabled": "Agente habilitado",
"components.Settings.Notifications.NotificationsPushover.accessToken": "Token de aplicación/API",
"components.Settings.Notifications.NotificationsPushover.accessToken": "Token de aplicación API",
"components.RequestList.sortModified": "Última modificación",
"components.RequestList.sortAdded": "Fecha de solicitud",
"components.RequestList.showallrequests": "Mostrar todas las solicitudes",
@ -294,7 +293,7 @@
"components.UserList.validationpasswordminchars": "La contraseña es demasiado corta; debe tener 8 caracteres como mínimo",
"components.UserList.usercreatedsuccess": "¡Usuario creado con éxito!",
"components.UserList.usercreatedfailed": "Algo salió mal al intentar crear al usuario.",
"components.UserList.passwordinfodescription": "Habilita las notificaciones por email para poder utilizar las contraseñas generadas automáticamente.",
"components.UserList.passwordinfodescription": "Configura una URL de aplicación y habilita las notificaciones por email para poder utilizar las contraseñas generadas automáticamente.",
"components.UserList.password": "Contraseña",
"components.UserList.localuser": "Usuario local",
"components.UserList.email": "Dirección de correo electrónico",
@ -323,7 +322,7 @@
"components.RequestModal.AdvancedRequester.destinationserver": "Servidor de destino",
"components.RequestModal.AdvancedRequester.default": "{name} (Predeterminado)",
"components.RequestModal.AdvancedRequester.animenote": "* Esta serie es un anime.",
"components.RequestModal.AdvancedRequester.advancedoptions": "Opciones avanzadas",
"components.RequestModal.AdvancedRequester.advancedoptions": "Avanzadas",
"components.RequestButton.viewrequest4k": "Ver Petición 4K",
"components.RequestButton.viewrequest": "Ver Petición",
"components.RequestButton.requestmore4k": "Solicitar más en 4K",
@ -348,7 +347,7 @@
"components.Login.email": "Dirección de correo electrónico",
"components.NotificationTypeSelector.mediadeclined": "Contenido Rechazado",
"components.RequestModal.autoapproval": "Aprobación Automática",
"components.NotificationTypeSelector.mediadeclinedDescription": "Envía una notificación cuando una solicitud es rechazada.",
"components.NotificationTypeSelector.mediadeclinedDescription": "Envía notificaciones cuando las peticiones sean rechazadas.",
"i18n.experimental": "Experimental",
"components.Settings.hideAvailable": "Ocultar los Medios Disponibles",
"components.Login.signingin": "Iniciando sesión…",
@ -413,7 +412,7 @@
"components.PermissionEdit.advancedrequestDescription": "Concede permisos para configurar opciones avanzadas en las peticiones.",
"components.PermissionEdit.advancedrequest": "Peticiones Avanzadas",
"components.PermissionEdit.adminDescription": "Acceso completo de administrador. Ignora otras comprobaciones de permisos.",
"components.NotificationTypeSelector.mediaAutoApprovedDescription": "Envía una notificación cuando el contenido solicitado se apruebe automáticamente.",
"components.NotificationTypeSelector.mediaAutoApprovedDescription": "Envía notificaciones cuando los usuarios solicitan nuevos contenidos que se aprueban automáticamente.",
"components.NotificationTypeSelector.mediaAutoApproved": "Contenidos Aprobados Automáticamente",
"components.MovieDetails.playonplex": "Ver en Plex",
"components.MovieDetails.play4konplex": "Ver en Plex en 4K",
@ -524,7 +523,7 @@
"components.UserList.owner": "Propietario",
"components.UserList.edituser": "Editar Permisos de Usuario",
"components.UserList.bulkedit": "Edición Masiva",
"components.UserList.accounttype": "Tipo de Cuenta",
"components.UserList.accounttype": "Tipo",
"components.TvDetails.playonplex": "Ver en Plex",
"components.TvDetails.opensonarr4k": "Abrir Serie 4K en Sonarr",
"components.TvDetails.play4konplex": "Ver en Plex en 4K",
@ -659,7 +658,7 @@
"components.UserProfile.UserSettings.UserPasswordChange.toastSettingsFailure": "Algo fue mal al guardar la contraseña.",
"components.UserProfile.UserSettings.UserPasswordChange.password": "Contraseña",
"components.UserProfile.UserSettings.UserPasswordChange.nopermissionDescription": "No tienes permiso para modificar la contraseña del usuario.",
"components.Settings.enablessl": "Habilitar SSL",
"components.Settings.enablessl": "Usar SSL",
"components.Settings.cacheImagesTip": "Optimizar y guardar todas las imágenes localmente (consume mucho espacio en disco)",
"components.Settings.cacheImages": "Habilitar Cacheado de Imagen",
"components.Settings.SettingsLogs.logDetails": "Detalles del Log",
@ -700,7 +699,7 @@
"components.UserProfile.limit": "{remaining} de {limit}",
"components.UserProfile.UserSettings.UserGeneralSettings.seriesrequestlimit": "Límite de Peticiones de Series",
"components.UserProfile.UserSettings.UserGeneralSettings.movierequestlimit": "Límite de Peticiones de Películas",
"components.UserProfile.UserSettings.UserGeneralSettings.enableOverride": "Habilitar Sobreescritura",
"components.UserProfile.UserSettings.UserGeneralSettings.enableOverride": "Límite global de Sobreescritura",
"components.TvDetails.originaltitle": "Título Original",
"components.Settings.SettingsUsers.tvRequestLimitLabel": "Límite Global de Peticiones de Series",
"components.Settings.SettingsUsers.movieRequestLimitLabel": "Límite Global de Peticiones de Películas",
@ -757,9 +756,9 @@
"components.Settings.RadarrModal.edit4kradarr": "Modificar servidor Radarr 4K",
"components.Settings.RadarrModal.default4kserver": "Servidor 4K por defecto",
"components.Settings.RadarrModal.create4kradarr": "Añadir un nuevo servidor Radarr 4K",
"components.Settings.Notifications.validationPgpPrivateKey": "Debes indicar una clave privada PGP si se ha introducido una contraseña PGP",
"components.Settings.Notifications.validationPgpPassword": "Debes indicar una contraseña PGP si se ha introducido una clave privada PGP",
"components.Settings.Notifications.botUsernameTip": "Permite a los usuarios iniciar un chat con el bot y configurar sus propias notificaciones",
"components.Settings.Notifications.validationPgpPrivateKey": "Debes indicar una clave privada PGP",
"components.Settings.Notifications.validationPgpPassword": "Debes indicar una contraseña PGP",
"components.Settings.Notifications.botUsernameTip": "Permite a los usuarios iniciar también un chat con tu bot y configurar sus propias notificaciones",
"components.RequestModal.pendingapproval": "Tu petición está pendiente de aprobación.",
"components.RequestModal.AdvancedRequester.tags": "Etiquetas",
"components.RequestModal.AdvancedRequester.selecttags": "Seleccionar etiquetas",
@ -790,7 +789,7 @@
"components.Settings.noDefault4kServer": "Un servidor 4K de {serverType} debe ser marcado por defecto para poder habilitar las peticiones 4K de {mediaType} de los usuarios.",
"components.Settings.is4k": "4K",
"components.Settings.SettingsUsers.newPlexLoginTip": "Habilitar inicio de sesión de usuarios de Plex sin importarse previamente",
"components.Settings.SettingsUsers.newPlexLogin": "Habilitar inicio de sesión de nuevo usuario de Plex",
"components.Settings.SettingsUsers.newPlexLogin": "Habilitar nuevo inicio de sesión de Plex",
"components.Settings.Notifications.toastTelegramTestSuccess": "¡Notificación de Telegram enviada con éxito!",
"components.Settings.Notifications.toastTelegramTestSending": "Enviando notificación de prueba de Telegram…",
"components.Settings.Notifications.toastTelegramTestFailed": "Fallo al enviar notificación de prueba de Telegram.",
@ -845,5 +844,49 @@
"components.MovieDetails.showmore": "Mostrar más",
"components.MovieDetails.showless": "Mostrar menos",
"components.Layout.LanguagePicker.displaylanguage": "Mostrar idioma",
"components.DownloadBlock.estimatedtime": "Estimación de {time}"
"components.DownloadBlock.estimatedtime": "Estimación de {time}",
"components.Settings.Notifications.encryptionOpportunisticTls": "Usa siempre STARTTLS",
"components.TvDetails.streamingproviders": "Emisión Actual en",
"components.UserProfile.UserSettings.UserGeneralSettings.languageDefault": "{{Language}} por defecto",
"components.Settings.Notifications.NotificationsWebPush.httpsRequirement": "Para recibir notificaciones web push, Overseerr debe servirse mediante HTTPS.",
"components.Settings.Notifications.NotificationsWebhook.validationTypes": "Debes seleccionar, al menos, un tipo de notificación",
"components.Settings.Notifications.validationTypes": "Debes seleccionar, al menos, un tipo de notificación",
"components.Settings.SettingsUsers.localLoginTip": "Permite a los usuarios registrarse consumo email y password, en lugar de la OAuth de Plex",
"components.Settings.webAppUrl": "Url de la <WebAppLink>Web App</WebAppLink>",
"components.Settings.locale": "Idioma en Pantalla",
"components.UserList.displayName": "Nombre en Pantalla",
"components.Settings.Notifications.encryption": "Método de Encriptación",
"components.Settings.Notifications.encryptionDefault": "Usa STARTTLS si está disponible",
"components.Settings.Notifications.encryptionNone": "Ninguna",
"components.Settings.Notifications.NotificationsLunaSea.webhookUrlTip": "Tu <LunaSeaLink>URL del webhook de notificación</LunaSeaLink> basado en tu usuario o dispositivo",
"components.Settings.Notifications.NotificationsPushbullet.accessTokenTip": "Crea un token desde tu <PushbulletSettingsLink>Opciones de Cuenta</PushbulletSettingsLink>",
"components.Settings.Notifications.NotificationsPushover.accessTokenTip": "<ApplicationRegistrationLink>Registrar una aplicación</ApplicationRegistrationLink> para su uso con Overseerr",
"components.Settings.Notifications.NotificationsPushover.userTokenTip": "Tu <UsersGroupsLink>identificador de usuario o grupo</UsersGroupsLink> de 30 caracteres",
"components.Settings.Notifications.NotificationsPushbullet.validationTypes": "Debes seleccionar, al menos, un tipo de notificación",
"components.Settings.Notifications.NotificationsPushover.validationTypes": "Debes seleccionar, al menos, un tipo de notificación",
"components.QuotaSelector.seasons": "{count, plural, one {temporada} other {temporadas}}",
"components.QuotaSelector.movies": "{count, plural, one {película} other {películas}}",
"components.Settings.Notifications.NotificationsSlack.validationTypes": "Debes seleccionar, al menos, un tipo de notificación",
"components.Settings.Notifications.chatIdTip": "Empieza un chat con tu bot, añade el <GetIdBotLink>@get_id_bot</GetIdBotLink> e indica el comando <code>/my_id</code>",
"components.Settings.Notifications.encryptionImplicitTls": "Usa TLS Implícito",
"components.Settings.Notifications.webhookUrlTip": "Crea una <DiscordWebhookLink>integración webhook</DiscordWebhookLink> en tu servidor",
"components.MovieDetails.streamingproviders": "Emisión Actual en",
"components.QuotaSelector.movieRequests": "{quotaLimit} <quotaUnits>{películas} per {quotaDays} {días}</quotaUnits>",
"components.Settings.Notifications.NotificationsSlack.webhookUrlTip": "Crea una integración con un <WebhookLink>Webhook de Entrada</WebhookLink>",
"components.Settings.validationWebAppUrl": "Debes proporcionar una URL válida para la Plex Web App",
"components.Settings.webAppUrlTip": "Dirige a los usuarios, opcionalmente, a la web app en tu servidor, en lugar de la app alojada en Plex",
"components.QuotaSelector.days": "{count, plural, one {día} other {días}}",
"components.QuotaSelector.tvRequests": "{quotaLimit} <quotaUnits>{temporadas} per {quotaDays} {días}</quotaUnits>",
"components.Settings.Notifications.botApiTip": "<CreateBotLink>Crea un bot</CreateBotLink> para usar con Overseerr",
"components.Settings.Notifications.encryptionTip": "Normalmente, TLS Implícito usa el puerto 465 y STARTTLS usa el puerto 587",
"components.UserList.localLoginDisabled": "El ajuste para <strong>Habilitar el Inicio de Sesión Local</strong> está actualmente deshabilitado.",
"components.Settings.SettingsUsers.defaultPermissionsTip": "Permisos iniciales asignados a nuevos usuarios",
"components.Settings.SettingsAbout.runningDevelop": "Estás utilizando la rama de <code>develop</code> de Overseerr, la cual solo se recomienda para aquellos que contribuyen al desarrollo o al soporte de las pruebas de nuevos desarrollos.",
"components.StatusBadge.status": "{status}",
"components.Settings.SettingsJobsCache.editJobScheduleSelectorMinutes": "Cada {jobScheduleMinutes, plural, one {minuto} other {{jobScheduleMinutes} minutos}}",
"components.Settings.SettingsJobsCache.editJobScheduleSelectorHours": "Cada {jobScheduleHours, plural, one {hora} other {{jobScheduleHours} horas}}",
"components.Settings.SettingsJobsCache.jobScheduleEditFailed": "Algo fue mal al guardar la tarea programada.",
"components.Settings.SettingsJobsCache.editJobSchedule": "Modificar tarea programada",
"components.Settings.SettingsJobsCache.editJobSchedulePrompt": "Frecuencia",
"components.Settings.SettingsJobsCache.jobScheduleEditSaved": "¡Tarea programada modificada con éxito!"
}

@ -60,7 +60,7 @@
"components.Settings.Notifications.webhookUrl": "URL de webhook",
"components.Settings.RadarrModal.add": "Ajouter un serveur",
"components.Settings.RadarrModal.apiKey": "Clé d'API",
"components.Settings.RadarrModal.baseUrl": "URL Base",
"components.Settings.RadarrModal.baseUrl": "Base URL",
"components.Settings.RadarrModal.createradarr": "Ajouter un nouveau serveur Radarr",
"components.Settings.RadarrModal.defaultserver": "Serveur par défaut",
"components.Settings.RadarrModal.editradarr": "Modifier le serveur Radarr",
@ -160,7 +160,7 @@
"components.TvDetails.similar": "Séries similaires",
"components.UserList.admin": "Admin",
"components.UserList.created": "Créé",
"components.UserList.lastupdated": "Denière mise à jour",
"components.UserList.lastupdated": "Mise à jour",
"components.UserList.plexuser": "Utilisateur Plex",
"components.UserList.role": "Rôle",
"components.UserList.totalrequests": "Requêtes",
@ -229,7 +229,6 @@
"components.Settings.SettingsAbout.Releases.viewongithub": "Voir sur GitHub",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Voir le journal des modifications",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Journal des modifications de version",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "Les dernières modifications apportées à la branche <code>develop</code> d'Overseerr ne sont pas affichées ci-dessous. Veuillez consulter l'historique des validations de cette branche sur <GithubLink>GitHub</GithubLink> pour plus de détails.",
"components.Settings.SettingsAbout.Releases.releases": "Versions",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Données de sortie indisponibles. GitHub est-il en panne ?",
"components.Settings.SettingsAbout.Releases.latestversion": "Dernière version",
@ -250,7 +249,7 @@
"components.CollectionDetails.requestcollection": "Demander la collection",
"components.CollectionDetails.requestSuccess": "<strong>{title}</strong> demandé avec succès !",
"components.CollectionDetails.overview": "Résumé",
"components.CollectionDetails.numberofmovies": "{count} films",
"components.CollectionDetails.numberofmovies": "{count} Films",
"i18n.requested": "Demandé",
"i18n.retry": "Réessayer",
"i18n.failed": "Échec",
@ -279,7 +278,7 @@
"components.NotificationTypeSelector.mediaapprovedDescription": "Envoie une notification quand le média demandé est validé manuellement.",
"components.NotificationTypeSelector.mediaapproved": "Média validé",
"i18n.request": "Demander",
"components.Settings.Notifications.NotificationsPushover.validationUserTokenRequired": "Vous devez fournir un jeton utilisateur valide",
"components.Settings.Notifications.NotificationsPushover.validationUserTokenRequired": "Vous devez fournir un jeton utilisateur valide ou une clef partagée",
"components.Settings.Notifications.NotificationsPushover.validationAccessTokenRequired": "Vous devez fournir un jeton d'application valide",
"components.Settings.Notifications.NotificationsPushover.userToken": "Clé d'utilisateur ou de groupe",
"components.Settings.Notifications.NotificationsPushover.pushoversettingssaved": "Paramètres de notification pushover enregistrés avec succès !",
@ -323,7 +322,7 @@
"components.UserList.createlocaluser": "Créer un utilisateur local",
"components.UserList.create": "Créer",
"components.UserList.autogeneratepassword": "Générer automatiquement le mot de passe",
"components.UserList.passwordinfodescription": "Activez les notifications par e-mail pour permettre la génération automatique de mots de passe.",
"components.UserList.passwordinfodescription": "Configurez l'URL de l'application ainsi que les notifications par e-mail pour permettre la génération automatique de mots de passe.",
"components.UserList.email": "Adresse e-mail",
"components.Login.validationpasswordrequired": "Vous devez fournir un mot de passe",
"components.Login.validationemailrequired": "Vous devez fournir un e-mail valide",
@ -752,7 +751,7 @@
"components.Settings.SettingsAbout.uptodate": "À jour",
"components.Settings.SettingsAbout.outofdate": "Obsolète",
"components.Settings.Notifications.validationPgpPrivateKey": "Vous devez fournir une clé privée PGP valide si un mot de passe PGP est entré",
"components.Settings.Notifications.validationPgpPassword": "Vous devez fournir un mot de passe PGP si une clé privée PGP est saisie",
"components.Settings.Notifications.validationPgpPassword": "Vous devez fournir un mot de passe PGP",
"components.Settings.Notifications.botUsernameTip": "Permet aux utilisateurs de démarrer également une conversation avec votre bot et de configurer leurs propres notifications personnelles",
"components.RequestModal.pendingapproval": "Votre demande est en attente dapprobation.",
"components.RequestList.RequestItem.mediaerror": "Le titre associé à cette demande nest plus disponible.",
@ -835,7 +834,7 @@
"components.Settings.Notifications.NotificationsLunaSea.webhookUrlTip": "Votre <LunaSeaLink>URL webhook de notification </LunaSeaLink> basée sur l'utilisateur ou l'appareil",
"components.QuotaSelector.seasons": "{count, plural, one {saison} other {saisons}}",
"components.QuotaSelector.movies": "{count, plural, one {film} other {films}}",
"components.QuotaSelector.movieRequests": "{quotaLimit} <quotaUnits>{movies} per {quotaDays} {days}</quotaUnits>",
"components.QuotaSelector.movieRequests": "{quotaLimit} <quotaUnits>{movies} par {quotaDays} {days}</quotaUnits>",
"components.QuotaSelector.days": "{count, plural, one {jour} other {jours}}",
"components.Settings.SettingsAbout.betawarning": "Ceci est un logiciel BÊTA. Les fonctionnalités peuvent être non opérationnelles ou instables. Veuillez signaler tout problème sur GitHub !",
"components.UserProfile.UserSettings.UserNotificationSettings.webpushsettingsfailed": "Échec de l'enregistrement des paramètres de notification Web push.",
@ -878,5 +877,9 @@
"components.MovieDetails.showmore": "Montrer plus",
"components.MovieDetails.showless": "Montrer moins",
"components.Layout.LanguagePicker.displaylanguage": "Langue d'affichage",
"components.UserList.localLoginDisabled": "Le paramètre <strong>Activer la connexion locale</strong> est actuellement désactivé."
"components.UserList.localLoginDisabled": "Le paramètre <strong>Activer la connexion locale</strong> est actuellement désactivé.",
"components.TvDetails.streamingproviders": "Disponible en streaming sur",
"components.MovieDetails.streamingproviders": "Actuellement diffusé sur",
"components.Settings.Notifications.NotificationsSlack.webhookUrlTip": "Créer une <WebhookLink>Webhook entrant</WebhookLink> intégration",
"components.StatusBadge.status": "{status}"
}

@ -518,7 +518,6 @@
"components.Settings.SettingsAbout.Releases.viewongithub": "Megtekintés a GitHubon",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Változásnapló megtekintése",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Verzió változásnapló",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "Az Overseerr <code>develop</code> ágának legutóbbi módosításait az alábbiakban nem mutatjuk be. A részletekért lásd az ág \"commit history\"-ját a <GithubLink>GitHub</GithubLink>-on.",
"components.Settings.SettingsAbout.Releases.releases": "Kiadások",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Kiadási adatok nem állnak rendelkezésre. A GitHub nem elérhető?",
"components.Settings.SettingsAbout.Releases.latestversion": "Legújabb",
@ -879,5 +878,6 @@
"components.ResetPassword.gobacklogin": "Vissza a bejelentkező lapra",
"components.ResetPassword.emailresetlink": "Email visszaállítási link",
"components.ResetPassword.email": "Email cím",
"components.ResetPassword.confirmpassword": "Jelszó megerősítése"
"components.ResetPassword.confirmpassword": "Jelszó megerősítése",
"components.StatusBadge.status": "{status}"
}

@ -229,7 +229,6 @@
"components.Settings.SettingsAbout.Releases.viewongithub": "Visualizza su GitHub",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Visualizza il registro modifiche",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Registro versione",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "Le ultime modifiche di Overserr <code>develop</code> non sono mostrate di seguito. Consulta <GithubLink>GitHub</GithubLink> per maggiori dettagli.",
"components.Settings.SettingsAbout.Releases.releases": "Versioni",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Dati di versione non disponibili. GitHub è down?",
"components.Settings.SettingsAbout.Releases.latestversion": "Versione più recente",
@ -879,5 +878,8 @@
"components.NotificationTypeSelector.usermediaAutoApprovedDescription": "Ricevi una notifica quando altri utenti inviano nuove richieste che vengono approvate automaticamente.",
"components.Layout.LanguagePicker.displaylanguage": "Lingua Interfaccia",
"components.MovieDetails.showmore": "Mostra di più",
"components.MovieDetails.showless": "Mostra meno"
"components.MovieDetails.showless": "Mostra meno",
"components.TvDetails.streamingproviders": "Ora in streaming su",
"components.MovieDetails.streamingproviders": "Ora in streaming su",
"components.StatusBadge.status": "{status}"
}

@ -38,9 +38,9 @@
"components.RequestModal.cancel": "キャンセルリクエスト",
"components.RequestModal.extras": "おまけ",
"components.RequestModal.numberofepisodes": "エピソード数",
"components.RequestModal.pendingrequest": "{title}がリクエスト中",
"components.RequestModal.requestCancel": "<strong>{title}</strong>のリクエストは取り消されました。",
"components.RequestModal.requestSuccess": "<strong>{title}</strong>のリクエストは完了しました。",
"components.RequestModal.pendingrequest": "{title} がリクエスト中",
"components.RequestModal.requestCancel": "<strong>{title}</strong> のリクエストは取り消されました。",
"components.RequestModal.requestSuccess": "<strong>{title}</strong> のリクエストは完了しました。",
"components.RequestModal.requestadmin": "このリクエストは今すぐ承認されます。",
"components.RequestModal.requestfrom": "{username} はすでにリクエストを上げています。",
"components.RequestModal.requestseasons": "{seasonCount} シーズンをリクエスト",
@ -55,8 +55,8 @@
"components.Settings.Notifications.emailsender": "配信元メールアドレス",
"components.Settings.Notifications.smtpHost": "SMTP ホスト",
"components.Settings.Notifications.smtpPort": "SMTP ポート",
"components.Settings.Notifications.validationSmtpHostRequired": "SMTPホストの入力は必要です",
"components.Settings.Notifications.validationSmtpPortRequired": "SMTPポートの入力は必要です",
"components.Settings.Notifications.validationSmtpHostRequired": "有効なホスト名・IP アドレスを入力してください",
"components.Settings.Notifications.validationSmtpPortRequired": "有効なポートを入力してください",
"components.Settings.Notifications.webhookUrl": "ウェブフック URL",
"components.Settings.RadarrModal.add": "サーバーを追加",
"components.Settings.RadarrModal.apiKey": "API キー",
@ -64,7 +64,7 @@
"components.Settings.RadarrModal.createradarr": "Radarr サーバーを追加",
"components.Settings.RadarrModal.defaultserver": "デフォルトサーバー",
"components.Settings.RadarrModal.editradarr": "Radarr サーバーを編集",
"components.Settings.RadarrModal.hostname": "ホスト名",
"components.Settings.RadarrModal.hostname": "ホスト名・IP アドレス",
"components.Settings.RadarrModal.minimumAvailability": "最低リリース状況",
"components.Settings.RadarrModal.port": "ポート",
"components.Settings.RadarrModal.qualityprofile": "画質プロファイル",
@ -76,19 +76,19 @@
"components.Settings.RadarrModal.servername": "サーバー名",
"components.Settings.RadarrModal.ssl": "SSL を有効にする",
"components.Settings.RadarrModal.toastRadarrTestFailure": "Radarr サーバーの接続は失敗しました。",
"components.Settings.RadarrModal.toastRadarrTestSuccess": "Radarrサーバーの接続は成功しました!",
"components.Settings.RadarrModal.validationApiKeyRequired": "API キーの入力が必要です",
"components.Settings.RadarrModal.validationHostnameRequired": "ホスト名/IPの入力が必要です",
"components.Settings.RadarrModal.validationPortRequired": "ポートの入力が必要です",
"components.Settings.RadarrModal.validationProfileRequired": "プロファイルの選択が必要です",
"components.Settings.RadarrModal.validationRootFolderRequired": "ルートフォルダーの選択が必要です",
"components.Settings.RadarrModal.toastRadarrTestSuccess": "Radarr サーバーの接続は成功しました!",
"components.Settings.RadarrModal.validationApiKeyRequired": "API キーを入力してください",
"components.Settings.RadarrModal.validationHostnameRequired": "有効なホスト名・IP アドレスを入力してください",
"components.Settings.RadarrModal.validationPortRequired": "有効なポートを入力してください",
"components.Settings.RadarrModal.validationProfileRequired": "プロファイルを選択してください",
"components.Settings.RadarrModal.validationRootFolderRequired": "ルートフォルダーを選択してください",
"components.Settings.SonarrModal.add": "サーバーを追加",
"components.Settings.SonarrModal.apiKey": "API キー",
"components.Settings.SonarrModal.baseUrl": "ベース URL",
"components.Settings.SonarrModal.createsonarr": "Sonarr サーバーを追加",
"components.Settings.SonarrModal.defaultserver": "デフォルトサーバー",
"components.Settings.SonarrModal.editsonarr": "Sonarr サーバーを編集",
"components.Settings.SonarrModal.hostname": "ホスト名",
"components.Settings.SonarrModal.hostname": "ホスト名・IP アドレス",
"components.Settings.SonarrModal.port": "ポート",
"components.Settings.SonarrModal.qualityprofile": "画質プロファイル",
"components.Settings.SonarrModal.rootfolder": "ルートフォルダー",
@ -99,10 +99,10 @@
"components.Settings.SonarrModal.servername": "サーバー名",
"components.Settings.SonarrModal.ssl": "SSL を有効にする",
"components.Settings.SonarrModal.validationApiKeyRequired": "API キーの入力が必要です",
"components.Settings.SonarrModal.validationHostnameRequired": "ホスト名/IPの入力が必要です",
"components.Settings.SonarrModal.validationPortRequired": "ポートの入力が必要です",
"components.Settings.SonarrModal.validationProfileRequired": "プロファイルの選択が必要です",
"components.Settings.SonarrModal.validationRootFolderRequired": "ルートフォルダーの選択が必要です",
"components.Settings.SonarrModal.validationHostnameRequired": "有効なホスト名・IP アドレスを入力してください",
"components.Settings.SonarrModal.validationPortRequired": "有効なポートを入力してください",
"components.Settings.SonarrModal.validationProfileRequired": "プロファイルを選択してください",
"components.Settings.SonarrModal.validationRootFolderRequired": "ルートフォルダーを選択してください",
"components.Settings.activeProfile": "アクティブプロファイル",
"components.Settings.addradarr": "Radarr サーバーを追加",
"components.Settings.address": "アドレス",
@ -117,10 +117,10 @@
"components.Settings.deleteserverconfirm": "このサーバーを削除しますか?",
"components.Settings.generalsettings": "一般設定",
"components.Settings.generalsettingsDescription": "Overseerr の構成に関する設定です。",
"components.Settings.hostname": "ホスト名/IP",
"components.Settings.hostname": "ホスト名・IP アドレス",
"components.Settings.librariesRemaining": "残りのライブラリー:{count}",
"components.Settings.manualscan": "手動ライブラリースキャン",
"components.Settings.manualscanDescription": "通常は24時間に一度しか実行されません。Overseerr は、Plex サーバーの最近追加されたフォルダをより頻繁にチェックします。初めて Plex を設定する場合は、一度手動でライブラリーをスキャンすることをお勧めします",
"components.Settings.manualscanDescription": "通常は 24 時間に一度しか実行されません。Overseerr は、Plex サーバーの最近追加されたフォルダをより頻繁にチェックします。初めて Plex を設定する場合は、一度手動でライブラリーをスキャンすることをお勧めします",
"components.Settings.menuAbout": "Overseerr について",
"components.Settings.menuGeneralSettings": "一般",
"components.Settings.menuJobs": "ジョブ",
@ -160,10 +160,10 @@
"components.TvDetails.similar": "類似シリーズ",
"components.UserList.admin": "管理者",
"components.UserList.created": "作成日",
"components.UserList.lastupdated": "最終更新日",
"components.UserList.lastupdated": "更新日",
"components.UserList.plexuser": "Plexユーザー",
"components.UserList.role": "役割",
"components.UserList.totalrequests": "リクエスト数",
"components.UserList.totalrequests": "リクエスト数",
"components.UserList.user": "ユーザー",
"components.UserList.userlist": "ユーザーリスト",
"i18n.approve": "承認",
@ -182,20 +182,20 @@
"pages.oops": "ああ",
"pages.returnHome": "ホームへ戻る",
"components.TvDetails.TvCast.fullseriescast": "すべての出演者",
"components.Settings.validationPortRequired": "ポートの入力が必要です",
"components.Settings.validationHostnameRequired": "ホスト名/IPの入力が必要です",
"components.Settings.SonarrModal.validationNameRequired": "サーバー名を指定してください",
"components.Settings.validationPortRequired": "有効なポートを入力してください",
"components.Settings.validationHostnameRequired": "有効なホスト名・IP アドレスを入力してください",
"components.Settings.SonarrModal.validationNameRequired": "サーバー名を入力してください",
"components.Settings.SettingsAbout.version": "バージョン",
"components.Settings.SettingsAbout.totalrequests": "総リクエスト数",
"components.Settings.SettingsAbout.totalmedia": "総メディア数",
"components.Settings.SettingsAbout.overseerrinformation": "Overseerr 情報",
"components.Settings.SettingsAbout.githubdiscussions": "GitHub ディスカッション",
"components.Settings.SettingsAbout.gettingsupport": "サポート",
"components.Settings.RadarrModal.validationNameRequired": "サーバー名を指定してください",
"components.Settings.Notifications.emailsettingssaved": "メール通知設定が保存されました",
"components.Settings.RadarrModal.validationNameRequired": "サーバー名を入力してください",
"components.Settings.Notifications.emailsettingssaved": "メール通知設定が保存されました",
"components.Settings.Notifications.emailsettingsfailed": "メール通知設定の保存に失敗しました。",
"components.Settings.Notifications.discordsettingsfailed": "Discord の通知設定の保存に失敗しました。",
"components.Settings.Notifications.discordsettingssaved": "Discord の通知設定が保存されました",
"components.Settings.Notifications.discordsettingssaved": "Discord の通知設定が保存されました",
"components.MovieDetails.MovieCast.fullcast": "すべての出演者",
"i18n.deleting": "削除中…",
"components.UserList.userdeleteerror": "ユーザーの削除する時に問題が発生しました。",
@ -208,7 +208,7 @@
"components.Setup.tip": "ヒント",
"components.Settings.toastSettingsSuccess": "設定の変更は保存しました。",
"components.Settings.toastSettingsFailure": "設定保存中に問題が発生しました。",
"components.Settings.toastApiKeySuccess": "新しい API キーが生成されました",
"components.Settings.toastApiKeySuccess": "新しい API キーが生成されました",
"components.Settings.toastApiKeyFailure": "新しい API キーの生成中に問題が発生しました。",
"components.Settings.SonarrModal.testFirstRootFolders": "ルートフォルダーをロードするには先に接続をテストしてください",
"components.Settings.SonarrModal.testFirstQualityProfiles": "画質プロファイルをロードするには先に接続をテストしてください",
@ -219,7 +219,7 @@
"components.Settings.RadarrModal.validationMinimumAvailabilityRequired": "最低リリース状況を選択してください",
"components.Settings.RadarrModal.testFirstRootFolders": "ルートフォルダーをロードするには先に接続をテストしてください",
"components.Settings.RadarrModal.testFirstQualityProfiles": "画質プロファイルをロードするには先に接続をテストしてください",
"components.Settings.RadarrModal.loadingprofiles": "画質プロファイル読込中…",
"components.Settings.RadarrModal.loadingprofiles": "画質プロファイル読込中…",
"components.Settings.RadarrModal.loadingrootfolders": "ルートフォルダー読込中…",
"components.MovieDetails.studio": "制作会社",
"i18n.close": "閉じる",
@ -228,17 +228,16 @@
"components.Settings.SettingsAbout.helppaycoffee": "開発者のコーヒーのためにチップを",
"components.Settings.SettingsAbout.Releases.viewongithub": "GitHub で見る",
"components.Settings.SettingsAbout.Releases.viewchangelog": "変更履歴参照",
"components.Settings.SettingsAbout.Releases.versionChangelog": "バージョン変更履歴",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "お使いのバージョンのパッチノート以下に記載されていません。最新のアップデートは<GithubLink>GitHubリポジトリ</GithubLink>をご覧ください。",
"components.Settings.SettingsAbout.Releases.versionChangelog": "{version} の変更履歴",
"components.Settings.SettingsAbout.Releases.releases": "リリース",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "リリースデータがありません。GitHub はダウンしていますか?",
"components.Settings.SettingsAbout.Releases.latestversion": "最新",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "リリースデータがありません。",
"components.Settings.SettingsAbout.Releases.latestversion": "最新のバージョン",
"components.Settings.SettingsAbout.Releases.currentversion": "現在のバージョン",
"components.MovieDetails.MovieCrew.fullcrew": "フルクルー",
"components.MovieDetails.viewfullcrew": "フルクルーを表示",
"components.CollectionDetails.requestswillbecreated": "以下のタイトルをリクエストします:",
"components.CollectionDetails.requestcollection": "リクエストコレクション",
"components.CollectionDetails.requestSuccess": "<strong>{title}</strong>をリクエストしました!",
"components.CollectionDetails.requestSuccess": "<strong>{title}</strong> をリクエストしました。",
"components.CollectionDetails.overview": "ストーリー",
"components.CollectionDetails.numberofmovies": "{count} 本の映画",
"i18n.requested": "リクエスト済み",
@ -246,7 +245,7 @@
"components.MovieDetails.watchtrailer": "予告編を見る",
"components.UserList.importfromplexerror": "Plexからユーザーをインポート中に問題が発生しました。",
"components.UserList.importfromplex": "Plexからユーザーをインポート",
"components.UserList.importedfromplex": "Plexから{userCount, plural, =0 {新ユーザーはインポートされませんでした。} one {新ユーザー #名をインポートしました。} other {新ユーザー #名をインポートしました。}}",
"components.UserList.importedfromplex": "Plex から新ユーザー {userCount} 名をインポートしました。",
"components.TvDetails.viewfullcrew": "フルクルーを表示",
"components.TvDetails.firstAirDate": "初放送日",
"components.TvDetails.TvCrew.fullseriescrew": "フルシリーズクルー",
@ -255,7 +254,7 @@
"i18n.retry": "リトライ",
"i18n.failed": "失敗",
"components.Settings.Notifications.NotificationsSlack.webhookUrl": "ウェブフック URL",
"components.Settings.Notifications.NotificationsSlack.slacksettingssaved": "Slack の通知設定が保存されました",
"components.Settings.Notifications.NotificationsSlack.slacksettingssaved": "Slack の通知設定が保存されました",
"components.Settings.Notifications.NotificationsSlack.slacksettingsfailed": "Slack の通知設定の保存に失敗しました。",
"components.Login.signin": "ログイン",
"components.Login.password": "パスワード",
@ -278,7 +277,7 @@
"components.Login.signinheader": "続けるにはログインしてください",
"components.MovieDetails.downloadstatus": "ダウンロード状況",
"components.MediaSlider.ShowMoreCard.seemore": "もっと見る",
"components.Login.validationpasswordrequired": "パスワードの入力が必要です",
"components.Login.validationpasswordrequired": "パスワードを入力してください",
"components.ResetPassword.validationemailrequired": "有効なメールアドレスを入力してください",
"components.Settings.Notifications.validationEmail": "有効なメールアドレスを入力してください",
"components.UserList.validationEmail": "有効なメールアドレスを入力してください",
@ -334,13 +333,13 @@
"i18n.status": "状態",
"components.TvDetails.originaltitle": "原題",
"components.MovieDetails.originaltitle": "原題",
"components.Settings.Notifications.toastTelegramTestSuccess": "Telegram のテスト通知が送信されました",
"components.Settings.Notifications.toastEmailTestSuccess": "メールテスト通知が送信されました",
"components.Settings.Notifications.toastDiscordTestSuccess": "Discord のテスト通知が送信されました",
"components.Settings.Notifications.NotificationsLunaSea.toastLunaSeaTestSuccess": "LunaSea のテスト通知が送信されました",
"components.Settings.Notifications.NotificationsPushbullet.toastPushbulletTestSuccess": "Pushbullet のテスト通知が送信されました",
"components.Settings.Notifications.NotificationsPushover.toastPushoverTestSuccess": "Pushover のテスト通知が送信されました",
"components.Settings.Notifications.NotificationsSlack.toastSlackTestSuccess": "Slack のテスト通知が送信されました",
"components.Settings.Notifications.toastTelegramTestSuccess": "Telegram のテスト通知が送信されました",
"components.Settings.Notifications.toastEmailTestSuccess": "メールテスト通知が送信されました",
"components.Settings.Notifications.toastDiscordTestSuccess": "Discord のテスト通知が送信されました",
"components.Settings.Notifications.NotificationsLunaSea.toastLunaSeaTestSuccess": "LunaSea のテスト通知が送信されました",
"components.Settings.Notifications.NotificationsPushbullet.toastPushbulletTestSuccess": "Pushbullet のテスト通知が送信されました",
"components.Settings.Notifications.NotificationsPushover.toastPushoverTestSuccess": "Pushover のテスト通知が送信されました",
"components.Settings.Notifications.NotificationsSlack.toastSlackTestSuccess": "Slack のテスト通知が送信されました",
"components.UserProfile.UserSettings.UserNotificationSettings.telegramsettingsfailed": "Telegram の通知設定の保存に失敗しました。",
"components.UserProfile.UserSettings.UserNotificationSettings.emailsettingsfailed": "メール通知設定の保存に失敗しました。",
"components.UserProfile.UserSettings.UserNotificationSettings.discordsettingsfailed": "Discord の通知設定の保存に失敗しました。",
@ -348,19 +347,19 @@
"components.Settings.Notifications.NotificationsLunaSea.settingsFailed": "LunaSea の通知設定の保存に失敗しました。",
"components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsFailed": "Pushbullet の通知設定の保存に失敗しました。",
"components.Settings.Notifications.NotificationsPushover.pushoversettingsfailed": "Pushover の通知設定の保存に失敗しました。",
"components.UserProfile.UserSettings.UserNotificationSettings.telegramsettingssaved": "Telegram の通知設定が保存されました",
"components.UserProfile.UserSettings.UserNotificationSettings.emailsettingssaved": "メール通知設定が保存されました",
"components.UserProfile.UserSettings.UserNotificationSettings.discordsettingssaved": "Discord の通知設定が保存されました",
"components.Settings.Notifications.telegramsettingssaved": "Telegram の通知設定が保存されました",
"components.Settings.Notifications.NotificationsLunaSea.settingsSaved": "LunaSea の通知設定が保存されました",
"components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsSaved": "Pushbullet の通知設定が保存されました",
"components.Settings.Notifications.NotificationsPushover.pushoversettingssaved": "Pushover の通知設定が保存されました",
"components.ResetPassword.validationpasswordrequired": "パスワードの入力が必要です",
"components.Layout.VersionStatus.commitsbehind": "{commitsBehind} {commitsBehind, plural, one {commit} other {commits}} behind",
"components.UserProfile.UserSettings.UserNotificationSettings.telegramsettingssaved": "Telegram の通知設定が保存されました",
"components.UserProfile.UserSettings.UserNotificationSettings.emailsettingssaved": "メール通知設定が保存されました",
"components.UserProfile.UserSettings.UserNotificationSettings.discordsettingssaved": "Discord の通知設定が保存されました",
"components.Settings.Notifications.telegramsettingssaved": "Telegram の通知設定が保存されました",
"components.Settings.Notifications.NotificationsLunaSea.settingsSaved": "LunaSea の通知設定が保存されました",
"components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsSaved": "Pushbullet の通知設定が保存されました",
"components.Settings.Notifications.NotificationsPushover.pushoversettingssaved": "Pushover の通知設定が保存されました",
"components.ResetPassword.validationpasswordrequired": "パスワードを入力してください",
"components.Layout.VersionStatus.commitsbehind": "",
"components.Layout.LanguagePicker.displaylanguage": "表示言語",
"components.LanguageSelector.originalLanguageDefault": "すべての言語",
"components.LanguageSelector.languageServerDefault": "デフォルト言語 ({language})",
"components.DownloadBlock.estimatedtime": "所要時間 {time}",
"components.LanguageSelector.languageServerDefault": "デフォルト言語{language}",
"components.DownloadBlock.estimatedtime": "所要時間{time}",
"components.Discover.upcomingtv": "今後リリースされるシリーズ",
"components.Discover.noRequests": "リクエストが有りません。",
"components.Discover.TvGenreSlider.tvgenres": "シリーズのジャンル",
@ -373,7 +372,7 @@
"components.Discover.DiscoverNetwork.networkSeries": "{network}シーリーズ",
"components.Discover.DiscoverMovieLanguage.languageMovies": "{language}の映画",
"components.Discover.DiscoverMovieGenre.genreMovies": "{genre}映画",
"components.RequestModal.pending4krequest": "{title}が4Kリクエスト中",
"components.RequestModal.pending4krequest": "{title} 4K リクエスト中",
"components.RequestModal.errorediting": "リクエストを編集するときに問題が発生しました。",
"components.RequestModal.edit": "リクエストを編集",
"components.RequestModal.autoapproval": "自動承認",
@ -382,15 +381,15 @@
"components.RequestModal.SearchByNameModal.nosummary": "このタイトルの概要は見つかりませんでした。",
"components.RequestModal.QuotaDisplay.seasonlimit": "シーズン",
"components.RequestModal.QuotaDisplay.season": "シーズン",
"components.RequestModal.QuotaDisplay.requiredquotaUser": "このユーザーはこのシリーズをリクエストするには、最低でも<strong>{シーズン}</strong>シーズンリクエストが残っている必要があります。",
"components.RequestModal.QuotaDisplay.requiredquota": "このシリーズをリクエストするには、最低でも<strong>{シーズン}</strong>シーズンリクエストが残っている必要があります。",
"components.RequestModal.QuotaDisplay.requestsremaining": "残り{remaining, plural, =0 {<strong>0</strong>} other {<strong>#</strong>}} {type} {remaining, plural, one {リクエスト} other {リクエスト}}",
"components.RequestModal.QuotaDisplay.requiredquotaUser": "このユーザーはこのシリーズをリクエストするには、最低でも <strong>{seasons}</strong> シーズンリクエストが残っている必要があります。",
"components.RequestModal.QuotaDisplay.requiredquota": "このシリーズをリクエストするには、最低でも <strong>{seasons}</strong> シーズンリクエストが残っている必要があります。",
"components.RequestModal.QuotaDisplay.requestsremaining": "残り <strong>{remaining}</strong> {type}リクエスト",
"components.RequestModal.QuotaDisplay.quotaLinkUser": "このユーザーのリクエスト制限は<ProfileLink>プロフィールページ</ProfileLink>で確認できます。",
"components.RequestModal.QuotaDisplay.quotaLink": "リクエスト制限は<ProfileLink>プロフィールページ</ProfileLink>で確認できます。",
"components.RequestModal.QuotaDisplay.notenoughseasonrequests": "シーズンリクエストが足りません。",
"components.RequestModal.QuotaDisplay.movielimit": "{limit, plural, one {映画} other {映画}}",
"components.RequestModal.QuotaDisplay.allowedRequestsUser": "このユーザーは<strong> {days} </strong>日ごとに<strong> {limit} </strong> {type}をリクエストできます。",
"components.RequestModal.QuotaDisplay.allowedRequests": "<strong> {days} </strong>日ごとに<strong> {limit} </strong> {type}をリクエストできます。",
"components.RequestModal.QuotaDisplay.movielimit": "映画",
"components.RequestModal.QuotaDisplay.allowedRequestsUser": "このユーザーは <strong>{days}</strong> 日ごとに <strong>{limit}</strong> {type}をリクエストできます。",
"components.RequestModal.QuotaDisplay.allowedRequests": "<strong>{days}</strong> 日ごとに <strong>{limit}</strong> {type}をリクエストできます。",
"components.RequestModal.AdvancedRequester.tags": "タグ",
"components.RequestModal.AdvancedRequester.selecttags": "タグの選択",
"components.RequestModal.AdvancedRequester.rootfolder": "ルートフォルダ",
@ -398,9 +397,9 @@
"components.RequestModal.AdvancedRequester.qualityprofile": "画質プロファイル",
"components.RequestModal.AdvancedRequester.notagoptions": "タグなし。",
"components.RequestModal.AdvancedRequester.languageprofile": "言語プロフィール",
"components.RequestModal.AdvancedRequester.folder": "{path} ({space})",
"components.RequestModal.AdvancedRequester.folder": "{path}{space}",
"components.RequestModal.AdvancedRequester.destinationserver": "送信先サーバー",
"components.RequestModal.AdvancedRequester.default": "{name} (デフォルト)",
"components.RequestModal.AdvancedRequester.default": "{name}(デフォルト)",
"components.RequestModal.AdvancedRequester.animenote": "* このシリーズはアニメです。",
"components.RequestModal.AdvancedRequester.advancedoptions": "詳細オプション",
"components.RequestButton.viewrequest4k": "4Kリクエストを表示",
@ -409,10 +408,10 @@
"components.RequestList.sortModified": "最終更新日",
"components.RequestList.sortAdded": "リクエスト日",
"components.RequestList.showallrequests": "すべてのリクエストを表示",
"components.RequestList.RequestItem.requesteddate": "リクエスト",
"components.RequestList.RequestItem.requesteddate": "リクエストユーザー",
"components.RequestList.RequestItem.requested": "リクエスト",
"components.RequestList.RequestItem.modifieduserdate": "{date} - {user}",
"components.RequestList.RequestItem.modified": "更新",
"components.RequestList.RequestItem.modifieduserdate": "{user}{date}",
"components.RequestList.RequestItem.modified": "最終更新",
"components.RequestList.RequestItem.mediaerror": "このリクエストのタイトルはもうありません。",
"components.RequestList.RequestItem.failedretry": "リクエストを再試行するときに問題が発生しました。",
"components.RequestList.RequestItem.editrequest": "リクエストを編集",
@ -423,26 +422,26 @@
"components.RequestCard.deleterequest": "リクエストを削除",
"components.RequestButton.requestmore4k": "もっと4Kリクエストする",
"components.RequestButton.requestmore": "もっとリクエストする",
"components.RequestButton.declinerequests": "{requestCount, plural, one {1つのリクエスト} other {{requestCount}つのリクエスト}}を拒否",
"components.RequestButton.declinerequests": "{requestCount} つのリクエストを拒否",
"components.RequestButton.declinerequest4k": "4Kリクエストを拒否",
"components.RequestButton.declinerequest": "リクエストを拒否",
"components.RequestButton.decline4krequests": "{requestCount, plural, one {1つの4Kリクエスト} other {{requestCount}つの4Kリクエスト}}を拒否",
"components.RequestButton.approverequests": "{requestCount, plural, one {1つのリクエスト} other {{requestCount}つのリクエスト}}を承認",
"components.RequestButton.decline4krequests": "{requestCount} つの 4K リクエストを拒否",
"components.RequestButton.approverequests": "{requestCount} つのリクエストを承認",
"components.RequestButton.approverequest4k": "4Kリクエストを承認",
"components.RequestButton.approverequest": "リクエストを承認",
"components.RequestButton.approve4krequests": "{requestCount, plural, one {1つ4Kリクエスト} other {{requestCount}つ 4Kリクエスト}}を承認",
"components.RequestButton.approve4krequests": "{requestCount} つ 4K リクエストを承認",
"components.RequestBlock.server": "送信先サーバー",
"components.RequestBlock.rootfolder": "ルートフォルダ",
"components.RequestBlock.requestoverrides": "リクエストのオーバーライド",
"components.RequestBlock.profilechanged": "画質プロファイル",
"components.RegionSelector.regionServerDefault": "デフォルト ({region})",
"components.RegionSelector.regionServerDefault": "デフォルト{region}",
"components.RegionSelector.regionDefault": "全地域",
"components.QuotaSelector.unlimited": "無制限",
"components.QuotaSelector.tvRequests": "{quotaLimit} <quotaUnits>{quotaDays} {days}に{seasons}</quotaUnits>",
"components.QuotaSelector.seasons": "{count, plural, one {シーズン} other {シーズン}}",
"components.QuotaSelector.movies": "{count, plural, one {映画} other {映画}}",
"components.QuotaSelector.movieRequests": "{quotaLimit} <quotaUnits>{quotaDays} {days}に{movies}</quotaUnits>",
"components.QuotaSelector.days": "{count, plural, one {} other {日}}",
"components.QuotaSelector.tvRequests": "<quotaUnits>{quotaDays} {days}に </quotaUnits>{quotaLimit} {seasons}",
"components.QuotaSelector.seasons": "シーズン",
"components.QuotaSelector.movies": "映画",
"components.QuotaSelector.movieRequests": "<quotaUnits>{quotaDays} {days}に </quotaUnits>{quotaLimit} {movies}",
"components.QuotaSelector.days": "日",
"components.PermissionEdit.viewrequests": "リクエストを見る",
"components.PermissionEdit.usersDescription": "Overseerrユーザーを管理する権限を付与する。この権限を持つユーザーは、Admin 権限を持つユーザーの変更や、Admin 権限を付与することはできません。",
"components.NotificationTypeSelector.mediarequestedDescription": "ユーザーが承認を必要とする新メディアリクエストをすると通知する。",
@ -454,8 +453,8 @@
"components.PermissionEdit.requestMoviesDescription": "4K以外の映画をリクエストする権限を与える。",
"components.PermissionEdit.requestMovies": "映画をリクエスト",
"components.PermissionEdit.requestDescription": "4K以外のメディアをリクエストする権限を与える。",
"components.PermissionEdit.request4kTvDescription": "4Kシリーズをリクエストする権限を与える。",
"components.PermissionEdit.request4kTv": "4Kシリーズをリクエスト",
"components.PermissionEdit.request4kTvDescription": "4K シリーズをリクエストする権限を与える。",
"components.PermissionEdit.request4kTv": "4K シリーズをリクエスト",
"components.PermissionEdit.request4kDescription": "4Kメディアをリクエストする権限を与える。",
"components.PermissionEdit.request4kMoviesDescription": "4K映画をリクエストする権限を与える。",
"components.PermissionEdit.request4kMovies": "4K映画をリクエスト",
@ -468,14 +467,14 @@
"components.Layout.VersionStatus.streamstable": "Overseerr安定版",
"components.Layout.VersionStatus.streamdevelop": "Overseerr開発版",
"components.Layout.VersionStatus.outofdate": "期限切れ",
"components.PermissionEdit.autoapprove4kSeriesDescription": "4Kシリーズのリクエストを自動的に承認する。",
"components.PermissionEdit.autoapprove4kSeriesDescription": "4K シリーズのリクエストを自動的に承認する。",
"components.PermissionEdit.autoapprove4kMoviesDescription": "4K映画のリクエストを自動的に承認する。",
"components.PermissionEdit.autoapproveSeriesDescription": "4K以外のシリーズのリクエストを自動的に承認する。",
"components.PermissionEdit.autoapproveSeriesDescription": "4K 以外のシリーズのリクエストを自動的に承認する。",
"components.PermissionEdit.autoapproveSeries": "シリーズを自動的に承認する",
"components.PermissionEdit.autoapproveMoviesDescription": "4K以外の映画のリクエストを自動的に承認する。",
"components.PermissionEdit.autoapproveMovies": "映画を自動的に承認する",
"components.PermissionEdit.autoapproveDescription": "4K以外のリクエストをすべて自動的に承認する。",
"components.PermissionEdit.autoapprove4kSeries": "4Kシリーズを自動的に承認する",
"components.PermissionEdit.autoapprove4kSeries": "4K シリーズを自動的に承認する",
"components.PermissionEdit.autoapprove4kMovies": "4K映画の自動的に承認する",
"components.PermissionEdit.autoapprove4kDescription": "すべての4Kリクエストを自動的に承認する。",
"components.PermissionEdit.autoapprove4k": "4Kの自動承認",
@ -506,5 +505,21 @@
"components.MovieDetails.showless": "少なく表示",
"components.MovieDetails.playonplex": "Plexで再生",
"components.MovieDetails.play4konplex": "Plexで4K再生",
"components.RequestModal.pendingapproval": "リクエストは承認待ちです。"
"components.RequestModal.pendingapproval": "リクエストは承認待ちです。",
"components.UserProfile.UserSettings.UserGeneralSettings.languageDefault": "デフォルト言語({language}",
"components.TvDetails.episodeRuntimeMinutes": "{runtime} 分",
"components.Settings.RadarrModal.loadingTags": "タグ読込中…",
"components.Settings.RadarrModal.notagoptions": "タグなし。",
"components.Settings.SonarrModal.animeTags": "アニメタグ",
"components.Settings.SonarrModal.animelanguageprofile": "アニメ言語プロフィール",
"components.Settings.SonarrModal.notagoptions": "タグなし。",
"components.Settings.SonarrModal.selectLanguageProfile": "言語プロフィールを選ぶ",
"components.Settings.RadarrModal.selecttags": "タグを選ぶ",
"components.Settings.SonarrModal.loadingTags": "タグ読込中…",
"components.Settings.SonarrModal.languageprofile": "言語プロフィール",
"components.Settings.SonarrModal.loadinglanguageprofiles": "言語プロフィール読込中…",
"components.Settings.SonarrModal.validationLanguageProfileRequired": "言語プロフィールを選択してください",
"components.UserProfile.UserSettings.UserGeneralSettings.applanguage": "表示言語",
"components.Settings.locale": "表示言語",
"components.StatusBadge.status": "{status}"
}

@ -671,5 +671,7 @@
"components.Settings.Notifications.NotificationsWebPush.agentenabled": "Aktiver",
"components.Settings.Notifications.NotificationsSlack.validationTypes": "Du må velge minst én varseltype",
"components.Settings.Notifications.NotificationsPushover.validationAccessTokenRequired": "Du må oppgi en gyldig tilgangsnøkkel",
"components.Settings.Notifications.NotificationsPushbullet.validationTypes": "Du må velge minst én varseltype"
"components.Settings.Notifications.NotificationsPushbullet.validationTypes": "Du må velge minst én varseltype",
"components.StatusBadge.status4k": "",
"components.StatusBadge.status": "{status}"
}

@ -25,7 +25,7 @@
"components.MovieDetails.overview": "Overzicht",
"components.MovieDetails.overviewunavailable": "Overzicht niet beschikbaar.",
"components.MovieDetails.recommendations": "Aanbevelingen",
"components.MovieDetails.releasedate": "Releasedatum",
"components.MovieDetails.releasedate": "{releaseCount, plural, one {Releasedatum} other {Releasedata}}",
"components.MovieDetails.revenue": "Omzet",
"components.MovieDetails.runtime": "{minutes} minuten",
"components.MovieDetails.similar": "Vergelijkbare titels",
@ -194,7 +194,7 @@
"components.Settings.SettingsAbout.version": "Versie",
"components.Settings.SettingsAbout.totalrequests": "Totaal aantal verzoeken",
"components.Settings.SettingsAbout.totalmedia": "Totale aantal media",
"components.Settings.SettingsAbout.overseerrinformation": "Overseerr-informatie",
"components.Settings.SettingsAbout.overseerrinformation": "Over Overseerr",
"components.Settings.SettingsAbout.githubdiscussions": "GitHub-discussies",
"components.Setup.tip": "Tip",
"components.Settings.SonarrModal.testFirstRootFolders": "Test verbinding om hoofdmappen te laden",
@ -207,9 +207,9 @@
"components.Settings.RadarrModal.testFirstQualityProfiles": "Test verbinding om kwaliteitsprofielen te laden",
"components.Settings.RadarrModal.loadingrootfolders": "Bezig met laden van hoofdmappen…",
"components.Settings.RadarrModal.loadingprofiles": "Bezig met laden van kwaliteitsprofielen…",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Versiegegevens niet beschikbaar. Is GitHub offline?",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Versiegegevens zijn momenteel niet beschikbaar.",
"components.Settings.SettingsAbout.Releases.latestversion": "Nieuwste",
"components.Settings.SettingsAbout.Releases.currentversion": "Huidige versie",
"components.Settings.SettingsAbout.Releases.currentversion": "Huidig",
"components.MovieDetails.studio": "{studioCount, plural, one {Studio} other {Studio's}}",
"components.CollectionDetails.overview": "Overzicht",
"components.CollectionDetails.numberofmovies": "{count} films",
@ -249,7 +249,6 @@
"components.Settings.SettingsAbout.documentation": "Documentatie",
"components.Settings.SettingsAbout.Releases.viewongithub": "Bekijken op GitHub",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Changelog bekijken",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "De laatste wijzigingen aan de tak <code>develop</code> van Overseerr worden hieronder niet getoond. Zie de commit-geschiedenis voor deze tak op <GithubLink>GitHub</GithubLink> voor details.",
"components.Settings.Notifications.validationChatIdRequired": "Je moet een geldige chat-ID opgeven",
"components.Settings.Notifications.validationBotAPIRequired": "Je moet een bot-authorisatietoken opgeven",
"components.Settings.Notifications.telegramsettingssaved": "Instellingen Telegrammeldingen met succes opgeslagen!",
@ -271,7 +270,7 @@
"components.MovieDetails.MovieCrew.fullcrew": "Volledige crew",
"components.CollectionDetails.requestcollection": "Collectie aanvragen",
"components.UserList.importedfromplex": "{userCount, plural, one {# nieuwe gebruiker} other {# nieuwe gebruikers}} succesvol geïmporteerd vanuit Plex!",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Changelog",
"components.Settings.SettingsAbout.Releases.versionChangelog": "{version} changelog",
"components.Settings.SettingsAbout.Releases.releases": "Versies",
"components.Settings.Notifications.NotificationsSlack.slacksettingssaved": "Instellingen voor Slack-meldingen met succes opgeslagen!",
"components.Settings.Notifications.NotificationsSlack.slacksettingsfailed": "Instellingen voor Slack-meldingen konden niet opgeslagen worden.",
@ -879,5 +878,15 @@
"components.Settings.SettingsAbout.betawarning": "Dit is BETA software. Functies kunnen kapot en/of instabiel zijn. Meld eventuele problemen op GitHub!",
"components.Layout.LanguagePicker.displaylanguage": "Weergavetaal",
"components.MovieDetails.showmore": "Meer tonen",
"components.MovieDetails.showless": "Minder tonen"
"components.MovieDetails.showless": "Minder tonen",
"components.TvDetails.streamingproviders": "Momenteel te streamen op",
"components.MovieDetails.streamingproviders": "Momenteel te streamen op",
"components.Settings.SettingsJobsCache.jobScheduleEditSaved": "Taak met succes bewerkt!",
"components.Settings.SettingsJobsCache.editJobScheduleSelectorMinutes": "Elk(e) {jobScheduleMinutes, plural, one {minuut} other {{jobScheduleMinutes} minuten}}",
"components.Settings.SettingsJobsCache.editJobSchedulePrompt": "Frequentie",
"components.Settings.SettingsJobsCache.jobScheduleEditFailed": "Er ging iets mis bij het opslaan van de taak.",
"components.Settings.SettingsJobsCache.editJobSchedule": "Taak wijzigen",
"components.Settings.SettingsJobsCache.editJobScheduleSelectorHours": "Elk(e) {jobScheduleHours, plural, one {uur} other {{jobScheduleHours} uren}}",
"components.Settings.SettingsAbout.runningDevelop": "Je voert de <code>develop</code>versie van Overseerr uit, die alleen wordt aanbevolen als je bijdraagt aan de ontwikkeling of de allereerste versies helpt testen.",
"components.StatusBadge.status": "{status}"
}

@ -0,0 +1,3 @@
{
"components.StatusBadge.status": ""
}

@ -7,7 +7,7 @@
"components.MovieDetails.similar": "Títulos Semelhantes",
"components.MovieDetails.runtime": "{minutes} minutos",
"components.MovieDetails.revenue": "Receita",
"components.MovieDetails.releasedate": "Lançamento",
"components.MovieDetails.releasedate": "{releaseCount, plural, one {Lançamento} other {Lançamentos}}",
"components.MovieDetails.recommendations": "Recomendações",
"components.MovieDetails.overviewunavailable": "Sinopse indisponível.",
"components.MovieDetails.overview": "Sinopse",
@ -179,12 +179,11 @@
"components.Settings.SettingsAbout.supportoverseerr": "Apoie o Overseerr",
"components.Settings.SettingsAbout.Releases.viewongithub": "Ver no GitHub",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Ver Mudanças",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Mudanças Nessa Versão",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "As últimas mudanças na versão em <code>desenvolvimento</code> não serão exibidas abaixo. Por favor acesse o histórico de mudanças no <GithubLink>GitHub</GithubLink> para detalhes.",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Mudanças em {version}",
"components.Settings.SettingsAbout.Releases.releases": "Versões",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Informações de versão indisponíveis. O GitHub está indisponível?",
"components.Settings.SettingsAbout.Releases.latestversion": "Última Versão",
"components.Settings.SettingsAbout.Releases.currentversion": "Versão Atual",
"components.Settings.SettingsAbout.Releases.currentversion": "Atual",
"components.TvDetails.recommendations": "Recomendações",
"components.TvDetails.overviewunavailable": "Sinopse indisponível.",
"components.TvDetails.overview": "Sinopse",
@ -879,5 +878,12 @@
"components.Settings.SettingsAbout.betawarning": "Essa é uma versão BETA. Algumas funcionalidades podem ser instáveis ou não funcionarem. Por favor reporte qualquer problema no GitHub!",
"components.Layout.LanguagePicker.displaylanguage": "Idioma da Interface",
"components.MovieDetails.showmore": "Mostrar Mais",
"components.MovieDetails.showless": "Mostrar Menos"
"components.MovieDetails.showless": "Mostrar Menos",
"components.TvDetails.streamingproviders": "Em Exibição na",
"components.MovieDetails.streamingproviders": "Em Exibição na",
"components.Settings.SettingsJobsCache.jobScheduleEditSaved": "Tarefa editada com sucesso!",
"components.Settings.SettingsJobsCache.editJobSchedulePrompt": "Frequência",
"components.Settings.SettingsJobsCache.editJobScheduleSelectorHours": "A cada {jobScheduleHours, plural, one {hora} other {{jobScheduleHours} horas}}",
"components.Settings.SettingsJobsCache.editJobScheduleSelectorMinutes": "A cada {jobScheduleMinutes, plural, one {minuto} other {{jobScheduleMinutes} minutos}}",
"components.StatusBadge.status": "{status}"
}

@ -136,7 +136,7 @@
"components.MovieDetails.similar": "Títulos Similares",
"components.MovieDetails.runtime": "{minutes} minutos",
"components.MovieDetails.revenue": "Receita",
"components.MovieDetails.releasedate": "Data de Estreia",
"components.MovieDetails.releasedate": "{releaseCount, plural, one {Data} other {Datas}} de Estreia",
"components.MovieDetails.recommendations": "Recomendações",
"components.MovieDetails.overviewunavailable": "Sinopse indisponível.",
"components.MovieDetails.overview": "Sinopse",
@ -200,12 +200,12 @@
"components.UserList.usercreatedsuccess": "Utilizador criado com sucesso!",
"components.UserList.usercreatedfailed": "Ocorreu um erro ao criar o utilizador.",
"components.UserList.user": "Utilizador",
"components.UserList.totalrequests": "Total de Pedidos",
"components.UserList.totalrequests": "Pedidos",
"components.UserList.role": "Função",
"components.UserList.plexuser": "Utilizador Plex",
"components.UserList.passwordinfodescription": "Configurar um URL de aplicação e ativar as notificações por e-mail para permitir a geração automática de palavra-passe.",
"components.UserList.localuser": "Utilizador Local",
"components.UserList.lastupdated": "Última Atualização",
"components.UserList.lastupdated": "Atualizado",
"components.UserList.importfromplexerror": "Ocorreu um erro ao importar utilizadores do Plex.",
"components.UserList.importfromplex": "Importar Utilizadores do Plex",
"components.UserList.importedfromplex": "{userCount, plural, one {# novo utilizador} other {# novos utilizadores}} importados do Plex com sucesso!",
@ -306,7 +306,6 @@
"components.Settings.SettingsAbout.Releases.viewongithub": "Ver no GitHub",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Ver Mudanças",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Mudanças Nesta Versão",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "As últimas mudanças na branch <code>develop</code> do Overseerr não são mostradas abaixo. Por favor, veja o histórico de commits para esta branch no <GithubLink>GitHub</GithubLink> para detalhes.",
"components.Settings.SettingsAbout.Releases.releases": "Versões",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Informações de versão indisponíveis. O GitHub está abaixo?",
"components.Settings.SettingsAbout.Releases.latestversion": "Mais Recente",
@ -483,7 +482,7 @@
"components.ResetPassword.password": "Palavra-passe",
"components.ResetPassword.gobacklogin": "Voltar a Página de Inicio de Sessão",
"components.ResetPassword.resetpassword": "Repor a sua Palavra-passe",
"components.ResetPassword.emailresetlink": "Enviar um endereço de Recuperação por E-mail",
"components.ResetPassword.emailresetlink": "Link de Recuperação por E-mail",
"components.ResetPassword.email": "Endereço E-mail",
"components.ResetPassword.confirmpassword": "Confirmar Palavra-passe",
"components.Login.forgotpassword": "Esqueceu a Palavra-passe?",
@ -568,7 +567,7 @@
"components.UserProfile.UserSettings.UserGeneralSettings.admin": "Administrador",
"components.UserProfile.UserSettings.UserGeneralSettings.accounttype": "Tipo de Conta",
"components.UserList.owner": "Proprietário",
"components.UserList.accounttype": "Tipo de Conta",
"components.UserList.accounttype": "Tipo",
"i18n.loading": "A carregar…",
"components.UserProfile.UserSettings.UserNotificationSettings.validationTelegramChatId": "Deve fornecer um ID de chat válido",
"components.UserProfile.UserSettings.UserNotificationSettings.telegramChatIdTipLong": "<TelegramBotLink>Iniciar uma conversa</TelegramBotLink>, adicionar <GetIdBotLink>@get_id_bot</GetIdBotLink>, e enviar o comando <code>/my_id</code>",
@ -876,5 +875,11 @@
"components.NotificationTypeSelector.usermediadeclinedDescription": "Notificar quando seus pedidos de multimédia forem recusados.",
"components.NotificationTypeSelector.usermediaavailableDescription": "Notificar quando os seus pedidos de multimédia ficarem disponíveis.",
"components.QuotaSelector.days": "{conta, plural, um {dia} outro {dias}}",
"components.Settings.SettingsAbout.betawarning": "Isto é um software em BETA. As funcionalidades podem estar quebradas e/ou instáveis. Relate qualquer problema no GitHub!"
"components.Settings.SettingsAbout.betawarning": "Isto é um software em BETA. As funcionalidades podem estar quebradas e/ou instáveis. Relate qualquer problema no GitHub!",
"components.MovieDetails.streamingproviders": "Atualmente a Exibir em",
"components.TvDetails.streamingproviders": "Atualmente a Exibir em",
"components.MovieDetails.showmore": "Mostrar Mais",
"components.Layout.LanguagePicker.displaylanguage": "Idioma da Interface",
"components.MovieDetails.showless": "Mostrar Menos",
"components.StatusBadge.status": "{status}"
}

@ -4,12 +4,12 @@
"components.Discover.popularmovies": "Популярные фильмы",
"components.Discover.populartv": "Популярные сериалы",
"components.Discover.recentlyAdded": "Недавно добавленные",
"components.Discover.recentrequests": "Недавние запросы",
"components.Discover.recentrequests": "Последние запросы",
"components.Discover.trending": "В трендах",
"components.Discover.upcoming": "Предстоящие фильмы",
"components.Discover.upcomingmovies": "Предстоящие фильмы",
"components.Layout.SearchInput.searchPlaceholder": "Поиск фильмов и сериалов",
"components.Layout.Sidebar.dashboard": "Открыть что-то новое",
"components.Layout.Sidebar.dashboard": "Найти что-то новое",
"components.Layout.Sidebar.requests": "Запросы",
"components.Layout.Sidebar.settings": "Настройки",
"components.Layout.Sidebar.users": "Пользователи",
@ -25,145 +25,145 @@
"components.MovieDetails.overview": "Обзор",
"components.MovieDetails.overviewunavailable": "Обзор недоступен.",
"components.MovieDetails.recommendations": "Рекомендации",
"components.MovieDetails.releasedate": "Дата релиза",
"components.MovieDetails.releasedate": "{releaseCount, plural, one {Дата релиза} other {Даты релиза}}",
"components.MovieDetails.revenue": "Доход",
"components.MovieDetails.runtime": "{minutes} минут",
"components.MovieDetails.similar": "Похожие фильмы",
"components.PersonDetails.appearsin": "Появления в фильмах и сериалах",
"components.PersonDetails.ascharacter": "в роли {character}",
"components.RequestBlock.seasons": "{seasonCount, plural, one {сезон} other {сезонов}}",
"components.RequestCard.seasons": "{seasonCount, plural, one {сезон} other {сезонов}}",
"components.RequestList.RequestItem.seasons": "{seasonCount, plural, one {сезон} other {сезонов}}",
"components.RequestBlock.seasons": "{seasonCount, plural, one {сезон} other {сезона(ов)}}",
"components.RequestCard.seasons": "{seasonCount, plural, one {сезон} other {сезона(ов)}}",
"components.RequestList.RequestItem.seasons": "{seasonCount, plural, one {сезон} other {сезона(ов)}}",
"components.RequestList.requests": "Запросы",
"components.RequestModal.cancel": "Отменить запрос",
"components.RequestModal.extras": "Дополнительно",
"components.RequestModal.numberofepisodes": "# из эпизодов",
"components.RequestModal.pendingrequest": "",
"components.RequestModal.requestCancel": "",
"components.RequestModal.requestSuccess": "",
"components.RequestModal.numberofepisodes": "# эпизодов",
"components.RequestModal.pendingrequest": "В ожидании запрос на {title}",
"components.RequestModal.requestCancel": "Запрос на <strong>{title}</strong> отменён.",
"components.RequestModal.requestSuccess": "<strong>{title}</strong> успешно запрошен!",
"components.RequestModal.requestadmin": "Этот запрос будет одобрен автоматически.",
"components.RequestModal.requestfrom": "",
"components.RequestModal.requestseasons": "",
"components.RequestModal.requesttitle": "Запрос {title}",
"components.RequestModal.requestfrom": "Запрос пользователя {username} ожидает одобрения.",
"components.RequestModal.requestseasons": "Запросить {seasonCount} {seasonCount, plural, one {сезон} other {сезона(ов)}}",
"components.RequestModal.requesttitle": "Запросить {title}",
"components.RequestModal.season": "Сезон",
"components.RequestModal.seasonnumber": "Сезон {number}",
"components.RequestModal.selectseason": "Выберите сезон(ы)",
"components.Search.searchresults": "Результаты поиска",
"components.Settings.Notifications.agentenabled": "Включить агент",
"components.Settings.Notifications.agentenabled": "Активировать службу",
"components.Settings.Notifications.authPass": "Пароль SMTP",
"components.Settings.Notifications.authUser": "Имя пользователя SMTP",
"components.Settings.Notifications.emailsender": "Адрес отправителя",
"components.Settings.Notifications.smtpHost": "",
"components.Settings.Notifications.smtpPort": "",
"components.Settings.Notifications.validationSmtpHostRequired": "",
"components.Settings.Notifications.validationSmtpPortRequired": "",
"components.Settings.Notifications.webhookUrl": "",
"components.Settings.Notifications.smtpHost": "SMTP-хост",
"components.Settings.Notifications.smtpPort": "SMTP порт",
"components.Settings.Notifications.validationSmtpHostRequired": "Вы должны указать действительное имя хоста или IP-адрес",
"components.Settings.Notifications.validationSmtpPortRequired": "Вы должны указать действительный номер порта",
"components.Settings.Notifications.webhookUrl": "URL веб-перехватчика",
"components.Settings.RadarrModal.add": "Добавить сервер",
"components.Settings.RadarrModal.apiKey": "Ключ API",
"components.Settings.RadarrModal.baseUrl": "",
"components.Settings.RadarrModal.baseUrl": "Базовый URL",
"components.Settings.RadarrModal.createradarr": "Добавить новый сервер Radarr",
"components.Settings.RadarrModal.defaultserver": "Сервер по умолчанию",
"components.Settings.RadarrModal.editradarr": "Редактировать сервер Radarr",
"components.Settings.RadarrModal.hostname": "Имя хоста",
"components.Settings.RadarrModal.hostname": "Имя хоста или IP-адрес",
"components.Settings.RadarrModal.minimumAvailability": "Минимальная доступность",
"components.Settings.RadarrModal.port": "Порт",
"components.Settings.RadarrModal.qualityprofile": "Профиль качества",
"components.Settings.RadarrModal.rootfolder": "Корневой каталог",
"components.Settings.RadarrModal.selectMinimumAvailability": "",
"components.Settings.RadarrModal.selectMinimumAvailability": "Выберите минимальную доступность",
"components.Settings.RadarrModal.selectQualityProfile": "Выберите профиль качества",
"components.Settings.RadarrModal.selectRootFolder": "Выберите корневой каталог",
"components.Settings.RadarrModal.server4k": "4K Сервер",
"components.Settings.RadarrModal.server4k": "4К сервер",
"components.Settings.RadarrModal.servername": "Название сервера",
"components.Settings.RadarrModal.ssl": "Использовать SSL",
"components.Settings.RadarrModal.toastRadarrTestFailure": "",
"components.Settings.RadarrModal.toastRadarrTestSuccess": "",
"components.Settings.RadarrModal.validationApiKeyRequired": "",
"components.Settings.RadarrModal.validationHostnameRequired": "",
"components.Settings.RadarrModal.validationPortRequired": "",
"components.Settings.RadarrModal.toastRadarrTestFailure": "Не удалось подключиться к Radarr.",
"components.Settings.RadarrModal.toastRadarrTestSuccess": "Соединение с Radarr установлено успешно!",
"components.Settings.RadarrModal.validationApiKeyRequired": "Вы должны предоставить ключ API",
"components.Settings.RadarrModal.validationHostnameRequired": "Вы должны указать имя хоста или IP-адрес",
"components.Settings.RadarrModal.validationPortRequired": "Вы должны указать действительный номер порта",
"components.Settings.RadarrModal.validationProfileRequired": "Вы должны выбрать профиль качества",
"components.Settings.RadarrModal.validationRootFolderRequired": "Вы должны выбрать корневой каталог",
"components.Settings.SonarrModal.add": "Добавить сервер",
"components.Settings.SonarrModal.apiKey": "Ключ API",
"components.Settings.SonarrModal.baseUrl": "",
"components.Settings.SonarrModal.createsonarr": "",
"components.Settings.SonarrModal.baseUrl": "Базовый URL",
"components.Settings.SonarrModal.createsonarr": "Добавить новый сервер Sonarr",
"components.Settings.SonarrModal.defaultserver": "Сервер по умолчанию",
"components.Settings.SonarrModal.editsonarr": "",
"components.Settings.SonarrModal.hostname": "Имя хоста",
"components.Settings.SonarrModal.editsonarr": "Редактировать сервер Sonarr",
"components.Settings.SonarrModal.hostname": "Имя хоста или IP-адрес",
"components.Settings.SonarrModal.port": "Порт",
"components.Settings.SonarrModal.qualityprofile": "Профиль качества",
"components.Settings.SonarrModal.rootfolder": "Корневой каталог",
"components.Settings.SonarrModal.seasonfolders": "",
"components.Settings.SonarrModal.seasonfolders": "Папки для сезонов",
"components.Settings.SonarrModal.selectQualityProfile": "Выберите профиль качества",
"components.Settings.SonarrModal.selectRootFolder": "Выберите корневой каталог",
"components.Settings.SonarrModal.server4k": "4K Сервер",
"components.Settings.SonarrModal.server4k": "4К сервер",
"components.Settings.SonarrModal.servername": "Название сервера",
"components.Settings.SonarrModal.ssl": "Использовать SSL",
"components.Settings.SonarrModal.validationApiKeyRequired": "",
"components.Settings.SonarrModal.validationHostnameRequired": "",
"components.Settings.SonarrModal.validationPortRequired": "",
"components.Settings.SonarrModal.validationProfileRequired": "",
"components.Settings.SonarrModal.validationApiKeyRequired": "Вы должны предоставить ключ API",
"components.Settings.SonarrModal.validationHostnameRequired": "Вы должны указать имя хоста или IP-адрес",
"components.Settings.SonarrModal.validationPortRequired": "Вы должны указать действительный номер порта",
"components.Settings.SonarrModal.validationProfileRequired": "Вы должны выбрать профиль качества",
"components.Settings.SonarrModal.validationRootFolderRequired": "Вы должны выбрать корневой каталог",
"components.Settings.activeProfile": "Активный профиль",
"components.Settings.addradarr": "",
"components.Settings.addradarr": "Добавить сервер Radarr",
"components.Settings.address": "Адрес",
"components.Settings.addsonarr": "",
"components.Settings.addsonarr": "Добавить сервер Sonarr",
"components.Settings.apikey": "Ключ API",
"components.Settings.applicationurl": "URL-адрес приложения",
"components.Settings.cancelscan": "Отменить сканирование",
"components.Settings.copied": "",
"components.Settings.copied": "Ключ API скопирован в буфер обмена.",
"components.Settings.currentlibrary": "Текущая библиотека: {name}",
"components.Settings.default": "По умолчанию",
"components.Settings.default4k": "По умолчанию 4K",
"components.Settings.deleteserverconfirm": "",
"components.Settings.default4k": "4К по умолчанию",
"components.Settings.deleteserverconfirm": "Вы уверены, что хотите удалить этот сервер?",
"components.Settings.generalsettings": "Общие настройки",
"components.Settings.generalsettingsDescription": "",
"components.Settings.hostname": "",
"components.Settings.librariesRemaining": "",
"components.Settings.manualscan": "Сканирование библиотеки вручную",
"components.Settings.manualscanDescription": "",
"components.Settings.menuAbout": "",
"components.Settings.menuGeneralSettings": "Общие настройки",
"components.Settings.menuJobs": "",
"components.Settings.menuLogs": "",
"components.Settings.generalsettingsDescription": "Настройте глобальные параметры и параметры по умолчанию для Overseerr.",
"components.Settings.hostname": "Имя хоста или IP-адрес",
"components.Settings.librariesRemaining": "Осталось библиотек: {count}",
"components.Settings.manualscan": "Сканировать библиотеки вручную",
"components.Settings.manualscanDescription": "Обычно выполняется раз в 24 часа. Overseerr выполнит более агрессивную проверку вашего сервера Plex на предмет недавно добавленных мультимедиа. Если вы впервые настраиваете Plex, рекомендуется выполнить однократное полное сканирование библиотек вручную!",
"components.Settings.menuAbout": "О проекте",
"components.Settings.menuGeneralSettings": "Общее",
"components.Settings.menuJobs": "Задания и кэш",
"components.Settings.menuLogs": "Логи",
"components.Settings.menuNotifications": "Уведомления",
"components.Settings.menuPlexSettings": "Plex",
"components.Settings.menuServices": "",
"components.Settings.menuServices": "Службы",
"components.Settings.notificationsettings": "Настройки уведомлений",
"components.Settings.notrunning": "",
"components.Settings.notrunning": "Не работает",
"components.Settings.plexlibraries": "Библиотеки Plex",
"components.Settings.plexlibrariesDescription": "",
"components.Settings.plexlibrariesDescription": "Библиотеки, которые Overseerr сканирует на предмет наличия мультимедиа. Настройте и сохраните параметры подключения Plex, затем нажмите кнопку ниже, если список библиотек пуст.",
"components.Settings.plexsettings": "Настройки Plex",
"components.Settings.plexsettingsDescription": "",
"components.Settings.plexsettingsDescription": "Настройте параметры вашего сервера Plex. Overseerr сканирует ваши библиотеки Plex, чтобы определить доступность контента.",
"components.Settings.port": "Порт",
"components.Settings.radarrsettings": "Настройки Radarr",
"components.Settings.sonarrsettings": "Настройки Sonarr",
"components.Settings.ssl": "SSL",
"components.Settings.startscan": "Начать сканирование",
"components.Setup.configureplex": "",
"components.Setup.configureservices": "",
"components.Setup.configureplex": "Настройте Plex",
"components.Setup.configureservices": "Настройте службы",
"components.Setup.continue": "Продолжить",
"components.Setup.finish": "Завершить настройку",
"components.Setup.finishing": "Завершение…",
"components.Setup.loginwithplex": "Войти с помощью Plex",
"components.Setup.signinMessage": "",
"components.Setup.signinMessage": "Начните с входа в систему с помощью учётной записи Plex",
"components.Setup.welcome": "Добро пожаловать в Overseerr",
"components.TvDetails.cast": "В ролях",
"components.TvDetails.manageModalClearMedia": "Очистить все медиаданные",
"components.TvDetails.manageModalClearMediaWarning": "",
"components.TvDetails.manageModalNoRequests": "Нет запросов.",
"components.TvDetails.manageModalClearMedia": "Очистить данные мультимедиа",
"components.TvDetails.manageModalClearMediaWarning": "* Это приведет к безвозвратному удалению всех данных для этого сериала, включая все запросы. Если сериал существует в вашей библиотеке Plex, мультимедийная информация о нём будет воссоздана при следующем сканировании.",
"components.TvDetails.manageModalNoRequests": "Запросов нет.",
"components.TvDetails.manageModalRequests": "Запросы",
"components.TvDetails.manageModalTitle": "",
"components.TvDetails.originallanguage": "Оригинальный язык",
"components.TvDetails.manageModalTitle": "Управление сериалом",
"components.TvDetails.originallanguage": "Язык оригинала",
"components.TvDetails.overview": "Обзор",
"components.TvDetails.overviewunavailable": "Обзор недоступен.",
"components.TvDetails.recommendations": "Рекомендации",
"components.TvDetails.similar": "",
"components.TvDetails.similar": "Похожие сериалы",
"components.UserList.admin": "Администратор",
"components.UserList.created": "Созданно",
"components.UserList.lastupdated": "Последнее обновление",
"components.UserList.created": "Создан",
"components.UserList.lastupdated": "Обновлено",
"components.UserList.plexuser": "Пользователь Plex",
"components.UserList.role": "Роль",
"components.UserList.totalrequests": "Всего запросов",
"components.UserList.totalrequests": "Запросов",
"components.UserList.user": "Пользователь",
"components.UserList.userlist": "Список пользователей",
"i18n.approve": "Одобрить",
@ -174,11 +174,11 @@
"i18n.declined": "Отклонено",
"i18n.delete": "Удалить",
"i18n.movies": "Фильмы",
"i18n.partiallyavailable": "Частично доступно",
"i18n.partiallyavailable": "Доступно частично",
"i18n.pending": "В ожидании",
"i18n.processing": "Обработка",
"i18n.tvshows": "",
"i18n.unavailable": "Недоступен",
"i18n.tvshows": "Сериалы",
"i18n.unavailable": "Недоступно",
"pages.oops": "Упс",
"pages.returnHome": "Вернуться домой",
"components.CollectionDetails.overview": "Обзор",
@ -188,7 +188,7 @@
"components.Login.email": "Адрес электронной почты",
"components.UserList.users": "Пользователи",
"components.UserList.userdeleted": "Пользователь успешно удален!",
"components.UserList.usercreatedsuccess": "Пользователь создан успешно!",
"components.UserList.usercreatedsuccess": "Пользователь успешно создан!",
"components.Settings.SettingsAbout.totalrequests": "Всего запросов",
"components.UserList.sortRequests": "Количество запросов",
"components.UserList.sortCreated": "Дата создания",
@ -201,62 +201,62 @@
"components.UserList.creating": "Создание…",
"components.UserList.createlocaluser": "Создать локального пользователя",
"components.UserList.create": "Создать",
"components.TvDetails.network": "Сеть",
"components.TvDetails.network": "{networkCount, plural, one {Телеканал} other {Телеканалы}}",
"components.TvDetails.anime": "Аниме",
"components.StatusChacker.newversionavailable": "Доступна новая версия",
"components.Settings.toastSettingsSuccess": "Настройки сохранены!",
"components.StatusChacker.newversionavailable": "Обновить приложение",
"components.Settings.toastSettingsSuccess": "Настройки успешно сохранены!",
"components.Settings.serverpresetManualMessage": "Ручная настройка",
"components.Settings.serverpreset": "Сервер",
"i18n.deleting": "Удаление…",
"components.Settings.applicationTitle": "Название приложения",
"components.Settings.SettingsAbout.Releases.latestversion": "Самый последний",
"components.Settings.SettingsAbout.Releases.currentversion": "Текущая версия",
"components.Settings.SettingsAbout.Releases.latestversion": "Последняя",
"components.Settings.SettingsAbout.Releases.currentversion": "Текущая",
"components.Settings.SonarrModal.syncEnabled": "Включить сканирование",
"components.Settings.RadarrModal.syncEnabled": "Включить сканирование",
"components.Settings.Notifications.sendSilentlyTip": "Отправлять уведомления без звука",
"components.Settings.Notifications.telegramsettingssaved": "Настройки уведомлений Telegram успешно сохранены!",
"components.Settings.Notifications.senderName": "Имя отправителя",
"components.Settings.Notifications.botAPI": "Токен авторизации бота",
"components.Settings.Notifications.NotificationsPushover.agentenabled": "Агент включен",
"components.Settings.Notifications.NotificationsSlack.agentenabled": "Агент включен",
"components.Settings.Notifications.NotificationsWebhook.agentenabled": "Агент включен",
"components.Settings.Notifications.NotificationsPushover.agentenabled": "Активировать службу",
"components.Settings.Notifications.NotificationsSlack.agentenabled": "Активировать службу",
"components.Settings.Notifications.NotificationsWebhook.agentenabled": "Активировать службу",
"components.Search.search": "Поиск",
"components.ResetPassword.resetpassword": "Сбросить пароль",
"components.ResetPassword.resetpassword": "Сброс пароля",
"components.ResetPassword.password": "Пароль",
"components.ResetPassword.confirmpassword": "Подтвердить пароль",
"components.RequestModal.requesterror": "Что-то пошло не так при отправке запроса.",
"components.RequestModal.requestedited": "Запрос на <strong>{title}</strong> успешно отредактирован!",
"components.RequestModal.requestcancelled": "Запрос на <strong>{title}</strong> отменен.",
"components.RequestModal.requestcancelled": "Запрос на <strong>{title}</strong> отменён.",
"components.RequestModal.errorediting": "Что-то пошло не так при редактировании запроса.",
"components.RequestModal.AdvancedRequester.rootfolder": "Корневой каталог",
"components.RequestModal.AdvancedRequester.requestas": "Запросить как",
"components.RequestModal.AdvancedRequester.qualityprofile": "Профиль качества",
"components.RequestModal.AdvancedRequester.default": "{name} (по умолчанию)",
"components.RequestModal.AdvancedRequester.advancedoptions": "Дополнительно",
"components.RequestModal.AdvancedRequester.advancedoptions": "Расширенные настройки",
"components.RequestList.sortModified": "Последнее изменение",
"components.RequestList.sortAdded": "Дата запроса",
"components.RequestList.showallrequests": "Показать все запросы",
"components.RequestButton.viewrequest": "Посмотреть запрос",
"i18n.retry": "Повторить",
"i18n.requested": "Запросы",
"i18n.requested": "Запрошено",
"components.PermissionEdit.request4k": "Запрос 4K",
"components.PermissionEdit.request": "Запрос",
"i18n.request": "Запрос",
"i18n.request": "Запросить",
"i18n.failed": "Ошибка",
"i18n.experimental": "Экспериментально",
"i18n.experimental": "Экспериментальный параметр",
"i18n.close": "Закрыть",
"i18n.advanced": ополнительно",
"i18n.advanced": ля продвинутых пользователей",
"components.Settings.SonarrModal.externalUrl": "Внешний URL-адрес",
"components.Settings.RadarrModal.externalUrl": "Внешний URL-адрес",
"components.Settings.Notifications.sendSilently": "Отправить без звука",
"components.Settings.Notifications.NotificationsWebhook.resetPayload": "Восстановить значения по умолчанию",
"components.Settings.Notifications.sendSilently": "Отправлять без звука",
"components.Settings.Notifications.NotificationsWebhook.resetPayload": "Сбросить к настройкам по умолчанию",
"components.Settings.Notifications.NotificationsWebhook.validationWebhookUrl": "Вы должны указать действительный URL-адрес",
"components.Settings.validationApplicationUrl": "Вы должны указать действительный URL-адрес",
"components.Settings.Notifications.validationUrl": "Вы должны указать действительный URL-адрес",
"components.Settings.RadarrModal.validationApplicationUrl": "Вы должны указать действительный URL-адрес",
"components.Settings.SonarrModal.validationApplicationUrl": "Вы должны указать действительный URL-адрес",
"components.Settings.Notifications.NotificationsSlack.validationWebhookUrl": "Вы должны указать действительный URL-адрес",
"components.Settings.Notifications.NotificationsPushover.userToken": "Ключ пользователя",
"components.Settings.Notifications.NotificationsPushover.userToken": "Ключ пользователя или группы",
"components.UserList.email": "Адрес электронной почты",
"components.ResetPassword.email": "Адрес электронной почты",
"components.Settings.SonarrModal.languageprofile": "Языковой профиль",
@ -277,21 +277,21 @@
"components.UserProfile.UserSettings.menuPermissions": "Разрешения",
"components.UserProfile.UserSettings.UserPermissions.permissions": "Разрешения",
"components.UserProfile.UserSettings.menuNotifications": "Уведомления",
"components.UserProfile.UserSettings.menuGeneralSettings": "Общие настройки",
"components.UserProfile.UserSettings.menuGeneralSettings": "Общее",
"components.UserProfile.UserSettings.menuChangePass": "Пароль",
"components.UserProfile.UserSettings.UserGeneralSettings.localuser": "Локальный пользователь",
"components.UserProfile.UserSettings.UserGeneralSettings.generalsettings": "Общие настройки",
"components.UserList.sortDisplayName": "Отображаемое имя",
"components.UserProfile.UserSettings.UserGeneralSettings.displayName": "Отображаемое имя",
"components.UserProfile.UserSettings.UserPasswordChange.validationCurrentPassword": "Вы должны указать свой текущий пароль",
"components.UserProfile.UserSettings.UserPasswordChange.validationConfirmPassword": "Вы должны подтвердить свой новый пароль",
"components.UserProfile.UserSettings.UserPasswordChange.toastSettingsSuccess": "Пароль изменен!",
"components.UserProfile.UserSettings.UserPasswordChange.validationConfirmPassword": "Вы должны подтвердить новый пароль",
"components.UserProfile.UserSettings.UserPasswordChange.toastSettingsSuccess": "Пароль успешно сохранён!",
"components.UserProfile.UserSettings.UserPasswordChange.password": "Пароль",
"components.UserProfile.UserSettings.UserPasswordChange.newpassword": "Новый пароль",
"components.UserProfile.UserSettings.UserPasswordChange.currentpassword": "Текущий пароль",
"components.UserProfile.UserSettings.UserPasswordChange.confirmpassword": "Подтвердить пароль",
"components.UserProfile.UserSettings.UserGeneralSettings.toastSettingsSuccess": "Настройки сохранены!",
"components.UserProfile.UserSettings.UserPermissions.toastSettingsSuccess": "Настройки сохранены!",
"components.UserProfile.UserSettings.UserPasswordChange.confirmpassword": "Подтвердите пароль",
"components.UserProfile.UserSettings.UserGeneralSettings.toastSettingsSuccess": "Настройки успешно сохранены!",
"components.UserProfile.UserSettings.UserPermissions.toastSettingsSuccess": "Разрешения успешно сохранены!",
"components.Settings.toastSettingsFailure": "Что-то пошло не так при сохранении настроек.",
"components.UserProfile.UserSettings.UserGeneralSettings.toastSettingsFailure": "Что-то пошло не так при сохранении настроек.",
"components.UserProfile.UserSettings.UserPermissions.toastSettingsFailure": "Что-то пошло не так при сохранении настроек.",
@ -299,8 +299,8 @@
"components.UserProfile.UserSettings.UserGeneralSettings.plexuser": "Пользователь Plex",
"components.UserList.owner": "Владелец",
"components.UserProfile.UserSettings.UserGeneralSettings.owner": "Владелец",
"components.MovieDetails.markavailable": "Отметить как доступное",
"components.TvDetails.markavailable": "Отметить как доступное",
"components.MovieDetails.markavailable": "Пометить как доступный",
"components.TvDetails.markavailable": "Пометить как доступный",
"components.MovieDetails.downloadstatus": "Статус загрузки",
"components.TvDetails.downloadstatus": "Статус загрузки",
"components.StatusChacker.reloadOverseerr": "Перезагрузить",
@ -310,7 +310,7 @@
"components.Settings.Notifications.NotificationsLunaSea.validationWebhookUrl": "Вы должны указать действительный URL-адрес",
"components.Settings.Notifications.NotificationsLunaSea.profileName": "Название профиля",
"components.ResetPassword.resetpasswordsuccessmessage": "Пароль сброшен успешно!",
"components.ResetPassword.passwordreset": "Сброс пароля",
"components.ResetPassword.passwordreset": "Сбросить пароль",
"components.RequestModal.edit": "Редактировать запрос",
"components.RequestModal.QuotaDisplay.movie": "фильм",
"components.RequestModal.AdvancedRequester.tags": "Теги",
@ -339,23 +339,23 @@
"components.LanguageSelector.originalLanguageDefault": "Все языки",
"components.LanguageSelector.languageServerDefault": "По умолчанию ({language})",
"components.Discover.StudioSlider.studios": "Студии",
"components.Discover.NetworkSlider.networks": "TV-сети",
"components.Discover.NetworkSlider.networks": "Телеканалы",
"components.Discover.DiscoverStudio.studioMovies": "Фильмы {studio}",
"components.Discover.DiscoverMovieLanguage.languageMovies": "Фильмы на языке \"{language}\"",
"components.Discover.DiscoverMovieGenre.genreMovies": "Фильмы в жанре \"{genre}\"",
"components.Settings.SettingsAbout.overseerrinformation": "Информация о Overseerr",
"components.Settings.SettingsAbout.overseerrinformation": "Об Overseerr",
"components.Settings.SettingsAbout.githubdiscussions": "Обсуждения на GitHub",
"components.Settings.enablessl": "Использовать SSL",
"components.Settings.is4k": "4K",
"components.Settings.is4k": "4К",
"components.Settings.mediaTypeMovie": "фильм",
"components.Settings.SonarrModal.tags": "Теги",
"components.Settings.RadarrModal.tags": "Теги",
"i18n.testing": "Тестирование…",
"i18n.test": "Тест",
"i18n.test": "Протестировать",
"i18n.status": "Статус",
"i18n.saving": "Сохранение…",
"i18n.previous": "Предыдущий",
"i18n.next": "Следующий",
"i18n.previous": "Предыдущая",
"i18n.next": "Следующая",
"i18n.movie": "Фильм",
"i18n.canceling": "Отмена…",
"i18n.back": "Назад",
@ -365,20 +365,20 @@
"components.Settings.plex": "Plex",
"components.Settings.notifications": "Уведомления",
"components.Settings.SettingsUsers.users": "Пользователи",
"components.Settings.SettingsLogs.resumeLogs": "Продолжить",
"components.Settings.SettingsLogs.pauseLogs": ауза",
"components.Settings.SettingsLogs.resumeLogs": "Возобновить",
"components.Settings.SettingsLogs.pauseLogs": риостановить",
"components.Settings.SettingsLogs.message": "Сообщение",
"components.Settings.SettingsLogs.label": "Метка",
"components.Settings.SettingsLogs.filterWarn": "Предупреждение",
"components.Settings.SettingsLogs.filterInfo": "Информация",
"components.Settings.SettingsLogs.filterError": "Ошибка",
"components.Settings.SettingsLogs.filterWarn": "Предупреждения",
"components.Settings.SettingsLogs.filterInfo": "Информационные",
"components.Settings.SettingsLogs.filterError": "Ошибки",
"components.Settings.menuUsers": "Пользователи",
"components.Settings.scanning": "Синхронизация…",
"i18n.loading": "Загрузка…",
"components.UserProfile.UserSettings.UserGeneralSettings.user": "Пользователь",
"components.UserProfile.UserSettings.UserGeneralSettings.role": "Роль",
"components.Settings.webhook": "Webhook",
"components.Setup.setup": "Настройка",
"components.Settings.webhook": "Веб-перехватчик",
"components.Setup.setup": "Настройки",
"components.Settings.SettingsJobsCache.process": "Процесс",
"components.Settings.SettingsJobsCache.command": "Команда",
"components.Settings.SettingsJobsCache.jobtype": "Тип",
@ -389,46 +389,46 @@
"components.Settings.SettingsAbout.version": "Версия",
"components.UserProfile.ProfileHeader.profile": "Посмотреть профиль",
"components.Settings.SettingsJobsCache.cachename": "Название кэша",
"components.Settings.SettingsJobsCache.cacheksize": "Размер ключа",
"components.Settings.SettingsJobsCache.cacheksize": "Размер ключей",
"components.Settings.SettingsJobsCache.cachekeys": "Всего ключей",
"components.UserList.bulkedit": "Массовое редактирование",
"components.MediaSlider.ShowMoreCard.seemore": "Больше информации",
"components.TvDetails.watchtrailer": "Смотреть трейлер",
"components.Settings.SettingsAbout.timezone": "Часовой пояс",
"components.Settings.SettingsAbout.supportoverseerr": "Поддержка Overseerr",
"components.Settings.SettingsAbout.supportoverseerr": "Поддержать Overseerr",
"components.NotificationTypeSelector.usermediaAutoApprovedDescription": "Получать уведомления, когда другие пользователи отправляют новые медиа-запросы, которые одобряются автоматически.",
"components.NotificationTypeSelector.mediarequestedDescription": "Отправлять уведомления, когда пользователи отправляют новые медиа-запросы, требующие одобрения.",
"components.NotificationTypeSelector.mediarequested": "Медиафайлы запрошены",
"components.NotificationTypeSelector.mediarequested": "Запросы медиафайлов",
"components.NotificationTypeSelector.mediafailedDescription": "Отправлять уведомления, когда медиа-запросы не удаётся добавить в Radarr или Sonarr.",
"components.NotificationTypeSelector.mediafailed": "Не удалось добавить медиа-запрос",
"components.NotificationTypeSelector.mediafailed": "Ошибки при добавлении медиа-запросов",
"components.NotificationTypeSelector.mediadeclinedDescription": "Отправлять уведомления, когда медиа-запросы отклоняются.",
"components.NotificationTypeSelector.mediaAutoApprovedDescription": "Отправлять уведомления, когда пользователи отправляют новые медиа-запросы, которые одобряются автоматически.",
"components.NotificationTypeSelector.mediaAutoApproved": "Медиа-запрос одобрен автоматически",
"components.NotificationTypeSelector.mediaapproved": "Медиа-запрос одобрен",
"components.NotificationTypeSelector.mediaAutoApproved": "Автоматическое одобрение медиа-запросов",
"components.NotificationTypeSelector.mediaapproved": "Одобрение медиа-запросов",
"components.NotificationTypeSelector.mediaapprovedDescription": "Отправлять уведомления, когда медиа-запросы одобряются вручную.",
"components.NotificationTypeSelector.mediadeclined": "Медиа-запрос отклонён",
"components.NotificationTypeSelector.mediaavailableDescription": "Отправлять уведомления, когда медиа-запросы становятся доступны.",
"components.NotificationTypeSelector.mediaavailable": "Медиафайлы доступны",
"components.MovieDetails.MovieCrew.fullcrew": "Вся съёмочная группа",
"components.MovieDetails.viewfullcrew": "Посмотреть всю cъёмочную группу",
"components.NotificationTypeSelector.mediadeclined": "Отклонение медиа-запросов",
"components.NotificationTypeSelector.mediaavailableDescription": "Отправлять уведомления, когда запрошенные медиафайлы становятся доступны.",
"components.NotificationTypeSelector.mediaavailable": "Доступны новые медиафайлы",
"components.MovieDetails.MovieCrew.fullcrew": "Полная съёмочная группа",
"components.MovieDetails.viewfullcrew": "Посмотреть полную cъёмочную группу",
"components.MovieDetails.showmore": "Развернуть",
"components.MovieDetails.showless": "Свернуть",
"components.MovieDetails.playonplex": "Воспроизвести в Plex",
"components.MovieDetails.play4konplex": "Воспроизвести в Plex в 4К",
"components.MovieDetails.openradarr4k": "Открыть фильм в 4К Radarr",
"components.MovieDetails.openradarr": "Открыть фильм в Radarr",
"components.MovieDetails.mark4kavailable": "Отметить как доступное в 4К",
"components.MovieDetails.MovieCast.fullcast": "Весь актёрский состав",
"components.Login.validationpasswordrequired": "Необходимо предоставить пароль",
"components.Login.validationemailrequired": "Необходимо предоставить корректный адрес электронной почты",
"components.Login.signinwithoverseerr": "Используйте ваш {applicationTitle} аккаунт",
"components.MovieDetails.mark4kavailable": "Пометить как доступный в 4К",
"components.MovieDetails.MovieCast.fullcast": "Полный актёрский состав",
"components.Login.validationpasswordrequired": "Вы должны предоставить пароль",
"components.Login.validationemailrequired": "Вы должны указать действительный адрес электронной почты",
"components.Login.signinwithoverseerr": "Используйте ваш аккаунт {applicationTitle}",
"components.Login.signingin": "Выполняется вход…",
"components.Login.loginerror": "Что-то пошло не так при попытке выполнить вход.",
"components.Layout.LanguagePicker.displaylanguage": "Язык отображения",
"components.Layout.LanguagePicker.displaylanguage": "Язык интерфейса",
"components.DownloadBlock.estimatedtime": "Приблизительно {time}",
"components.Discover.upcomingtv": "Предстоящие сериалы",
"components.Discover.noRequests": "Запросов нет.",
"components.Discover.discover": "Открыть что-то новое",
"components.Discover.discover": "Найти что-то новое",
"components.Discover.TvGenreSlider.tvgenres": "Сериалы по жанрам",
"components.Discover.TvGenreList.seriesgenres": "Сериалы по жанрам",
"components.Discover.MovieGenreSlider.moviegenres": "Фильмы по жанрам",
@ -436,8 +436,8 @@
"components.Discover.DiscoverTvLanguage.languageSeries": "Сериалы на языке \"{language}\"",
"components.Discover.DiscoverTvGenre.genreSeries": "Сериалы в жанре \"{genre}\"",
"components.Discover.DiscoverNetwork.networkSeries": "Сериалы {network}",
"components.CollectionDetails.requestswillbecreated4k": "Будут созданы 4К запросы для следующих заголовков:",
"components.CollectionDetails.requestswillbecreated": "Будут созданы запросы для следующих заголовков:",
"components.CollectionDetails.requestswillbecreated4k": "Будут созданы 4К запросы на следующие названия:",
"components.CollectionDetails.requestswillbecreated": "Будут созданы запросы на следующие названия:",
"components.CollectionDetails.requestcollection4k": "Запросить Коллекцию в 4К",
"components.QuotaSelector.movies": "{count, plural, one {фильм} other {фильма(ов)}}",
"components.RequestModal.QuotaDisplay.movielimit": "{limit, plural, one {фильм} other {фильма(ов)}}",
@ -446,12 +446,12 @@
"components.Settings.SonarrModal.testFirstRootFolders": "Протестировать соединение для загрузки корневых каталогов",
"components.Settings.SonarrModal.loadingrootfolders": "Загрузка корневых каталогов…",
"components.Settings.SonarrModal.animerootfolder": "Корневой каталог для аниме",
"components.Settings.RadarrModal.testFirstRootFolders": "Протестировать соединение для загрузки корневых каталогов",
"components.Settings.RadarrModal.testFirstRootFolders": "Протестировать подключение для загрузки корневых каталогов",
"components.Settings.RadarrModal.loadingrootfolders": "Загрузка корневых каталогов…",
"components.RequestModal.AdvancedRequester.destinationserver": "Сервер-получатель",
"components.RequestList.RequestItem.mediaerror": "Соответствующий заголовок для этого запроса больше недоступен.",
"components.RequestList.RequestItem.mediaerror": "Соответствующее название для этого запроса больше недоступно.",
"components.RequestList.RequestItem.failedretry": "Что-то пошло не так при попытке повторить запрос.",
"components.RequestCard.mediaerror": "Соответствующий заголовок для этого запроса больше недоступен.",
"components.RequestCard.mediaerror": "Соответствующее название для этого запроса больше недоступно.",
"components.RequestCard.failedretry": "Что-то пошло не так при попытке повторить запрос.",
"components.RequestButton.viewrequest4k": "Посмотреть 4К запрос",
"components.RequestButton.requestmore4k": "Запросить больше в 4К",
@ -466,7 +466,7 @@
"components.RequestButton.approverequest": "Одобрить запрос",
"components.RequestBlock.server": "Сервер-получатель",
"components.QuotaSelector.tvRequests": "{quotaLimit} <quotaUnits>{сезонов} за {quotaDays} {дней}</quotaUnits>",
"components.QuotaSelector.seasons": "{count, plural, one {сезон} other {сезонов}}",
"components.QuotaSelector.seasons": "{count, plural, one {сезон} other {сезона(ов)}}",
"components.RequestBlock.requestoverrides": "Переопределение запроса",
"components.QuotaSelector.unlimited": "Неограниченно",
"components.QuotaSelector.movieRequests": "{quotaLimit} <quotaUnits>{фильмов} за {quotaDays} {дней}</quotaUnits>",
@ -505,7 +505,7 @@
"components.NotificationTypeSelector.usermediarequestedDescription": "Получать уведомления, когда другие пользователи отправляют новые медиа-запросы, требующие одобрения.",
"components.NotificationTypeSelector.usermediafailedDescription": "Получать уведомления, когда медиа-запросы не удаётся добавить в Radarr или Sonarr.",
"components.NotificationTypeSelector.usermediadeclinedDescription": "Получать уведомления, когда ваши медиа-запросы отклоняются.",
"components.NotificationTypeSelector.usermediaavailableDescription": "Получать уведомления, когда ваши медиа-запросы становятся доступны.",
"components.NotificationTypeSelector.usermediaavailableDescription": "Получать уведомления, когда запрошенные вами медиафайлы становятся доступны.",
"components.NotificationTypeSelector.usermediaapprovedDescription": "Получать уведомления, когда ваши медиа-запросы получают одобрение.",
"components.Layout.VersionStatus.commitsbehind": "{commitsBehind} {commitsBehind, plural, one {коммит} other {коммитов}} позади",
"components.MovieDetails.studio": "{studioCount, plural, one {Студия} other {Студии}}",
@ -516,5 +516,377 @@
"components.RequestModal.QuotaDisplay.requestsremaining": "{remaining, plural, =0 {запросов {type} не осталось} other {осталось <strong>#</strong> запроса(ов) {type}}}",
"components.RequestModal.QuotaDisplay.quotaLinkUser": "Вы можете посмотреть сводку ограничений на количество запросов этого пользователя на <ProfileLink>странице его профиля</ProfileLink>.",
"components.RequestModal.QuotaDisplay.quotaLink": "Вы можете посмотреть сводку ваших ограничений на количество запросов на <ProfileLink>странице вашего профиля</ProfileLink>.",
"components.RequestModal.QuotaDisplay.notenoughseasonrequests": "Запросов на TV-сезоны не осталось"
"components.RequestModal.QuotaDisplay.notenoughseasonrequests": "Осталось недостаточно запросов на сезоны",
"components.Settings.Notifications.NotificationsWebhook.toastWebhookTestSending": "Отправка тестового уведомления веб-перехватчику…",
"components.Settings.Notifications.NotificationsWebhook.toastWebhookTestFailed": "Не удалось отправить тестовое уведомление веб-перехватчику.",
"components.Settings.Notifications.NotificationsWebhook.templatevariablehelp": "Помощь по переменным шаблона",
"components.Settings.Notifications.NotificationsWebhook.resetPayloadSuccess": "Полезная нагрузка JSON успешно сброшена к настройкам по умолчанию!",
"components.Settings.Notifications.NotificationsWebhook.customJson": "Полезная нагрузка JSON",
"components.Settings.Notifications.NotificationsWebhook.authheader": "Заголовок авторизации",
"components.Settings.Notifications.NotificationsWebPush.webpushsettingssaved": "Настройки веб-push-уведомлений успешно сохранены!",
"components.Settings.Notifications.NotificationsWebPush.webpushsettingsfailed": "Не удалось сохранить настройки веб-push-уведомлений.",
"components.Settings.Notifications.NotificationsWebPush.toastWebPushTestSuccess": "Тестовое веб-push-уведомление отправлено!",
"components.Settings.Notifications.NotificationsWebPush.toastWebPushTestSending": "Отправка тестового веб-push-уведомления…",
"components.Settings.Notifications.NotificationsWebPush.toastWebPushTestFailed": "Не удалось отправить тестовое веб-push-уведомление.",
"components.Settings.Notifications.NotificationsWebPush.httpsRequirement": "Чтобы получать веб-push-уведомления, Overseerr должен обслуживаться по протоколу HTTPS.",
"components.Settings.Notifications.NotificationsSlack.webhookUrlTip": "Создайте интеграцию <WebhookLink>входящего веб-перехватчика</WebhookLink>",
"components.Settings.Notifications.NotificationsSlack.webhookUrl": "URL веб-перехватчика",
"components.Settings.Notifications.NotificationsSlack.toastSlackTestSuccess": "Тестовое уведомление отправлено в Slack!",
"components.Settings.Notifications.NotificationsSlack.toastSlackTestSending": "Отправка тестового уведомления в Slack…",
"components.Settings.Notifications.NotificationsSlack.toastSlackTestFailed": "Не удалось отправить тестовое уведомление в Slack.",
"components.Settings.Notifications.NotificationsSlack.slacksettingssaved": "Настройки уведомлений Slack успешно сохранены!",
"components.Settings.Notifications.NotificationsSlack.slacksettingsfailed": "Не удалось сохранить настройки уведомлений Slack.",
"components.Settings.Notifications.NotificationsPushover.validationUserTokenRequired": "Вы должны предоставить действительный ключ пользователя или группы",
"components.Settings.Notifications.validationTypes": "Вы должны выбрать хотя бы один тип уведомлений",
"components.Settings.Notifications.NotificationsWebhook.validationTypes": "Вы должны выбрать хотя бы один тип уведомлений",
"components.Settings.Notifications.NotificationsSlack.validationTypes": "Вы должны выбрать хотя бы один тип уведомлений",
"components.Settings.Notifications.NotificationsPushbullet.validationTypes": "Вы должны выбрать хотя бы один тип уведомлений",
"components.Settings.Notifications.NotificationsLunaSea.validationTypes": "Вы должны выбрать хотя бы один тип уведомлений",
"components.Settings.Notifications.NotificationsPushover.validationTypes": "Вы должны выбрать хотя бы один тип уведомлений",
"components.Settings.Notifications.NotificationsPushover.validationAccessTokenRequired": "Вы должны предоставить действительный токен приложения",
"components.Settings.Notifications.NotificationsPushover.userTokenTip": "Ваш тридцатизначный <UsersGroupsLink>идентификатор пользователя или группы</UsersGroupsLink>",
"components.Settings.Notifications.NotificationsPushover.toastPushoverTestSuccess": "Тестовое уведомление отправлено в Pushover!",
"components.Settings.Notifications.NotificationsPushover.toastPushoverTestSending": "Отправка тестового уведомления в Pushover…",
"components.Settings.Notifications.NotificationsPushover.toastPushoverTestFailed": "Не удалось отправить тестовое уведомление в Pushover.",
"components.Settings.Notifications.NotificationsPushover.pushoversettingssaved": "Настройки уведомлений Pushover успешно сохранены!",
"components.Settings.Notifications.NotificationsPushover.pushoversettingsfailed": "Не удалось сохранить настройки уведомлений Pushover.",
"components.Settings.Notifications.NotificationsPushover.accessTokenTip": "<ApplicationRegistrationLink>Зарегистрируйте приложение</ApplicationRegistrationLink> для использования с Overseerr",
"i18n.view": "Вид",
"i18n.notrequested": "Не запрошено",
"i18n.noresults": "Результатов нет.",
"i18n.delimitedlist": "{a}, {b}",
"components.Settings.Notifications.NotificationsLunaSea.webhookUrl": "URL веб-перехватчика",
"components.Settings.Notifications.NotificationsLunaSea.webhookUrlTip": "<LunaSeaLink>URL веб-перехватчика для уведомлений</LunaSeaLink> на основе вашего пользователя или устройства",
"components.Settings.Notifications.NotificationsPushover.accessToken": "Токен API приложения",
"components.Settings.Notifications.NotificationsPushbullet.validationAccessTokenRequired": "Вы должны предоставить токен доступа",
"components.Settings.Notifications.NotificationsPushbullet.toastPushbulletTestSuccess": "Тестовое уведомление отправлено в Pushbullet!",
"components.Settings.Notifications.NotificationsPushbullet.toastPushbulletTestSending": "Отправка тестового уведомления в Pushbullet…",
"components.Settings.Notifications.NotificationsPushbullet.toastPushbulletTestFailed": "Не удалось отправить тестовое уведомление в Pushbullet.",
"components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsSaved": "Настройки уведомлений Pushbullet успешно сохранены!",
"components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsFailed": "Не удалось сохранить настройки уведомлений Pushbullet.",
"components.Settings.Notifications.NotificationsPushbullet.accessTokenTip": "Создайте токен в <PushbulletSettingsLink>настройках учётной записи</PushbulletSettingsLink>",
"components.Settings.Notifications.NotificationsLunaSea.toastLunaSeaTestSuccess": "Тестовое уведомление отправлено в LunaSea!",
"components.Settings.Notifications.NotificationsLunaSea.toastLunaSeaTestSending": "Отправка тестового уведомления в LunaSea…",
"components.Settings.Notifications.NotificationsLunaSea.toastLunaSeaTestFailed": "Не удалось отправить тестовое уведомление в LunaSea.",
"components.Settings.Notifications.NotificationsLunaSea.settingsSaved": "Настройки уведомлений LunaSea успешно сохранены!",
"components.Settings.Notifications.NotificationsLunaSea.settingsFailed": "Не удалось сохранить настройки уведомлений LunaSea.",
"components.Settings.Notifications.NotificationsLunaSea.profileNameTip": "Требуется только в том случае, если не используется профиль <code>default</code>",
"components.Settings.Notifications.NotificationsWebPush.agentenabled": "Активировать службу",
"components.Settings.Notifications.NotificationsPushbullet.agentEnabled": "Активировать службу",
"components.Settings.Notifications.NotificationsLunaSea.agentenabled": "Активировать службу",
"components.Settings.notificationAgentSettingsDescription": "Настройте и активируйте службы уведомлений.",
"components.ResetPassword.emailresetlink": "Отправить ссылку для восстановления по электронной почте",
"pages.somethingwentwrong": "Что-то пошло не так",
"pages.serviceunavailable": "Сервис недоступен",
"pages.pagenotfound": "Страница не найдена",
"pages.internalservererror": "Внутренняя ошибка сервера",
"components.ResetPassword.validationpasswordrequired": "Вы должны предоставить пароль",
"components.ResetPassword.validationpasswordminchars": "Пароль слишком короткий: он должен содержать не менее 8 символов",
"components.ResetPassword.validationpasswordmatch": "Пароли должны совпадать",
"components.ResetPassword.validationemailrequired": "Вы должны указать действительный адрес электронной почты",
"components.ResetPassword.requestresetlinksuccessmessage": "Ссылка для сброса пароля будет отправлена на указанный адрес электронной почты, если он связан с действительным пользователем.",
"components.ResetPassword.gobacklogin": "Вернуться на страницу входа",
"components.UserProfile.UserSettings.UserGeneralSettings.originallanguage": "Языки для поиска фильмов и сериалов",
"components.Settings.region": "Регион для поиска фильмов и сериалов",
"components.Settings.originallanguage": "Языки для поиска фильмов и сериалов",
"components.TvDetails.seasons": "{seasonCount, plural, one {# сезон} other {# сезонов}}",
"components.RequestModal.QuotaDisplay.requiredquotaUser": "Этому пользователю необходимо иметь по крайней мере <strong>{seasons}</strong> {seasons, plural, one {запрос на сезоны} other {запроса(ов) на сезоны}} для того, чтобы отправить запрос на этот сериал.",
"components.RequestModal.QuotaDisplay.requiredquota": "Вам необходимо иметь по крайней мере <strong>{seasons}</strong> {seasons, plural, one {запрос на сезоны} other {запроса(ов) на сезоны}} для того, чтобы отправить запрос на этот сериал.",
"components.RequestModal.request4ktitle": "Запросить {title} в 4К",
"components.RequestModal.pending4krequest": "В ожидании 4К запрос на {title}",
"components.RequestModal.autoapproval": "Автоматическое одобрение",
"i18n.usersettings": "Настройки пользователя",
"i18n.showingresults": "Показываются результаты с <strong>{from}</strong> по <strong>{to}</strong> из <strong>{total}</strong>",
"i18n.save": "Сохранить изменения",
"i18n.retrying": "Повтор…",
"i18n.resultsperpage": "Отобразить {pageSize} результатов на странице",
"i18n.requesting": "Запрос…",
"i18n.request4k": "Запросить в 4К",
"i18n.areyousure": "Вы уверены?",
"components.StatusChacker.newversionDescription": "Overseerr был обновлён! Пожалуйста, нажмите кнопку ниже, чтобы перезагрузить страницу.",
"components.RequestModal.alreadyrequested": "Уже запрошен",
"components.RequestModal.SearchByNameModal.notvdbiddescription": "Мы не смогли автоматически выполнить ваш запрос. Пожалуйста, выберите правильное совпадение из списка ниже.",
"components.TvDetails.originaltitle": "Название оригинала",
"components.Settings.validationApplicationTitle": "Вы должны указать название приложения",
"components.RequestModal.SearchByNameModal.nosummary": "Аннотации для этого названия не найдено.",
"i18n.tvshow": "Сериал",
"components.Settings.partialRequestsEnabled": "Разрешить частичные запросы сериалов",
"components.Settings.mediaTypeSeries": "сериал",
"components.UserProfile.UserSettings.UserGeneralSettings.region": "Регион для поиска фильмов и сериалов",
"components.TvDetails.allseasonsmarkedavailable": "* Все сезоны будут помечены как доступные.",
"components.RequestModal.QuotaDisplay.seasonlimit": "{limit, plural, one {сезон} other {сезона(ов)}}",
"components.RequestModal.QuotaDisplay.season": "сезон",
"components.RequestModal.requestall": "Запросить все сезоны",
"components.RequestModal.pendingapproval": "Ваш запрос ожидает одобрения.",
"components.UserProfile.UserSettings.UserNotificationSettings.emailsettingssaved": "Настройки уведомлений по электронной почте успешно сохранены!",
"components.UserProfile.UserSettings.UserNotificationSettings.emailsettingsfailed": "Не удалось сохранить настройки уведомлений по электронной почте.",
"components.UserProfile.UserSettings.UserGeneralSettings.applanguage": "Язык интерфейса",
"components.UserList.validationpasswordminchars": "Пароль слишком короткий: он должен содержать не менее 8 символов",
"components.UserList.nouserstoimport": "Нет новых пользователей для импорта из Plex.",
"components.UserList.autogeneratepasswordTip": "Отправить пользователю пароль, сгенерированный сервером, по электронной почте",
"components.TvDetails.viewfullcrew": "Посмотреть полную cъёмочную группу",
"components.TvDetails.showtype": "Тип сериала",
"components.TvDetails.TvCrew.fullseriescrew": "Полная съёмочная группа сериала",
"components.TvDetails.TvCast.fullseriescast": "Полный актёрский состав сериала",
"components.Settings.trustProxyTip": "Позволяет Overseerr корректно регистрировать IP-адреса клиентов за прокси-сервером (Overseerr необходимо перезагрузить, чтобы изменения вступили в силу)",
"components.Settings.originallanguageTip": "Контент фильтруется по языку оригинала",
"components.Settings.noDefaultNon4kServer": "Если вы используете один сервер {serverType} для контента, в том числе и для 4К, или если вы загружаете только контент 4K, ваш сервер {serverType} <strong>НЕ</strong> должен быть помечен как 4К сервер.",
"components.UserList.localLoginDisabled": "Параметр <strong>Включить локальный вход</strong> в настоящее время отключен.",
"components.Settings.SettingsLogs.showall": "Показать все логи",
"components.UserProfile.UserSettings.UserGeneralSettings.seriesrequestlimit": "Ограничение количества запросов на сериалы",
"components.UserProfile.UserSettings.UserGeneralSettings.regionTip": "Контент фильтруется по доступности в выбранном регионе",
"components.UserProfile.UserSettings.UserGeneralSettings.movierequestlimit": "Ограничение количества запросов на фильмы",
"components.UserProfile.UserSettings.UserGeneralSettings.enableOverride": "Переопределить глобальные ограничения",
"components.Settings.noDefaultServer": "По крайней мере один сервер {serverType} должен быть помечен как сервер по умолчанию для обработки запросов на {mediaType}.",
"components.Settings.noDefault4kServer": "4K сервер {serverType} должен быть помечен как сервер по умолчанию, чтобы пользователи могли отправлять запросы на 4K {mediaType}.",
"components.Settings.SonarrModal.validationLanguageProfileRequired": "Вы должны выбрать языковой профиль",
"components.Settings.validationApplicationUrlTrailingSlash": "URL-адрес не должен заканчиваться косой чертой",
"components.Settings.RadarrModal.validationBaseUrlLeadingSlash": "Базовый URL-адрес должен иметь косую черту в начале",
"components.Settings.SonarrModal.validationBaseUrlLeadingSlash": "Базовый URL-адрес должен иметь косую черту в начале",
"components.Settings.SonarrModal.testFirstLanguageProfiles": "Протестировать подключение для загрузки языковых профилей",
"components.Settings.SonarrModal.loadingTags": "Загрузка тегов…",
"components.Settings.SonarrModal.enableSearch": "Включить автоматический поиск",
"components.Settings.SonarrModal.edit4ksonarr": "Редактировать 4К сервер Sonarr",
"components.Settings.toastApiKeyFailure": "Что-то пошло не так при создании нового ключа API.",
"components.Settings.csrfProtectionTip": "Устанавливает доступ к API извне только для чтения (требуется HTTPS, для вступления изменений в силу необходимо перезагрузить Overseerr)",
"components.Settings.SonarrModal.animequalityprofile": "Профиль качества для аниме",
"components.Settings.SonarrModal.animelanguageprofile": "Языковой профиль для аниме",
"components.Settings.SonarrModal.animeTags": "Теги для аниме",
"components.Settings.SettingsUsers.userSettings": "Настройки пользователей",
"components.Settings.SettingsUsers.tvRequestLimitLabel": "Общее ограничение на количество запросов сериалов",
"components.Settings.SettingsUsers.toastSettingsSuccess": "Настройки пользователей успешно сохранены!",
"components.Settings.SettingsUsers.toastSettingsFailure": "Что-то пошло не так при сохранении настроек.",
"components.Settings.SettingsUsers.newPlexLoginTip": "Разрешить пользователям Plex входить в систему без предварительного импорта",
"components.Settings.SettingsUsers.newPlexLogin": "Включить вход через Plex для новых пользователей",
"components.Settings.SettingsUsers.movieRequestLimitLabel": "Общее ограничение на количество запросов фильмов",
"components.Settings.SettingsUsers.localLoginTip": "Разрешить пользователям входить в систему, используя свой адрес электронной почты и пароль вместо Plex OAuth",
"components.Settings.SettingsUsers.localLogin": "Включить локальный вход",
"components.Settings.SettingsUsers.defaultPermissionsTip": "Начальные разрешения, присваемые новым пользователям",
"components.Settings.SettingsUsers.defaultPermissions": "Разрешения по умолчанию",
"components.Settings.SettingsLogs.time": "Время",
"components.Settings.SettingsLogs.level": "Важность",
"components.Settings.SettingsLogs.filterDebug": "Отладочные",
"components.Settings.SettingsLogs.extraData": "Дополнительная информация",
"components.Settings.SettingsLogs.copyToClipboard": "Скопировать в буфер обмена",
"components.Settings.serverpresetRefreshing": "Получение списка серверов…",
"components.Settings.SettingsJobsCache.jobstarted": "Задание \"{jobname}\" запущено.",
"components.Settings.cacheImagesTip": "Оптимизировать и хранить все изображения локально (потребляет значительный объем дискового пространства)",
"components.Settings.cacheImages": "Включить кэширование изображений",
"components.Settings.SettingsJobsCache.unknownJob": "Неизвестное задание",
"components.Settings.SettingsJobsCache.sonarr-scan": "Сканирование Sonarr",
"components.Settings.SettingsJobsCache.runnow": "Выполнить сейчас",
"components.Settings.SettingsJobsCache.radarr-scan": "Сканирование Radarr",
"components.Settings.SettingsJobsCache.plex-recently-added-scan": "Сканирование недавно добавленных медиафайлов в Plex",
"components.Settings.SettingsJobsCache.plex-full-scan": "Полное сканирование библиотек Plex",
"components.Settings.SettingsJobsCache.nextexecution": "Следующее выполнение",
"components.Settings.SettingsJobsCache.jobsandcache": "Задания и кэш",
"components.Settings.SettingsJobsCache.jobs": "Задания",
"components.Settings.SettingsJobsCache.jobname": "Название задания",
"components.Settings.SettingsJobsCache.jobcancelled": "Задание \"{jobname}\" отменено.",
"components.Settings.SettingsJobsCache.canceljob": "Отменить задание",
"components.Settings.SettingsJobsCache.jobsDescription": "Overseerr выполняет определенные задачи по обслуживанию в виде регулярно запланированных заданий, но они также могут быть запущены вручную ниже. Выполнение задания вручную не изменит его расписание.",
"components.Settings.SettingsJobsCache.flushcache": "Очистить кэш",
"components.Settings.SettingsJobsCache.download-sync-reset": "Сбросить синхронизацию загрузок",
"components.Settings.SettingsJobsCache.download-sync": "Синхронизировать загрузки",
"components.Settings.SettingsJobsCache.cachehits": "Удачных обращений",
"components.Settings.SettingsJobsCache.cachemisses": "Неудачных обращений",
"components.Settings.SettingsJobsCache.cachevsize": "Размер значений",
"components.Settings.SettingsAbout.uptodate": "Актуальная",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Изменения в версии {version}",
"components.Settings.SettingsAbout.preferredmethod": "Предпочтительный способ",
"components.Settings.SettingsJobsCache.cacheflushed": "{cachename} кэш сброшен.",
"components.Settings.SettingsJobsCache.cacheDescription": "Overseerr кэширует запросы к внешним конечным точкам API, чтобы оптимизировать производительность и избежать ненужных вызовов API.",
"components.Settings.SettingsAbout.totalmedia": "Всего мультимедиа",
"components.Settings.SettingsAbout.outofdate": "Устарела",
"components.Settings.SettingsAbout.helppaycoffee": "Помочь оплатить кофе",
"components.Settings.SettingsAbout.gettingsupport": "Получить поддержку",
"components.Settings.SettingsAbout.betawarning": "Это бета-версия программного обеспечения. Некоторые функции могут не работать или работать нестабильно. Пожалуйста, сообщайте о любых проблемах на GitHub!",
"components.Settings.SettingsAbout.about": "О проекте",
"components.Settings.SettingsAbout.Releases.viewongithub": "Посмотреть на GitHub",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Посмотреть список изменений",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Данные о релизе в настоящее время недоступны.",
"components.UserProfile.UserSettings.UserPasswordChange.validationNewPassword": "Вы должны ввести новый пароль",
"components.UserProfile.UserSettings.UserNotificationSettings.validationTelegramChatId": "Вы должны предоставить действительный ID чата",
"components.UserProfile.UserSettings.UserNotificationSettings.validationPgpPublicKey": "Вы должны предоставить действительный открытый ключ PGP",
"components.UserProfile.UserSettings.UserNotificationSettings.validationDiscordId": "Вы должны предоставить действительный ID пользователя",
"components.UserList.validationEmail": "Вы должны указать действительный адрес электронной почты",
"components.UserList.usercreatedfailedexisting": "Указанный адрес электронной почты уже используется другим пользователем.",
"components.TvDetails.streamingproviders": "Сейчас транслируется",
"components.Settings.validationWebAppUrl": "Вы должны указать действительный URL-адрес веб-приложения Plex",
"components.Settings.validationPortRequired": "Вы должны указать действительный номер порта",
"components.Settings.validationHostnameRequired": "Вы должны указать действительное имя хоста или IP-адрес",
"components.Settings.SonarrModal.validationNameRequired": "Вы должны указать имя сервера",
"components.Settings.RadarrModal.validationNameRequired": "Вы должны указать имя сервера",
"components.Settings.Notifications.validationEmail": "Вы должны указать действительный адрес электронной почты",
"components.MovieDetails.streamingproviders": "Сейчас транслируется",
"components.Settings.SonarrModal.validationBaseUrlTrailingSlash": "Базовый URL-адрес не должен заканчиваться косой чертой",
"components.Settings.RadarrModal.validationMinimumAvailabilityRequired": "Вы должны выбрать минимальную доступность",
"components.Settings.RadarrModal.validationBaseUrlTrailingSlash": "Базовый URL-адрес не должен заканчиваться косой чертой",
"components.Settings.RadarrModal.validationApplicationUrlTrailingSlash": "URL-адрес не должен заканчиваться косой чертой",
"components.Settings.RadarrModal.testFirstTags": "Протестировать подключение для загрузки тегов",
"components.Settings.RadarrModal.testFirstQualityProfiles": "Протестировать подключение для загрузки профилей качества",
"components.Settings.RadarrModal.selecttags": "Выберите теги",
"components.Settings.RadarrModal.notagoptions": "Тегов нет.",
"components.Settings.RadarrModal.loadingprofiles": "Загрузка профилей качества…",
"components.Settings.RadarrModal.loadingTags": "Загрузка тегов…",
"components.Settings.RadarrModal.enableSearch": "Включить автоматический поиск",
"components.Settings.RadarrModal.default4kserver": "4К сервер по умолчанию",
"components.Settings.Notifications.webhookUrlTip": "Создайте <DiscordWebhookLink>интеграцию веб-перехватчика</DiscordWebhookLink> на своём сервере",
"components.Settings.Notifications.NotificationsWebhook.webhooksettingssaved": "Настройки уведомлений веб-перехватчика успешно сохранены!",
"components.Settings.Notifications.NotificationsWebhook.webhooksettingsfailed": "Не удалось сохранить настройки уведомлений веб-перехватчика.",
"components.Settings.Notifications.NotificationsWebhook.toastWebhookTestSuccess": "Тестовое уведомление веб-перехватчику отправлено!",
"components.Settings.Notifications.NotificationsWebhook.webhookUrl": "URL веб-перехватчика",
"components.Settings.Notifications.validationPgpPrivateKey": "Вы должны предоставить действительный закрытый ключ PGP",
"components.Settings.Notifications.validationPgpPassword": "Вы должны предоставить пароль PGP",
"components.Settings.Notifications.validationChatIdRequired": "Вы должны предоставить действительный ID чата",
"components.Settings.Notifications.validationBotAPIRequired": "Вы должны предоставить токен авторизации бота",
"components.Settings.Notifications.telegramsettingsfailed": "Не удалось сохранить настройки уведомлений Telegram.",
"components.Settings.Notifications.pgpPrivateKeyTip": "Подписывать зашифрованные сообщения электронной почты с помощью <OpenPgpLink>OpenPGP</OpenPgpLink>",
"components.Settings.Notifications.pgpPrivateKey": "Закрытый ключ PGP",
"components.Settings.Notifications.pgpPasswordTip": "Подписывать зашифрованные сообщения электронной почты с помощью <OpenPgpLink>OpenPGP</OpenPgpLink>",
"components.Settings.Notifications.pgpPassword": "Пароль PGP",
"components.Settings.Notifications.encryptionTip": "В большинстве случаев неявный TLS использует порт 465, а STARTTLS порт 587",
"components.Settings.Notifications.encryptionOpportunisticTls": "Всегда использовать STARTTLS",
"components.Settings.Notifications.encryptionNone": "Без шифрования",
"components.Settings.Notifications.encryptionImplicitTls": "Использовать неявный TLS",
"components.Settings.Notifications.encryptionDefault": "Использовать STARTTLS, если доступно",
"components.Settings.Notifications.encryption": "Метод шифрования",
"components.Settings.Notifications.emailsettingssaved": "Настройки уведомлений по электронной почте успешно сохранены!",
"components.Settings.Notifications.emailsettingsfailed": "Не удалось сохранить настройки уведомлений по электронной почте.",
"components.Settings.Notifications.discordsettingssaved": "Настройки уведомлений Discord успешно сохранены!",
"components.Settings.Notifications.discordsettingsfailed": "Не удалось сохранить настройки уведомлений Discord.",
"components.Settings.Notifications.chatIdTip": "Начните чат со своим ботом, добавьте <GetIdBotLink>@get_id_bot</GetIdBotLink> и выполните команду <code>/my_id</code>",
"components.Settings.Notifications.chatId": "ID чата",
"components.Settings.Notifications.botUsernameTip": "Разрешить пользователям начинать чат с вашим ботом и настраивать свои собственные уведомления",
"components.Settings.Notifications.botUsername": "Имя бота",
"components.Settings.Notifications.botAvatarUrl": "URL аватара бота",
"components.Settings.Notifications.botApiTip": "<CreateBotLink>Создайте бота</CreateBotLink> для использования с Overseerr",
"components.Settings.Notifications.allowselfsigned": "Разрешить самозаверенные сертификаты",
"components.Settings.Notifications.NotificationsWebhook.validationJsonPayloadRequired": "Вы должны предоставить допустимую полезную нагрузку JSON",
"components.Settings.Notifications.toastTelegramTestSuccess": "Тестовое уведомление отправлено в Telegram!",
"components.Settings.Notifications.toastTelegramTestSending": "Отправка тестового уведомления в Telegram…",
"components.Settings.Notifications.toastDiscordTestSuccess": "Тестовое уведомление отправлено в Discord!",
"components.Settings.Notifications.toastDiscordTestSending": "Отправка тестового уведомления в Discord…",
"components.Settings.Notifications.toastDiscordTestFailed": "Не удалось отправить тестовое уведомление в Discord.",
"components.Settings.Notifications.toastTelegramTestFailed": "Не удалось отправить тестовое уведомление в Telegram.",
"components.Settings.Notifications.toastEmailTestSuccess": "Тестовое уведомление отправлено по электронной почте!",
"components.Settings.Notifications.toastEmailTestSending": "Отправка тестового уведомления по электронной почте…",
"components.Settings.Notifications.toastEmailTestFailed": "Не удалось отправить тестовое уведомление по электронной почте.",
"components.UserProfile.unlimited": "Неограниченно",
"components.UserProfile.totalrequests": "Всего запросов",
"components.UserProfile.requestsperdays": "осталось {limit}",
"components.UserProfile.pastdays": "{type} (за {days} день(ей))",
"components.UserProfile.seriesrequest": "Запросов сериалов",
"components.UserProfile.movierequests": "Запросов фильмов",
"components.UserProfile.norequests": "Запросов нет.",
"components.UserProfile.limit": "{remaining} из {limit}",
"components.UserProfile.UserSettings.unauthorizedDescription": "У вас нет разрешения на изменение настроек этого пользователя.",
"components.UserProfile.UserSettings.UserPasswordChange.nopermissionDescription": "У вас нет разрешения на изменение пароля этого пользователя.",
"components.UserProfile.UserSettings.UserPasswordChange.validationConfirmPasswordSame": "Пароли должны совпадать",
"components.UserProfile.UserSettings.UserPasswordChange.toastSettingsFailureVerifyCurrent": "Что-то пошло не так при сохранении пароля. Правильно ли введен ваш текущий пароль?",
"components.UserProfile.UserSettings.UserPasswordChange.toastSettingsFailure": "Что-то пошло не так при сохранении пароля.",
"components.UserProfile.UserSettings.UserPasswordChange.noPasswordSet": "В настоящее время для этой учётной записи не установлен пароль. Установите пароль ниже, чтобы с этой учётной записью можно было войти в систему как \"локальный пользователь\".",
"components.UserProfile.UserSettings.UserPasswordChange.noPasswordSetOwnAccount": "В настоящее время для вашей учётной записи не установлен пароль. Установите пароль ниже, чтобы иметь возможность войти в систему как \"локальный пользователь\", используя свой адрес электронной почты.",
"components.UserProfile.UserSettings.UserNotificationSettings.webpushsettingssaved": "Настройки веб-push-уведомлений успешно сохранены!",
"components.UserProfile.UserSettings.UserNotificationSettings.webpushsettingsfailed": "Не удалось сохранить настройки веб-push-уведомлений.",
"components.UserProfile.UserSettings.UserNotificationSettings.webpush": "Веб-push",
"components.UserProfile.UserSettings.UserNotificationSettings.telegramsettingssaved": "Настройки уведомлений Telegram успешно сохранены!",
"components.UserProfile.UserSettings.UserNotificationSettings.telegramsettingsfailed": "Не удалось сохранить настройки уведомлений Telegram.",
"components.UserProfile.UserSettings.UserNotificationSettings.telegramChatIdTipLong": "<TelegramBotLink>Начните чат</TelegramBotLink>, добавьте <GetIdBotLink>@get_id_bot</GetIdBotLink> и выполните команду <code>/my_id</code>",
"components.UserProfile.UserSettings.UserNotificationSettings.telegramChatId": "ID чата",
"components.UserProfile.UserSettings.UserNotificationSettings.sendSilently": "Отправлять без звука",
"components.UserProfile.UserSettings.UserNotificationSettings.pgpPublicKeyTip": "Шифровать сообщения электронной почты с помощью <OpenPgpLink>OpenPGP</OpenPgpLink>",
"components.UserProfile.UserSettings.UserNotificationSettings.pgpPublicKey": "Открытый ключ PGP",
"components.UserProfile.UserSettings.UserNotificationSettings.notificationsettings": "Настройки уведомлений",
"components.UserProfile.UserSettings.UserNotificationSettings.email": "Электронная почта",
"components.UserProfile.UserSettings.UserNotificationSettings.discordsettingssaved": "Настройки уведомлений Discord успешно сохранены!",
"components.UserProfile.UserSettings.UserNotificationSettings.discordsettingsfailed": "Не удалось сохранить настройки уведомлений Discord.",
"components.UserProfile.UserSettings.UserNotificationSettings.discordIdTip": "<FindDiscordIdLink>ID</FindDiscordIdLink> вашей учётной записи",
"components.UserProfile.UserSettings.UserNotificationSettings.discordId": "ID пользователя",
"components.Settings.locale": "Язык интерфейса",
"components.UserProfile.UserSettings.UserGeneralSettings.accounttype": "Тип учётной записи",
"components.UserProfile.ProfileHeader.userid": "ID пользователя: {userid}",
"components.UserProfile.ProfileHeader.settings": "Редактировать настройки",
"components.UserProfile.ProfileHeader.joindate": "Присоединился {joindate}",
"components.UserProfile.UserSettings.UserPasswordChange.validationNewPasswordLength": "Пароль слишком короткий: он должен содержать не менее 8 символов",
"components.UserProfile.UserSettings.UserPermissions.unauthorizedDescription": "Вы не можете изменять собственные разрешения.",
"components.UserList.userssaved": "Разрешения пользователя успешно сохранены!",
"components.UserList.userfail": "Что-то пошло не так при сохранении разрешений пользователя.",
"components.UserList.userdeleteerror": "Что-то пошло не так при удалении пользователя.",
"components.UserList.usercreatedfailed": "Что-то пошло не так при создании пользователя.",
"components.UserList.passwordinfodescription": "Настройте URL-адрес приложения и включите уведомления по электронной почте, чтобы обеспечить возможность автоматической генерации пароля.",
"components.UserList.importfromplexerror": "Что-то пошло не так при импорте пользователей из Plex.",
"components.UserList.importfromplex": "Импортировать пользователей из Plex",
"components.UserList.importedfromplex": "{userCount, plural, one {# новый пользователь} other {# новых пользователя(ей)}} успешно импортированы из Plex!",
"components.UserList.edituser": "Изменить разрешения пользователя",
"components.UserList.displayName": "Отображаемое имя",
"components.UserList.deleteconfirm": "Вы уверены, что хотите удалить этого пользователя? Все данные о его запросах будут удалены без возможности восстановления.",
"components.UserList.autogeneratepassword": "Сгенерировать пароль автоматически",
"components.UserList.accounttype": "Тип",
"components.TvDetails.playonplex": "Воспроизвести в Plex",
"components.TvDetails.play4konplex": "Воспроизвести в Plex в 4К",
"components.TvDetails.opensonarr4k": "Открыть сериал в 4К Sonarr",
"components.TvDetails.opensonarr": "Открыть сериал в Sonarr",
"components.TvDetails.nextAirDate": "Следующая дата выхода в эфир",
"components.TvDetails.mark4kavailable": "Пометить как доступный в 4К",
"components.TvDetails.firstAirDate": "Дата первого эфира",
"components.TvDetails.episodeRuntimeMinutes": "{runtime} минут",
"components.TvDetails.episodeRuntime": "Продолжительность эпизода",
"components.Setup.tip": "Подсказка",
"components.Setup.scanbackground": "Сканирование будет выполняться в фоновом режиме. А пока вы можете продолжить процесс настройки.",
"components.Settings.webpush": "Веб-push",
"components.Settings.webAppUrlTip": "При необходимости направляйте пользователей в веб-приложение на вашем сервере вместо размещённого на plex.tv",
"components.Settings.webAppUrl": "URL <WebAppLink>веб-приложения</WebAppLink>",
"components.Settings.trustProxy": "Включить поддержку прокси",
"components.Settings.toastPlexRefreshSuccess": "Список серверов Plex успешно получен!",
"components.Settings.toastPlexRefresh": "Получение списка серверов Plex…",
"components.Settings.toastPlexRefreshFailure": "Не удалось получить список серверов Plex.",
"components.Settings.toastPlexConnecting": "Попытка подключения к Plex…",
"components.Settings.settingUpPlexDescription": "Чтобы настроить Plex, вы можете либо ввести данные вручную, либо выбрать сервер, полученный со страницы <RegisterPlexTVLink>plex.tv</RegisterPlexTVLink>. Нажмите кнопку справа от выпадающего списка, чтобы получить список доступных серверов.",
"components.Settings.services": "Службы",
"components.Settings.serviceSettingsDescription": "Настройте сервер(ы) {serverType} ниже. Вы можете подключить несколько серверов {serverType}, но только два из них могут быть помечены как серверы по умолчанию (один не 4К и один 4К). Администраторы могут переопределить сервер для обработки новых запросов до их одобрения.",
"components.Settings.serverpresetLoad": "Нажмите кнопку, чтобы загрузить список доступных серверов",
"components.Settings.serverSecure": "защищённый",
"components.Settings.serverRemote": "удалённый",
"components.Settings.serverLocal": "локальный",
"components.Settings.scan": "Синхронизировать библиотеки",
"components.Settings.regionTip": "Контент фильтруется по доступности в выбранном регионе",
"components.Settings.SettingsLogs.logsDescription": "Вы также можете просматривать эти логи напрямую через <code>stdout</code> или в <code>{configDir}/logs/overseerr.log</code>.",
"components.Settings.SettingsLogs.logs": "Логи",
"components.Settings.SettingsLogs.logDetails": "Подробные сведения о логе",
"components.Settings.SettingsLogs.copiedLogMessage": "Сообщение лога скопировано в буфер обмена.",
"components.UserProfile.UserSettings.UserGeneralSettings.originallanguageTip": "Контент фильтруется по языку оригинала",
"components.UserProfile.UserSettings.UserGeneralSettings.languageDefault": "По умолчанию ({language})",
"components.UserProfile.UserSettings.UserGeneralSettings.general": "Общее",
"components.Settings.general": "Общее",
"components.Settings.hideAvailable": "Скрывать доступные медиа",
"components.Settings.SettingsUsers.userSettingsDescription": "Настройте глобальные параметры и параметры по умолчанию для пользователей.",
"components.Settings.email": "Адрес электронной почты",
"components.Settings.csrfProtectionHoverTip": "НЕ включайте этот параметр, если вы не понимаете, что делаете!",
"components.Settings.csrfProtection": "Включить защиту от CSRF",
"components.Settings.SonarrModal.validationApplicationUrlTrailingSlash": "URL-адрес не должен заканчиваться косой чертой",
"components.Settings.toastPlexConnectingSuccess": "Соединение с Plex установлено успешно!",
"components.Settings.SonarrModal.toastSonarrTestSuccess": "Соединение с Sonarr установлено успешно!",
"components.Settings.toastPlexConnectingFailure": "Не удалось подключиться к Plex.",
"components.Settings.SonarrModal.toastSonarrTestFailure": "Не удалось подключиться к Sonarr.",
"components.Settings.SonarrModal.testFirstTags": "Протестировать подключение для загрузки тегов",
"components.Settings.SonarrModal.testFirstQualityProfiles": "Протестировать подключение для загрузки профилей качества",
"components.Settings.SonarrModal.selecttags": "Выберите теги",
"components.Settings.SonarrModal.selectLanguageProfile": "Выберите языковой профиль",
"components.Settings.SonarrModal.notagoptions": "Тегов нет.",
"components.Settings.SonarrModal.loadingprofiles": "Загрузка профилей качества…",
"components.Settings.SonarrModal.loadinglanguageprofiles": "Загрузка языковых профилей…",
"components.Settings.SonarrModal.create4ksonarr": "Добавить новый 4К сервер Sonarr",
"components.Settings.RadarrModal.edit4kradarr": "Редактировать 4К сервер Radarr",
"components.Settings.RadarrModal.create4kradarr": "Добавить новый 4К сервер Radarr",
"components.Settings.SonarrModal.default4kserver": "4К сервер по умолчанию",
"components.Settings.toastApiKeySuccess": "Новый ключ API успешно сгенерирован!",
"components.Settings.SettingsJobsCache.editJobSchedule": "Изменить задание",
"components.Settings.SettingsJobsCache.editJobSchedulePrompt": "Частота",
"components.Settings.SettingsJobsCache.jobScheduleEditSaved": "Задание успешно отредактировано!",
"components.Settings.SettingsAbout.runningDevelop": "Вы используете ветку <code>develop</code> проекта Overseerr, которая рекомендуется только для тех, кто вносит вклад в разработку или помогает в тестировании.",
"components.Settings.SettingsJobsCache.jobScheduleEditFailed": "Что-то пошло не так при сохранении задания.",
"components.Settings.SettingsJobsCache.editJobScheduleSelectorHours": "Каждый {jobScheduleHours, plural, one {час} other {{jobScheduleHours} часа(ов)}}",
"components.Settings.SettingsJobsCache.editJobScheduleSelectorMinutes": "Каждую {jobScheduleMinutes, plural, one {минуту} other {{jobScheduleMinutes} минут(ы)}}",
"components.StatusBadge.status": "{status}"
}

@ -222,5 +222,6 @@
"components.Discover.popularmovies": "Popularni Filmovi",
"components.Discover.discovertv": "Popularne Serije",
"components.Discover.discovermovies": "Popunarni Filmov",
"pages.errormessagewithcode": "{statusCode} - {error}"
"pages.errormessagewithcode": "{statusCode} - {error}",
"components.StatusBadge.status": "{status}"
}

@ -77,7 +77,7 @@
"components.Settings.SettingsAbout.version": "Version",
"components.Settings.SettingsAbout.totalrequests": "Totalt antal förfrågningar",
"components.Settings.SettingsAbout.totalmedia": "Totalt antal mediaobjekt",
"components.Settings.SettingsAbout.overseerrinformation": "Information om Overseerr",
"components.Settings.SettingsAbout.overseerrinformation": "Om Overseerr",
"components.Settings.SettingsAbout.githubdiscussions": "GitHub Diskussioner",
"components.Settings.SettingsAbout.gettingsupport": "Få Support",
"components.Settings.RadarrModal.validationRootFolderRequired": "Du måste ange en root-mapp",
@ -146,7 +146,7 @@
"components.MovieDetails.similar": "Liknande Titlar",
"components.MovieDetails.runtime": "{minutes} minuter",
"components.MovieDetails.revenue": "Inkomster",
"components.MovieDetails.releasedate": "Utgivningsdatum",
"components.MovieDetails.releasedate": "{releaseCount, plural, one {Utgivningsdatum} other {Utgivningsdatum}}",
"components.MovieDetails.recommendations": "Rekommendationer",
"components.MovieDetails.overview": "Beskrivning",
"components.MovieDetails.overviewunavailable": "Beskrivning otillgänglig.",
@ -228,12 +228,11 @@
"components.Settings.SettingsAbout.helppaycoffee": "Stötta med en kopp kaffe",
"components.Settings.SettingsAbout.Releases.viewongithub": "Visa på GitHub",
"components.Settings.SettingsAbout.Releases.viewchangelog": "Visa ändringslogg",
"components.Settings.SettingsAbout.Releases.versionChangelog": "Ändringslogg",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "De senaste ändringarna i <code>utvecklings</code>-grenen av Overseerr visas inte nedan. Se ändringshistoriken på <GithubLink>GitHub</GithubLink> för mer information.",
"components.Settings.SettingsAbout.Releases.versionChangelog": "{version} Ändringslogg",
"components.Settings.SettingsAbout.Releases.releases": "Versioner",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Versionsdata saknas. Ligger GitHub nere?",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "Versionsdata är för närvarande inte tillgänglig.",
"components.Settings.SettingsAbout.Releases.latestversion": "Senaste Versionen",
"components.Settings.SettingsAbout.Releases.currentversion": "Aktuell Version",
"components.Settings.SettingsAbout.Releases.currentversion": "Aktuell",
"components.UserList.importfromplex": "Importera användare från Plex",
"components.UserList.importfromplexerror": "Någonting gick fel vid importen av användare från Plex.",
"components.TvDetails.watchtrailer": "Kolla Trailer",
@ -879,5 +878,15 @@
"components.Settings.SettingsAbout.betawarning": "Detta är en BETA-programvara. Funktioner kan vara trasiga och/eller instabila. Rapportera eventuella problem på GitHub!",
"components.Layout.LanguagePicker.displaylanguage": "Visningsspråk",
"components.MovieDetails.showmore": "Visa mer",
"components.MovieDetails.showless": "Visa mindre"
"components.MovieDetails.showless": "Visa mindre",
"components.TvDetails.streamingproviders": "Strömmas för närvarande på",
"components.MovieDetails.streamingproviders": "Strömmas för närvarande på",
"components.Settings.SettingsJobsCache.editJobSchedule": "Ändra jobb",
"components.Settings.SettingsJobsCache.editJobSchedulePrompt": "Frekvens",
"components.Settings.SettingsJobsCache.editJobScheduleSelectorHours": "Varje {jobScheduleHours, plural, one {timme} other {{jobScheduleHours} timmar}}",
"components.Settings.SettingsJobsCache.editJobScheduleSelectorMinutes": "varje{jobScheduleMinutes, plural, one {minut} other {{jobScheduleMinutes} minuter}}",
"components.Settings.SettingsJobsCache.jobScheduleEditFailed": "Något gick fel vid sparning av jobbet.",
"components.Settings.SettingsJobsCache.jobScheduleEditSaved": "Jobbet har redigerats!",
"components.Settings.SettingsAbout.runningDevelop": "Du använder <code>develop</code> grenen av Overseerr, som endast rekommenderas för dem som bidrar till utvecklingen eller hjälper till med tester i den absoluta framkanten.",
"components.StatusBadge.status": "{status}"
}

@ -143,7 +143,7 @@
"components.Settings.notifications": "通知",
"components.Settings.notificationAgentSettingsDescription": "设置通知类型和代理服务。",
"components.Settings.noDefaultServer": "您必须至少指定一个 {serverType} 服务器为默认,才能处理{mediaType}请求。",
"components.Settings.noDefaultNon4kServer": "如果您只有一个 {serverType} 服务器,请勿把它设置为 4K 服务器。",
"components.Settings.noDefaultNon4kServer": "如果你只有一台 {serverType} 服务器用于非 4K 和 4K 内容(或者如果你只下载 4k 内容),你的 {serverType} 服务器 <strong>不应该</strong>被指定为 4K 服务器。",
"components.Settings.noDefault4kServer": "您必须指定一个 4K {serverType} 服务器为默认,才能处理 4K 的{mediaType}请求。",
"components.Settings.menuUsers": "用户",
"components.Settings.menuServices": "服务器",
@ -423,8 +423,8 @@
"components.UserProfile.UserSettings.UserPasswordChange.toastSettingsFailure": "重设密码中出了点问题。",
"components.UserProfile.UserSettings.UserPasswordChange.password": "密码设置",
"components.UserProfile.UserSettings.UserPasswordChange.nopermissionDescription": "您无权设置此用户的密码。",
"components.UserProfile.UserSettings.UserPasswordChange.noPasswordSetOwnAccount": "您的账户目前没有密码。设置密码以允许使用电子邮件地址登录。",
"components.UserProfile.UserSettings.UserPasswordChange.noPasswordSet": "此用户目前没有密码。设置密码以允许此用户使用电子邮件地址登录。",
"components.UserProfile.UserSettings.UserPasswordChange.noPasswordSetOwnAccount": "您的帐户目前没有设置密码。在下方配置密码,您能够作为「本地用户」登录。",
"components.UserProfile.UserSettings.UserPasswordChange.noPasswordSet": "此用户帐户目前没有设置密码。在下方配置密码,使该帐户能够作为「本地用户」登录。",
"components.UserProfile.UserSettings.UserPasswordChange.newpassword": "新密码",
"components.UserProfile.UserSettings.UserPasswordChange.currentpassword": "当前的密码",
"components.UserProfile.UserSettings.UserPasswordChange.confirmpassword": "确认密码",
@ -516,7 +516,7 @@
"components.Settings.SettingsLogs.resumeLogs": "恢复",
"components.Settings.SettingsLogs.pauseLogs": "暫停",
"components.Settings.SettingsLogs.message": "消息",
"components.Settings.SettingsLogs.logsDescription": "日志档案位置:<code>{configDir}/logs/overseerr.log</code>",
"components.Settings.SettingsLogs.logsDescription": "你也可以直接查看这些日志,方法是借助 <code>stdout</code>, 或者打开 <code>{configDir}/logs/overseerr.log</code>",
"components.Settings.SettingsLogs.logs": "日志",
"components.Settings.SettingsLogs.logDetails": "日志详細信息",
"components.Settings.SettingsLogs.level": "等級",
@ -542,7 +542,7 @@
"components.Settings.SettingsJobsCache.jobsDescription": "Overseerr 将定时运行以下的維護任務。手动执行工作不会影响它正常的时间表。",
"components.Settings.SettingsJobsCache.jobs": "作业",
"components.Settings.SettingsJobsCache.jobname": "作业名",
"components.Settings.SettingsJobsCache.jobcancelled": "{jobname} 已被取消。",
"components.Settings.SettingsJobsCache.jobcancelled": "{jobname}已被取消。",
"components.Settings.SettingsJobsCache.flushcache": "清除缓存",
"components.Settings.SettingsJobsCache.download-sync-reset": "下载状态同步复位",
"components.Settings.SettingsJobsCache.download-sync": "下载状态同步",
@ -574,12 +574,11 @@
"components.Settings.SettingsAbout.about": "关于 Overseerr",
"components.Settings.SettingsAbout.Releases.viewongithub": "在 GitHub 上查看",
"components.Settings.SettingsAbout.Releases.viewchangelog": "查看变更日志",
"components.Settings.SettingsAbout.Releases.versionChangelog": "变更日志",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "<code>develop</code> 分支的变更日志不会显示在以下。请直接到 <GithubLink>GitHub</GithubLink> 查看变更日志。",
"components.Settings.SettingsAbout.Releases.versionChangelog": "{version} 更新日志",
"components.Settings.SettingsAbout.Releases.releases": "软件版本",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "无法获取软件版本资料。GitHub 崩潰了吗?",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "软件发行数据当前不可用。",
"components.Settings.SettingsAbout.Releases.latestversion": "最新软件版本",
"components.Settings.SettingsAbout.Releases.currentversion": "目前的软件版本",
"components.Settings.SettingsAbout.Releases.currentversion": "当前版本",
"components.Settings.RadarrModal.validationRootFolderRequired": "必须设置根目录",
"components.Settings.RadarrModal.validationProfileRequired": "必须设置质量",
"components.Settings.RadarrModal.validationPortRequired": "请输入有效的端口",
@ -879,5 +878,6 @@
"components.Settings.Notifications.encryptionNone": "不使用加密",
"components.Settings.Notifications.encryptionImplicitTls": "使用传输层安全标准TLS",
"components.Settings.Notifications.encryptionDefault": "盡可能使用 STARTTLS",
"components.Settings.Notifications.encryption": "加密方式"
"components.Settings.Notifications.encryption": "加密方式",
"components.StatusBadge.status": "{status}"
}

@ -2,7 +2,7 @@
"components.Settings.Notifications.webhookUrl": "Webhook 網址",
"components.Settings.Notifications.NotificationsWebhook.webhookUrl": "Webhook 網址",
"components.Settings.Notifications.NotificationsSlack.webhookUrl": "Webhook 網址",
"components.Settings.applicationurl": "應用程式網址URL",
"components.Settings.applicationurl": "應用程式網址",
"components.Settings.SonarrModal.apiKey": "應用程式密鑰",
"components.Settings.apikey": "應用程式密鑰",
"components.Settings.RadarrModal.apiKey": "應用程式密鑰",
@ -33,7 +33,7 @@
"i18n.failed": "失敗",
"i18n.close": "關閉",
"i18n.cancel": "取消",
"i18n.request": "提請求",
"i18n.request": "提請求",
"i18n.requested": "已經有請求",
"i18n.retry": "重試",
"pages.returnHome": "返回首頁",
@ -93,23 +93,23 @@
"components.RequestList.showallrequests": "查看所有請求",
"components.RequestList.requests": "請求",
"components.RequestList.RequestItem.seasons": "季數",
"components.RequestList.RequestItem.failedretry": "重試提請求中出了點問題。",
"components.RequestList.RequestItem.failedretry": "重試提請求中出了點問題。",
"components.RequestCard.seasons": "季數",
"components.RequestButton.viewrequest4k": "查看 4K 請求",
"components.RequestButton.viewrequest": "查看請求",
"components.RequestButton.requestmore4k": "再提 4K 請求",
"components.RequestButton.requestmore": "提更多季數的請求",
"components.RequestButton.requestmore4k": "再提 4K 請求",
"components.RequestButton.requestmore": "提更多季數的請求",
"components.RequestButton.declinerequests": "拒絕{requestCount, plural, one {請求} other {{requestCount} 個請求}}",
"components.RequestButton.declinerequest4k": "拒絕 4K 請求",
"components.RequestButton.declinerequest": "拒絕請求",
"components.RequestButton.decline4krequests": "拒絕{requestCount, plural, one { 4K 請求} other { {requestCount} 個 4K 請求}}",
"components.RequestButton.approverequests": "批准{requestCount, plural, one {請求} other {{requestCount} 個請求}}",
"components.RequestButton.decline4krequests": "拒絕 {requestCount, plural, one {4K 請求} other {{requestCount} 個 4K 請求}}",
"components.RequestButton.approverequests": "批准{requestCount, plural, one {請求} other { {requestCount} 個請求}}",
"components.RequestButton.approverequest4k": "批准 4K 請求",
"components.RequestButton.approverequest": "批准請求",
"components.RequestButton.approve4krequests": "批准{requestCount, plural, one { 4K 請求} other { {requestCount} 個 4K 請求}}",
"components.RequestBlock.seasons": "季數",
"components.PersonDetails.crewmember": "製作群成員",
"components.NotificationTypeSelector.mediarequested": "請求提",
"components.NotificationTypeSelector.mediarequested": "請求提",
"components.NotificationTypeSelector.mediafailed": "請求失敗",
"components.NotificationTypeSelector.mediaapproved": "請求批准",
"components.NotificationTypeSelector.mediaavailableDescription": "當請求的媒體可觀看時發送通知。",
@ -146,15 +146,15 @@
"components.Discover.upcomingmovies": "即將上映的電影",
"components.Discover.upcoming": "即將上映的電影",
"components.Discover.trending": "趨勢",
"components.Discover.recentlyAdded": "最新添加",
"components.Discover.recentlyAdded": "最新新增",
"components.Discover.recentrequests": "最新請求",
"components.Discover.populartv": "熱門電視節目",
"components.Discover.popularmovies": "熱門電影",
"components.Discover.discovertv": "熱門電視節目",
"components.Discover.discovermovies": "熱門電影",
"components.CollectionDetails.requestswillbecreated": "為以下的電影提請求:",
"components.CollectionDetails.requestcollection": "提系列請求",
"components.CollectionDetails.requestSuccess": "為 <strong>{title}</strong> 提請求成功!",
"components.CollectionDetails.requestswillbecreated": "為以下的電影提請求:",
"components.CollectionDetails.requestcollection": "提系列請求",
"components.CollectionDetails.requestSuccess": "為 <strong>{title}</strong> 提請求成功!",
"components.CollectionDetails.overview": "概要",
"components.UserList.userdeleteerror": "刪除使用者中出了點問題。",
"components.UserList.userdeleted": "使用者刪除成功!",
@ -176,9 +176,9 @@
"components.Settings.RadarrModal.baseUrl": "網站根目錄",
"components.StatusChacker.reloadOverseerr": "刷新頁面",
"components.Settings.notrunning": "未運行",
"components.Settings.activeProfile": "現行品質設定",
"components.Settings.activeProfile": "目前的品質設定",
"components.Settings.notificationsettings": "通知設定",
"components.Settings.default4k": "設定 4K 為默認分辨率",
"components.Settings.default4k": "設定 4K 為預設分辨率",
"components.Settings.currentlibrary": "當前媒體庫: {name}",
"components.Settings.SonarrModal.seasonfolders": "季數檔案夾",
"components.Settings.SettingsAbout.overseerrinformation": "關於 Overseerr",
@ -198,10 +198,10 @@
"components.Settings.SonarrModal.testFirstQualityProfiles": "請先測試連線",
"components.Settings.RadarrModal.testFirstRootFolders": "請先測試連線",
"components.Settings.RadarrModal.testFirstQualityProfiles": "請先測試連線",
"components.Settings.SonarrModal.defaultserver": "默認伺服器",
"components.Settings.SonarrModal.defaultserver": "預設伺服器",
"components.Settings.deleteserverconfirm": "確定要刪除這個伺服器嗎?",
"components.Settings.addradarr": "添加 Radarr 伺服器",
"components.Settings.addsonarr": "添加 Sonarr 伺服器",
"components.Settings.addradarr": "新增 Radarr 伺服器",
"components.Settings.addsonarr": "新增 Sonarr 伺服器",
"components.Settings.SonarrModal.server4k": "4K 伺服器",
"components.Settings.SettingsAbout.supportoverseerr": "支持 Overseerr",
"components.Settings.SonarrModal.validationProfileRequired": "必須設定品質",
@ -228,18 +228,18 @@
"components.Settings.SonarrModal.animerootfolder": "動漫根目錄",
"components.Settings.SonarrModal.rootfolder": "根目錄",
"components.Settings.RadarrModal.rootfolder": "根目錄",
"components.Settings.Notifications.NotificationsWebhook.resetPayload": "重置為默認",
"components.Settings.Notifications.NotificationsWebhook.resetPayload": "重設為預設",
"components.Settings.Notifications.NotificationsWebhook.customJson": "JSON 有效負載",
"components.Settings.Notifications.NotificationsWebhook.resetPayloadSuccess": "JSON 有效負載重設為默認負載成功!",
"components.Settings.Notifications.NotificationsPushover.validationUserTokenRequired": "請輸入有效的使用者或群組金鑰",
"components.Settings.Notifications.NotificationsWebhook.resetPayloadSuccess": "JSON 有效負載重設為預設負載成功!",
"components.Settings.Notifications.NotificationsPushover.validationUserTokenRequired": "請輸入有效的使用者或群組令牌",
"components.Settings.menuJobs": "作業和快取",
"components.Settings.toastApiKeyFailure": "生成應用程式密鑰出了點問題。",
"components.Settings.toastSettingsFailure": "保存設定中出了點問題。",
"components.UserList.deleteconfirm": "確定要刪除這個使用者嗎?此使用者的所有儲存資料將被清除。",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "無法獲取軟體版本資料。GitHub 崩潰了嗎?",
"components.Settings.SettingsAbout.Releases.releasedataMissing": "無法獲取軟體版本資料。",
"components.UserList.passwordinfodescription": "設定應用程式網址以及啟用電子郵件通知,才能自動生成密碼。",
"components.Settings.Notifications.validationBotAPIRequired": "請輸入機器人授權金鑰",
"components.Settings.Notifications.botAPI": "Bot 機器人授權金鑰",
"components.Settings.Notifications.validationBotAPIRequired": "請輸入機器人授權令牌",
"components.Settings.Notifications.botAPI": "Bot 機器人授權令牌",
"components.Settings.menuServices": "伺服器",
"components.Settings.address": "網址",
"components.Settings.ssl": "SSL",
@ -248,30 +248,30 @@
"components.Settings.port": "通訊埠",
"components.Settings.SonarrModal.port": "通訊埠",
"components.Settings.RadarrModal.port": "通訊埠",
"components.Settings.Notifications.NotificationsPushover.userToken": "使用者或群組金鑰",
"components.Settings.Notifications.NotificationsPushover.accessToken": "應用程式 API 金鑰",
"components.Settings.Notifications.NotificationsPushover.userToken": "使用者或群組令牌",
"components.Settings.Notifications.NotificationsPushover.accessToken": "應用程式 API 令牌",
"components.Settings.menuNotifications": "通知",
"components.Settings.menuLogs": "日誌",
"components.Settings.menuAbout": "關於 Overseerr",
"components.Settings.default": "默認",
"components.Settings.default": "預設",
"components.Settings.SettingsAbout.version": "軟體版本",
"components.Settings.SettingsAbout.Releases.latestversion": "最新軟體版本",
"components.Settings.SettingsAbout.Releases.currentversion": "目前的軟體版本",
"components.Settings.SettingsAbout.Releases.latestversion": "最新版本",
"components.Settings.SettingsAbout.Releases.currentversion": "目前的版本",
"components.Settings.SettingsAbout.timezone": "時區",
"components.Settings.SettingsAbout.documentation": "文檔",
"components.Settings.SettingsAbout.documentation": "使用說明",
"components.RequestModal.pending4krequest": "{title} 的 4K 請求",
"components.RequestModal.pendingrequest": "{title} 的請求",
"components.RequestModal.extras": "特輯",
"components.Settings.SettingsAbout.Releases.versionChangelog": "變更日誌",
"components.Settings.SettingsAbout.Releases.versionChangelog": "{version} 變更日誌",
"components.Settings.SettingsAbout.Releases.releases": "軟體版本",
"components.Settings.plexsettings": "Plex 設定",
"components.RequestModal.selectseason": "季數選擇",
"components.RequestModal.requesttitle": "為 {title} 提請求",
"components.RequestModal.requestseasons": "提請求",
"components.RequestModal.requesttitle": "為 {title} 提請求",
"components.RequestModal.requestseasons": "提請求",
"components.RequestModal.requestadmin": "此請求將自動被批准。",
"components.RequestModal.requestSuccess": "為 <strong>{title}</strong> 提請求成功!",
"components.RequestModal.requestSuccess": "為 <strong>{title}</strong> 提請求成功!",
"components.RequestModal.requestCancel": "<strong>{title}</strong> 的請求已被取消。",
"components.RequestModal.request4ktitle": "為 {title} 提 4K 請求",
"components.RequestModal.request4ktitle": "為 {title} 提 4K 請求",
"components.PersonDetails.appearsin": "演出",
"components.PersonDetails.ascharacter": "飾演 {character}",
"components.TvDetails.overviewunavailable": "沒有概要。",
@ -296,7 +296,7 @@
"components.Settings.Notifications.NotificationsWebhook.authheader": "Authorization 頭欄位",
"components.Settings.RadarrModal.minimumAvailability": "最低狀態",
"components.Settings.Notifications.allowselfsigned": "允許自簽名證書",
"components.Settings.Notifications.NotificationsPushover.validationAccessTokenRequired": "請輸入應用程式 API 金鑰",
"components.Settings.Notifications.NotificationsPushover.validationAccessTokenRequired": "請輸入應用程式 API 令牌",
"components.Settings.RadarrModal.hostname": "主機名稱或 IP 位址",
"components.Settings.SonarrModal.hostname": "主機名稱或 IP 位址",
"components.Settings.hostname": "主機名稱或 IP 位址",
@ -310,21 +310,21 @@
"components.Settings.Notifications.NotificationsPushover.pushoversettingssaved": "Pushover 通知設定保存成功!",
"components.UserList.created": "建立日期",
"components.UserList.create": "建立",
"components.Settings.SonarrModal.createsonarr": "添加 Sonarr 伺服器",
"components.Settings.RadarrModal.createradarr": "添加 Radarr 伺服器",
"components.Settings.SonarrModal.createsonarr": "新增 Sonarr 伺服器",
"components.Settings.RadarrModal.createradarr": "新增 Radarr 伺服器",
"components.Settings.SonarrModal.servername": "伺服器名稱",
"components.Settings.SonarrModal.editsonarr": "編輯 Sonarr 伺服器",
"components.Settings.SonarrModal.add": "添加伺服器",
"components.Settings.SonarrModal.add": "新增伺服器",
"components.Settings.RadarrModal.servername": "伺服器名稱",
"components.Settings.RadarrModal.editradarr": "編輯 Radarr 伺服器",
"components.Settings.RadarrModal.defaultserver": "默認伺服器",
"components.Settings.RadarrModal.add": "添加伺服器",
"components.Settings.RadarrModal.defaultserver": "預設伺服器",
"components.Settings.RadarrModal.add": "新增伺服器",
"components.StatusChacker.newversionDescription": "Overseerr 軟體已更新。請點擊以下的按鈕刷新頁面。",
"components.RequestModal.requestcancelled": "<strong>{title}</strong> 的請求已被取消。",
"components.RequestModal.AdvancedRequester.qualityprofile": "品質設定",
"components.RequestModal.AdvancedRequester.animenote": "*這是個動漫節目。",
"components.RequestModal.AdvancedRequester.advancedoptions": "進階選項",
"components.RequestModal.AdvancedRequester.default": "{name}默認",
"components.RequestModal.AdvancedRequester.default": "{name}預設",
"components.RequestModal.AdvancedRequester.destinationserver": "目標伺服器",
"components.RequestBlock.server": "目標伺服器",
"components.RequestModal.AdvancedRequester.rootfolder": "根目錄",
@ -348,7 +348,7 @@
"components.UserList.userssaved": "使用者權限保存成功!",
"components.Settings.hideAvailable": "隱藏可觀看的電影和電視節目",
"components.Settings.SonarrModal.externalUrl": "外部網址",
"components.Settings.RadarrModal.externalUrl": "外部網址URL",
"components.Settings.RadarrModal.externalUrl": "外部網址",
"components.Settings.csrfProtection": "防止跨站請求偽造CSRF攻擊",
"components.RequestBlock.requestoverrides": "覆寫請求",
"components.Settings.toastPlexConnectingSuccess": "Plex 伺服器連線成功!",
@ -375,10 +375,10 @@
"components.PlexLoginButton.signingin": "登入中…",
"components.PermissionEdit.users": "管理使用者",
"components.PermissionEdit.settings": "設定管理",
"components.PermissionEdit.request4kTv": "提 4K 電視節目請求",
"components.PermissionEdit.request4kMovies": "提 4K 電影請求",
"components.PermissionEdit.request4k": "提 4K 請求",
"components.PermissionEdit.request": "提請求",
"components.PermissionEdit.request4kTv": "提 4K 電視節目請求",
"components.PermissionEdit.request4kMovies": "提 4K 電影請求",
"components.PermissionEdit.request4k": "提 4K 請求",
"components.PermissionEdit.request": "提請求",
"components.PermissionEdit.managerequests": "請求管理",
"components.MovieDetails.downloadstatus": "下載狀態",
"components.RequestBlock.profilechanged": "品質設定",
@ -386,7 +386,7 @@
"components.RequestModal.requestedited": "<strong>{title}</strong> 的請求編輯成功!",
"components.Settings.trustProxy": "啟用代理伺服器所需功能",
"components.RequestModal.errorediting": "編輯請求中出了點問題。",
"components.RequestModal.requesterror": "提請求中出了點問題。",
"components.RequestModal.requesterror": "提請求中出了點問題。",
"components.Settings.SettingsJobsCache.cachekeys": "鍵數",
"components.Settings.SettingsJobsCache.cachevsize": "值儲存大小",
"components.Settings.SettingsJobsCache.cacheksize": "鍵儲存大小",
@ -398,14 +398,14 @@
"components.Settings.SettingsJobsCache.nextexecution": "下一次執行時間",
"components.Settings.SettingsJobsCache.jobtype": "作業類型",
"components.Settings.SettingsJobsCache.jobstarted": "{jobname} 已開始運行。",
"components.Settings.SettingsJobsCache.jobcancelled": "{jobname} 已被取消。",
"components.Settings.SettingsJobsCache.jobcancelled": "{jobname}已被取消。",
"components.Settings.SettingsJobsCache.jobs": "作業",
"components.Settings.SettingsJobsCache.jobname": "作業名",
"components.Settings.SettingsJobsCache.flushcache": "清除快取",
"components.Settings.SettingsJobsCache.canceljob": "取消作業",
"components.Settings.SettingsJobsCache.cache": "快取記憶體",
"components.Settings.SettingsJobsCache.cache": "快取",
"components.Settings.SonarrModal.toastSonarrTestSuccess": "Sonarr 伺服器連線成功!",
"components.Settings.SettingsJobsCache.command": "令",
"components.Settings.SettingsJobsCache.command": "令",
"components.Settings.SettingsJobsCache.process": "程序",
"components.Settings.SettingsAbout.preferredmethod": "首選",
"i18n.advanced": "進階",
@ -416,8 +416,8 @@
"components.Settings.toastPlexConnectingFailure": "Plex 伺服器連線失敗。",
"components.TvDetails.mark4kavailable": "標記 4K 版為可觀看",
"components.TvDetails.markavailable": "標記為可觀看",
"components.TvDetails.manageModalClearMediaWarning": "*這電視節目的所有儲存資料將被永久刪除(包括使用者提交的請求)。如果節目存在於您的 Plex 伺服器,資料會在媒體庫掃描時重新建立。",
"components.MovieDetails.manageModalClearMediaWarning": "*這將會刪除包括使用者請求在內所有有關這部電影的資料。如果電影存在於您的 Plex 伺服器,資料將會在媒體庫掃描時重新建立。",
"components.TvDetails.manageModalClearMediaWarning": "*這將會刪除包括使用者請求在內所有有關這個電視節目的資料。如果這個節目存在於您的 Plex 伺服器,資料將會在媒體庫掃描時重新建立。",
"components.MovieDetails.manageModalClearMediaWarning": "*這將會刪除包括使用者請求在內所有有關這部電影的資料。如果這部電影存在於您的 Plex 伺服器,資料將會在媒體庫掃描時重新建立。",
"components.TvDetails.allseasonsmarkedavailable": "*每季將被標記為可觀看。",
"components.Settings.csrfProtectionHoverTip": "除非您了解此功能,請勿啟用它!",
"components.UserList.users": "使用者",
@ -425,7 +425,7 @@
"components.Search.search": "搜尋",
"components.Setup.setup": "配置",
"components.Discover.discover": "探索",
"components.AppDataWarning.dockerVolumeMissingDescription": "必須使用繫結掛載bind mount指定某個宿主機器的資料夾跟容器內的 <code>{appDataPath}</code> 資料夾連通,才能保存 Overseerr 的配置和數據。",
"components.AppDataWarning.dockerVolumeMissingDescription": "您必須使用繫結掛載bind mount來繫結主機上的目錄跟 Docker 容器內的 <code>{appDataPath}</code> 目錄,才能保存 Overseerr 的配置和數據。",
"components.RequestModal.AdvancedRequester.requestas": "請求者",
"components.Settings.RadarrModal.validationApplicationUrlTrailingSlash": "必須刪除結尾斜線",
"components.Settings.SonarrModal.validationApplicationUrlTrailingSlash": "必須刪除結尾斜線",
@ -435,8 +435,8 @@
"components.Settings.SonarrModal.validationApplicationUrl": "請輸入有效的網址",
"components.Settings.RadarrModal.validationApplicationUrl": "請輸入有效的網址",
"components.PermissionEdit.viewrequests": "查看請求",
"components.Settings.RadarrModal.validationBaseUrlLeadingSlash": "必須加前置斜線",
"components.Settings.SonarrModal.validationBaseUrlLeadingSlash": "必須加前置斜線",
"components.Settings.RadarrModal.validationBaseUrlLeadingSlash": "必須加前置斜線",
"components.Settings.SonarrModal.validationBaseUrlLeadingSlash": "必須加前置斜線",
"components.Settings.SonarrModal.validationBaseUrlTrailingSlash": "必須刪除結尾斜線",
"components.Settings.RadarrModal.validationBaseUrlTrailingSlash": "必須刪除結尾斜線",
"components.UserList.validationEmail": "請輸入有效的電子郵件地址",
@ -455,13 +455,13 @@
"components.ResetPassword.password": "密碼",
"components.Login.forgotpassword": "忘記密碼?",
"components.TvDetails.nextAirDate": "下一次播出日期",
"components.NotificationTypeSelector.mediarequestedDescription": "當使用者提需要管理員批准的請求時發送通知。",
"components.NotificationTypeSelector.mediarequestedDescription": "當使用者提需要管理員批准的請求時發送通知。",
"components.NotificationTypeSelector.mediafailedDescription": "當 Radarr 或 Sonarr 處理請求失敗時發送通知。",
"components.NotificationTypeSelector.mediadeclinedDescription": "當請求拒被絕時發送通知。",
"components.PermissionEdit.request4kDescription": "授予提 4K 請求的權限。",
"components.PermissionEdit.request4kMoviesDescription": "授予為電影提 4K 請求的權限。",
"components.PermissionEdit.request4kTvDescription": "授予提 4K 電視節目請求的權限。",
"components.PermissionEdit.requestDescription": "授予提非 4K 請求的權限。",
"components.PermissionEdit.request4kDescription": "授予提 4K 請求的權限。",
"components.PermissionEdit.request4kMoviesDescription": "授予為電影提 4K 請求的權限。",
"components.PermissionEdit.request4kTvDescription": "授予提 4K 電視節目請求的權限。",
"components.PermissionEdit.requestDescription": "授予提非 4K 請求的權限。",
"components.PermissionEdit.viewrequestsDescription": "授予查看其他使用者的請求的權限。",
"components.Settings.SonarrModal.validationLanguageProfileRequired": "必須設定語言",
"components.Settings.SonarrModal.testFirstLanguageProfiles": "請先測試連線",
@ -508,7 +508,7 @@
"components.UserList.edituser": "編輯使用者權限",
"components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsFailed": "Pushbullet 通知設定保存失敗。",
"components.Settings.Notifications.NotificationsPushbullet.pushbulletSettingsSaved": "Pushbullet 通知設定保存成功!",
"components.Settings.Notifications.NotificationsPushbullet.validationAccessTokenRequired": "請輸入 API 金鑰",
"components.Settings.Notifications.NotificationsPushbullet.validationAccessTokenRequired": "請輸入 API 令牌",
"components.UserProfile.UserSettings.UserNotificationSettings.discordId": "使用者 ID",
"components.UserProfile.ProfileHeader.profile": "顯示個人資料",
"components.UserProfile.ProfileHeader.settings": "使用者設定",
@ -520,23 +520,22 @@
"components.UserProfile.UserSettings.UserPermissions.toastSettingsFailure": "保存設定中出了點問題。",
"components.UserProfile.UserSettings.UserGeneralSettings.toastSettingsFailure": "保存設定中出了點問題。",
"components.Settings.Notifications.NotificationsPushbullet.agentEnabled": "啟用通知",
"components.Settings.Notifications.NotificationsPushbullet.accessToken": "API 金鑰",
"components.Settings.Notifications.NotificationsPushbullet.accessToken": "API 令牌",
"components.Layout.UserDropdown.settings": "設定",
"components.Layout.UserDropdown.myprofile": "個人資料",
"components.UserProfile.UserSettings.UserPasswordChange.validationConfirmPassword": "密碼必須匹配",
"components.UserProfile.UserSettings.UserPasswordChange.currentpassword": "目前密碼",
"components.UserProfile.UserSettings.UserPasswordChange.currentpassword": "目前密碼",
"components.UserProfile.UserSettings.UserPasswordChange.newpassword": "新密碼",
"components.UserProfile.UserSettings.UserPasswordChange.validationCurrentPassword": "請輸入當前的密碼",
"components.UserProfile.UserSettings.UserPasswordChange.validationNewPassword": "請輸入新密碼",
"components.UserProfile.UserSettings.UserPasswordChange.toastSettingsSuccess": "密碼設定成功!",
"components.RequestModal.SearchByNameModal.nosummary": "沒有概要。",
"components.UserProfile.UserSettings.UserNotificationSettings.validationDiscordId": "請輸入有效的使用者 ID",
"components.UserProfile.UserSettings.UserNotificationSettings.discordIdTip": "您的<FindDiscordIdLink>使用者 ID</FindDiscordIdLink>",
"components.UserProfile.UserSettings.UserNotificationSettings.discordIdTip": "您的<FindDiscordIdLink>使用者 ID 號碼</FindDiscordIdLink>",
"components.UserProfile.UserSettings.UserPasswordChange.toastSettingsFailure": "重設密碼中出了點問題。",
"components.RequestModal.SearchByNameModal.notvdbiddescription": "無法自動配對您的請求。請從以下列表中選擇正確的媒體項。",
"components.CollectionDetails.requestswillbecreated4k": "為以下的電影提交 4K 請求:",
"components.CollectionDetails.requestcollection4k": "提交 4K 系列請求",
"components.Settings.SettingsAbout.Releases.runningDevelopMessage": "<code>develop</code> 分支的變更日誌不會顯示在以下。請直接到 <GithubLink>GitHub</GithubLink> 查看變更日誌。",
"components.CollectionDetails.requestswillbecreated4k": "為以下的電影提出 4K 請求:",
"components.CollectionDetails.requestcollection4k": "提出 4K 系列請求",
"components.Settings.trustProxyTip": "使用代理伺服器時,允許 Overseerr 探明客戶端 IP 位址Overseerr 必須重新啟動)",
"components.Settings.csrfProtectionTip": "設定外部訪問權限為只讀Overseerr 必須重新啟動)",
"components.ResetPassword.requestresetlinksuccessmessage": "通過電子郵件發送了密碼重設鏈接。",
@ -555,9 +554,9 @@
"components.Settings.regionTip": "以地區可用性篩選結果",
"components.UserProfile.UserSettings.UserGeneralSettings.originallanguageTip": "以原始語言篩選結果",
"components.Settings.originallanguageTip": "以原始語言篩選結果",
"components.Settings.SettingsJobsCache.jobsDescription": "Overseerr 將定時運行以下的維護任務。手動執行工作不會影響它正常的時間表。",
"components.Settings.SettingsJobsCache.jobsDescription": "Overseerr 將定時運行以下的維護任務。手動執行工作不會影響它正常的行程。",
"components.Settings.plexsettingsDescription": "關於 Plex 伺服器的設定。Overseerr 將定時執行媒體庫掃描。",
"components.Settings.manualscanDescription": "在正常情況下Overseerr 會每24小時掃描您的 Plex 媒體庫。最新添加的媒體將更頻繁掃描。設定新的 Plex 伺服器時,我們建議您執行一次手動掃描!",
"components.Settings.manualscanDescription": "在正常情況下Overseerr 會每24小時掃描您的 Plex 媒體庫。最新新增的媒體將更頻繁掃描。設定新的 Plex 伺服器時,我們建議您執行一次手動掃描!",
"components.RegionSelector.regionServerDefault": "預設設定({region}",
"components.Settings.settingUpPlexDescription": "您可以手動輸入您的 Plex 伺服器資料,或從 <RegisterPlexTVLink>plex.tv</RegisterPlexTVLink> 返回的設定做選擇以及自動配置。請點下拉式選單右邊的按鈕獲取伺服器列表。",
"components.Settings.plexlibrariesDescription": "Overseerr 將掃描的媒體庫。",
@ -587,7 +586,7 @@
"components.Discover.NetworkSlider.networks": "電視網",
"components.Discover.StudioSlider.studios": "製作公司",
"components.Settings.Notifications.validationUrl": "請輸入有效的網址",
"components.Settings.Notifications.botAvatarUrl": "Bot 機器人頭像網址URL",
"components.Settings.Notifications.botAvatarUrl": "Bot 機器人頭像網址",
"components.RequestList.RequestItem.modified": "最後修改者",
"components.RequestList.RequestItem.modifieduserdate": "{user}{date}",
"components.RequestList.RequestItem.requested": "請求者",
@ -596,20 +595,20 @@
"components.Settings.scan": "媒體庫同步",
"components.Settings.SettingsJobsCache.sonarr-scan": "Sonarr 掃描",
"components.Settings.SettingsJobsCache.radarr-scan": "Radarr 掃描",
"components.Settings.SettingsJobsCache.plex-recently-added-scan": "Plex 最新添加掃描",
"components.Settings.SettingsJobsCache.plex-recently-added-scan": "Plex 最新新增掃描",
"components.Settings.SettingsJobsCache.plex-full-scan": "Plex 媒體庫掃描",
"components.Discover.DiscoverTvLanguage.languageSeries": "{language}電視節目",
"components.Discover.DiscoverMovieLanguage.languageMovies": "{language}電影",
"components.UserProfile.ProfileHeader.userid": "使用者 ID{userid}",
"components.UserProfile.ProfileHeader.joindate": "建立日期:{joindate}",
"components.Settings.SettingsUsers.localLogin": "允許本地登入",
"components.Settings.SettingsUsers.defaultPermissions": "默認權限",
"components.Settings.SettingsUsers.defaultPermissions": "預設權限",
"components.Settings.SettingsUsers.userSettingsDescription": "關於使用者的全局和預設設定。",
"components.Settings.SettingsUsers.userSettings": "使用者設定",
"components.Settings.menuUsers": "使用者",
"components.Settings.SettingsUsers.toastSettingsSuccess": "使用者設定保存成功!",
"components.Settings.SettingsUsers.toastSettingsFailure": "保存設定中出了點問題。",
"components.NotificationTypeSelector.mediaAutoApprovedDescription": "當使用者提自動批准的請求時發送通知。",
"components.NotificationTypeSelector.mediaAutoApprovedDescription": "當使用者提自動批准的請求時發送通知。",
"components.NotificationTypeSelector.mediaAutoApproved": "請求自動批准",
"components.UserProfile.UserSettings.UserPermissions.unauthorizedDescription": "您不能編輯自己的權限。",
"components.UserProfile.UserSettings.unauthorizedDescription": "您無權編輯此使用者的設定。",
@ -626,7 +625,7 @@
"components.Discover.MovieGenreList.moviegenres": "電影類型",
"components.Discover.TvGenreList.seriesgenres": "電視節目類型",
"components.Settings.partialRequestsEnabled": "允許不完整的電視節目請求",
"components.RequestModal.requestall": "提請求",
"components.RequestModal.requestall": "提請求",
"components.RequestModal.alreadyrequested": "已經有請求",
"components.Settings.SettingsLogs.time": "時間戳",
"components.Settings.SettingsLogs.resumeLogs": "恢復",
@ -659,7 +658,7 @@
"components.Settings.SettingsJobsCache.jobsandcache": "作業和快取",
"components.Settings.SettingsAbout.about": "關於 Overseerr",
"components.Settings.cacheImages": "啟用圖像緩存",
"components.Settings.SettingsLogs.logsDescription": "日誌檔案位置:<code>{configDir}/logs/overseerr.log</code>",
"components.Settings.SettingsLogs.logsDescription": "您也能直接查看 <code>stdout</code> 數據流或位置於 <code>{configDir}/logs/overseerr.log</code> 的日誌檔案。",
"components.Settings.cacheImagesTip": "把所有的圖像優化和保存到快取記憶體(需要大量的磁碟空間)",
"components.Settings.SettingsLogs.logDetails": "日誌詳細信息",
"components.Settings.SettingsLogs.extraData": "附加數據",
@ -673,13 +672,13 @@
"i18n.delimitedlist": "{a}、{b}",
"components.Settings.SettingsUsers.tvRequestLimitLabel": "電視節目請求全局限制",
"components.Settings.SettingsUsers.movieRequestLimitLabel": "電影請求全局限制",
"components.RequestModal.QuotaDisplay.seasonlimit": "季數",
"components.RequestModal.QuotaDisplay.seasonlimit": "季數",
"components.RequestModal.QuotaDisplay.season": "電視節目季數",
"components.RequestModal.QuotaDisplay.requestsremaining": "{remaining, plural, =0 {電影請求剩餘數不足} other {剩餘 <strong>#</strong> 個{type}請求}}",
"components.RequestModal.QuotaDisplay.notenoughseasonrequests": "請求剩餘數不足",
"components.RequestModal.QuotaDisplay.movielimit": "電影",
"components.RequestModal.QuotaDisplay.allowedRequestsUser": "此使用者每 <strong>{days}</strong> 天能提交 <strong>{limit}</strong> {type}個請求。",
"components.RequestModal.QuotaDisplay.allowedRequests": "您每 <strong>{days}</strong> 天能為 <strong>{limit}</strong> {type}提交請求。",
"components.RequestModal.QuotaDisplay.movielimit": "電影",
"components.RequestModal.QuotaDisplay.allowedRequestsUser": "此使用者每 <strong>{days}</strong> 天能提出 <strong>{limit}</strong> 個{type}請求。",
"components.RequestModal.QuotaDisplay.allowedRequests": "您每 <strong>{days}</strong> 天能提出 <strong>{limit}</strong> 個{type}請求。",
"components.UserProfile.UserSettings.UserGeneralSettings.seriesrequestlimit": "電視節目請求限制",
"components.UserProfile.UserSettings.UserGeneralSettings.movierequestlimit": "電影請求限制",
"components.UserProfile.movierequests": "電影請求",
@ -701,8 +700,8 @@
"i18n.saving": "保存中…",
"i18n.save": "保存",
"i18n.resultsperpage": "每頁顯示 {pageSize} 列",
"i18n.requesting": "提請求中…",
"i18n.request4k": "提 4K 請求",
"i18n.requesting": "提請求中…",
"i18n.request4k": "提 4K 請求",
"i18n.previous": "上一頁",
"i18n.notrequested": "沒有請求",
"i18n.noresults": "沒有結果。",
@ -712,8 +711,8 @@
"i18n.back": "返回",
"i18n.all": "所有",
"i18n.areyousure": "確定嗎?",
"components.RequestModal.QuotaDisplay.requiredquotaUser": "此使用者的電視節目請求數量必須至少剩餘 <strong>{seasons}</strong> 個季數才能為此節目提交請求。",
"components.RequestModal.QuotaDisplay.requiredquota": "您的電視節目請求數量必須至少剩餘 <strong>{seasons}</strong> 個季數才能為此節目提交請求。",
"components.RequestModal.QuotaDisplay.requiredquotaUser": "此使用者的電視節目請求數量必須至少剩餘 <strong>{seasons}</strong> 個季數才能提出此節目請求。",
"components.RequestModal.QuotaDisplay.requiredquota": "您的電視節目請求數量必須至少剩餘 <strong>{seasons}</strong> 個季數才能提出此節目請求。",
"components.TvDetails.originaltitle": "原始標題",
"components.MovieDetails.originaltitle": "原始標題",
"components.RequestModal.QuotaDisplay.quotaLinkUser": "訪問此使用者的<ProfileLink>個人資料頁面</ProfileLink>以查看使用者的請求限制 。",
@ -728,10 +727,10 @@
"components.RequestModal.AdvancedRequester.notagoptions": "沒有標籤。",
"components.Settings.SonarrModal.edit4ksonarr": "編輯 4K Sonarr 伺服器",
"components.Settings.RadarrModal.edit4kradarr": "編輯 4K Radarr 伺服器",
"components.Settings.RadarrModal.create4kradarr": "添加 4K Radarr 伺服器",
"components.Settings.SonarrModal.create4ksonarr": "添加 4K Sonarr 伺服器",
"components.Settings.SonarrModal.default4kserver": "默認 4K 伺服器",
"components.Settings.RadarrModal.default4kserver": "默認 4K 伺服器",
"components.Settings.RadarrModal.create4kradarr": "新增 4K Radarr 伺服器",
"components.Settings.SonarrModal.create4ksonarr": "新增 4K Sonarr 伺服器",
"components.Settings.SonarrModal.default4kserver": "預設 4K 伺服器",
"components.Settings.RadarrModal.default4kserver": "預設 4K 伺服器",
"components.Settings.SonarrModal.testFirstTags": "請先測試連線",
"components.Settings.RadarrModal.testFirstTags": "請先測試連線",
"components.Settings.SonarrModal.loadingTags": "載入中…",
@ -761,19 +760,19 @@
"components.RequestList.RequestItem.cancelRequest": "取消請求",
"components.NotificationTypeSelector.notificationTypes": "通知類型",
"components.Discover.noRequests": "沒有請求。",
"components.Layout.VersionStatus.commitsbehind": "落後 {commitsBehind} 提交",
"components.Layout.VersionStatus.outofdate": "過時",
"components.Layout.VersionStatus.commitsbehind": "落後 {commitsBehind} 提交",
"components.Layout.VersionStatus.outofdate": "非最新版本",
"components.Layout.VersionStatus.streamstable": "Overseerr 穩定版",
"components.Layout.VersionStatus.streamdevelop": "Overseerr「develop」開發版",
"components.Settings.SettingsAbout.outofdate": "過時",
"components.Settings.SettingsAbout.outofdate": "非最新版本",
"components.Settings.SettingsAbout.uptodate": "最新",
"components.Settings.noDefaultNon4kServer": "如果您只有一個 {serverType} 伺服器,請勿把它設定為 4K 伺服器。",
"components.Settings.noDefaultServer": "您必須至少指定一個 {serverType} 伺服器為默認,才能處理{mediaType}請求。",
"components.Settings.serviceSettingsDescription": "關於 {serverType} 伺服器的設定。{serverType} 伺服器數沒有最大值限制,但您只能指定兩個伺服器為默認(一個非 4K、一個 4K。",
"components.Settings.noDefaultServer": "您必須至少指定一個預設 {serverType} 伺服器,才能處理{mediaType}請求。",
"components.Settings.serviceSettingsDescription": "關於 {serverType} 伺服器的設定。{serverType} 伺服器數沒有最大值限制,但您只能指定兩個預設伺服器(一個非 4K、一個 4K。",
"components.Settings.mediaTypeSeries": "電視節目",
"components.Settings.mediaTypeMovie": "電影",
"components.UserProfile.UserSettings.UserPasswordChange.noPasswordSet": "此使用者目前沒有密碼。設定密碼以允許此使用者使用電子郵件地址登入。",
"components.UserProfile.UserSettings.UserPasswordChange.noPasswordSetOwnAccount": "您的帳戶目前沒有密碼。設定密碼以允許使用電子郵件地址登入。",
"components.UserProfile.UserSettings.UserPasswordChange.noPasswordSet": "此使用者的帳戶目前沒有設密碼。若在以下設定密碼,此使用者就能使用「本地登入」。",
"components.UserProfile.UserSettings.UserPasswordChange.noPasswordSetOwnAccount": "您的帳戶目前沒有設密碼。若在以下設定密碼,您就能使用「本地登入」。",
"components.UserList.autogeneratepasswordTip": "通過電子郵件發送伺服器生成的密碼給使用者",
"i18n.retrying": "重試中…",
"components.Settings.serverSecure": "SSL",
@ -782,10 +781,10 @@
"components.RequestList.RequestItem.editrequest": "編輯請求",
"components.Settings.RadarrModal.enableSearch": "啟用自動搜尋",
"components.Settings.SonarrModal.enableSearch": "啟用自動搜尋",
"components.UserProfile.UserSettings.UserNotificationSettings.webpush": "網路推",
"components.Settings.webpush": "網路推",
"components.Settings.Notifications.NotificationsWebPush.webpushsettingssaved": "網路推通知設定保存成功!",
"components.Settings.Notifications.NotificationsWebPush.webpushsettingsfailed": "網路推通知設定保存失敗。",
"components.UserProfile.UserSettings.UserNotificationSettings.webpush": "網路推",
"components.Settings.webpush": "網路推",
"components.Settings.Notifications.NotificationsWebPush.webpushsettingssaved": "網路推通知設定保存成功!",
"components.Settings.Notifications.NotificationsWebPush.webpushsettingsfailed": "網路推通知設定保存失敗。",
"components.UserProfile.UserSettings.UserGeneralSettings.applanguage": "顯示語言",
"components.Settings.Notifications.NotificationsWebPush.agentenabled": "啟用通知",
"components.Settings.Notifications.NotificationsLunaSea.settingsSaved": "LunaSea 通知設定保存成功!",
@ -794,29 +793,29 @@
"components.Settings.Notifications.NotificationsLunaSea.validationWebhookUrl": "請輸入有效的網址",
"components.Settings.Notifications.NotificationsLunaSea.agentenabled": "啟用通知",
"components.Settings.is4k": "4K",
"components.UserProfile.UserSettings.UserNotificationSettings.webpushsettingsfailed": "網路推知設定保存失敗。",
"components.UserProfile.UserSettings.UserNotificationSettings.webpushsettingssaved": "網路推知設定保存成功!",
"components.UserProfile.UserSettings.UserNotificationSettings.webpushsettingsfailed": "網路推送通知設定保存失敗。",
"components.UserProfile.UserSettings.UserNotificationSettings.webpushsettingssaved": "網路推送通知設定保存成功!",
"components.Settings.Notifications.toastEmailTestSuccess": "電子郵件測試通知已發送!",
"components.Settings.Notifications.NotificationsWebPush.toastWebPushTestSuccess": "網路推測試通知已發送!",
"components.Settings.Notifications.NotificationsWebPush.toastWebPushTestSuccess": "網路推測試通知已發送!",
"components.Settings.Notifications.toastTelegramTestSuccess": "Telegram 測試通知已發送!",
"components.Settings.Notifications.toastDiscordTestSuccess": "Discord 測試通知已發送!",
"components.Settings.Notifications.NotificationsSlack.toastSlackTestSuccess": "Slack 測試通知已發送!",
"components.Settings.Notifications.NotificationsPushover.toastPushoverTestSuccess": "Pushover 測試通知已發送!",
"components.Settings.Notifications.NotificationsPushbullet.toastPushbulletTestSuccess": "Pushbullet 測試通知已發送!",
"components.Settings.Notifications.NotificationsLunaSea.toastLunaSeaTestSuccess": "LunaSea 測試通知已發送!",
"components.Settings.noDefault4kServer": "您必須指定一個 4K {serverType} 伺服器為默認,才能處理 4K 的{mediaType}請求。",
"components.Settings.Notifications.NotificationsLunaSea.profileNameTip": "不使用 <code>default</code> 默認設定檔才必須輸入",
"components.Settings.noDefault4kServer": "您必須指定一個 4K {serverType} 伺服器為預設,才能處理 4K 的{mediaType}請求。",
"components.Settings.Notifications.NotificationsLunaSea.profileNameTip": "不使用 <code>default</code> 預設設定檔才必須輸入",
"components.Settings.Notifications.NotificationsLunaSea.profileName": "設定檔名",
"components.Settings.Notifications.toastTelegramTestSending": "發送 Telegram 測試通知中…",
"components.Settings.Notifications.toastEmailTestSending": "發送電子郵件測試通知中…",
"components.Settings.Notifications.toastDiscordTestSending": "發送 Discord 測試通知中…",
"components.Settings.Notifications.NotificationsWebhook.toastWebhookTestSending": "發送 Webhook 測試通知中…",
"components.Settings.Notifications.NotificationsWebPush.toastWebPushTestSending": "發送網路推測試通知中…",
"components.Settings.Notifications.NotificationsWebhook.toastWebhookTestSending": "發送 webhook 測試通知中…",
"components.Settings.Notifications.NotificationsWebPush.toastWebPushTestSending": "發送網路推測試通知中…",
"components.Settings.Notifications.NotificationsSlack.toastSlackTestSending": "發送 Slack 測試通知中…",
"components.Settings.Notifications.NotificationsPushover.toastPushoverTestSending": "發送 Pushover 測試通知中…",
"components.Settings.Notifications.NotificationsPushbullet.toastPushbulletTestSending": "發送 Pushbullet 測試通知中…",
"components.Settings.Notifications.NotificationsLunaSea.toastLunaSeaTestSending": "發送 LunaSea 測試通知中…",
"components.Settings.Notifications.NotificationsWebPush.toastWebPushTestFailed": "網路推測試通知發送失敗。",
"components.Settings.Notifications.NotificationsWebPush.toastWebPushTestFailed": "網路推測試通知發送失敗。",
"components.Settings.Notifications.NotificationsWebhook.toastWebhookTestFailed": "Webhook 測試通知發送失敗。",
"components.Settings.Notifications.toastEmailTestFailed": "電子郵件測試通知發送失敗。",
"components.Settings.Notifications.toastTelegramTestFailed": "Telegram 測試通知發送失敗。",
@ -828,10 +827,10 @@
"components.Settings.Notifications.NotificationsWebhook.toastWebhookTestSuccess": "Webhook 測試通知已發送!",
"components.Settings.SettingsUsers.newPlexLoginTip": "讓還沒匯入的 Plex 使用者登入",
"components.Settings.SettingsUsers.newPlexLogin": "允許新的 Plex 登入",
"components.PermissionEdit.requestTv": "提電視節目請求",
"components.PermissionEdit.requestMovies": "提電影請求",
"components.PermissionEdit.requestMoviesDescription": "授予提非 4K 電影請求的權限。",
"components.PermissionEdit.requestTvDescription": "授予提非 4K 電視節目請求的權限。",
"components.PermissionEdit.requestTv": "提電視節目請求",
"components.PermissionEdit.requestMovies": "提電影請求",
"components.PermissionEdit.requestMoviesDescription": "授予提非 4K 電影請求的權限。",
"components.PermissionEdit.requestTvDescription": "授予提非 4K 電視節目請求的權限。",
"components.UserProfile.UserSettings.UserGeneralSettings.languageDefault": "預設設定({language}",
"components.Settings.locale": "顯示語言",
"components.DownloadBlock.estimatedtime": "預計:{time}",
@ -841,21 +840,21 @@
"components.Settings.Notifications.encryptionOpportunisticTls": "始終使用 STARTTLS",
"components.Settings.Notifications.encryptionNone": "不使用加密",
"components.Settings.Notifications.encryption": "加密方式",
"components.Settings.Notifications.NotificationsPushover.userTokenTip": "您 30 個字符的<UsersGroupsLink>使用者 或群組識別符</UsersGroupsLink>",
"components.Settings.Notifications.NotificationsPushbullet.accessTokenTip": "從您的<PushbulletSettingsLink>帳號設定</PushbulletSettingsLink>取得 API 金鑰",
"components.Settings.Notifications.NotificationsPushover.userTokenTip": "您 30 個字符的<UsersGroupsLink>使用者或群組識別碼</UsersGroupsLink>",
"components.Settings.Notifications.NotificationsPushbullet.accessTokenTip": "從您的<PushbulletSettingsLink>帳號設定</PushbulletSettingsLink>取得 API 令牌",
"components.Settings.Notifications.NotificationsPushover.accessTokenTip": "建立一個 Overseerr 專用的<ApplicationRegistrationLink>應用程式</ApplicationRegistrationLink>",
"components.Settings.Notifications.NotificationsSlack.webhookUrlTip": "創建一個「<WebhookLink>incoming webhook</WebhookLink>」整合",
"components.Settings.Notifications.NotificationsLunaSea.webhookUrlTip": "使用者或設備通知的<LunaSeaLink>Webhook 網址</LunaSeaLink>",
"components.Settings.Notifications.webhookUrlTip": "在您的伺服器裡建立一個<DiscordWebhookLink>Webhook</DiscordWebhookLink>",
"components.Settings.Notifications.NotificationsSlack.webhookUrlTip": "創建一個「<WebhookLink>Incoming Webhook</WebhookLink>」整合",
"components.Settings.Notifications.NotificationsLunaSea.webhookUrlTip": "使用者或設備通知的 <LunaSeaLink>webhook 網址</LunaSeaLink>",
"components.Settings.Notifications.webhookUrlTip": "在您的伺服器裡建立一個 <DiscordWebhookLink>webhook</DiscordWebhookLink>",
"components.Settings.Notifications.botApiTip": "建立一個 Overseerr 專用的<CreateBotLink>機器人</CreateBotLink>",
"components.Settings.Notifications.chatIdTip": "先與您的機器人建立一個聊天室以及把 <GetIdBotLink>@get_id_bot</GetIdBotLink> 也加到聊天室,然後在聊天室裡發出 <code>/my_id</code> 命令",
"components.Settings.webAppUrlTip": "使用伺服器的網路應用代替「託管」的網路應用",
"components.Settings.webAppUrl": "<WebAppLink>網路應用</WebAppLink>網址URL",
"components.Settings.webAppUrl": "<WebAppLink>網路應用</WebAppLink>網址",
"components.Settings.validationWebAppUrl": "請輸入有效的 Plex 網路應用網址",
"components.Settings.Notifications.NotificationsWebPush.httpsRequirement": "Overseerr 必須通過 HTTPS 投放才能使用網路推通知。",
"components.Settings.Notifications.NotificationsWebPush.httpsRequirement": "Overseerr 必須通過 HTTPS 投放才能使用網路推通知。",
"components.UserList.localLoginDisabled": "<strong>允許本地登入</strong>的設定目前被禁用。",
"components.RequestList.RequestItem.requesteddate": "請求日期",
"components.RequestCard.failedretry": "重試提請求中出了點問題。",
"components.RequestCard.failedretry": "重試提請求中出了點問題。",
"components.UserList.displayName": "顯示名稱",
"components.Settings.SettingsUsers.localLoginTip": "讓使用者使用電子郵件地址和密碼登入",
"components.Settings.SettingsUsers.defaultPermissionsTip": "授予給新使用者的權限",
@ -870,14 +869,24 @@
"components.Settings.Notifications.NotificationsPushover.validationTypes": "請選擇通知類型",
"components.Settings.Notifications.NotificationsPushbullet.validationTypes": "請選擇通知類型",
"components.Settings.Notifications.NotificationsLunaSea.validationTypes": "請選擇通知類型",
"components.NotificationTypeSelector.usermediarequestedDescription": "當其他使用者提需要管理員批准的請求時取得通知。",
"components.NotificationTypeSelector.usermediafailedDescription": "當 Radarr 或 Sonarr 處理請求失敗時通知。",
"components.NotificationTypeSelector.usermediadeclinedDescription": "當您的請求被拒絕時通知。",
"components.NotificationTypeSelector.usermediaavailableDescription": "當您請求的媒體可觀看時通知。",
"components.NotificationTypeSelector.usermediaapprovedDescription": "當您的請求被手動批准時通知。",
"components.NotificationTypeSelector.usermediaAutoApprovedDescription": "當其他使用者提自動批准的請求時取得通知。",
"components.Settings.SettingsAbout.betawarning": "這是測試版軟體,所以可能會不穩定或被破壞。請向 GitHub 報告問題!",
"components.NotificationTypeSelector.usermediarequestedDescription": "當其他使用者提需要管理員批准的請求時取得通知。",
"components.NotificationTypeSelector.usermediafailedDescription": "當 Radarr 或 Sonarr 處理請求失敗時得通知。",
"components.NotificationTypeSelector.usermediadeclinedDescription": "當您的請求被拒絕時得通知。",
"components.NotificationTypeSelector.usermediaavailableDescription": "當您請求的媒體可觀看時得通知。",
"components.NotificationTypeSelector.usermediaapprovedDescription": "當您的請求被手動批准時得通知。",
"components.NotificationTypeSelector.usermediaAutoApprovedDescription": "當其他使用者提自動批准的請求時取得通知。",
"components.Settings.SettingsAbout.betawarning": "這是測試版軟體,有些功能可能損壞或不穩定。請在 GitHub 上回報問題!",
"components.Layout.LanguagePicker.displaylanguage": "顯示語言",
"components.MovieDetails.showmore": "顯示更多",
"components.MovieDetails.showless": "顯示更少"
"components.MovieDetails.showless": "顯示更少",
"components.TvDetails.streamingproviders": "目前的流媒體服務",
"components.MovieDetails.streamingproviders": "目前的流媒體服務",
"components.Settings.SettingsJobsCache.editJobSchedule": "編輯作業",
"components.Settings.SettingsJobsCache.editJobScheduleSelectorHours": "每 {jobScheduleHours} 小時",
"components.Settings.SettingsJobsCache.editJobSchedulePrompt": "頻率",
"components.Settings.SettingsJobsCache.editJobScheduleSelectorMinutes": "每 {jobScheduleMinutes} 分鐘",
"components.Settings.SettingsJobsCache.jobScheduleEditFailed": "保存作業設定中出了點問題。",
"components.Settings.SettingsJobsCache.jobScheduleEditSaved": "作業編輯成功!",
"components.Settings.SettingsAbout.runningDevelop": "您正在使用 Overseerr 的 <code>develop</code> 開發版。我們只建議開發者和協助測試的人員使用。",
"components.StatusBadge.status": "{status}"
}

@ -25,6 +25,10 @@ const loadLocaleData = (locale: AvailableLocale): Promise<any> => {
switch (locale) {
case 'ca':
return import('../i18n/locale/ca.json');
case 'cs':
return import('../i18n/locale/cs.json');
case 'da':
return import('../i18n/locale/da.json');
case 'de':
return import('../i18n/locale/de.json');
case 'el':

@ -1,7 +1,6 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@tailwind screens;
html {
min-height: calc(100% + env(safe-area-inset-top));
@ -182,7 +181,7 @@ a.crew-name,
}
.media-ratings {
@apply flex items-center justify-center px-4 py-2 border-b border-gray-700 last:border-b-0;
@apply flex items-center justify-center px-4 py-2 font-medium border-b border-gray-700 last:border-b-0;
}
.media-rating {
@ -213,6 +212,10 @@ img.avatar-sm {
@apply mr-2 font-bold;
}
.card-field a {
@apply transition duration-300 hover:text-white hover:underline;
}
.section {
@apply mt-6 mb-10 text-white;
}
@ -296,6 +299,10 @@ select.short {
@apply w-min;
}
button > span {
@apply whitespace-nowrap;
}
button.input-action {
@apply relative inline-flex items-center px-3 sm:px-3.5 py-2 -ml-px text-sm font-medium leading-5 text-white transition duration-150 ease-in-out bg-indigo-600 border border-gray-500 hover:bg-indigo-500 active:bg-gray-100 active:text-gray-700 last:rounded-r-md;
}

@ -15,7 +15,8 @@
"jsx": "preserve",
"strictPropertyInitialization": false,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
"emitDecoratorMetadata": true,
"useUnknownInCatchVariables": false
},
"include": ["next-env.d.ts", "src/**/*.ts", "src/**/*.tsx"],
"exclude": ["node_modules"]

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save