Compare commits

...

24 Commits

Author SHA1 Message Date
Bogdan 21a7c29197
Merge 61b8aec732 into 3db78079f3 2024-04-26 15:48:46 +02:00
Bogdan 3db78079f3 Fixed: Retrying download on not suppressed HTTP errors 2024-04-25 17:22:49 +03:00
Bogdan c8a6b9f565 Database corruption message linking to wiki 2024-04-25 11:29:26 +03:00
Bogdan 811cafd9ae Bump dotnet to 6.0.29 2024-04-22 08:08:41 +03:00
fireph ac7039d651 New: Footnote to indicate some renaming tokens support truncation
(cherry picked from commit 7fc3bebc91db217a1c24ab2d01ebbc5bf03c918e)

Closes #9905
2024-04-21 18:36:51 +03:00
Bogdan a2d11cf684 Bump typescript eslint plugin and parser 2024-04-21 12:40:23 +03:00
Bogdan cc32635f6f Bump frontend dependencies 2024-04-21 10:31:56 +03:00
Bogdan 10f9cb64ac Bump version to 5.5.1 2024-04-21 09:16:33 +03:00
Weblate f77e27bace Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Altair <villagermd@outlook.com>
Co-authored-by: Ano10 <arnaudthommeray+github@ik.me>
Co-authored-by: Fonkio <maxime.fabre10@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Jacopo Luca Maria Latrofa <jacopo.latrofa@gmail.com>
Co-authored-by: Mailme Dashite <mailmedashite@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: YSLG <1451164040@qq.com>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: myrad2267 <myrad2267@gmail.com>
Co-authored-by: toeiazarothis <patrickdealmeida89000@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translation: Servarr/Radarr
2024-04-19 17:25:34 +03:00
Servarr 8ea6d59d59 Automated API Docs update 2024-04-19 17:24:01 +03:00
Bogdan 98668d0d25 Bump SixLabors.ImageSharp to 3.1.4 2024-04-19 07:59:50 +03:00
Gauthier 649d57a234 Improve Multi Language Regex and field translations
(cherry picked from commit 6c232b062c5c11b76a2f205fcd949619e4346d16)

Closes #9931
2024-04-16 12:53:04 +03:00
Josh McKinney dc7c8bf800 Add dev container workspace
Allows the linting and style settings for the frontend to be applied even when you load the main repo as a workspace

(cherry picked from commit d6278fced49b26be975c3a6039b38a94f700864b)

Closes #9929
2024-04-16 11:41:14 +03:00
Bogdan 8d90c7678f Fixed: Re-testing edited providers will forcibly test them
(cherry picked from commit e9662544621b2d1fb133ff9d96d0eb20b8198725)

Closes #9933
2024-04-16 11:39:43 +03:00
Bogdan 02518e2116 Fixed: Validate provider's settings in Test All endpoint 2024-04-16 11:39:35 +03:00
Mark McDowall 3191a883dc New: Improve multi-language negate Custom Format
(cherry picked from commit 42b11528b4699b8343887185c93a02b139192d83)

Closes #9720
2024-04-13 11:03:37 +03:00
Bogdan 31a714e6b3 Bump version to 5.5.0 2024-04-13 08:46:17 +03:00
Mark McDowall f7ca0b8b06 New: Auto tag movies based on tags present/absent on movies
(cherry picked from commit f4c19a384bd9bb4e35c9fa0ca5d9a448c04e409e)

Closes #9916
2024-04-10 23:40:26 +03:00
Josh McKinney 56be9502af Add DevContainer, VSCode config and extensions.json
(cherry picked from commit 5061dc4b5e5ea9925740496a5939a1762788b793)

Closes #9914
2024-04-10 22:59:13 +03:00
Mark McDowall 77381d3f72 New: Option to prefix app name on Telegram notification titles
(cherry picked from commit 37863a8deb339ef730b2dd5be61e1da1311fdd23)

Closes #9913
2024-04-10 22:34:52 +03:00
Bogdan 198e6324e0 Truncate long names for import lists 2024-04-09 18:19:26 +03:00
Alan Collins 81c9537e5a New: 'Custom Format:Format Name' rename token
cherry picked from commit 48cb5d227187a06930aad5ee1b4e7b76422d8421)

New: Update Custom Format renaming token to allow excluding specific formats

(cherry picked from commit 6584d95331d0e0763e1688a397a3ccaf5fa6ca38)

Closes #9835
Closes #9826
2024-04-09 08:04:57 +03:00
Bogdan d3cbb9be8d New: Detect shfs mounts 2024-04-08 22:25:42 +03:00
Bogdan 61b8aec732 Add IMDb RSS Import List 2023-05-22 18:30:41 +03:00
64 changed files with 3280 additions and 1949 deletions

View File

@ -0,0 +1,13 @@
// This file is used to open the backend and frontend in the same workspace, which is necessary as
// the frontend has vscode settings that are distinct from the backend
{
"folders": [
{
"path": ".."
},
{
"path": "../frontend"
}
],
"settings": {}
}

View File

@ -0,0 +1,19 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/dotnet
{
"name": "Radarr",
"image": "mcr.microsoft.com/devcontainers/dotnet:1-6.0",
"features": {
"ghcr.io/devcontainers/features/node:1": {
"nodeGypDependencies": true,
"version": "16",
"nvmVersion": "latest"
}
},
"forwardPorts": [7878],
"customizations": {
"vscode": {
"extensions": ["esbenp.prettier-vscode"]
}
}
}

12
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,12 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for more information:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
# https://containers.dev/guide/dependabot
version: 2
updates:
- package-ecosystem: "devcontainers"
directory: "/"
schedule:
interval: weekly

1
.gitignore vendored
View File

@ -126,6 +126,7 @@ coverage*.xml
coverage*.json
setup/Output/
*.~is
.mono
# VS outout folders
bin

7
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"recommendations": [
"esbenp.prettier-vscode",
"ms-dotnettools.csdevkit",
"ms-vscode-remote.remote-containers"
]
}

26
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,26 @@
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md
"name": "Run Radarr",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build dotnet",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/_output/net6.0/Radarr",
"args": [],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "integratedTerminal",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}

44
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,44 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build dotnet",
"command": "dotnet",
"type": "process",
"args": [
"msbuild",
"-restore",
"${workspaceFolder}/src/Radarr.sln",
"-p:GenerateFullPaths=true",
"-p:Configuration=Debug",
"-p:Platform=Posix",
"-consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/src/Radarr.sln",
"-property:GenerateFullPaths=true",
"-consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/src/Radarr.sln"
],
"problemMatcher": "$msCompile"
}
]
}

View File

@ -9,13 +9,13 @@ variables:
testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '5.4.6'
majorVersion: '5.5.1'
minorVersion: $[counter('minorVersion', 2000)]
radarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(radarrVersion)'
sentryOrg: 'servarr'
sentryUrl: 'https://sentry.servarr.com'
dotnetVersion: '6.0.417'
dotnetVersion: '6.0.421'
nodeVersion: '20.X'
innoVersion: '6.2.2'
windowsImage: 'windows-2022'

View File

@ -17,6 +17,7 @@ import IndexerSelectInputConnector from './IndexerSelectInputConnector';
import KeyValueListInput from './KeyValueListInput';
import LanguageSelectInputConnector from './LanguageSelectInputConnector';
import MovieMonitoredSelectInput from './MovieMonitoredSelectInput';
import MovieTagInput from './MovieTagInput';
import NumberInput from './NumberInput';
import OAuthInputConnector from './OAuthInputConnector';
import PasswordInput from './PasswordInput';
@ -89,6 +90,10 @@ function getComponent(type) {
case inputTypes.DYNAMIC_SELECT:
return EnhancedSelectInputConnector;
case inputTypes.MOVIE_TAG:
return MovieTagInput;
case inputTypes.TAG:
return TagInputConnector;

View File

@ -0,0 +1,53 @@
import React, { useCallback } from 'react';
import TagInputConnector from './TagInputConnector';
interface MovieTagInputProps {
name: string;
value: number | number[];
onChange: ({
name,
value,
}: {
name: string;
value: number | number[];
}) => void;
}
export default function MovieTagInput(props: MovieTagInputProps) {
const { value, onChange, ...otherProps } = props;
const isArray = Array.isArray(value);
const handleChange = useCallback(
({ name, value: newValue }: { name: string; value: number[] }) => {
if (isArray) {
onChange({ name, value: newValue });
} else {
onChange({
name,
value: newValue.length ? newValue[newValue.length - 1] : 0,
});
}
},
[isArray, onChange]
);
let finalValue: number[] = [];
if (isArray) {
finalValue = value;
} else if (value === 0) {
finalValue = [];
} else {
finalValue = [value];
}
return (
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore 2786 'TagInputConnector' isn't typed yet
<TagInputConnector
{...otherProps}
value={finalValue}
onChange={handleChange}
/>
);
}

View File

@ -27,6 +27,8 @@ function getType({ type, selectOptionsProviderAction }) {
return inputTypes.DYNAMIC_SELECT;
}
return inputTypes.SELECT;
case 'movieTag':
return inputTypes.MOVIE_TAG;
case 'tag':
return inputTypes.TEXT_TAG;
case 'tagSelect':

View File

@ -17,6 +17,7 @@ export const INDEXER_FLAGS_SELECT = 'indexerFlagsSelect';
export const LANGUAGE_SELECT = 'languageSelect';
export const DOWNLOAD_CLIENT_SELECT = 'downloadClientSelect';
export const SELECT = 'select';
export const MOVIE_TAG = 'movieTag';
export const DYNAMIC_SELECT = 'dynamicSelect';
export const TAG = 'tag';
export const TEXT = 'text';
@ -45,6 +46,7 @@ export const all = [
INDEXER_FLAGS_SELECT,
LANGUAGE_SELECT,
SELECT,
MOVIE_TAG,
DYNAMIC_SELECT,
TAG,
TEXT,

View File

@ -17,6 +17,8 @@
}
.name {
@add-mixin truncate;
text-align: center;
font-weight: lighter;
font-size: 24px;

View File

@ -72,15 +72,15 @@ const fileNameTokens = [
];
const movieTokens = [
{ token: '{Movie Title}', example: 'Movie\'s Title' },
{ token: '{Movie Title:DE}', example: 'Titel des Films' },
{ token: '{Movie CleanTitle}', example: 'Movies Title' },
{ token: '{Movie TitleThe}', example: 'Movie\'s Title, The' },
{ token: '{Movie OriginalTitle}', example: 'Τίτλος ταινίας' },
{ token: '{Movie CleanOriginalTitle}', example: 'Τίτλος ταινίας' },
{ token: '{Movie Title}', example: 'Movie\'s Title', footNote: 1 },
{ token: '{Movie Title:DE}', example: 'Titel des Films', footNote: 1 },
{ token: '{Movie CleanTitle}', example: 'Movies Title', footNote: 1 },
{ token: '{Movie TitleThe}', example: 'Movie\'s Title, The', footNote: 1 },
{ token: '{Movie OriginalTitle}', example: 'Τίτλος ταινίας', footNote: 1 },
{ token: '{Movie CleanOriginalTitle}', example: 'Τίτλος ταινίας', footNote: 1 },
{ token: '{Movie TitleFirstCharacter}', example: 'M' },
{ token: '{Movie TitleFirstCharacter:DE}', example: 'T' },
{ token: '{Movie Collection}', example: 'The Movie Collection' },
{ token: '{Movie Collection}', example: 'The Movie Collection', footNote: 1 },
{ token: '{Movie Certification}', example: 'R' },
{ token: '{Release Year}', example: '2009' }
];
@ -112,15 +112,16 @@ const mediaInfoTokens = [
];
const releaseGroupTokens = [
{ token: '{Release Group}', example: 'Rls Grp' }
{ token: '{Release Group}', example: 'Rls Grp', footNote: 1 }
];
const editionTokens = [
{ token: '{Edition Tags}', example: 'IMAX' }
{ token: '{Edition Tags}', example: 'IMAX', footNote: 1 }
];
const customFormatTokens = [
{ token: '{Custom Formats}', example: 'Surround Sound x264' }
{ token: '{Custom Formats}', example: 'Surround Sound x264' },
{ token: '{Custom Format:FormatName}', example: 'AMZN' }
];
const originalTokens = [
@ -267,7 +268,7 @@ class NamingModal extends Component {
<FieldSet legend={translate('Movie')}>
<div className={styles.groups}>
{
movieTokens.map(({ token, example }) => {
movieTokens.map(({ token, example, footNote }) => {
return (
<NamingOption
key={token}
@ -275,6 +276,7 @@ class NamingModal extends Component {
value={value}
token={token}
example={example}
footNote={footNote}
tokenSeparator={tokenSeparator}
tokenCase={tokenCase}
onPress={this.onOptionPress}
@ -284,6 +286,11 @@ class NamingModal extends Component {
)
}
</div>
<div className={styles.footNote}>
<Icon className={styles.icon} name={icons.FOOTNOTE} />
<InlineMarkdown data={translate('MovieFootNote')} />
</div>
</FieldSet>
<FieldSet legend={translate('MovieID')}>
@ -364,7 +371,7 @@ class NamingModal extends Component {
<FieldSet legend={translate('ReleaseGroup')}>
<div className={styles.groups}>
{
releaseGroupTokens.map(({ token, example }) => {
releaseGroupTokens.map(({ token, example, footNote }) => {
return (
<NamingOption
key={token}
@ -372,6 +379,7 @@ class NamingModal extends Component {
value={value}
token={token}
example={example}
footNote={footNote}
tokenSeparator={tokenSeparator}
tokenCase={tokenCase}
onPress={this.onOptionPress}
@ -381,12 +389,17 @@ class NamingModal extends Component {
)
}
</div>
<div className={styles.footNote}>
<Icon className={styles.icon} name={icons.FOOTNOTE} />
<InlineMarkdown data={translate('ReleaseGroupFootNote')} />
</div>
</FieldSet>
<FieldSet legend={translate('Edition')}>
<div className={styles.groups}>
{
editionTokens.map(({ token, example }) => {
editionTokens.map(({ token, example, footNote }) => {
return (
<NamingOption
key={token}
@ -394,6 +407,7 @@ class NamingModal extends Component {
value={value}
token={token}
example={example}
footNote={footNote}
tokenSeparator={tokenSeparator}
tokenCase={tokenCase}
onPress={this.onOptionPress}
@ -403,6 +417,11 @@ class NamingModal extends Component {
)
}
</div>
<div className={styles.footNote}>
<Icon className={styles.icon} name={icons.FOOTNOTE} />
<InlineMarkdown data={translate('EditionFootNote')} />
</div>
</FieldSet>
<FieldSet legend={translate('CustomFormats')}>

View File

@ -12,7 +12,7 @@ export default function TagInUse(props) {
return null;
}
if (count > 1 && labelPlural ) {
if (count > 1 && labelPlural) {
return (
<div>
{count} {labelPlural.toLowerCase()}

View File

@ -1,8 +1,11 @@
import $ from 'jquery';
import _ from 'lodash';
import createAjaxRequest from 'Utilities/createAjaxRequest';
import getProviderState from 'Utilities/State/getProviderState';
import { set } from '../baseActions';
const abortCurrentRequests = {};
let lastTestData = null;
export function createCancelTestProviderHandler(section) {
return function(getState, payload, dispatch) {
@ -17,10 +20,25 @@ function createTestProviderHandler(section, url) {
return function(getState, payload, dispatch) {
dispatch(set({ section, isTesting: true }));
const testData = getProviderState(payload, getState, section);
const {
queryParams = {},
...otherPayload
} = payload;
const testData = getProviderState({ ...otherPayload }, getState, section);
const params = { ...queryParams };
// If the user is re-testing the same provider without changes
// force it to be tested.
if (_.isEqual(testData, lastTestData)) {
params.forceTest = true;
}
lastTestData = testData;
const ajaxOptions = {
url: `${url}/test`,
url: `${url}/test?${$.param(params, true)}`,
method: 'POST',
contentType: 'application/json',
dataType: 'json',
@ -32,6 +50,8 @@ function createTestProviderHandler(section, url) {
abortCurrentRequests[section] = abortRequest;
request.done((data) => {
lastTestData = null;
dispatch(set({
section,
isTesting: false,

View File

@ -31,9 +31,9 @@
"@microsoft/signalr": "6.0.25",
"@sentry/browser": "7.51.2",
"@sentry/integrations": "7.51.2",
"@types/node": "18.16.8",
"@types/react": "18.2.6",
"@types/react-dom": "18.2.4",
"@types/node": "18.19.31",
"@types/react": "18.2.79",
"@types/react-dom": "18.2.25",
"classnames": "2.3.2",
"clipboard": "2.0.11",
"connected-react-router": "6.9.3",
@ -84,16 +84,16 @@
"reselect": "4.1.8",
"stacktrace-js": "2.0.2",
"swiper": "8.3.2",
"typescript": "4.9.5"
"typescript": "5.1.6"
},
"devDependencies": {
"@babel/core": "7.22.11",
"@babel/eslint-parser": "7.22.11",
"@babel/plugin-proposal-export-default-from": "7.22.5",
"@babel/core": "7.24.4",
"@babel/eslint-parser": "7.24.1",
"@babel/plugin-proposal-export-default-from": "7.24.1",
"@babel/plugin-syntax-dynamic-import": "7.8.3",
"@babel/preset-env": "7.22.14",
"@babel/preset-react": "7.22.5",
"@babel/preset-typescript": "7.22.11",
"@babel/preset-env": "7.24.4",
"@babel/preset-react": "7.24.1",
"@babel/preset-typescript": "7.24.1",
"@types/lodash": "4.14.195",
"@types/react-lazyload": "3.2.0",
"@types/react-router-dom": "5.3.3",
@ -101,31 +101,31 @@
"@types/react-window": "1.8.5",
"@types/redux-actions": "2.6.2",
"@types/webpack-livereload-plugin": "2.3.3",
"@typescript-eslint/eslint-plugin": "5.59.5",
"@typescript-eslint/parser": "5.59.5",
"@typescript-eslint/eslint-plugin": "6.21.0",
"@typescript-eslint/parser": "6.21.0",
"autoprefixer": "10.4.14",
"babel-loader": "9.1.3",
"babel-plugin-inline-classnames": "2.0.1",
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
"core-js": "3.32.1",
"core-js": "3.37.0",
"css-loader": "6.7.3",
"css-modules-typescript-loader": "4.0.1",
"eslint": "8.45.0",
"eslint-config-prettier": "8.8.0",
"eslint": "8.57.0",
"eslint-config-prettier": "8.10.0",
"eslint-plugin-filenames": "1.3.2",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-json": "3.1.0",
"eslint-plugin-prettier": "4.2.1",
"eslint-plugin-react": "7.32.2",
"eslint-plugin-react": "7.34.1",
"eslint-plugin-react-hooks": "4.6.0",
"eslint-plugin-simple-import-sort": "10.0.0",
"eslint-plugin-simple-import-sort": "12.1.0",
"file-loader": "6.2.0",
"filemanager-webpack-plugin": "8.0.0",
"fork-ts-checker-webpack-plugin": "8.0.0",
"html-webpack-plugin": "5.5.3",
"loader-utils": "^3.2.1",
"mini-css-extract-plugin": "2.7.6",
"postcss": "8.4.23",
"postcss": "8.4.38",
"postcss-color-function": "4.1.0",
"postcss-loader": "7.3.0",
"postcss-mixins": "9.0.4",

View File

@ -101,8 +101,8 @@
<!-- Standard testing packages -->
<ItemGroup Condition="'$(TestProject)'=='true'">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="NunitXml.TestLogger" Version="3.0.131" />
</ItemGroup>
@ -147,16 +147,46 @@
</Otherwise>
</Choose>
<!--
Set architecture to RuntimeInformation.ProcessArchitecture if not specified -->
<Choose>
<When Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture)' == 'X64'">
<PropertyGroup>
<Architecture>x64</Architecture>
</PropertyGroup>
</When>
<When Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture)' == 'X86'">
<PropertyGroup>
<Architecture>x86</Architecture>
</PropertyGroup>
</When>
<When Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture)' == 'Arm64'">
<PropertyGroup>
<Architecture>arm64</Architecture>
</PropertyGroup>
</When>
<When Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture)' == 'Arm'">
<PropertyGroup>
<Architecture>arm</Architecture>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<Architecture></Architecture>
</PropertyGroup>
</Otherwise>
</Choose>
<PropertyGroup Condition="'$(IsWindows)' == 'true' and
'$(RuntimeIdentifier)' == ''">
<_UsingDefaultRuntimeIdentifier>true</_UsingDefaultRuntimeIdentifier>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<RuntimeIdentifier>win-$(Architecture)</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinux)' == 'true' and
'$(RuntimeIdentifier)' == ''">
<_UsingDefaultRuntimeIdentifier>true</_UsingDefaultRuntimeIdentifier>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
<RuntimeIdentifier>linux-$(Architecture)</RuntimeIdentifier>
</PropertyGroup>
<PropertyGroup Condition="'$(IsOSX)' == 'true' and

View File

@ -0,0 +1,71 @@
using System.Collections.Generic;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.CustomFormats;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.CustomFormats.Specifications.LanguageSpecification
{
[TestFixture]
public class MultiLanguageFixture : CoreTest<Core.CustomFormats.LanguageSpecification>
{
private CustomFormatInput _input;
[SetUp]
public void Setup()
{
_input = new CustomFormatInput
{
MovieInfo = Builder<ParsedMovieInfo>.CreateNew().Build(),
Movie = Builder<Movie>.CreateNew().With(m => m.MovieMetadata.Value.OriginalLanguage = Language.English).Build(),
Size = 100.Megabytes(),
Languages = new List<Language>
{
Language.English,
Language.French
},
Filename = "Movie.Title.2024"
};
}
[Test]
public void should_match_one_language()
{
Subject.Value = Language.French.Id;
Subject.Negate = false;
Subject.IsSatisfiedBy(_input).Should().BeTrue();
}
[Test]
public void should_not_match_different_language()
{
Subject.Value = Language.Spanish.Id;
Subject.Negate = false;
Subject.IsSatisfiedBy(_input).Should().BeFalse();
}
[Test]
public void should_not_match_negated_when_one_language_matches()
{
Subject.Value = Language.French.Id;
Subject.Negate = true;
Subject.IsSatisfiedBy(_input).Should().BeFalse();
}
[Test]
public void should_not_match_negated_when_all_languages_do_not_match()
{
Subject.Value = Language.Spanish.Id;
Subject.Negate = true;
Subject.IsSatisfiedBy(_input).Should().BeTrue();
}
}
}

View File

@ -0,0 +1,80 @@
using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.CustomFormats;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.CustomFormats.Specifications.LanguageSpecification
{
[TestFixture]
public class OriginalLanguageFixture : CoreTest<Core.CustomFormats.LanguageSpecification>
{
private CustomFormatInput _input;
[SetUp]
public void Setup()
{
_input = new CustomFormatInput
{
MovieInfo = Builder<ParsedMovieInfo>.CreateNew().Build(),
Movie = Builder<Movie>.CreateNew().With(m => m.MovieMetadata.Value.OriginalLanguage = Language.English).Build(),
Size = 100.Megabytes(),
Languages = new List<Language>
{
Language.French
},
Filename = "Movie.Title.2024"
};
}
public void GivenLanguages(params Language[] languages)
{
_input.Languages = languages.ToList();
}
[Test]
public void should_match_same_single_language()
{
GivenLanguages(Language.English);
Subject.Value = Language.Original.Id;
Subject.Negate = false;
Subject.IsSatisfiedBy(_input).Should().BeTrue();
}
[Test]
public void should_not_match_different_single_language()
{
Subject.Value = Language.Original.Id;
Subject.Negate = false;
Subject.IsSatisfiedBy(_input).Should().BeFalse();
}
[Test]
public void should_not_match_negated_same_single_language()
{
GivenLanguages(Language.English);
Subject.Value = Language.Original.Id;
Subject.Negate = true;
Subject.IsSatisfiedBy(_input).Should().BeFalse();
}
[Test]
public void should_match_negated_different_single_language()
{
Subject.Value = Language.Original.Id;
Subject.Negate = true;
Subject.IsSatisfiedBy(_input).Should().BeTrue();
}
}
}

View File

@ -0,0 +1,70 @@
using System.Collections.Generic;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.CustomFormats;
using NzbDrone.Core.Languages;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.CustomFormats.Specifications.LanguageSpecification
{
[TestFixture]
public class SingleLanguageFixture : CoreTest<Core.CustomFormats.LanguageSpecification>
{
private CustomFormatInput _input;
[SetUp]
public void Setup()
{
_input = new CustomFormatInput
{
MovieInfo = Builder<ParsedMovieInfo>.CreateNew().Build(),
Movie = Builder<Movie>.CreateNew().With(m => m.MovieMetadata.Value.OriginalLanguage = Language.English).Build(),
Size = 100.Megabytes(),
Languages = new List<Language>
{
Language.French
},
Filename = "Movie.Title.2024"
};
}
[Test]
public void should_match_same_language()
{
Subject.Value = Language.French.Id;
Subject.Negate = false;
Subject.IsSatisfiedBy(_input).Should().BeTrue();
}
[Test]
public void should_not_match_different_language()
{
Subject.Value = Language.Spanish.Id;
Subject.Negate = false;
Subject.IsSatisfiedBy(_input).Should().BeFalse();
}
[Test]
public void should_not_match_negated_same_language()
{
Subject.Value = Language.French.Id;
Subject.Negate = true;
Subject.IsSatisfiedBy(_input).Should().BeFalse();
}
[Test]
public void should_match_negated_different_language()
{
Subject.Value = Language.Spanish.Id;
Subject.Negate = true;
Subject.IsSatisfiedBy(_input).Should().BeTrue();
}
}
}

View File

@ -1,6 +1,9 @@
using System.Collections.Generic;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.AutoTagging;
using NzbDrone.Core.AutoTagging.Specifications;
using NzbDrone.Core.Housekeeping.Housekeepers;
using NzbDrone.Core.Profiles.Releases;
using NzbDrone.Core.Tags;
@ -43,5 +46,35 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
Subject.Clean();
AllStoredModels.Should().HaveCount(1);
}
[Test]
public void should_not_delete_used_auto_tagging_tag_specification_tags()
{
var tags = Builder<Tag>
.CreateListOfSize(2)
.All()
.With(x => x.Id = 0)
.BuildList();
Db.InsertMany(tags);
var autoTags = Builder<AutoTag>.CreateListOfSize(1)
.All()
.With(x => x.Id = 0)
.With(x => x.Specifications = new List<IAutoTaggingSpecification>
{
new TagSpecification
{
Name = "Test",
Value = tags[0].Id
}
})
.BuildList();
Mocker.GetMock<IAutoTaggingRepository>().Setup(s => s.All())
.Returns(autoTags);
Subject.Clean();
AllStoredModels.Should().HaveCount(1);
}
}
}

View File

@ -0,0 +1,138 @@
using System.Collections.Generic;
using System.Linq;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.CustomFormats;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Organizer;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
{
[TestFixture]
public class CustomFormatsFixture : CoreTest<FileNameBuilder>
{
private Movie _movie;
private MovieFile _movieFile;
private NamingConfig _namingConfig;
private List<CustomFormat> _customFormats;
[SetUp]
public void Setup()
{
_movie = Builder<Movie>
.CreateNew()
.With(s => s.Title = "South Park")
.Build();
_namingConfig = NamingConfig.Default;
_namingConfig.RenameMovies = true;
Mocker.GetMock<INamingConfigService>()
.Setup(c => c.GetConfig()).Returns(_namingConfig);
_movieFile = new MovieFile { Quality = new QualityModel(Quality.HDTV720p), ReleaseGroup = "RadarrTest" };
_customFormats = new List<CustomFormat>()
{
new CustomFormat()
{
Name = "INTERNAL",
IncludeCustomFormatWhenRenaming = true
},
new CustomFormat()
{
Name = "AMZN",
IncludeCustomFormatWhenRenaming = true
},
new CustomFormat()
{
Name = "NAME WITH SPACES",
IncludeCustomFormatWhenRenaming = true
},
new CustomFormat()
{
Name = "NotIncludedFormat",
IncludeCustomFormatWhenRenaming = false
}
};
Mocker.GetMock<IQualityDefinitionService>()
.Setup(v => v.Get(Moq.It.IsAny<Quality>()))
.Returns<Quality>(v => Quality.DefaultQualityDefinitions.First(c => c.Quality == v));
}
[TestCase("{Custom Formats}", "INTERNAL AMZN NAME WITH SPACES")]
public void should_replace_custom_formats(string format, string expected)
{
_namingConfig.StandardMovieFormat = format;
Subject.BuildFileName(_movie, _movieFile, customFormats: _customFormats)
.Should().Be(expected);
}
[TestCase("{Custom Formats}", "")]
public void should_replace_custom_formats_with_no_custom_formats(string format, string expected)
{
_namingConfig.StandardMovieFormat = format;
Subject.BuildFileName(_movie, _movieFile, customFormats: new List<CustomFormat>())
.Should().Be(expected);
}
[TestCase("{Custom Formats:-INTERNAL}", "AMZN NAME WITH SPACES")]
[TestCase("{Custom Formats:-NAME WITH SPACES}", "INTERNAL AMZN")]
[TestCase("{Custom Formats:-INTERNAL,NAME WITH SPACES}", "AMZN")]
[TestCase("{Custom Formats:INTERNAL}", "INTERNAL")]
[TestCase("{Custom Formats:NAME WITH SPACES}", "NAME WITH SPACES")]
[TestCase("{Custom Formats:INTERNAL,NAME WITH SPACES}", "INTERNAL NAME WITH SPACES")]
public void should_replace_custom_formats_with_filtered_names(string format, string expected)
{
_namingConfig.StandardMovieFormat = format;
Subject.BuildFileName(_movie, _movieFile, customFormats: _customFormats)
.Should().Be(expected);
}
[TestCase("{Custom Formats:-}", "{Custom Formats:-}")]
[TestCase("{Custom Formats:}", "{Custom Formats:}")]
public void should_not_replace_custom_formats_due_to_invalid_token(string format, string expected)
{
_namingConfig.StandardMovieFormat = format;
Subject.BuildFileName(_movie, _movieFile, customFormats: _customFormats)
.Should().Be(expected);
}
[TestCase("{Custom Format}", "")]
[TestCase("{Custom Format:INTERNAL}", "INTERNAL")]
[TestCase("{Custom Format:AMZN}", "AMZN")]
[TestCase("{Custom Format:NAME WITH SPACES}", "NAME WITH SPACES")]
[TestCase("{Custom Format:DOESNOTEXIST}", "")]
[TestCase("{Custom Format:INTERNAL} - {Custom Format:AMZN}", "INTERNAL - AMZN")]
[TestCase("{Custom Format:AMZN} - {Custom Format:INTERNAL}", "AMZN - INTERNAL")]
public void should_replace_custom_format(string format, string expected)
{
_namingConfig.StandardMovieFormat = format;
Subject.BuildFileName(_movie, _movieFile, customFormats: _customFormats)
.Should().Be(expected);
}
[TestCase("{Custom Format}", "")]
[TestCase("{Custom Format:INTERNAL}", "")]
[TestCase("{Custom Format:AMZN}", "")]
public void should_replace_custom_format_with_no_custom_formats(string format, string expected)
{
_namingConfig.StandardMovieFormat = format;
Subject.BuildFileName(_movie, _movieFile, customFormats: new List<CustomFormat>())
.Should().Be(expected);
}
}
}

View File

@ -3,7 +3,7 @@
<TargetFrameworks>net6.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.143" />
<PackageReference Include="Dapper" Version="2.0.151" />
<PackageReference Include="NBuilder" Version="6.1.0" />
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />
</ItemGroup>

View File

@ -84,7 +84,8 @@ namespace NzbDrone.Core.Annotations
Device,
TagSelect,
RootFolder,
QualityProfile
QualityProfile,
MovieTag
}
public enum HiddenType

View File

@ -0,0 +1,36 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Movies;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.AutoTagging.Specifications
{
public class TagSpecificationValidator : AbstractValidator<TagSpecification>
{
public TagSpecificationValidator()
{
RuleFor(c => c.Value).GreaterThan(0);
}
}
public class TagSpecification : AutoTaggingSpecificationBase
{
private static readonly TagSpecificationValidator Validator = new ();
public override int Order => 1;
public override string ImplementationName => "Tag";
[FieldDefinition(1, Label = "AutoTaggingSpecificationTag", Type = FieldType.MovieTag)]
public int Value { get; set; }
protected override bool IsSatisfiedByWithoutNegate(Movie movie)
{
return movie.Tags.Contains(Value);
}
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
}
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Datastore;

View File

@ -20,7 +20,7 @@ namespace NzbDrone.Core.CustomFormats
public abstract NzbDroneValidationResult Validate();
public bool IsSatisfiedBy(CustomFormatInput input)
public virtual bool IsSatisfiedBy(CustomFormatInput input)
{
var match = IsSatisfiedByWithoutNegate(input);

View File

@ -30,6 +30,16 @@ namespace NzbDrone.Core.CustomFormats
[FieldDefinition(1, Label = "Language", Type = FieldType.Select, SelectOptions = typeof(LanguageFieldConverter))]
public int Value { get; set; }
public override bool IsSatisfiedBy(CustomFormatInput input)
{
if (Negate)
{
return IsSatisfiedByWithNegate(input);
}
return IsSatisfiedByWithoutNegate(input);
}
protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input)
{
var comparedLanguage = input.MovieInfo != null && input.Movie != null && Value == Language.Original.Id && input.Movie.MovieMetadata.Value.OriginalLanguage != Language.Unknown
@ -39,6 +49,15 @@ namespace NzbDrone.Core.CustomFormats
return input?.Languages?.Contains(comparedLanguage) ?? false;
}
private bool IsSatisfiedByWithNegate(CustomFormatInput input)
{
var comparedLanguage = input.MovieInfo != null && input.Movie != null && Value == Language.Original.Id && input.Movie.MovieMetadata.Value.OriginalLanguage != Language.Unknown
? input.Movie.MovieMetadata.Value.OriginalLanguage
: (Language)Value;
return !input.Languages?.Contains(comparedLanguage) ?? false;
}
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

View File

@ -16,12 +16,12 @@ namespace NzbDrone.Core.Datastore
}
public CorruptDatabaseException(string message, Exception innerException, params object[] args)
: base(message, innerException, args)
: base(innerException, message, args)
{
}
public CorruptDatabaseException(string message, Exception innerException)
: base(message, innerException)
: base(innerException, message)
{
}
}

View File

@ -34,6 +34,7 @@ namespace NzbDrone.Core.Download
{
{ Result.HasHttpServerError: true } => PredicateResult.True(),
{ Result.StatusCode: HttpStatusCode.RequestTimeout } => PredicateResult.True(),
{ Exception: HttpException { Response.HasHttpServerError: true } } => PredicateResult.True(),
_ => PredicateResult.False()
},
Delay = TimeSpan.FromSeconds(3),

View File

@ -3,6 +3,8 @@ using System.Data;
using System.Linq;
using Dapper;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.AutoTagging;
using NzbDrone.Core.AutoTagging.Specifications;
using NzbDrone.Core.Datastore;
namespace NzbDrone.Core.Housekeeping.Housekeepers
@ -10,17 +12,24 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
public class CleanupUnusedTags : IHousekeepingTask
{
private readonly IMainDatabase _database;
private readonly IAutoTaggingRepository _autoTaggingRepository;
public CleanupUnusedTags(IMainDatabase database)
public CleanupUnusedTags(IMainDatabase database, IAutoTaggingRepository autoTaggingRepository)
{
_database = database;
_autoTaggingRepository = autoTaggingRepository;
}
public void Clean()
{
using var mapper = _database.OpenConnection();
var usedTags = new[] { "Movies", "Notifications", "DelayProfiles", "ReleaseProfiles", "ImportLists", "Indexers", "AutoTagging", "DownloadClients" }
var usedTags = new[]
{
"Movies", "Notifications", "DelayProfiles", "ReleaseProfiles", "ImportLists", "Indexers",
"AutoTagging", "DownloadClients"
}
.SelectMany(v => GetUsedTags(v, mapper))
.Concat(GetAutoTaggingTagSpecificationTags(mapper))
.Distinct()
.ToList();
@ -45,10 +54,31 @@ namespace NzbDrone.Core.Housekeeping.Housekeepers
private int[] GetUsedTags(string table, IDbConnection mapper)
{
return mapper.Query<List<int>>($"SELECT DISTINCT \"Tags\" FROM \"{table}\" WHERE NOT \"Tags\" = '[]' AND NOT \"Tags\" IS NULL")
return mapper
.Query<List<int>>(
$"SELECT DISTINCT \"Tags\" FROM \"{table}\" WHERE NOT \"Tags\" = '[]' AND NOT \"Tags\" IS NULL")
.SelectMany(x => x)
.Distinct()
.ToArray();
}
private List<int> GetAutoTaggingTagSpecificationTags(IDbConnection mapper)
{
var tags = new List<int>();
var autoTags = _autoTaggingRepository.All();
foreach (var autoTag in autoTags)
{
foreach (var specification in autoTag.Specifications)
{
if (specification is TagSpecification tagSpec)
{
tags.Add(tagSpec.Value);
}
}
}
return tags;
}
}
}

View File

@ -0,0 +1,54 @@
using System.Collections.Generic;
using NLog;
using NzbDrone.Common.Http;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.Parser;
using NzbDrone.Core.ThingiProvider;
namespace NzbDrone.Core.ImportLists.Rss.Imdb
{
public class ImdbRssImport : RssImportBase<ImdbRssImportSettings>
{
public override string Name => "IMDb RSS";
public override ImportListType ListType => ImportListType.Advanced;
public ImdbRssImport(IHttpClient httpClient,
IImportListStatusService importListStatusService,
IConfigService configService,
IParsingService parsingService,
Logger logger)
: base(httpClient, importListStatusService, configService, parsingService, logger)
{
}
public override IEnumerable<ProviderDefinition> DefaultDefinitions
{
get
{
yield return new ImportListDefinition
{
Name = "IMDb RSS List",
Enabled = Enabled,
EnableAuto = true,
ProfileId = 1,
Implementation = GetType().Name,
Settings = new ImdbRssImportSettings { Url = "https://rss.imdb.com/list/YOURLISTID" },
};
yield return new ImportListDefinition
{
Name = "IMDb RSS Watchlist",
Enabled = Enabled,
EnableAuto = true,
ProfileId = 1,
Implementation = GetType().Name,
Settings = new ImdbRssImportSettings { Url = "https://rss.imdb.com/user/IMDBUSERID/watchlist" },
};
}
}
public override IParseImportListResponse GetParser()
{
return new ImdbRssImportParser(_logger);
}
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Xml.Linq;
using NLog;
using NzbDrone.Core.ImportLists.ImportListMovies;
namespace NzbDrone.Core.ImportLists.Rss.Imdb
{
public class ImdbRssImportParser : RssImportBaseParser
{
public ImdbRssImportParser(Logger logger)
: base(logger)
{
}
protected override ImportListMovie ProcessItem(XElement item)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,27 @@
using FluentValidation;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.ImportLists.Rss.Imdb
{
public class ImdbRssImportSettingsValidator : AbstractValidator<ImdbRssImportSettings>
{
public ImdbRssImportSettingsValidator()
{
RuleFor(c => c.Url).NotEmpty();
}
}
public class ImdbRssImportSettings : RssImportBaseSettings
{
private ImdbRssImportSettingsValidator Validator => new ();
[FieldDefinition(0, Label = "Url", Type = FieldType.Textbox)]
public override string Url { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
}
}

View File

@ -46,27 +46,27 @@ namespace NzbDrone.Core.Indexers.FileList
[FieldDefinition(1, Label = "Passkey", Privacy = PrivacyLevel.ApiKey)]
public string Passkey { get; set; }
[FieldDefinition(2, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "Multi Languages", HelpText = "What languages are normally in a multi release on this indexer?", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(3, Label = "API URL", Advanced = true, HelpText = "Do not change this unless you know what you're doing. Since your API key will be sent to that host.")]
[FieldDefinition(2, Label = "API URL", Advanced = true, HelpText = "Do not change this unless you know what you're doing. Since your API key will be sent to that host.")]
public string BaseUrl { get; set; }
[FieldDefinition(4, Label = "Categories", Type = FieldType.Select, SelectOptions = typeof(FileListCategories), HelpText = "Categories for use in search and feeds. If unspecified, all options are used.")]
[FieldDefinition(3, Label = "Categories", Type = FieldType.Select, SelectOptions = typeof(FileListCategories), HelpText = "Categories for use in search and feeds. If unspecified, all options are used.")]
public IEnumerable<int> Categories { get; set; }
[FieldDefinition(5, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
[FieldDefinition(4, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(6, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
[FieldDefinition(7)]
[FieldDefinition(5)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
[FieldDefinition(8, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
[FieldDefinition(6, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
[FieldDefinition(7, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(8, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

View File

@ -53,21 +53,21 @@ namespace NzbDrone.Core.Indexers.HDBits
[FieldDefinition(5, Label = "Mediums", Type = FieldType.Select, SelectOptions = typeof(HdBitsMedium), Advanced = true, HelpText = "If unspecified, all options are used.")]
public IEnumerable<int> Mediums { get; set; }
[FieldDefinition(6, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "Multi Languages", HelpText = "What languages are normally in a multi release on this indexer?", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(7, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
[FieldDefinition(6, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(8, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
[FieldDefinition(9)]
[FieldDefinition(7)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new ();
[FieldDefinition(10, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
[FieldDefinition(8, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
[FieldDefinition(9, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(10, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

View File

@ -41,21 +41,21 @@ namespace NzbDrone.Core.Indexers.IPTorrents
[FieldDefinition(0, Label = "Feed URL", HelpText = "The full RSS feed url generated by IPTorrents, using only the categories you selected (HD, SD, x264, etc ...)")]
public string BaseUrl { get; set; }
[FieldDefinition(1, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "Multi Languages", HelpText = "What languages are normally in a multi release on this indexer?", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(2, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
[FieldDefinition(1, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(3, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
[FieldDefinition(4)]
[FieldDefinition(2)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
[FieldDefinition(5, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
[FieldDefinition(3, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
[FieldDefinition(4, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(5, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

View File

@ -19,7 +19,7 @@ namespace NzbDrone.Core.Indexers
public abstract class IndexerBase<TSettings> : IIndexer
where TSettings : IIndexerSettings, new()
{
private static readonly Regex MultiRegex = new (@"\b(?<multi>multi)\b", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex MultiRegex = new (@"[_. ](?<multi>multi)[_. ]", RegexOptions.Compiled | RegexOptions.IgnoreCase);
protected readonly IIndexerStatusService _indexerStatusService;
protected readonly IConfigService _configService;

View File

@ -65,23 +65,19 @@ namespace NzbDrone.Core.Indexers.Newznab
[FieldDefinition(1, Label = "API Path", HelpText = "Path to the api, usually /api", Advanced = true)]
public string ApiPath { get; set; }
[FieldDefinition(1, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "Multi Languages", HelpText = "What languages are normally in a multi release on this indexer?", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(2, Label = "API Key", Privacy = PrivacyLevel.ApiKey)]
public string ApiKey { get; set; }
[FieldDefinition(3, Label = "Categories", Type = FieldType.Select, SelectOptionsProviderAction = "newznabCategories", HelpText = "Drop down list; at least one category must be selected.")]
public IEnumerable<int> Categories { get; set; }
[FieldDefinition(5, Label = "Additional Parameters", HelpText = "Additional Newznab parameters", Advanced = true)]
[FieldDefinition(4, Label = "Additional Parameters", HelpText = "Additional Newznab parameters", Advanced = true)]
public string AdditionalParameters { get; set; }
[FieldDefinition(6,
Label = "Remove year from search string",
HelpText = "Should Radarr remove the year after the title when searching this indexer?",
Advanced = true,
Type = FieldType.Checkbox)]
[FieldDefinition(5, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(6, Label = "Remove year from search string", HelpText = "Should Radarr remove the year after the title when searching this indexer?", Type = FieldType.Checkbox, Advanced = true)]
public bool RemoveYear { get; set; }
// Field 8 is used by TorznabSettings MinimumSeeders

View File

@ -36,24 +36,24 @@ namespace NzbDrone.Core.Indexers.Nyaa
[FieldDefinition(0, Label = "Website URL")]
public string BaseUrl { get; set; }
[FieldDefinition(1, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "Multi Languages", HelpText = "What languages are normally in a multi release on this indexer?", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(2, Label = "Additional Parameters", Advanced = true, HelpText = "Please note if you change the category you will have to add required/restricted rules about the subgroups to avoid foreign language releases.")]
[FieldDefinition(1, Label = "Additional Parameters", Advanced = true, HelpText = "Please note if you change the category you will have to add required/restricted rules about the subgroups to avoid foreign language releases.")]
public string AdditionalParameters { get; set; }
[FieldDefinition(3, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
[FieldDefinition(2, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(4, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
[FieldDefinition(5)]
[FieldDefinition(3)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
[FieldDefinition(6, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
[FieldDefinition(4, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
[FieldDefinition(5, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(6, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

View File

@ -35,27 +35,27 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
[FieldDefinition(0, Label = "URL", Advanced = true, HelpText = "Do not change this unless you know what you're doing. Since your cookie will be sent to that host.")]
public string BaseUrl { get; set; }
[FieldDefinition(1, Label = "APIUser", HelpText = "These settings are found in your PassThePopcorn security settings (Edit Profile > Security).", Privacy = PrivacyLevel.UserName)]
[FieldDefinition(1, Label = "API User", HelpText = "These settings are found in your PassThePopcorn security settings (Edit Profile > Security).", Privacy = PrivacyLevel.UserName)]
public string APIUser { get; set; }
[FieldDefinition(2, Label = "APIKey", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
[FieldDefinition(2, Label = "API Key", Type = FieldType.Password, Privacy = PrivacyLevel.Password)]
public string APIKey { get; set; }
[FieldDefinition(3, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "Multi Languages", HelpText = "What languages are normally in a multi release on this indexer?", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(4, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
[FieldDefinition(3, Type = FieldType.Textbox, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(5, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
[FieldDefinition(6)]
[FieldDefinition(4)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
[FieldDefinition(7, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
[FieldDefinition(5, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
[FieldDefinition(6, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(7, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

View File

@ -39,21 +39,21 @@ namespace NzbDrone.Core.Indexers.TorrentPotato
[FieldDefinition(2, Label = "Passkey", HelpText = "The password you use at your Indexer.", Privacy = PrivacyLevel.Password)]
public string Passkey { get; set; }
[FieldDefinition(3, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "Multi Languages", HelpText = "What languages are normally in a multi release on this indexer?", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(4, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
[FieldDefinition(3, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(5, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
[FieldDefinition(6)]
[FieldDefinition(4)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
[FieldDefinition(7, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
[FieldDefinition(5, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
[FieldDefinition(6, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(7, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

View File

@ -40,21 +40,21 @@ namespace NzbDrone.Core.Indexers.TorrentRss
[FieldDefinition(2, Type = FieldType.Checkbox, Label = "Allow Zero Size", HelpText = "Enabling this will allow you to use feeds that don't specify release size, but be careful, size related checks will not be performed.")]
public bool AllowZeroSize { get; set; }
[FieldDefinition(3, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "Multi Languages", HelpText = "What languages are normally in a multi release on this indexer?", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(4, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
[FieldDefinition(3, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
[FieldDefinition(5, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
[FieldDefinition(6)]
[FieldDefinition(4)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
[FieldDefinition(7, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
[FieldDefinition(5, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
[FieldDefinition(6, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
public IEnumerable<int> MultiLanguages { get; set; }
[FieldDefinition(7, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

View File

@ -58,12 +58,12 @@ namespace NzbDrone.Core.Indexers.Torznab
[FieldDefinition(9)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new ();
[FieldDefinition(10, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
[FieldDefinition(11, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
[FieldDefinition(10, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
[FieldDefinition(11, Type = FieldType.Select, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://wiki.servarr.com/radarr/settings#indexer-flags", Advanced = true)]
public IEnumerable<int> RequiredFlags { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

View File

@ -623,10 +623,10 @@
"DownloadClientUnavailable": "Downloader ist nicht verfügbar",
"DeleteTagMessageText": "Sind Sie sicher, dass Sie das Tag „{label}“ löschen möchten?",
"DeleteRestrictionHelpText": "Beschränkung '{0}' wirklich löschen?",
"DeleteNotificationMessageText": "Sind Sie sicher, dass Sie die Benachrichtigung „{name}“ löschen möchten?",
"DeleteIndexerMessageText": "Sind Sie sicher, dass Sie den Indexer „{name}“ löschen möchten?",
"DeleteDownloadClientMessageText": "Sind Sie sicher, dass Sie den Download-Client „{name}“ löschen möchten?",
"DeleteBackupMessageText": "Sind Sie sicher, dass Sie die Sicherung „{name}“ löschen möchten?",
"DeleteNotificationMessageText": "Bist du sicher, dass du die Benachrichtigung '{name}' wirklich löschen willst?",
"DeleteIndexerMessageText": "Bist du sicher, dass du den Indexer '{name}' wirklich löschen willst?",
"DeleteDownloadClientMessageText": "Bist du sicher, dass du den Download Client '{name}' wirklich löschen willst?",
"DeleteBackupMessageText": "Soll das Backup '{name}' wirklich gelöscht werden?",
"Cutoff": "Schwelle",
"ClickToChangeMovie": "Klicken um den Film zu bearbeiten",
"CheckDownloadClientForDetails": "Weitere Informationen finden Sie im Download-Client",
@ -925,10 +925,10 @@
"AllMoviesInPathHaveBeenImported": "Alle Filme in {path} wurden importiert",
"AllFiles": "Alle Dateien",
"AfterManualRefresh": "Nach manueller Aktualisierung",
"AddToDownloadQueue": "Zur Download-Warteschlange hinzufügen",
"AddToDownloadQueue": "Zur Download Warteschlange hinzufügen",
"AddRootFolder": "Stammverzeichnis hinzufügen",
"AddQualityProfile": "Qualitäts Profil hinzufügen",
"AddedToDownloadQueue": "Zur Download-Warteschlange hinzugefügt",
"AddedToDownloadQueue": "Zur Download Warteschlange hinzugefügt",
"AddDownloadClient": "Downloadmanager hinzufügen",
"AddCustomFormat": "Eigenes Format hinzufügen",
"AddDelayProfile": "Verzögerungsprofil hinzufügen",
@ -1079,7 +1079,7 @@
"RemoveSelectedItemsQueueMessageText": "Bist du sicher, dass du {selectedCount} Einträge aus der Warteschlange entfernen willst?",
"ResetDefinitionTitlesHelpText": "Definitionstitel und -werte zurücksetzen",
"DeleteConditionMessageText": "Bist du sicher, dass du die Bedingung '{0}' löschen willst?",
"DeleteCustomFormatMessageText": "Bist du sicher, dass du das eigene Format '{name}' löschen willst?",
"DeleteCustomFormatMessageText": "Bist du sicher, dass du das benutzerdefinierte Format '{name}' wirklich löschen willst?",
"DeleteDelayProfileMessageText": "Sind Sie sicher, dass Sie dieses Verzögerungsprofil löschen möchten?",
"DeleteFormatMessageText": "Bist du sicher, dass du das Formatierungstag {0} löschen willst?",
"ResetAPIKeyMessageText": "Sind Sie sicher, dass Sie Ihren API-Schlüssel zurücksetzen möchten?",
@ -1109,24 +1109,24 @@
"NoImportListsFound": "Keine Einspiel-Listen gefunden",
"NoIndexersFound": "Keine Indexer gefunden",
"CountIndexersSelected": "{count} Indexer ausgewählt",
"ApplyTagsHelpTextAdd": "Hinzufügen: Fügen Sie die Tags der vorhandenen Tag-Liste hinzu",
"ApplyTagsHelpTextRemove": "Entfernen: Die eingegebenen Tags entfernen",
"ApplyTagsHelpTextHowToApplyIndexers": "So wenden Sie Tags auf die ausgewählten Indexer an",
"ApplyTagsHelpTextReplace": "Ersetzen: Ersetzen Sie die Tags durch die eingegebenen Tags (geben Sie keine Tags ein, um alle Tags zu löschen).",
"ApplyTagsHelpTextAdd": "Hinzufügen: Füge Tags zu den bestehenden Tags hinzu",
"ApplyTagsHelpTextRemove": "Entfernen: Entferne die hinterlegten Tags",
"ApplyTagsHelpTextHowToApplyIndexers": "Wie Tags zu den selektierten Indexern hinzugefügt werden können",
"ApplyTagsHelpTextReplace": "Ersetzen: Ersetze die Tags mit den eingegebenen Tags (keine Tags eingeben um alle Tags zu löschen)",
"DeleteImportList": "Importliste löschen",
"DeleteImportListMessageText": "Sind Sie sicher, dass Sie die Liste „{name}“ löschen möchten?",
"DeleteQualityProfileMessageText": "Sind Sie sicher, dass Sie das Qualitätsprofil „{name}“ löschen möchten?",
"DeleteImportListMessageText": "Bist du sicher, dass du die Liste '{name}' wirklich löschen willst?",
"DeleteQualityProfileMessageText": "Bist du sicher, dass du das Qualitätsprofil '{name}' wirklich löschen willst?",
"RemoveQueueItemConfirmation": "Bist du sicher, dass du {0} Einträge aus der Warteschlange entfernen willst?",
"SkipRedownload": "Überspringe erneuten Download",
"MoveAutomatically": "Automatisch verschieben",
"AutoTaggingNegateHelpText": "Falls aktiviert wird das eigene Format nicht angewendet solange diese {0} Bedingung zutrifft.",
"AutoTaggingNegateHelpText": "Falls aktiviert wird die Auto Tagging Regel nicht angewendet, solange diese Bedingung {implementationName} zutrifft.",
"AutoTaggingRequiredHelpText": "Diese {0} Bedingungen müssen erfüllt sein, damit das eigene Format zutrifft. Ansonsten reicht ein einzelner {1} Treffer.",
"DeleteAutoTagHelpText": "Sind Sie sicher, dass Sie das automatische Tag „{name}“ löschen möchten?",
"DeleteSelectedDownloadClientsMessageText": "Sind Sie sicher, dass Sie {count} ausgewählte Download-Clients löschen möchten?",
"DeleteSelectedImportListsMessageText": "Sind Sie sicher, dass Sie {count} ausgewählte Importliste(n) löschen möchten?",
"DeleteSelectedIndexersMessageText": "Sind Sie sicher, dass Sie {count} ausgewählte(n) Indexer löschen möchten?",
"ApplyTagsHelpTextHowToApplyDownloadClients": "So wenden Sie Tags auf die ausgewählten Download-Clients an",
"ApplyTagsHelpTextHowToApplyImportLists": "So wenden Sie Tags auf die ausgewählten Importlisten an",
"ApplyTagsHelpTextHowToApplyDownloadClients": "Wie Tags zu den selektierten Downloadclients hinzugefügt werden können",
"ApplyTagsHelpTextHowToApplyImportLists": "Wie Tags den selektierten Importlisten hinzugefügt werden können",
"DeleteRootFolderMessageText": "Sind Sie sicher, dass Sie den Stammordner „{path}“ löschen möchten?",
"DeleteRootFolder": "Stammordner löschen",
"AddConnection": "Verbindung hinzufügen",

View File

@ -113,6 +113,7 @@
"AutoTaggingLoadError": "Unable to load auto tagging",
"AutoTaggingNegateHelpText": "If checked, the auto tagging rule will not apply if this {implementationName} condition matches.",
"AutoTaggingRequiredHelpText": "This {implementationName} condition must match for the auto tagging rule to apply. Otherwise a single {implementationName} match is sufficient.",
"AutoTaggingSpecificationTag": "Tag",
"AutoUnmonitorPreviouslyDownloadedMoviesHelpText": "Movies deleted from the disk are automatically unmonitored in {appName}",
"Automatic": "Automatic",
"AutomaticAdd": "Automatic Add",
@ -257,8 +258,8 @@
"CustomFormats": "Custom Formats",
"CustomFormatsLoadError": "Unable to load Custom Formats",
"CustomFormatsSettings": "Custom Formats Settings",
"CustomFormatsSettingsTriggerInfo": "A Custom Format will be applied to a release or file when it matches at least one of each of the different condition types chosen.",
"CustomFormatsSettingsSummary": "Custom Formats and Settings",
"CustomFormatsSettingsTriggerInfo": "A Custom Format will be applied to a release or file when it matches at least one of each of the different condition types chosen.",
"CustomFormatsSpecificationFlag": "Flag",
"CustomFormatsSpecificationRegularExpression": "Regular Expression",
"CustomFormatsSpecificationRegularExpressionHelpText": "Custom Format RegEx is Case Insensitive",
@ -554,6 +555,7 @@
"EditSelectedIndexers": "Edit Selected Indexers",
"EditSelectedMovies": "Edit Selected Movies",
"Edition": "Edition",
"EditionFootNote": "Optionally control truncation to a maximum number of bytes including ellipsis (`...`). Truncating from the end (e.g. `{Edition Tags:30}`) or the beginning (e.g. `{Edition Tags:-30}`) are both supported.",
"Enable": "Enable",
"EnableAutomaticAdd": "Enable Automatic Add",
"EnableAutomaticAddMovieHelpText": "If enabled, movies will be automatically added to {appName} from this list",
@ -746,6 +748,8 @@
"IndexerSearchCheckNoAvailableIndexersMessage": "All search-capable indexers are temporarily unavailable due to recent indexer errors",
"IndexerSearchCheckNoInteractiveMessage": "No indexers available with Interactive Search enabled, {appName} will not provide any interactive search results",
"IndexerSettings": "Indexer Settings",
"IndexerSettingsMultiLanguageRelease": "Multi Languages",
"IndexerSettingsMultiLanguageReleaseHelpText": "What languages are normally in a multi release on this indexer?",
"IndexerSettingsRejectBlocklistedTorrentHashes": "Reject Blocklisted Torrent Hashes While Grabbing",
"IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "If a torrent is blocked by hash it may not properly be rejected during RSS/Search for some indexers, enabling this will allow it to be rejected after the torrent is grabbed, but before it is sent to the client.",
"IndexerStatusCheckAllClientMessage": "All indexers are unavailable due to failures",
@ -919,6 +923,7 @@
"MovieFolderFormat": "Movie Folder Format",
"MovieFolderFormatHelpText": "Used when adding a new movie or moving movies via the movie editor",
"MovieFolderImportedTooltip": "Movie imported from movie folder",
"MovieFootNote": "Optionally control truncation to a maximum number of bytes including ellipsis (`...`). Truncating from the end (e.g. `{Movie Title:30}`) or the beginning (e.g. `{Movie Title:-30}`) are both supported.",
"MovieGrabbedHistoryTooltip": "Movie grabbed from {indexer} and sent to {downloadClient}",
"MovieID": "Movie ID",
"MovieImported": "Movie Imported",
@ -1140,6 +1145,8 @@
"NotificationsTelegramSettingsBotToken": "Bot Token",
"NotificationsTelegramSettingsChatId": "Chat ID",
"NotificationsTelegramSettingsChatIdHelpText": "You must start a conversation with the bot or add it to your group to receive messages",
"NotificationsTelegramSettingsIncludeAppName": "Include {appName} in Title",
"NotificationsTelegramSettingsIncludeAppNameHelpText": "Optionally prefix message title with {appName} to differentiate notifications from different applications",
"NotificationsTelegramSettingsSendSilently": "Send Silently",
"NotificationsTelegramSettingsSendSilentlyHelpText": "Sends the message silently. Users will receive a notification with no sound",
"NotificationsTelegramSettingsTopicId": "Topic ID",
@ -1332,6 +1339,7 @@
"ReleaseBranchCheckOfficialBranchMessage": "Branch {0} is not a valid {appName} release branch, you will not receive updates",
"ReleaseDates": "Release Dates",
"ReleaseGroup": "Release Group",
"ReleaseGroupFootNote": "Optionally control truncation to a maximum number of bytes including ellipsis (`...`). Truncating from the end (e.g. `{Release Group:30}`) or the beginning (e.g. `{Release Group:-30}`) are both supported.`).",
"ReleaseGroups": "Release Groups",
"ReleaseHash": "Release Hash",
"ReleaseProfileIndexerHelpText": "Specify what indexer the profile applies to",

View File

@ -164,7 +164,7 @@
"QualitySettingsSummary": "Tamaños de calidad y nombrado",
"Protocol": "Protocolo",
"Progress": "Progreso",
"ProfilesSettingsSummary": "Calidad, Idioma y Perfiles de retraso",
"ProfilesSettingsSummary": "Calidad, idioma, retraso y perfiles de lanzamiento",
"PhysicalRelease": "Estreno Físico",
"OutputPath": "Ruta de salida",
"MovieTitle": "Título de la Película",
@ -320,7 +320,7 @@
"DeleteRestriction": "Borrar Restricción",
"DeleteQualityProfile": "Borrar perfil de calidad",
"DeleteNotification": "Borrar Notificacion",
"DeleteIndexer": "Borrar Indexer",
"DeleteIndexer": "Borrar indexador",
"DeleteImportListExclusion": "Eliminar exclusión de listas de importación",
"DeleteFile": "Borrar archivo",
"DeleteEmptyFoldersHelpText": "Borrar carpetas vacías durante la exploración del disco y cuando se eliminen archivos",
@ -452,7 +452,7 @@
"RescanMovieFolderAfterRefresh": "Reescanear la Carpeta de Películas después de Actualizar",
"RescanAfterRefreshHelpTextWarning": "{appName} no detectará automáticamente cambios en los archivos si no se elige 'Siempre'",
"RescanAfterRefreshMovieHelpText": "Reescanear la carpeta de películas después de actualizar la película",
"RequiredHelpText": "Esta condición {0} ha de igualar al formato propio para aplicarse. Si no, una sóla {1} es suficiente.",
"RequiredHelpText": "Esta condición {implementationName} debe coincidir con el formato personalizado para aplicarse. De otro modo, una simple coincidencia {implementationName} es suficiente.",
"ReplaceIllegalCharactersHelpText": "Reemplaza los caracteres ilegales. Si no está marcado, {appName} los eliminará en su lugar",
"ReplaceIllegalCharacters": "Reemplazar caracteres ilegales",
"Reorder": "Reordenar",
@ -557,7 +557,7 @@
"IgnoredAddresses": "Direcciones Ignoradas",
"IconForCutoffUnmet": "Icono de Corte no alcanzado",
"ICalFeedHelpText": "Copia esta URL a tu gestor(es) o haz click en subscribir si tu navegador soporta webcal",
"ICalFeed": "iCal Feed",
"ICalFeed": "Feed de iCal",
"Hostname": "Nombre del Host",
"EnableSsl": "Habilitar SSL",
"EnableRss": "Habilitar RSS",
@ -598,7 +598,7 @@
"Pending": "Pendiente",
"Paused": "Pausado",
"NegateHelpText": "Si se marca, el formato personalizado no se aplica si coincide la condición {implementationName}.",
"MoviesSelectedInterp": "{0} Película(s) Seleccionada(s)",
"MoviesSelectedInterp": "{count} película(s) seleccionada(s)",
"MovieIsUnmonitored": "La película no está monitoreada",
"MovieIsMonitored": "La película está monitoreada",
"MovieExcludedFromAutomaticAdd": "Película Excluida de Adición Automática",
@ -627,7 +627,7 @@
"DeleteNotificationMessageText": "¿Seguro que quieres eliminar la notificación '{name}'?",
"DeleteBackupMessageText": "Seguro que quieres eliminar la copia de seguridad '{name}'?",
"DeleteDownloadClientMessageText": "Seguro que quieres eliminar el gestor de descargas '{name}'?",
"DeleteIndexerMessageText": "Seguro que quieres eliminar el indexer '{name}'?",
"DeleteIndexerMessageText": "¿Estás seguro que quieres eliminar el indexador '{name}'?",
"Cutoff": "Umbral",
"ClickToChangeMovie": "Clic para cambiar película",
"CheckDownloadClientForDetails": "Revisar el cliente de descarga para más detalles",
@ -639,7 +639,7 @@
"SupportedCustomConditions": "{appName} soporta condiciones personalizadas para las siguientes propiedades de lanzamiento.",
"YouCanAlsoSearch": "También puedes buscar usando la ID de TMDb o la ID de IMDb de una película. ej. `tmdb:71663`",
"VisitTheWikiForMoreDetails": "Visita la wiki para más detalles: ",
"Unreleased": "Inédito",
"Unreleased": "Sin estrenar",
"UiSettingsLoadError": "No se pudo cargar las opciones de interfaz",
"CalendarLoadError": "No se ha podido cargar el calendario",
"UnableToLoadRootFolders": "No se han podido cargar las carpetas raiz",
@ -663,7 +663,7 @@
"TagIsNotUsedAndCanBeDeleted": "La etiqueta no se usa y puede ser borrada",
"StartTypingOrSelectAPathBelow": "Comienza a escribir o selecciona una ruta debajo",
"Restore": "Restaurar",
"RegularExpressionsCanBeTested": "Las expresiones regulares se pueden testear ",
"RegularExpressionsCanBeTested": "Las expresiones regulares pueden ser probadas [aquí](http://regexstorm.net/tester).",
"SupportedListsMovie": "{appName} soporta cualquier lista RSS de películas, como también la listada debajo.",
"SupportedIndexers": "{appName} soporta cualquier indexador que use el estándar Newznab, así como otros indexadores listados a continuación.",
"SupportedDownloadClients": "{appName} soporta muchos torrent populares y clientes de descarga de usenet.",
@ -676,8 +676,8 @@
"MissingNotMonitored": "No encontrada (No Monitoreada)",
"MissingMonitoredAndConsideredAvailable": "No encontrada (Monitoreada)",
"MinutesSixty": "60 minutos: {sixty}",
"MinutesNinety": "90 Minutos: {0}",
"MinutesHundredTwenty": "120 Minutos: {0}",
"MinutesNinety": "90 Minutos: {ninety}",
"MinutesHundredTwenty": "120 Minutos: {hundredTwenty}",
"MaintenanceRelease": "Lanzamiento de mantenimiento: Corrección de errores y otras mejoras. Ver historial de commits de Github para mas detalle",
"LoadingMovieFilesFailed": "La carga de los archivos ha fallado",
"LoadingMovieExtraFilesFailed": "La carga de los extras de la película ha fallado",
@ -711,8 +711,8 @@
"DownloadPropersAndRepacksHelpTextCustomFormat": "Usar \"No Preferir\" para ordenar por puntuación de palabras preferidas en vez de proper/repacks",
"DownloadPropersAndRepacksHelpText": "Decidir si automaticamente actualizar a Propers/Repacks",
"DownloadPropersAndRepacks": "Propers y repacks",
"CustomFormatUnknownConditionOption": "Opción Desconocida '{0}' para condición '{1}'",
"CustomFormatUnknownCondition": "Condición de Formato Personalizado Desconocida '{0}'",
"CustomFormatUnknownConditionOption": "Opción Desconocida '{key}' para condición '{implementation}'",
"CustomFormatUnknownCondition": "Condición de Formato Personalizado Desconocida '{implementation}'",
"Priority": "Prioridad",
"InteractiveSearch": "Búsqueda Interactiva",
"IndexerPriorityHelpText": "Prioridad del Indexador de 1 (la más alta) a 50 (la más baja). Por defecto: 25. Usada para desempatar lanzamientos iguales cuando se capturan, {appName} seguirá usando todos los indexadores habilitados para Sincronización de RSS y Búsqueda",
@ -884,7 +884,7 @@
"Negate": "Negar",
"Negated": "Anulado",
"NoListRecommendations": "No se encontraron elementos de lista ni recomendaciones; para comenzar, querrá agregar una nueva película, importar algunas existentes o agregar una lista.",
"OrganizeConfirm": "¿Está seguro de que desea organizar todos los archivos de las {0} películas seleccionadas?",
"OrganizeConfirm": "¿Estás seguro que quieres organizar todos los archivos en las {count} película(s) seleccionada(s)?",
"OrganizeSelectedMovies": "Organizar películas seleccionadas",
"PhysicalReleaseDate": "Fecha de lanzamiento físico",
"PreferAndUpgrade": "Preferir y actualizar",
@ -1074,7 +1074,7 @@
"ApplyTagsHelpTextRemove": "Eliminar: Elimina las etiquetas introducidas",
"ApplyTagsHelpTextReplace": "Reemplazar: Sustituye las etiquetas por las introducidas (introduce \"no tags\" para borrar todas las etiquetas)",
"DeleteSelectedDownloadClients": "Borrar Cliente de Descarga(s)",
"DeleteSelectedIndexers": "Borrar indexer(s)",
"DeleteSelectedIndexers": "Borrar indexador(es)",
"ApplyChanges": "Aplicar Cambios",
"AddAutoTag": "Añadir Etiqueta Automática",
"AddCondition": "Añadir Condición",
@ -1160,7 +1160,7 @@
"AppUpdatedVersion": "{appName} ha sido actualizado a la versión `{version}`, para obtener los cambios más recientes, necesitará recargar {appName}",
"DeleteSelectedIndexersMessageText": "¿Está seguro de querer eliminar {count} indexador(es) seleccionado(s)?",
"DisabledForLocalAddresses": "Deshabilitado para Direcciones Locales",
"DeletedReasonManual": "El archivo fue borrado por vía UI",
"DeletedReasonManual": "El archivo fue eliminado usando {appName}, o bien manualmente o por otra herramienta a través de la API",
"DeletedReasonMissingFromDisk": "{appName} no ha podido encontrar el archivo en el disco, por lo que se ha desvinculado de la película en la base de datos",
"DeletedReasonUpgrade": "Se ha borrado el archivo para importar una versión mejorada",
"DeleteSelectedMovieFilesHelpText": "¿Está seguro de que desea eliminar los archivos de película seleccionados?",
@ -1172,7 +1172,7 @@
"ClearBlocklistMessageText": "¿Estás seguro de que quieres borrar todos los elementos de la lista de bloqueos?",
"ClientPriority": "Prioridad del Cliente",
"ColonReplacement": "Reemplazar dos puntos",
"CloneIndexer": "Clonar Indexer",
"CloneIndexer": "Clonar indexador",
"CompletedDownloadHandling": "Manipulación de descargas completas",
"CopyToClipboard": "Copiar al portapapeles",
"CloneCustomFormat": "Clonar formato personalizado",
@ -1594,5 +1594,162 @@
"DownloadClientQbittorrentSettingsInitialStateHelpText": "Estado inicial para los torrents añadidos a qBittorrent. Ten en cuenta que Forzar torrents no cumple las restricciones de semilla",
"DownloadClientRTorrentSettingsDirectoryHelpText": "Ubicación opcional en la que poner las descargas, dejar en blanco para usar la ubicación predeterminada de rTorrent",
"DownloadClientSettingsDestinationHelpText": "Especifica manualmente el destino de descarga, dejar en blanco para usar el predeterminado",
"DownloadClientSettingsInitialState": "Estado inicial"
"DownloadClientSettingsInitialState": "Estado inicial",
"CustomFormatsSettingsTriggerInfo": "Un formato personalizado será aplicado al lanzamiento o archivo cuando coincida con al menos uno de los diferentes tipos de condición elegidos.",
"IndexerSettingsMultiLanguageRelease": "Múltiples idiomas",
"IndexerSettingsMultiLanguageReleaseHelpText": "¿Qué idiomas están normalmente en un lanzamiento múltiple en este indexador?",
"PopularityIndex": "Índice de popularidad actual",
"AutoTaggingSpecificationTag": "Etiqueta",
"BlackholeWatchFolderHelpText": "Carpeta desde la que {appName} debería importar las descargas completadas",
"DeleteSpecificationHelpText": "¿Estás seguro que quieres eliminar la especificación '{name}'?",
"DownloadClientDelugeTorrentStateError": "Deluge está reportando un error",
"DownloadClientDelugeValidationLabelPluginInactive": "Plugin de etiqueta no activado",
"DownloadClientDownloadStationValidationNoDefaultDestination": "Sin destino predeterminado",
"DownloadClientDownloadStationValidationSharedFolderMissingDetail": "El Diskstation no tiene una carpeta compartida con el nombre '{sharedFolder}'. ¿Estás seguro que lo has especificado correctamente?",
"DownloadClientFloodSettingsRemovalInfo": "{appName} manejará la eliminación automática de torrents basados en los criterios de sembrado actuales en Opciones -> Indexadores",
"DownloadClientNzbgetValidationKeepHistoryOverMax": "La configuración KeepHistory de NzbGet debería ser menor de 25000",
"DownloadClientSabnzbdValidationEnableDisableDateSorting": "Deshabilitar ordenamiento de fecha",
"DownloadClientSabnzbdValidationEnableDisableMovieSorting": "Deshabilitar ordenamiento de película",
"DownloadClientSabnzbdValidationEnableDisableMovieSortingDetail": "Debes deshabilitar el ordenamiento de película para la categoría que {appName} usa para evitar problemas al importar. Ve a Sabnzbd para corregirlo.",
"DownloadClientSabnzbdValidationEnableDisableTvSorting": "Deshabilitar ordenamiento de TV",
"DownloadClientSabnzbdValidationEnableJobFolders": "Habilitar carpetas de trabajo",
"DownloadClientSabnzbdValidationEnableJobFoldersDetail": "{appName} prefiere que cada descarga tenga una carpeta separada. Con * añadido a la carpeta/ruta, Sabnzbd no creará esas carpetas de trabajo. Ve a Sabnzbd para corregirlo.",
"DownloadClientSettingsOlderPriority": "Priorizar más antiguos",
"DownloadClientSettingsOlderPriorityMovieHelpText": "Prioridad a usar cuando se capturan películas que empezaron su emisión hace más de 21 días",
"DownloadClientSettingsRecentPriority": "Priorizar recientes",
"DownloadClientValidationApiKeyRequired": "Clave API requerida",
"DownloadClientValidationApiKeyIncorrect": "Clave API incorrecta",
"DownloadClientValidationAuthenticationFailure": "Fallo de autenticación",
"DownloadClientValidationSslConnectFailureDetail": "{appName} no se pudo conectar a {clientName} usando SSL. Este problema puede estar relacionado con el ordenador. Por favor intenta configurar tanto {appName} como {clientName} para no usar SSL.",
"NotificationsTelegramSettingsIncludeAppNameHelpText": "Opcionalmente prefija el título del mensaje con {appName} para diferenciar las notificaciones de las diferentes aplicaciones",
"NotificationsTelegramSettingsIncludeAppName": "Incluir {appName} en el título",
"Recommended": "Recomendado",
"ShowTmdbRating": "Mostrar valoraciones de TMDb",
"MovieMatchType": "Tipo de coincidencia de película",
"BlackholeWatchFolder": "Monitorizar carpeta",
"Category": "Categoría",
"DownloadClientDownloadStationValidationSharedFolderMissing": "La carpeta compartida no existe",
"DownloadClientFloodSettingsAddPaused": "Añadir pausados",
"DownloadClientFreeboxNotLoggedIn": "Sin sesión iniciada",
"DownloadClientFreeboxUnableToReachFreebox": "No se pudo alcanzar la API de Freebox. Verifica las opciones 'Host', 'Puerto' o 'Usar SSL'. (Error: {exceptionMessage})",
"DownloadClientNzbVortexMultipleFilesMessage": "La descarga contiene múltiples archivos y no está en una carpeta de trabajo: {outputPath}",
"DownloadClientNzbgetValidationKeepHistoryOverMaxDetail": "La configuración KeepHistory de NzbGet está establecida demasiado alta.",
"DownloadClientQbittorrentTorrentStateDhtDisabled": "qBittorrent no puede resolver el enlace magnet con DHT deshabilitado",
"DownloadClientQbittorrentTorrentStateMetadata": "qBittorrent está descargando metadatos",
"DownloadClientSettingsPostImportCategoryHelpText": "Categoría para que {appName} establezca una vez se haya importado la descarga. {appName} no eliminará torrents en esa categoría incluso si finalizó el sembrado. Dejar en blanco para mantener la misma categoría.",
"DownloadClientUTorrentTorrentStateError": "uTorrent está reportando un error",
"DownloadClientValidationCategoryMissing": "La categoría no existe",
"DownloadClientValidationCategoryMissingDetail": "La categoría que has introducido no existe en {clientName}. Créala en {clientName} primero.",
"DownloadClientValidationGroupMissing": "El grupo no existe",
"DownloadClientValidationErrorVersion": "La versión de {clientName} debería ser al menos {requiredVersion}. La versión reportada es {reportedVersion}",
"DownloadClientValidationGroupMissingDetail": "El grupo que introdujiste no existe en {clientName}. Créalo en {clientName} primero.",
"DownloadClientValidationSslConnectFailure": "No se pudo conectar a través de SSL",
"DownloadClientValidationTestTorrents": "Fallo al obtener la lista de torrents: {exceptionMessage}",
"DownloadClientValidationTestNzbs": "Fallo al obtener la lista de NZBs: {exceptionMessage}",
"DownloadClientValidationUnableToConnectDetail": "Por favor verifica el nombre de host y el puerto.",
"OrganizeNamingPattern": "Patrón de nombrado: `{standardMovieFormat}`",
"WhySearchesCouldBeFailing": "Pulsa aquí para descubrir por qué las búsquedas podrían estar fallando",
"MovieSearchResultsLoadError": "No se pudo cargar los resultados para esta búsqueda de película. Intentar de nuevo más tarde",
"DelayMinutes": "{delay} minutos",
"DelayProfileProtocol": "Protocolo: {preferredProtocol}",
"DeleteReleaseProfile": "Eliminar perfil de lanzamiento",
"DeleteReleaseProfileMessageText": "¿Estás seguro que quieres eliminar este perfil de lanzamiento '{name}'?",
"DeleteSpecification": "Eliminar especificación",
"DownloadClientDelugeValidationLabelPluginFailure": "La configuración de etiqueta falló",
"DownloadClientDelugeValidationLabelPluginFailureDetail": "{appName} no pudo añadir la etiqueta a {clientName}.",
"DownloadClientDelugeValidationLabelPluginInactiveDetail": "Debes tener el plugir de etiqueta habilitado en {clientName} para usar categorías.",
"DownloadClientDownloadStationValidationApiVersion": "Versión API de estación de descarga no soportada, debería ser al menos {requiredVersion}. Soporta desde {minVersion} hasta {maxVersion}",
"DownloadClientDownloadStationValidationNoDefaultDestinationDetail": "Debes iniciar sesión en tu Diskstation como {username} y configurarlo manualmente en las opciones de DownloadStation en BT/HTTP/FTP/NZB -> Ubicación.",
"DownloadClientFloodSettingsPostImportTags": "Etiquetas post-importación",
"DownloadClientFloodSettingsStartOnAdd": "Iniciar al añadir",
"DownloadClientNzbgetValidationKeepHistoryZero": "La configuración KeepHistory de NzbGet debería ser mayor de 0",
"DownloadClientQbittorrentTorrentStateError": "qBittorrent está reportando un error",
"DownloadClientQbittorrentValidationCategoryAddFailure": "La configuración de categoría falló",
"DownloadClientQbittorrentTorrentStateStalled": "La descarga está parada sin conexiones",
"DownloadClientQbittorrentTorrentStateUnknown": "Estado de descarga desconocido: {state}",
"DownloadClientQbittorrentValidationCategoryRecommended": "Una categoría es recomendada",
"DownloadClientQbittorrentValidationCategoryAddFailureDetail": "{appName} no pudo añadir la etiqueta a qBittorrent.",
"DownloadClientQbittorrentValidationCategoryUnsupportedDetail": "Las categorías no están soportadas por debajo de la versión 3.3.0 de qBittorrent. Por favor actualiza o inténtalo de nuevo con una categoría vacía.",
"DownloadClientQbittorrentValidationCategoryUnsupported": "La categoría no está soportada",
"DownloadClientQbittorrentValidationQueueingNotEnabledDetail": "El encolado de torrent no está habilitado en las opciones de tu qBittorrent. Habilítalo en qBittorrent o selecciona 'Último' como prioridad.",
"DownloadClientQbittorrentValidationRemovesAtRatioLimit": "qBittorrent está configurado para eliminar torrents cuando alcanzan su Límite de ratio de compartición",
"DownloadClientSabnzbdValidationDevelopVersion": "Versión de desarrollo de Sabnzbd, asumiendo versión 3.0.0 o superior.",
"DownloadClientSabnzbdValidationEnableDisableDateSortingDetail": "Debes deshabilitar el ordenamiento de fecha para la categoría que {appName} usa para evitar problemas al importar. Ve a Sabnzbd para corregirlo.",
"DownloadClientSabnzbdValidationEnableDisableTvSortingDetail": "Debes deshabilitar el ordenamiento de TV para la categoría que {appName} usa para evitar problemas al importar. Ve a Sabnzbd para corregirlo.",
"DownloadClientSabnzbdValidationUnknownVersion": "Versión desconocida: {rawVersion}",
"DownloadClientSettingsCategoryHelpText": "Añade una categoría específica para que {appName} evite conflictos con descargas no relacionadas con {appName}. Usar una categoría es opcional, pero altamente recomendado.",
"DownloadClientSettingsCategorySubFolderHelpText": "Añade una categoría específica para que {appName} evite conflictos con descargas no relacionadas con {appName}. Usar una categoría es opcional, pero altamente recomendado. Crea un subdirectorio [categoría] en el directorio de salida.",
"DownloadClientSettingsRecentPriorityMovieHelpText": "Prioridad a usar cuando se capturan películas que empezaron la emisión dentro de los últimos 21 días",
"DownloadClientValidationUnableToConnect": "No se pudo conectar a {clientName}",
"DownloadClientValidationVerifySslDetail": "Por favor verifica tu configuración SSL tanto en {clientName} como en {appName}",
"DownloadStationStatusExtracting": "Extrayendo: {progress}%",
"EditReleaseProfile": "Editar perfil de lanzamiento",
"NewNonExcluded": "Nuevos no excluidos",
"NoExtraFilesToManage": "Ningún archivo adicional para gestionar.",
"OnManualInteractionRequiredHelpText": "En interacción manual requerida",
"Recommendation": "Recomendación",
"ShowRottenTomatoesRating": "Mostrar valoraciones de Tomato",
"Popularity": "Popularidad",
"OverrideGrabNoMovie": "La película debe ser seleccionada",
"RecycleBinUnableToWriteHealthCheck": "No se pudo escribir a la carpeta de papelera de reciclaje configurada: {path}. Asegúrate de que existe esta ruta y es modificable por el usuario que ejecuta {appName}",
"ThereWasAnErrorLoadingThisItem": "Hubo un error cargando este elemento",
"DownloadClientSabnzbdValidationCheckBeforeDownloadDetail": "Usar 'Verificar antes de descargar' afecta a la habilidad de {appName} para rastrear nuevas descargas. Sabnzbd recomienda 'Abortar trabajos que no pueden ser completados' en su lugar ya que es más efectivo.",
"AddListExclusion": "Añadir lista de exclusión",
"AddReleaseProfile": "Añadir perfil de lanzamiento",
"SearchMoviesConfirmationMessageText": "¿Estás seguro que quieres realizar una búsqueda para {count} película(s)?",
"ShowUnknownMovieItemsHelpText": "Mostrar elementos sin una película en la cola. Esto podría incluir películas eliminadas o cualquier otra cosa en la categoría de {appName}",
"AutoTaggingLoadError": "No se pudo cargar el etiquetado automático",
"DownloadClientRTorrentProviderMessage": "rTorrent no pausará torrents cuando cumplan el criterio de sembrado. {appName} manejará la eliminación automática de torrents basados en el criterio de sembrado actual en Opciones -> Indexadores solo cuando Eliminar completados esté habilitado. Después de importarlo también se establecerá {importedView} como una vista de rTorrent, lo que puede ser usado en los scripts de rTorrent para personalizar su comportamiento.",
"DownloadClientValidationAuthenticationFailureDetail": "Por favor verifica tu usuario y contraseña. Verifica también si al host que ejecuta {appName} no se le ha bloqueado el acceso a {clientName} por limitaciones en la lista blanca en la configuración de {clientName}.",
"ThereWasAnErrorLoadingThisPage": "Hubo un error cargando esta página",
"MovieIsTrending": "La película es tendencia en TMDb",
"MovieIsPopular": "La película es popular en TMDb",
"RemotePathMappingsInfo": "El mapeo de rutas remotas es muy raramente requerido, si {appName} y tu cliente de descarga están en el mismo sistema es mejor para coincidir tus rutas. Para más información consulta la [wiki]({wikiLink}).",
"NotificationsPlexValidationNoMovieLibraryFound": "Se requiere al menos una biblioteca de películas",
"IncludeHealthWarnings": "Incluir avisos de salud",
"Trending": "Tendencia",
"EditMetadata": "Editar metadatos {metadataType}",
"Example": "Ejemplo",
"HourShorthand": "h",
"ReleaseProfileIndexerHelpTextWarning": "Establecer un indexador específico en un perfil de lanzamiento causará que este perfil solo se aplique a lanzamientos desde ese indexador.",
"ReleaseProfileTagMovieHelpText": "Los perfiles de lanzamiento se aplicarán a películas con al menos una etiqueta coincidente. Dejar en blanco para aplicar a todas las películas",
"ShowImdbRatingHelpText": "Mostrar valoraciones de IMDb debajo del póster",
"ShowImdbRating": "Mostrar valoraciones de IMDb",
"MovieFileMissingTooltip": "Archivo de película perdido",
"CutoffNotMet": "Umbrales no alcanzados",
"Dash": "Guion",
"ImportScriptPathHelpText": "La ruta al script a usar para importar",
"MovieFolderFormatHelpText": "Usado cuando se añade una nueva película o se mueven películas a través del editor de películas",
"Popular": "Popular",
"ShowTmdbRatingHelpText": "Mostrar valoraciones de TMDb debajo del póster",
"SearchMoviesOnAdd": "Buscar películas al añadir",
"ShowRottenTomatoesRatingHelpText": "Mostrar valoraciones de Tomato debajo del póster",
"ConditionUsingRegularExpressions": "Esta condición coincide usando expresiones regulares. Ten en cuenta que los caracteres `\\^$.|?*+()[{` tienen significados especiales y necesitan ser escapados con un `\\`",
"DelayProfileMovieTagsHelpText": "Se aplica a películas con al menos una etiqueta coincidente",
"ExistsInLibrary": "Existe en la biblioteca",
"Lists": "Listas",
"NotificationsTagsMovieHelpText": "Enviar notificaciones solo para películas con al menos una etiqueta coincidente",
"OnExcludedList": "En lista de excluidos",
"DownloadClientDownloadStationValidationFolderMissing": "La carpeta no existe",
"DownloadClientDownloadStationValidationFolderMissingDetail": "La carpeta '{downloadDir}' no existe, debe ser creada manualmente dentro de la carpeta compartida '{sharedFolder}'.",
"DownloadClientFloodSettingsPostImportTagsHelpText": "Añadir etiquetas una vez una descarga sea importada.",
"DownloadClientFreeboxAuthenticationError": "La autenticación a la API de Freebox falló. Motivo: {errorDescription}",
"DownloadClientFreeboxUnableToReachFreeboxApi": "No se pudo alcanzar la API de Freebox. Verifica la opción 'URL de la API' para la URL base y la versión.",
"DownloadClientNzbgetValidationKeepHistoryZeroDetail": "La configuración KeepHistory de NzbGet está establecida a 0. Esto evita que {appName} vea las descargas completadas.",
"Yes": "Sí",
"NotificationsGotifySettingIncludeMoviePoster": "Incluir póster de la película",
"NotificationsGotifySettingIncludeMoviePosterHelpText": "Incluye el póster de la película en el mensaje",
"DownloadClientFreeboxApiError": "La API de Freebox devolvió el error: {errorDescription}",
"DownloadClientQbittorrentValidationCategoryRecommendedDetail": "{appName} no intentará importar las descargas completadas sin una categoría.",
"DownloadClientQbittorrentValidationQueueingNotEnabled": "Encolado no habilitado",
"DownloadClientSabnzbdValidationCheckBeforeDownload": "Deshabilita la opción 'Verificar antes de descargar' en Sabnbzd",
"DownloadClientQbittorrentTorrentStatePathError": "No se pudo importar. La ruta coincide con el directorio de descarga base del cliente. ¿Es posible que 'Mantener carpeta de nivel superior' esté deshabilitado para este torrent o que 'Distribución de contenido de torrent' NO esté configurado a 'Original' o 'Crear subcarpeta'?",
"DownloadClientValidationUnknownException": "Excepción desconocida: {exception}",
"DownloadClientValidationVerifySsl": "Verificar opciones de SSL",
"DownloadClientVuzeValidationErrorVersion": "Versión de protocolo no soportada, usa Vuze 5.0.0.0 o superior con el plugin de web remota de Vuze.",
"NoMovieFilesToManage": "Ningún archivo de película para gestionar.",
"Underscore": "Guion bajo",
"AddDelayProfileError": "No se pudo añadir un nuevo perfil de retraso, por favor inténtalo de nuevo.",
"ChownGroup": "chown grupo",
"RegularExpressionsTutorialLink": "Más detalles de las expresiones regulares pueden ser encontrados [aquí](https://www.regular-expressions.info/tutorial.html)."
}

View File

@ -1,6 +1,6 @@
{
"IndexerStatusCheckAllClientMessage": "Tous les indexeurs sont indisponibles en raison d'échecs",
"IndexerSearchCheckNoInteractiveMessage": "Aucun indexeur n'est disponible avec la recherche interactive activée. {appName} ne fournira aucun résultat de recherche interactif.",
"IndexerSearchCheckNoInteractiveMessage": "Aucun indexeur n'est disponible avec la recherche interactive activée, {appName} ne fournira aucun résultat de recherche interactif",
"IndexerSearchCheckNoAvailableIndexersMessage": "Tous les indexeurs compatibles avec la recherche sont temporairement indisponibles en raison d'erreurs d'indexation récentes",
"IndexerSearchCheckNoAutomaticMessage": "Aucun indexeur disponible avec la recherche automatique activée, {appName} ne fournira aucun résultat de recherche automatique",
"Indexers": "Indexeurs",
@ -26,7 +26,7 @@
"Edit": "Modifier",
"Downloaded": "Téléchargé",
"DownloadClientStatusCheckAllClientMessage": "Aucun client de téléchargement n'est disponible en raison d'échecs",
"DownloadClients": "Clients de télécharg.",
"DownloadClients": "Clients de téléchargement",
"DownloadClientCheckNoneAvailableMessage": "Aucun client de téléchargement n'est disponible",
"Dates": "Dates",
"Date": "Date",
@ -141,7 +141,7 @@
"MountCheckMessage": "Le montage contenant un chemin de film est monté en lecture seule: ",
"MoreInfo": "Plus d'informations",
"Month": "Mois",
"ImportListsSettingsSummary": "Importer des Listes, exclure des listes",
"ImportListsSettingsSummary": "Importer depuis une autre instance {appName} ou des listes Trakt et gérer les exclusions de listes",
"ImportListExclusions": "Liste des exclusions",
"IndexersSettingsSummary": "Indexeurs et restrictions de version",
"Grabbed": "Saisie",
@ -188,7 +188,7 @@
"InCinemas": "Dans les cinémas",
"Imported": "Importé",
"Ignored": "Ignoré",
"GeneralSettingsSummary": "Port, SSL/TLS, nom d'utilisateur/mot de passe, proxy, analyses et mises à jour",
"GeneralSettingsSummary": "Port, SSL, nom d'utilisateur/mot de passe, proxy, analyses et mises à jour",
"Filename": "Nom de fichier",
"Failed": "Échoué",
"EventType": "Type d'événement",
@ -819,14 +819,14 @@
"ExcludeTitle": "Exclure {0} ? {appName} n'importera plus automatiquement ce film des listes de synchronisation.",
"FailedToLoadMovieFromAPI": "Erreur lors du chargement du film via l'API",
"FeatureRequests": "Requêtes de nouvelles fonctionnalités",
"FileNameTokens": "Tokens des noms de fichier",
"FileNameTokens": "Jetons de nom de fichier",
"FolderMoveRenameWarning": "Ceci va également renommer le dossier du film par le format de dossier défini dans les paramètres.",
"Images": "Images",
"IMDb": "IMDb",
"Hours": "Heures",
"HomePage": "Page d'accueil",
"HttpHttps": "HTTP(S)",
"ImportLibrary": "Importer biblio.",
"ImportLibrary": "Importation de bibliothèque",
"MovieIsRecommend": "Le film est recommandé en fonction de l'ajout récent",
"NoAltTitle": "Pas de titres alternatifs.",
"NoLinks": "Aucun liens",
@ -838,7 +838,7 @@
"UpgradesAllowed": "Mises à niveau autorisées",
"WhatsNew": "Quoi de neuf ?",
"InCinemasMsg": "Le film est dans les cinémas",
"Lowercase": "Minuscules",
"Lowercase": "Minuscule",
"ManualImportSelectMovie": "Importation manuelle - Sélectionnez un film",
"MappedDrivesRunningAsService": "Les lecteurs réseau mappés ne sont pas disponibles en fonctionnement en tant que service Windows. Veuillez consulter la FAQ pour plus d'informations",
"RequiredRestrictionHelpText": "La version doit contenir au moins un de ces termes (insensible à la casse)",
@ -856,7 +856,7 @@
"NoMoveFilesSelf": " Non, je vais déplacer les fichiers moi-même",
"None": "Aucun",
"NoResultsFound": "Aucun résultat trouvé",
"OnGrab": "À saisir",
"OnGrab": "Lors de la saisie",
"OnHealthIssue": "Sur la question de la santé",
"OnImport": "À l'importation",
"OnLatestVersion": "La dernière version de {appName} est déjà installée",
@ -872,7 +872,7 @@
"PreferUsenet": "Préférer Usenet",
"ReplaceWithDash": "Remplacer par un tiret",
"InCinemasDate": "Dans les cinémas Date",
"InstallLatest": "Installer le dernier",
"InstallLatest": "Installer la dernière",
"KeepAndUnmonitorMovie": "Conserver et annuler la surveillance du film",
"Large": "Grand",
"LastUsed": "Dernière utilisation",
@ -1110,7 +1110,7 @@
"DeleteImportListMessageText": "Êtes-vous sûr de vouloir supprimer la liste « {name} » ?",
"DeleteQualityProfileMessageText": "Êtes-vous sûr de vouloir supprimer le profil de qualité \"{name}\" ?",
"RemoveQueueItemConfirmation": "Êtes-vous sûr de vouloir retirer '{sourceTitle}' de la file d'attente ?",
"MoveAutomatically": "Se déplacer automatiquement",
"MoveAutomatically": "Importation automatique",
"AutoTaggingNegateHelpText": "Si cette case est cochée, la règle de marquage automatique ne s'appliquera pas si cette condition {implementationName} correspond.",
"AutoTaggingRequiredHelpText": "Cette condition {implementationName} doit correspondre pour que la règle de marquage automatique s'applique. Sinon, une seule correspondance {implementationName} suffit.",
"DeleteAutoTagHelpText": "Voulez-vous vraiment supprimer la balise automatique « {name} » ?",
@ -1182,7 +1182,7 @@
"Or": "ou",
"FormatAgeHours": "heures",
"Implementation": "Mise en œuvre",
"FormatTimeSpanDays": "{days}j {time}",
"FormatTimeSpanDays": "{days} j {time}",
"FormatAgeMinute": "minute",
"FormatAgeMinutes": "minutes",
"FormatDateTimeRelative": "{relativeDay}, {formattedDate} {formattedTime}",
@ -1199,7 +1199,7 @@
"OrganizeNothingToRename": "C'est fait ! Mon travail est terminé, plus aucun fichier à renommer.",
"False": "Faux",
"DefaultNameCopiedProfile": "{name} - Copier",
"IndexerDownloadClientHealthCheckMessage": "Indexeurs avec des clients de téléchargement invalides : {0].",
"IndexerDownloadClientHealthCheckMessage": "Indexeurs avec des clients de téléchargement invalides : {0}.",
"DeleteRootFolder": "Supprimer le dossier racine",
"SelectDownloadClientModalTitle": "{modalTitle} Sélectionnez le client de téléchargement",
"HistoryLoadError": "Impossible de charger l'historique",
@ -1283,7 +1283,7 @@
"CustomFormatJson": "Format personnalisé JSON",
"DeleteAutoTag": "Supprimer la balise automatique",
"MovieImportedTooltip": "Film téléchargé avec succès et récupéré à partir du client de téléchargement",
"DeletedReasonManual": "Le fichier a été supprimé via l'interface utilisateur",
"DeletedReasonManual": "Le fichier a été supprimé à l'aide de {appName}, soit manuellement, soit par un autre outil via l'API.",
"DownloadIgnored": "Téléchargement ignoré",
"EditAutoTag": "Modifier la balise automatique",
"OrganizeNamingPattern": "Modèle de nommage : `{standardMovieFormat}`",
@ -1468,7 +1468,7 @@
"NotificationsValidationUnableToSendTestMessage": "Impossible d'envoyer un message d'essai : {exceptionMessage}",
"NotificationsNtfySettingsAccessTokenHelpText": "Autorisation basée sur jeton facultative. A la priorité sur le couple nom d'utilisateur / mot de passe",
"NotificationsValidationInvalidUsernamePassword": "Nom d'utilisateur ou mot de passe invalides",
"NotificationsKodiSettingsUpdateLibraryHelpText": "Mettre à jour la bibliothèque dans Importer & Renommer ?",
"NotificationsKodiSettingsUpdateLibraryHelpText": "Mettre à jour la bibliothèque lors de l'importation et du renommage ?",
"NotificationsAppriseSettingsTagsHelpText": "Notifier facultativement uniquement ceux mentionnés.",
"NotificationsAppriseSettingsStatelessUrlsHelpText": "Une ou plusieurs URL séparées par des virgules identifiant où la notification doit être envoyée. Laisser vide si le stockage persistant est utilisé.",
"NotificationsValidationInvalidApiKey": "La clé d'API est invalide",
@ -1505,7 +1505,7 @@
"DoNotBlocklist": "Ne pas mettre sur liste noire",
"DoNotBlocklistHint": "Supprimer sans mettre sur liste noire",
"IgnoreDownload": "Ignorer le téléchargement",
"IndexerSettingsRejectBlocklistedTorrentHashes": "Rejeter les hachages de torrents bloqués lors de la saisie",
"IndexerSettingsRejectBlocklistedTorrentHashes": "Rejeter les hachages de torrent sur liste noir lors de la saisie",
"RemoveQueueItemRemovalMethod": "Méthode de suppression",
"RemoveMultipleFromDownloadClientHint": "Supprime les téléchargements et les fichiers du client de téléchargement",
"RemoveQueueItemRemovalMethodHelpTextWarning": "\"Supprimer du client de téléchargement\" supprimera le téléchargement et le(s) fichier(s) du client de téléchargement.",
@ -1527,7 +1527,7 @@
"ClickToChangeIndexerFlags": "Cliquez pour changer les drapeaux de l'indexeur",
"CustomFormatsSpecificationFlag": "Drapeau",
"DelayMinutes": "{delay} minutes",
"DelayProfileProtocol": "Protocole: {preferredProtocol}",
"DelayProfileProtocol": "Protocole : {preferredProtocol}",
"Donate": "Donation",
"AddListExclusion": "Ajouter une liste d'exclusion",
"AddReleaseProfile": "Ajouter un profil de version",
@ -1744,5 +1744,12 @@
"Lists": "Listes",
"DownloadClientRTorrentProviderMessage": "rTorrent ne mettra pas les torrents en pause lorsqu'ils répondent aux critères d'ensemencement. {appName} traitera la suppression automatique des torrents en fonction des critères d'ensemencement actuels dans Paramètres->Indexeurs uniquement lorsque l'option Supprimer terminé est activée. Après l'importation, il définira également {importedView} comme une vue rTorrent, qui peut être utilisée dans les scripts rTorrent pour personnaliser le comportement.",
"MediaInfoFootNote": "MediaInfo Full/AudioLanguages/SubtitleLanguages supporte un suffixe `:EN+DE` vous permettant de filtrer les langues incluses dans le nom de fichier. Utilisez `-DE` pour exclure des langues spécifiques. En ajoutant `+` (par exemple `:EN+`), vous obtiendrez `[EN]`/`[EN+--]`/`[--]` en fonction des langues exclues. Par exemple `{MediaInfo Full:EN+DE}`.",
"ReleaseProfileIndexerHelpTextWarning": "L'utilisation d'un indexeur spécifique avec des profils de version peut entraîner la saisie de publications en double."
"ReleaseProfileIndexerHelpTextWarning": "L'utilisation d'un indexeur spécifique avec des profils de version peut entraîner la saisie de publications en double.",
"IncludeHealthWarnings": "Inclure les avertissements de santé",
"CustomFormatsSettingsTriggerInfo": "Un format personnalisé sera appliqué à une version ou à un fichier lorsqu'il correspond à au moins un de chacun des différents types de conditions choisis.",
"AutoTaggingSpecificationTag": "Étiquette",
"NotificationsTelegramSettingsIncludeAppName": "Inclure {appName} dans le Titre",
"NotificationsTelegramSettingsIncludeAppNameHelpText": "Préfixer éventuellement le titre du message par {appName} pour différencier les notifications des différentes applications",
"IndexerSettingsMultiLanguageReleaseHelpText": "Quelles langues sont normalement présentes dans une version multiple de l'indexeur ?",
"IndexerSettingsMultiLanguageRelease": "Multilingue"
}

View File

@ -1087,5 +1087,6 @@
"AddImportListImplementation": "Aggiungi lista di importazione - {implementationName}",
"AutoRedownloadFailed": "Download fallito",
"AddAutoTagError": "Impossibile aggiungere un nuovo tag automatico, riprova.",
"AddDelayProfileError": "Impossibile aggiungere un nuovo profilo di ritardo, riprova."
"AddDelayProfileError": "Impossibile aggiungere un nuovo profilo di ritardo, riprova.",
"AddListExclusion": "Aggiungi elenco esclusioni"
}

View File

@ -22,7 +22,7 @@
"Indexers": "Indexadores",
"IndexerRssHealthCheckNoIndexers": "Nenhum indexador disponível com sincronização RSS habilitada, o {appName} não capturará novas versões automaticamente",
"IndexerRssHealthCheckNoAvailableIndexers": "Todos os indexadores compatíveis com rss estão temporariamente indisponíveis devido a erros recentes do indexador",
"IndexerPriorityHelpText": "Prioridade do indexador de 1 (maior) a 50 (menor). Padrão: 25. Usado quando obtendo lançamentos como um desempate para lançamentos iguais, o {appName} ainda usará todos os indexadores habilitados para Sync e pesquisa de RSS",
"IndexerPriorityHelpText": "Prioridade do indexador de 1 (mais alta) a 50 (mais baixa). Padrão: 25. Usado ao capturar lançamentos como desempate para lançamentos iguais, {appName} ainda usará todos os indexadores habilitados para sincronização e pesquisa de RSS",
"IndexerPriority": "Prioridade do indexador",
"IndexerLongTermStatusCheckSingleClientMessage": "Indexadores indisponíveis devido a falhas por mais de 6 horas: {indexerNames}",
"IndexerLongTermStatusCheckAllClientMessage": "Todos os indexadores estão indisponíveis devido a falhas por mais de 6 horas",
@ -1241,7 +1241,7 @@
"FullColorEventsHelpText": "Estilo alterado para colorir todo o evento com a cor do status, em vez de apenas a borda esquerda. Não se aplica à Programação",
"Unknown": "Desconhecido",
"UnknownEventTooltip": "Evento desconhecido",
"DeletedReasonManual": "O arquivo foi excluído por meio da interface",
"DeletedReasonManual": "O arquivo foi excluído usando {appName} manualmente ou por outra ferramenta por meio da API",
"FormatAgeDay": "dia",
"MovieDownloadFailedTooltip": "Falha no download do filme",
"MovieDownloadIgnoredTooltip": "Download do Filme Ignorado",
@ -1745,5 +1745,11 @@
"DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Local opcional para mover os downloads concluídos, deixe em branco para usar o local padrão do Deluge",
"ConnectionSettingsUrlBaseHelpText": "Adiciona um prefixo a URL {connectionName}, como {url}",
"ReleaseProfileIndexerHelpTextWarning": "Definir um indexador específico em um perfil de lançamento fará com que esse perfil seja aplicado apenas a lançamentos desse indexador.",
"IncludeHealthWarnings": "Incluir Alertas de Saúde"
"IncludeHealthWarnings": "Incluir Alertas de Saúde",
"CustomFormatsSettingsTriggerInfo": "Um formato personalizado será aplicado a um lançamento ou arquivo quando corresponder a pelo menos um de cada um dos diferentes tipos de condição escolhidos.",
"AutoTaggingSpecificationTag": "Etiqueta",
"NotificationsTelegramSettingsIncludeAppName": "Incluir {appName} no Título",
"NotificationsTelegramSettingsIncludeAppNameHelpText": "Opcionalmente, prefixe o título da mensagem com {appName} para diferenciar notificações de diferentes aplicativos",
"IndexerSettingsMultiLanguageReleaseHelpText": "Quais idiomas normalmente estão em um lançamento multi neste indexador?",
"IndexerSettingsMultiLanguageRelease": "Multi Idiomas"
}

View File

@ -149,14 +149,14 @@
"Failed": "Başarısız oldu",
"Edit": "Düzenle",
"Downloaded": "İndirildi",
"DownloadClientCheckUnableToCommunicateMessage": "{downloadClientName} ile iletişim kurulamıyor.",
"DownloadClientCheckUnableToCommunicateMessage": "{downloadClientName} ile iletişim kurulamıyor. {errorMessage}",
"DigitalRelease": "Dijital Yayın",
"DelayProfiles": "Gecikme Profilleri",
"CustomFilters": "Özel Filtreler",
"ConnectSettingsSummary": "Bildirimler, medya sunucularına/oynatıcılara bağlantılar ve özel komut dosyaları",
"CompletedDownloadHandling": "Tamamlanan İndirme İşlemleri",
"ChooseAnotherFolder": "Başka bir dosya seç",
"Analytics": "Analitik",
"Analytics": "Analiz",
"All": "Herşey",
"Agenda": "Ajanda",
"Added": "Eklendi",
@ -480,7 +480,7 @@
"OnlyUsenet": "Sadece Usenet",
"PendingChangesMessage": "Kaydedilmemiş değişiklikleriniz var, bu sayfadan ayrılmak istediğinizden emin misiniz?",
"ProxyType": "Proxy Türü",
"RegularExpressionsCanBeTested": "Normal ifadeler test edilebilir ",
"RegularExpressionsCanBeTested": "Normal ifadeler [burada](http://regexstorm.net/tester) test edilebilir.",
"ShowGenres": "Türleri Göster",
"UpgradesAllowed": "Yükseltmelere İzin Verildi",
"Pending": "Bekliyor",
@ -515,8 +515,8 @@
"AddingTag": "Etiket ekleniyor",
"Age": "Yaş",
"AgeWhenGrabbed": "Yaş (yakalandığında)",
"AnalyticsEnabledHelpText": "Anonim kullanım ve hata bilgilerini {appName} sunucularına gönderin. Bu, tarayıcınızla ilgili bilgileri, kullandığınız {appName} WebUI sayfalarını, hata raporlamasının yanı sıra işletim sistemi ve çalışma zamanı sürümünü içerir. Bu bilgileri, özellikleri ve hata düzeltmelerini önceliklendirmek için kullanacağız.",
"Apply": "Uygulamak",
"AnalyticsEnabledHelpText": "Anonim kullanım ve hata bilgilerini {appName} sunucularına gönderin. Bu, tarayıcınızla ilgili bilgileri, kullandığınız {appName} Web arayüz sayfalarını, hata raporlamasının yanı sıra işletim sistemi ve çalışma zamanı sürümünü içerir. Bu bilgileri, özellikleri ve hata düzeltmelerini önceliklendirmek için kullanacağız.",
"Apply": "Uygula",
"ICalShowAsAllDayEventsHelpText": "Etkinlikler, takviminizde tüm gün süren etkinlikler olarak görünecek",
"Authentication": "Doğrulama",
"ApplyTags": "Etiketleri Uygula",
@ -531,7 +531,7 @@
"BackupRetentionHelpText": "Saklama süresinden daha eski olan otomatik yedeklemeler otomatik olarak temizlenecektir",
"Backups": "Yedeklemeler",
"BeforeUpdate": "Güncellemeden önce",
"BindAddress": "Bağlama Adresi",
"BindAddress": "Bind Adresi",
"BindAddressHelpText": "Tüm arayüzler için geçerli IP adresi, localhost veya '*'",
"CertificateValidation": "Sertifika Doğrulama",
"CertificateValidationHelpText": "HTTPS sertifika doğrulamasının sıkılığını değiştirin. Riskleri anlamadığınız sürece değişmeyin.",
@ -624,7 +624,7 @@
"TotalFileSize": "Toplam Dosya Boyutu",
"TotalSpace": "Toplam alan",
"UpgradesAllowedHelpText": "Devre dışı bırakılırsa nitelikler yükseltilmez",
"Backup": "Destek olmak",
"Backup": "Yedek",
"Username": "Kullanıcı adı",
"WaitingToImport": "İçe Aktarma Bekleniyor",
"BackupFolderHelpText": "Göreli yollar {appName}'ın AppData dizini altında olacaktır",
@ -773,7 +773,7 @@
"IncludeRecommendationsHelpText": "{appName} tarafından önerilen filmleri keşif görünümüne dahil et",
"IncludeUnmonitored": "İzlenmeyenleri Dahil Et",
"ImportMovies": "Filmleri İçe Aktar",
"IndexerPriorityHelpText": "1 (En Yüksek) ila 50 (En Düşük) arasında Dizin Oluşturucu Önceliği. Varsayılan: 25.",
"IndexerPriorityHelpText": "Dizin Oluşturucu Önceliği (En Yüksek) 1'den (En Düşük) 50'ye kadar. Varsayılan: 25'dir. Eşit olmayan sürümler için eşitlik bozucu olarak sürümler alınırken kullanılan {appName}, RSS Senkronizasyonu ve Arama için etkinleştirilmiş tüm dizin oluşturucuları kullanmaya devam edecek",
"IndexerRssHealthCheckNoAvailableIndexers": "Yakın zamanda yapılan dizin oluşturucu hataları nedeniyle, rss özellikli tüm dizinleyiciler geçici olarak kullanılamıyor",
"IndexerRssHealthCheckNoIndexers": "RSS senkronizasyonunun etkin olduğu dizinleyici yok, {appName} yeni sürümleri otomatik olarak almayacak",
"Indexers": "Dizin oluşturucular",
@ -878,7 +878,7 @@
"RenameMovies": "Filmleri Yeniden Adlandır",
"RenameMoviesHelpText": "Yeniden adlandırma devre dışı bırakılırsa, {appName} mevcut dosya adını kullanacaktır",
"ReplaceIllegalCharacters": "Yasadışı Karakterleri Değiştirin",
"ReplaceIllegalCharactersHelpText": "Geçersiz karakterleri değiştirin. İşaretli değilse, {appName} onları kaldıracaktır.",
"ReplaceIllegalCharactersHelpText": "Geçersiz karakterleri değiştirin. İşaretlenmezse bunun yerine {appName} bunları kaldıracak",
"ReplaceWithSpaceDash": "Space Dash ile değiştirin",
"Required": "gereklidir",
"RequiredRestrictionHelpText": "Sürüm, bu terimlerden en az birini içermelidir (büyük / küçük harfe duyarlı değildir)",
@ -964,7 +964,7 @@
"BlocklistRelease": "Kara Liste Yayını",
"RemoveFromBlocklist": "Kara listeden kaldır",
"Blocklisted": "Kara liste",
"BlocklistReleases": "Kara Liste Yayını",
"BlocklistReleases": "Kara Liste Sürümü",
"ImportList": "Listeler",
"Filters": "Filtre",
"Rating": "Puanlar",
@ -973,7 +973,7 @@
"AllCollectionsHiddenDueToFilter": "Uygulanan filtre nedeniyle tüm filmler gizlendi.",
"Collections": "Koleksiyon",
"MonitorMovies": "Filmi İzle",
"NoCollections": "Film bulunamadı, başlamak için yeni bir film eklemek veya mevcut filmlerden bazılarını içe aktarmak isteyeceksiniz.",
"NoCollections": "Koleksiyon bulunamadı. Başlamak için yeni bir film eklemek veya mevcut filmlerden bazılarını içe aktarmak isteyebilirsiniz",
"File": "Dosyalar",
"ShowCinemaReleaseHelpText": "Posterin altında çıkış tarihini göster",
"EditMovies": "Filmi Düzenle",
@ -1028,7 +1028,7 @@
"ChangeCategoryMultipleHint": "İndirme istemcisinden indirmeleri 'İçe Aktarma Sonrası Kategorisi' olarak değiştirir",
"CollectionShowPostersHelpText": "Koleksiyon öğesi posterlerini göster",
"CloneCondition": "Klon Durumu",
"ApiKeyValidationHealthCheckMessage": "Lütfen API anahtarınızı en az {length} karakter uzunluğunda olacak şekilde güncelleyin. Bunu ayarlar veya yapılandırma dosyası aracılığıyla yapabilirsiniz",
"ApiKeyValidationHealthCheckMessage": "Lütfen API anahtarınızı en az {length} karakter sayısı kadar güncelleyiniz. Bunu ayarlar veya yapılandırma dosyası üzerinden yapabilirsiniz",
"AutoRedownloadFailed": "Yeniden İndirme Başarısız",
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Yeni şifreyi onayla",
"BypassDelayIfAboveCustomFormatScoreMinimumScore": "Minimum Özel Format Puanı",
@ -1074,5 +1074,93 @@
"ChownGroup": "Chown Grubu",
"AutoTaggingLoadError": "Otomatik etiketleme yüklenemiyor",
"ConditionUsingRegularExpressions": "Bu koşul Normal İfadeler kullanılarak eşleşir. `\\^$.|?*+()[{` karakterlerinin özel anlamlara sahip olduğunu ve `\\` ile kaçılması gerektiğini unutmayın",
"ConnectionLostReconnect": "{appName} otomatik bağlanmayı deneyecek veya aşağıda yeniden yükle seçeneğini işaretleyebilirsiniz."
"ConnectionLostReconnect": "{appName} otomatik bağlanmayı deneyecek veya aşağıda yeniden yükle seçeneğini işaretleyebilirsiniz.",
"DefaultNameCopiedProfile": "{name} - Kopyala",
"DelayingDownloadUntil": "İndirme işlemi {date} tarihine, {time} tarihine kadar erteleniyor",
"DeleteDelayProfileMessageText": "Bu gecikme profilini silmek istediğinizden emin misiniz?",
"DeleteImportListMessageText": "'{name}' listesini silmek istediğinizden emin misiniz?",
"DeleteQualityProfileMessageText": "'{name}' kalite profilini silmek istediğinizden emin misiniz?",
"DeleteSelectedImportListsMessageText": "Seçilen {count} içe aktarma listesini silmek istediğinizden emin misiniz?",
"DeleteSelectedImportLists": "İçe Aktarma Listelerini Sil",
"DeleteSelectedMovieFilesHelpText": "Seçilen film dosyalarını silmek istediğinizden emin misiniz?",
"DeletedReasonUpgrade": "Bir yükseltmeyi içe aktarmak için dosya silindi",
"AutoTaggingSpecificationTag": "Etiket",
"CustomFormatsSettingsTriggerInfo": "Bir yayına veya dosyaya, seçilen farklı koşul türlerinden en az biriyle eşleştiğinde Özel Format uygulanacaktır.",
"CutoffNotMet": "Kesim Noktasına Ulaşılmadı",
"Default": "Varsayılan",
"Dash": "Çizgi",
"DefaultNameCopiedSpecification": "{name} - Kopyala",
"DeleteAutoTag": "Etiketi Otomatik Sil",
"DeleteCondition": "Koşulu Sil",
"Directory": "Rehber",
"Donate": "Bağış yap",
"DeleteImportListExclusionMessageText": "Bu içe aktarma listesi hariç tutma işlemini silmek istediğinizden emin misiniz?",
"DoNotBlocklist": "Engelleme Listesine Eklemeyin",
"DiscordUrlInSlackNotification": "Slack bildirimi olarak bir Discord bildirim kurulumunuz var. Daha iyi işlevsellik için bunu bir Discord bildirimi olarak ayarlayın. Etkilenen bildirimler şunlardır: {0}",
"DoNotBlocklistHint": "Engellenenler listesine eklemeden kaldır",
"Database": "Veri tabanı",
"DownloadClientDelugeSettingsUrlBaseHelpText": "Deluge json URL'sine bir önek ekler, bkz. {url}",
"DownloadClientDelugeValidationLabelPluginFailure": "Etiket yapılandırılması başarısız oldu",
"DownloadClientDownloadStationProviderMessage": "DSM hesabınızda 2 Faktörlü Kimlik Doğrulama etkinleştirilmişse {appName}, Download Station'a bağlanamaz",
"DownloadClientFloodSettingsAddPaused": "Duraklatma Ekle",
"DownloadClientFloodSettingsPostImportTags": "İçe Aktarma Sonrası Etiketler",
"DownloadClientFloodSettingsPostImportTagsHelpText": "İndirmelere içe aktarıldıktan sonra etiket ekler.",
"DownloadClientFloodSettingsStartOnAdd": "Eklemeye Başla",
"DownloadClientFloodSettingsUrlBaseHelpText": "Flood API'sine {url} gibi bir önek ekler",
"DownloadClientFreeboxApiError": "Freebox API'si şu hatayı döndürdü: {errorDescription}",
"DownloadClientFreeboxSettingsPortHelpText": "Freebox arayüzüne erişim için kullanılan bağlantı noktası, varsayılan olarak '{port}' şeklindedir",
"DeleteAutoTagHelpText": "'{name}' etiketini otomatik silmek istediğinizden emin misiniz?",
"DeleteCustomFormatMessageText": "'{name}' özel biçimini silmek istediğinizden emin misiniz?",
"DeleteImportList": "İçe Aktarma Listesini Sil",
"DeleteRootFolder": "Kök Klasörü Sil",
"DeleteSelectedIndexers": "Dizin Oluşturucuları Sil",
"DisabledForLocalAddresses": "Yerel Adresler için Devre Dışı Bırakıldı",
"DeleteRootFolderMessageText": "'{path}' kök klasörünü silmek istediğinizden emin misiniz?",
"DeleteSelectedIndexersMessageText": "Seçilen {count} dizin oluşturucuyu silmek istediğinizden emin misiniz?",
"Destination": "Hedef",
"DeletedReasonMissingFromDisk": "{appName} dosyayı diskte bulamadığından dosyanın veritabanındaki filmle bağlantısı kaldırıldı",
"DownloadClientDelugeTorrentStateError": "Deluge bir hata bildiriyor",
"DownloadClientDelugeValidationLabelPluginInactive": "Etiket eklentisi etkinleştirilmedi",
"DownloadClientDelugeValidationLabelPluginInactiveDetail": "Kategorileri kullanmak için {clientName} uygulamasında Etiket eklentisini etkinleştirmiş olmanız gerekir.",
"DownloadClientDownloadStationValidationApiVersion": "Download Station API sürümü desteklenmiyor; en az {requiredVersion} olmalıdır. {minVersion}'dan {maxVersion}'a kadar destekler",
"DownloadClientDownloadStationValidationSharedFolderMissingDetail": "Diskstation'da '{sharedFolder}' adında bir Paylaşımlı Klasör yok, bunu doğru belirttiğinizden emin misiniz?",
"DownloadClientFloodSettingsRemovalInfo": "{appName}, Ayarlar -> Dizin Oluşturucular'daki mevcut tohum kriterlerine göre torrentlerin otomatik olarak kaldırılmasını gerçekleştirecek",
"DownloadClientFloodSettingsTagsHelpText": "Bir indirme işleminin başlangıç etiketleri. Bir indirmenin tanınabilmesi için tüm başlangıç etiketlerine sahip olması gerekir. Bu, ilgisiz indirmelerle çakışmaları önler.",
"DownloadClientFreeboxUnableToReachFreebox": "Freebox API'sine ulaşılamıyor. 'Ana Bilgisayar', 'Bağlantı Noktası' veya 'SSL Kullan' ayarlarını doğrulayın. (Hata: {istisnaMessage})",
"DownloadClientAriaSettingsDirectoryHelpText": "İndirilenlerin yerleştirileceği isteğe bağlı konum, varsayılan Aria2 konumunu kullanmak için boş bırakın",
"DownloadClientDownloadStationValidationFolderMissing": "Klasör mevcut değil",
"DownloadClientDownloadStationValidationSharedFolderMissing": "Paylaşılan klasör mevcut değil",
"DeleteReleaseProfile": "Sürüm Profilini Sil",
"DeleteReleaseProfileMessageText": "'{name}' bu sürüm profilini silmek istediğinizden emin misiniz?",
"DelayMinutes": "{delay} Dakika",
"DelayProfileMovieTagsHelpText": "En az bir eşleşen etiketli filmlere uygulanır",
"DelayProfileProtocol": "Protokol: {preferredProtocol}",
"DeleteSpecificationHelpText": "'{name}' spesifikasyonunu silmek istediğinizden emin misiniz?",
"DownloadClientDownloadStationValidationFolderMissingDetail": "'{downloadDir}' klasörü mevcut değil, '{sharedFolder}' Paylaşımlı Klasöründe manuel olarak oluşturulması gerekiyor.",
"DownloadClientDownloadStationSettingsDirectoryHelpText": "İndirilenlerin yerleştirileceği isteğe bağlı paylaşımlı klasör, varsayılan Download Station konumunu kullanmak için boş bırakın",
"DeleteConditionMessageText": "'{name}' koşulunu silmek istediğinizden emin misiniz?",
"DeleteFormatMessageText": "{0} biçim etiketini silmek istediğinizden emin misiniz?",
"DeleteSelectedDownloadClients": "İndirme İstemcilerini Sil",
"DeleteSelectedDownloadClientsMessageText": "Seçilen {count} indirme istemcisini silmek istediğinizden emin misiniz?",
"DeletedReasonManual": "Dosya, {appName} kullanılarak manuel olarak veya API aracılığıyla başka bir araçla silindi",
"DownloadClientDownloadStationValidationNoDefaultDestination": "Varsayılan hedef yok",
"DownloadClientDownloadStationValidationNoDefaultDestinationDetail": "Diskstation'ınızda {username} olarak oturum açmalı ve BT/HTTP/FTP/NZB -> Konum altında DownloadStation ayarlarında manuel olarak ayarlamalısınız.",
"DownloadClientDelugeSettingsDirectory": "İndirme Dizini",
"DownloadClientDelugeSettingsDirectoryCompleted": "Tamamlandığında Dizini Taşı",
"DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Tamamlanan indirmelerin taşınacağı isteğe bağlı konum; varsayılan Deluge konumunu kullanmak için boş bırakın",
"DownloadClientDelugeSettingsDirectoryHelpText": "İndirilenlerin yerleştirileceği isteğe bağlı konum; varsayılan Deluge konumunu kullanmak için boş bırakın",
"DownloadClientFloodSettingsAdditionalTags": "Ek Etiketler",
"DownloadClientFloodSettingsAdditionalTagsHelpText": "Medyanın özelliklerini etiket olarak ekler. İpuçları örnektir.",
"ConnectionSettingsUrlBaseHelpText": "{connectionName} URL'sine {url} gibi bir önek ekler",
"DeleteSpecification": "Spesifikasyonu Sil",
"DownloadClientDelugeValidationLabelPluginFailureDetail": "{appName}, etiketi {clientName} uygulamasına ekleyemedi.",
"DownloadClientFreeboxSettingsAppId": "Uygulama kimliği",
"DownloadClientFreeboxSettingsApiUrl": "API URL'si",
"DownloadClientFreeboxSettingsAppToken": "Uygulama Token'ı",
"DownloadClientFreeboxSettingsHostHelpText": "Freebox'un ana bilgisayar adı veya ana bilgisayar IP adresi, varsayılan olarak '{url}' şeklindedir (yalnızca aynı ağdaysa çalışır)",
"DownloadClientFreeboxAuthenticationError": "Freebox API'sinde kimlik doğrulama başarısız oldu. Sebep: {errorDescription}",
"DownloadClientFreeboxNotLoggedIn": "Giriş yapmadınız",
"DownloadClientFreeboxSettingsApiUrlHelpText": "Freebox API temel URL'sini API sürümüyle tanımlayın, örneğin '{url}', varsayılan olarak '{defaultApiUrl}' olur",
"DownloadClientFreeboxSettingsAppIdHelpText": "Freebox API'sine erişim oluşturulurken verilen uygulama kimliği (ör. 'app_id')",
"DownloadClientFreeboxSettingsAppTokenHelpText": "Freebox API'sine erişim oluşturulurken alınan uygulama jetonu (ör. 'app_token')"
}

View File

@ -20,54 +20,74 @@ namespace NzbDrone.Core.Notifications.Telegram
public override void OnGrab(GrabMessage grabMessage)
{
_proxy.SendNotification(MOVIE_GRABBED_TITLE_BRANDED, grabMessage.Message, Settings);
var title = Settings.IncludeAppNameInTitle ? MOVIE_GRABBED_TITLE_BRANDED : MOVIE_GRABBED_TITLE;
_proxy.SendNotification(title, grabMessage.Message, Settings);
}
public override void OnDownload(DownloadMessage message)
{
if (message.OldMovieFiles.Any())
{
_proxy.SendNotification(MOVIE_UPGRADED_TITLE_BRANDED, message.Message, Settings);
var title = Settings.IncludeAppNameInTitle ? MOVIE_UPGRADED_TITLE_BRANDED : MOVIE_UPGRADED_TITLE;
_proxy.SendNotification(title, message.Message, Settings);
}
else
{
_proxy.SendNotification(MOVIE_DOWNLOADED_TITLE_BRANDED, message.Message, Settings);
var title = Settings.IncludeAppNameInTitle ? MOVIE_DOWNLOADED_TITLE_BRANDED : MOVIE_DOWNLOADED_TITLE;
_proxy.SendNotification(title, message.Message, Settings);
}
}
public override void OnMovieAdded(Movie movie)
{
_proxy.SendNotification(MOVIE_ADDED_TITLE_BRANDED, $"{movie.Title} added to library", Settings);
var title = Settings.IncludeAppNameInTitle ? MOVIE_ADDED_TITLE_BRANDED : MOVIE_ADDED_TITLE;
_proxy.SendNotification(title, $"{movie.Title} added to library", Settings);
}
public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage)
{
_proxy.SendNotification(MOVIE_FILE_DELETED_TITLE_BRANDED, deleteMessage.Message, Settings);
var title = Settings.IncludeAppNameInTitle ? MOVIE_FILE_DELETED_TITLE_BRANDED : MOVIE_FILE_DELETED_TITLE;
_proxy.SendNotification(title, deleteMessage.Message, Settings);
}
public override void OnMovieDelete(MovieDeleteMessage deleteMessage)
{
_proxy.SendNotification(MOVIE_DELETED_TITLE_BRANDED, deleteMessage.Message, Settings);
var title = Settings.IncludeAppNameInTitle ? MOVIE_DELETED_TITLE_BRANDED : MOVIE_DELETED_TITLE;
_proxy.SendNotification(title, deleteMessage.Message, Settings);
}
public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck)
{
_proxy.SendNotification(HEALTH_ISSUE_TITLE_BRANDED, healthCheck.Message, Settings);
var title = Settings.IncludeAppNameInTitle ? HEALTH_ISSUE_TITLE_BRANDED : HEALTH_ISSUE_TITLE;
_proxy.SendNotification(title, healthCheck.Message, Settings);
}
public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck)
{
_proxy.SendNotification(HEALTH_RESTORED_TITLE_BRANDED, $"The following issue is now resolved: {previousCheck.Message}", Settings);
var title = Settings.IncludeAppNameInTitle ? HEALTH_RESTORED_TITLE_BRANDED : HEALTH_RESTORED_TITLE;
_proxy.SendNotification(title, $"The following issue is now resolved: {previousCheck.Message}", Settings);
}
public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage)
{
_proxy.SendNotification(APPLICATION_UPDATE_TITLE_BRANDED, updateMessage.Message, Settings);
var title = Settings.IncludeAppNameInTitle ? APPLICATION_UPDATE_TITLE_BRANDED : APPLICATION_UPDATE_TITLE;
_proxy.SendNotification(title, updateMessage.Message, Settings);
}
public override void OnManualInteractionRequired(ManualInteractionRequiredMessage message)
{
_proxy.SendNotification(MANUAL_INTERACTION_REQUIRED_TITLE_BRANDED, message.Message, Settings);
var title = Settings.IncludeAppNameInTitle ? MANUAL_INTERACTION_REQUIRED_TITLE_BRANDED : MANUAL_INTERACTION_REQUIRED_TITLE;
_proxy.SendNotification(title, message.Message, Settings);
}
public override ValidationResult Test()

View File

@ -53,10 +53,11 @@ namespace NzbDrone.Core.Notifications.Telegram
{
try
{
const string brandedTitle = "Radarr - Test Notification";
const string title = "Test Notification";
const string body = "This is a test message from Radarr";
SendNotification(title, body, settings);
SendNotification(settings.IncludeAppNameInTitle ? brandedTitle : title, body, settings);
}
catch (Exception ex)
{

View File

@ -32,6 +32,9 @@ namespace NzbDrone.Core.Notifications.Telegram
[FieldDefinition(3, Label = "NotificationsTelegramSettingsSendSilently", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsSendSilentlyHelpText")]
public bool SendSilently { get; set; }
[FieldDefinition(4, Label = "NotificationsTelegramSettingsIncludeAppName", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsIncludeAppNameHelpText")]
public bool IncludeAppNameInTitle { get; set; }
public NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));

View File

@ -39,7 +39,7 @@ namespace NzbDrone.Core.Organizer
private readonly ICustomFormatCalculationService _formatCalculator;
private readonly Logger _logger;
private static readonly Regex TitleRegex = new Regex(@"(?<tag>\{(?:imdb-|edition-))?\{(?<prefix>[- ._\[(]*)(?<token>(?:[a-z0-9]+)(?:(?<separator>[- ._]+)(?:[a-z0-9]+))?)(?::(?<customFormat>[a-z0-9|+-]+(?<!-)))?(?<suffix>[-} ._)\]]*)\}",
private static readonly Regex TitleRegex = new Regex(@"(?<tag>\{(?:imdb-|edition-))?\{(?<prefix>[- ._\[(]*)(?<token>(?:[a-z0-9]+)(?:(?<separator>[- ._]+)(?:[a-z0-9]+))?)(?::(?<customFormat>[ ,a-z0-9|+-]+(?<![- ])))?(?<suffix>[-} ._)\]]*)\}",
RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
public static readonly Regex MovieTitleRegex = new Regex(@"(?<token>\{((?:(Movie|Original))(?<separator>[- ._])(Clean)?(Original)?(Title|Filename)(The)?)(?::(?<customFormat>[a-z0-9|-]+))?\})",
@ -414,7 +414,39 @@ namespace NzbDrone.Core.Organizer
customFormats = _formatCalculator.ParseCustomFormat(movieFile, movie);
}
tokenHandlers["{Custom Formats}"] = m => string.Join(" ", customFormats.Where(x => x.IncludeCustomFormatWhenRenaming));
tokenHandlers["{Custom Formats}"] = m => GetCustomFormatsToken(customFormats, m.CustomFormat);
tokenHandlers["{Custom Format}"] = m =>
{
if (m.CustomFormat.IsNullOrWhiteSpace())
{
return string.Empty;
}
return customFormats.FirstOrDefault(x => x.IncludeCustomFormatWhenRenaming && x.Name == m.CustomFormat)?.ToString() ?? string.Empty;
};
}
private string GetCustomFormatsToken(List<CustomFormat> customFormats, string filter)
{
var tokens = customFormats.Where(x => x.IncludeCustomFormatWhenRenaming).ToList();
var filteredTokens = tokens;
if (filter.IsNotNullOrWhiteSpace())
{
if (filter.StartsWith("-"))
{
var splitFilter = filter.Substring(1).Split(',');
filteredTokens = tokens.Where(c => !splitFilter.Contains(c.Name)).ToList();
}
else
{
var splitFilter = filter.Split(',');
filteredTokens = tokens.Where(c => splitFilter.Contains(c.Name)).ToList();
}
}
return string.Join(" ", filteredTokens);
}
private string GetLanguagesToken(List<string> mediaInfoLanguages, string filter, bool skipEnglishOnly, bool quoted)

View File

@ -3,7 +3,7 @@
<TargetFrameworks>net6.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.143" />
<PackageReference Include="Dapper" Version="2.0.151" />
<PackageReference Include="Diacritical.Net" Version="1.0.4" />
<PackageReference Include="Equ" Version="2.3.0" />
<PackageReference Include="MailKit" Version="3.6.0" />
@ -13,14 +13,14 @@
<PackageReference Include="Servarr.FFprobe" Version="5.1.4.112" />
<PackageReference Include="System.Memory" Version="4.5.5" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="6.0.21" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="6.0.29" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
<PackageReference Include="Servarr.FluentMigrator.Runner" Version="3.3.2.9" />
<PackageReference Include="Servarr.FluentMigrator.Runner.SQLite" Version="3.3.2.9" />
<PackageReference Include="Servarr.FluentMigrator.Runner.Postgres" Version="3.3.2.9" />
<PackageReference Include="FluentValidation" Version="9.5.4" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.3" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="5.2.3" />
<PackageReference Include="System.Data.SQLite.Core.Servarr" Version="1.0.115.5-18" />

View File

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.AutoTagging;
using NzbDrone.Core.AutoTagging.Specifications;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Download;
using NzbDrone.Core.ImportLists;
@ -120,7 +121,7 @@ namespace NzbDrone.Core.Tags
var releaseProfiles = _releaseProfileService.All();
var movies = _movieService.AllMovieTags();
var indexers = _indexerService.All();
var autotags = _autoTaggingService.All();
var autoTags = _autoTaggingService.All();
var downloadClients = _downloadClientFactory.All();
var details = new List<TagDetails>();
@ -137,7 +138,7 @@ namespace NzbDrone.Core.Tags
ReleaseProfileIds = releaseProfiles.Where(c => c.Tags.Contains(tag.Id)).Select(c => c.Id).ToList(),
MovieIds = movies.Where(c => c.Value.Contains(tag.Id)).Select(c => c.Key).ToList(),
IndexerIds = indexers.Where(c => c.Tags.Contains(tag.Id)).Select(c => c.Id).ToList(),
AutoTagIds = autotags.Where(c => c.Tags.Contains(tag.Id)).Select(c => c.Id).ToList(),
AutoTagIds = GetAutoTagIds(tag, autoTags),
DownloadClientIds = downloadClients.Where(c => c.Tags.Contains(tag.Id)).Select(c => c.Id).ToList(),
});
}
@ -188,5 +189,23 @@ namespace NzbDrone.Core.Tags
_repo.Delete(tagId);
_eventAggregator.PublishEvent(new TagsUpdatedEvent());
}
private List<int> GetAutoTagIds(Tag tag, List<AutoTag> autoTags)
{
var autoTagIds = autoTags.Where(c => c.Tags.Contains(tag.Id)).Select(c => c.Id).ToList();
foreach (var autoTag in autoTags)
{
foreach (var specification in autoTag.Specifications)
{
if (specification is TagSpecification)
{
autoTagIds.Add(autoTag.Id);
}
}
}
return autoTagIds.Distinct().ToList();
}
}
}

View File

@ -4,7 +4,7 @@
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="6.0.25" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="6.0.29" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NzbDrone.Test.Common\Radarr.Test.Common.csproj" />

View File

@ -6,15 +6,16 @@ namespace NzbDrone.Mono.Disk
{
public static class FindDriveType
{
private static readonly Dictionary<string, DriveType> DriveTypeMap = new Dictionary<string, DriveType>
{
{ "afpfs", DriveType.Network },
{ "apfs", DriveType.Fixed },
{ "fuse.mergerfs", DriveType.Fixed },
{ "fuse.glusterfs", DriveType.Network },
{ "nullfs", DriveType.Fixed },
{ "zfs", DriveType.Fixed }
};
private static readonly Dictionary<string, DriveType> DriveTypeMap = new ()
{
{ "afpfs", DriveType.Network },
{ "apfs", DriveType.Fixed },
{ "fuse.mergerfs", DriveType.Fixed },
{ "fuse.shfs", DriveType.Fixed },
{ "fuse.glusterfs", DriveType.Network },
{ "nullfs", DriveType.Fixed },
{ "zfs", DriveType.Fixed }
};
public static DriveType Find(string driveFormat)
{

View File

@ -7,7 +7,7 @@
<PackageReference Include="FluentValidation" Version="9.5.4" />
<PackageReference Include="Moq" Version="4.16.1" />
<PackageReference Include="NLog" Version="5.2.3" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="RestSharp" Version="106.15.0" />
</ItemGroup>
<ItemGroup>

View File

@ -48,6 +48,7 @@ namespace Radarr.Api.V3
}
[HttpGet]
[Produces("application/json")]
public List<TProviderResource> GetAll()
{
var providerDefinitions = _providerFactory.All();
@ -165,6 +166,7 @@ namespace Radarr.Api.V3
public object DeleteProvider(int id)
{
_providerFactory.Delete(id);
return new { };
}
@ -178,6 +180,7 @@ namespace Radarr.Api.V3
}
[HttpGet("schema")]
[Produces("application/json")]
public List<TProviderResource> GetTemplates()
{
var defaultDefinitions = _providerFactory.GetDefaultDefinitions().OrderBy(p => p.ImplementationName).ToList();
@ -201,10 +204,11 @@ namespace Radarr.Api.V3
[SkipValidation(true, false)]
[HttpPost("test")]
public object Test([FromBody] TProviderResource providerResource)
[Consumes("application/json")]
public object Test([FromBody] TProviderResource providerResource, [FromQuery] bool forceTest = false)
{
var existingDefinition = providerResource.Id > 0 ? _providerFactory.Find(providerResource.Id) : null;
var providerDefinition = GetDefinition(providerResource, existingDefinition, true, true, true);
var providerDefinition = GetDefinition(providerResource, existingDefinition, true, !forceTest, true);
Test(providerDefinition, true);
@ -222,12 +226,15 @@ namespace Radarr.Api.V3
foreach (var definition in providerDefinitions)
{
var validationResult = _providerFactory.Test(definition);
var validationFailures = new List<ValidationFailure>();
validationFailures.AddRange(definition.Settings.Validate().Errors);
validationFailures.AddRange(_providerFactory.Test(definition).Errors);
result.Add(new ProviderTestAllResult
{
Id = definition.Id,
ValidationFailures = validationResult.Errors.ToList()
ValidationFailures = validationFailures
});
}

View File

@ -1802,14 +1802,6 @@
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DownloadClientResource"
}
}
},
"application/json": {
"schema": {
"type": "array",
@ -1817,14 +1809,6 @@
"$ref": "#/components/schemas/DownloadClientResource"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DownloadClientResource"
}
}
}
}
}
@ -2028,14 +2012,6 @@
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DownloadClientResource"
}
}
},
"application/json": {
"schema": {
"type": "array",
@ -2043,14 +2019,6 @@
"$ref": "#/components/schemas/DownloadClientResource"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DownloadClientResource"
}
}
}
}
}
@ -2062,22 +2030,22 @@
"tags": [
"DownloadClient"
],
"parameters": [
{
"name": "forceTest",
"in": "query",
"schema": {
"type": "boolean",
"default": false
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DownloadClientResource"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/DownloadClientResource"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/DownloadClientResource"
}
}
}
},
@ -3044,14 +3012,6 @@
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ImportListResource"
}
}
},
"application/json": {
"schema": {
"type": "array",
@ -3059,14 +3019,6 @@
"$ref": "#/components/schemas/ImportListResource"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ImportListResource"
}
}
}
}
}
@ -3270,14 +3222,6 @@
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ImportListResource"
}
}
},
"application/json": {
"schema": {
"type": "array",
@ -3285,14 +3229,6 @@
"$ref": "#/components/schemas/ImportListResource"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ImportListResource"
}
}
}
}
}
@ -3304,22 +3240,22 @@
"tags": [
"ImportList"
],
"parameters": [
{
"name": "forceTest",
"in": "query",
"schema": {
"type": "boolean",
"default": false
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ImportListResource"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/ImportListResource"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/ImportListResource"
}
}
}
},
@ -3563,14 +3499,6 @@
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IndexerResource"
}
}
},
"application/json": {
"schema": {
"type": "array",
@ -3578,14 +3506,6 @@
"$ref": "#/components/schemas/IndexerResource"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IndexerResource"
}
}
}
}
}
@ -3789,14 +3709,6 @@
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IndexerResource"
}
}
},
"application/json": {
"schema": {
"type": "array",
@ -3804,14 +3716,6 @@
"$ref": "#/components/schemas/IndexerResource"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/IndexerResource"
}
}
}
}
}
@ -3823,22 +3727,22 @@
"tags": [
"Indexer"
],
"parameters": [
{
"name": "forceTest",
"in": "query",
"schema": {
"type": "boolean",
"default": false
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/IndexerResource"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/IndexerResource"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/IndexerResource"
}
}
}
},
@ -4504,14 +4408,6 @@
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MetadataResource"
}
}
},
"application/json": {
"schema": {
"type": "array",
@ -4519,14 +4415,6 @@
"$ref": "#/components/schemas/MetadataResource"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MetadataResource"
}
}
}
}
}
@ -4683,14 +4571,6 @@
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MetadataResource"
}
}
},
"application/json": {
"schema": {
"type": "array",
@ -4698,14 +4578,6 @@
"$ref": "#/components/schemas/MetadataResource"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MetadataResource"
}
}
}
}
}
@ -4717,22 +4589,22 @@
"tags": [
"Metadata"
],
"parameters": [
{
"name": "forceTest",
"in": "query",
"schema": {
"type": "boolean",
"default": false
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MetadataResource"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/MetadataResource"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/MetadataResource"
}
}
}
},
@ -5771,14 +5643,6 @@
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NotificationResource"
}
}
},
"application/json": {
"schema": {
"type": "array",
@ -5786,14 +5650,6 @@
"$ref": "#/components/schemas/NotificationResource"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NotificationResource"
}
}
}
}
}
@ -5950,14 +5806,6 @@
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NotificationResource"
}
}
},
"application/json": {
"schema": {
"type": "array",
@ -5965,14 +5813,6 @@
"$ref": "#/components/schemas/NotificationResource"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NotificationResource"
}
}
}
}
}
@ -5984,22 +5824,22 @@
"tags": [
"Notification"
],
"parameters": [
{
"name": "forceTest",
"in": "query",
"schema": {
"type": "boolean",
"default": false
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NotificationResource"
}
},
"text/json": {
"schema": {
"$ref": "#/components/schemas/NotificationResource"
}
},
"application/*+json": {
"schema": {
"$ref": "#/components/schemas/NotificationResource"
}
}
}
},

3322
yarn.lock

File diff suppressed because it is too large Load Diff