1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-03-05 13:20:20 -05:00

Compare commits

...

57 Commits

Author SHA1 Message Date
Stevie Robinson
028d2414e7 Fixed: Plexmatch special episode numbers
Closes #8270
2025-12-22 12:28:23 -08:00
Stevie Robinson
cbd7df2c91 Fixed: Multiple XML declarations in kodi/xmbc episodes metadata
Closes #8242
2025-12-22 12:14:12 -08:00
Mark McDowall
52972e7efc Add private IPv6 networks 2025-11-03 07:35:36 -08:00
Mark McDowall
8c50919499 Bump version to 4.0.16 2025-10-28 15:53:41 -07:00
Polgonite
fdc07a47b1 Fixed: qBittorrent /login API success check 2025-10-26 08:31:50 -07:00
Collin Heist
36225c3709 Fixed: Prevent modals from overflowing screen width
Closes #8085
2025-10-26 08:31:50 -07:00
康小广
bc037ae356 Follow redirects when fetching Custom Lists 2025-10-26 08:31:50 -07:00
Mark McDowall
77a335de30 Fixed: Default runtime to 45 minutes if unavailable when importing episode files
Closes #7780
2025-10-26 08:31:50 -07:00
Mark McDowall
88d56361c4 Add XML declaration and clean up Kodi metadata generation
Closes #7753
2025-10-26 08:31:50 -07:00
Mark McDowall
d10107739b Set known networks to RFC 1918 ranges during startup 2025-10-25 19:18:43 -07:00
Mark McDowall
7db7567c8e Bump version to 4.0.15 2025-06-09 17:19:54 -07:00
Michael Peleshenko
2b2b973b30 Fixed: Prevent series without IMDB ID from being removed erroneously 2025-06-09 17:19:10 -07:00
Mark McDowall
bb954a7424 Fixed: Trakt Import List authentication after 24 hours
Closes #7874
2025-06-09 17:18:54 -07:00
Mark McDowall
640e3e5d44 Bump version to 4.0.14 2025-03-15 09:43:34 -07:00
Mark McDowall
1260d3c800 Upgrade ImageSharp 2025-03-15 09:29:03 -07:00
v3DJG6GL
feeed9a7cf New: .arj and .lzh extensions are potentially dangerous 2025-03-15 09:25:40 -07:00
Mark McDowall
c8cb74a976 Fixed: Downloads failed for file contents will be removed from client 2025-03-08 19:59:13 -08:00
Stevie Robinson
7193acb5ee Fixed: Improve rejected download handling 2025-03-08 19:59:07 -08:00
Stevie Robinson
6f1fc1686f Fixed: Don't return warning in title field for rejected downloads
Closes #7663
2025-02-22 12:42:35 -08:00
Stevie Robinson
b7407837b7 Fixed: Rejected Imports with no associated release or indexer 2025-02-22 12:40:49 -08:00
Mark McDowall
4e65669c48 Bump version to 4.0.13 2025-02-11 19:25:11 -08:00
Weblate
fa38498db0 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Magnus5405 <magnus5405@outlook.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/da/
Translation: Servarr/Sonarr
2025-02-11 19:24:56 -08:00
Mark McDowall
3b024443c5 Fixed: Drop downs flickering in some cases
Closes #7608
2025-01-30 20:58:11 -08:00
Weblate
4ba9b21bb7 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fi/
Translation: Servarr/Sonarr
2025-01-30 20:57:59 -08:00
Stevie Robinson
e37684e045 Fixed: Failing dangerous and executable single file downloads 2025-01-25 18:29:07 -08:00
Stevie Robinson
103ccd74f3 New: Treat .scr as dangerous file
Closes #7588
2025-01-25 18:27:32 -08:00
Stevie Robinson
ba22992265 Fixed: Don't search for unmonitored specials when searching season
Closes #7589
2025-01-25 18:26:48 -08:00
Bogdan
963395b969 Prevent page crash on console.error being used with non-string values 2025-01-25 18:26:10 -08:00
Weblate
970df1a1d8 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Dani Talens <databio@gmail.com>
Co-authored-by: Gallyam Biktashev <gallyamb@gmail.com>
Co-authored-by: Georgi Panov <darkfella91@gmail.com>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ru/
Translation: Servarr/Sonarr
2025-01-25 18:26:02 -08:00
kephasdev
2ac139ab4d Fixed: Augmenting languages for releases with MULTI and other languages
(cherry picked from commit d58135bf1754b6185eef19a2f4069b27a918d01e)
2025-01-17 19:58:22 -08:00
Bogdan
c69db1ff92 New: Parsing titles with AKA separating multiple titles
Closes #7576
2025-01-17 19:57:52 -08:00
Bogdan
6dae2f0d84 Fixed: Images after series are updated via Series Editor 2025-01-17 19:57:13 -08:00
Bogdan
87934c7761 Fix typo in logging for custom format score 2025-01-17 19:55:57 -08:00
Bogdan
fe8478f42a Fix translation key for RSS in History Details 2025-01-17 19:55:57 -08:00
jcassette
a840bb5423 New: reflink support for ZFS 2025-01-17 19:55:37 -08:00
Weblate
8f5d628c55 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Florian Savouré <florian.savoure@gmail.com>
Co-authored-by: Georgi Panov <darkfella91@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: keysuck <joshkkim@gmail.com>
Co-authored-by: warkurre86 <tom.novo.86@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translation: Servarr/Sonarr
2025-01-17 19:55:19 -08:00
Mark McDowall
acebe87dba New: Parse releases with year and season number in brackets
Closes #7559
2025-01-10 17:06:40 -08:00
Mark McDowall
7d77500667 Fixed: Series being unmonitored when still in Import List
Closes #7555
2025-01-10 17:06:33 -08:00
Stevie Robinson
ec73a13396 Update translation widget 2025-01-10 17:06:19 -08:00
Stevie Robinson
fa0f77659c Additional logging for delay profile decisions
Closes #7558
2025-01-10 17:06:05 -08:00
Stevie Robinson
1609f0c964 New: Show release source in history grab popup 2025-01-10 17:05:46 -08:00
Bogdan
1fea0b3d10 Remote image links for Discord's manual interaction needed 2025-01-10 17:05:32 -08:00
Stevie Robinson
3c8268c428 Additional logging for custom format score 2025-01-10 17:05:23 -08:00
Mark McDowall
c589c4f85e Fixed: Tooltips for detailed error messages 2025-01-10 17:05:05 -08:00
Weblate
f843107c25 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: CaveMan474 <Caveman_TheLastOne@proton.me>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Lars <lars.erik.heloe@gmail.com>
Co-authored-by: Mickaël O <mickael.ouillon@ac-bordeaux.fr>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: RabSsS01 <royermatthieu78@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: mryx007 <mryx@mail.de>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translation: Servarr/Sonarr
2025-01-10 17:04:56 -08:00
Stevie Robinson
035c474f10 Fixed: Listening on all IPv4 Addresses
Closes #7526
2025-01-04 17:58:24 -08:00
Stevie Robinson
4dcc015fb1 Fixed: qBittorrent Ratio Limit Check
Closes #7527
2025-01-04 17:56:49 -08:00
Mark McDowall
1969e0107f Bump version to 4.0.12 2025-01-04 17:17:20 -08:00
Weblate
ac7c05c050 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Ano10 <Ano10@users.noreply.translate.servarr.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Matti Meikäläinen <diefor-93@hotmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translation: Servarr/Sonarr
2025-01-04 17:17:10 -08:00
Bogdan
8aad79fd3e Check if backup folder is writable on backup 2024-12-30 21:16:30 -08:00
Bogdan
f05e552e8e Suggest adding IP to RPC whitelist for on failed Transmission auth 2024-12-30 21:16:16 -08:00
Mark McDowall
8cd5cd603a Fixed: Improve synchronization logic for import list items
Closes #7511
2024-12-30 21:16:02 -08:00
Weblate
ef358e6f24 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Alexander Balya <alexander.balya@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translation: Servarr/Sonarr
2024-12-30 21:15:52 -08:00
Mark McDowall
fae24e98fb Don't send session information to Sentry
Closes #7518
2024-12-28 02:12:33 +01:00
Harry Pollard
c885fb81f9 Fixed: Searching by title not using all titles 2024-12-26 11:40:35 -08:00
Bogdan
514c04935f Fixed: Advanced settings for Metadata consumers 2024-12-26 11:39:59 -08:00
Weblate
4b14368736 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: 1 <1228553526@qq.com>
Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Tommy Au <smarttommyau@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: marapavelka <mara.pavelka@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_TW/
Translation: Servarr/Sonarr
2024-12-26 11:39:50 -08:00
72 changed files with 3021 additions and 1401 deletions

View File

@@ -22,7 +22,7 @@ env:
FRAMEWORK: net6.0
RAW_BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
SONARR_MAJOR_VERSION: 4
VERSION: 4.0.11
VERSION: 4.0.16
jobs:
backend:

View File

@@ -1,6 +1,6 @@
# <img width="24px" src="./Logo/256.png" alt="Sonarr"></img> Sonarr
[![Translated](https://translate.servarr.com/widgets/servarr/-/sonarr/svg-badge.svg)](https://translate.servarr.com/engage/servarr/)
[![Translated](https://translate.servarr.com/widget/servarr/sonarr/svg-badge.svg)](https://translate.servarr.com/engage/servarr/)
[![Backers on Open Collective](https://opencollective.com/Sonarr/backers/badge.svg)](#backers)
[![Sponsors on Open Collective](https://opencollective.com/Sonarr/sponsors/badge.svg)](#sponsors)
[![Mega Sponsors on Open Collective](https://opencollective.com/Sonarr/megasponsors/badge.svg)](#mega-sponsors)

View File

@@ -41,6 +41,7 @@ function HistoryDetails(props: HistoryDetailsProps) {
indexer,
releaseGroup,
seriesMatchType,
releaseSource,
customFormatScore,
nzbInfoUrl,
downloadClient,
@@ -53,6 +54,31 @@ function HistoryDetails(props: HistoryDetailsProps) {
const downloadClientNameInfo = downloadClientName ?? downloadClient;
let releaseSourceMessage = '';
switch (releaseSource) {
case 'Unknown':
releaseSourceMessage = translate('Unknown');
break;
case 'Rss':
releaseSourceMessage = translate('Rss');
break;
case 'Search':
releaseSourceMessage = translate('Search');
break;
case 'UserInvokedSearch':
releaseSourceMessage = translate('UserInvokedSearch');
break;
case 'InteractiveSearch':
releaseSourceMessage = translate('InteractiveSearch');
break;
case 'ReleasePush':
releaseSourceMessage = translate('ReleasePush');
break;
default:
releaseSourceMessage = '';
}
return (
<DescriptionList>
<DescriptionListItem
@@ -88,6 +114,14 @@ function HistoryDetails(props: HistoryDetailsProps) {
/>
) : null}
{releaseSource ? (
<DescriptionListItem
descriptionClassName={styles.description}
title={translate('ReleaseSource')}
data={releaseSourceMessage}
/>
) : null}
{nzbInfoUrl ? (
<span>
<DescriptionListItemTitle>

View File

@@ -258,14 +258,7 @@ function FormInputGroup<T>(props: FormInputGroupProps<T>) {
{helpLink ? <Link to={helpLink}>{translate('MoreInfo')}</Link> : null}
{errors.map((error, index) => {
return 'message' in error ? (
<FormInputHelpText
key={index}
text={error.message}
isError={true}
isCheckInput={checkInput}
/>
) : (
return 'errorMessage' in error ? (
<FormInputHelpText
key={index}
text={error.errorMessage}
@@ -274,23 +267,30 @@ function FormInputGroup<T>(props: FormInputGroupProps<T>) {
isError={true}
isCheckInput={checkInput}
/>
) : (
<FormInputHelpText
key={index}
text={error.message}
isError={true}
isCheckInput={checkInput}
/>
);
})}
{warnings.map((warning, index) => {
return 'message' in warning ? (
return 'errorMessage' in warning ? (
<FormInputHelpText
key={index}
text={warning.message}
text={warning.errorMessage}
link={warning.infoLink}
tooltip={warning.detailedDescription}
isWarning={true}
isCheckInput={checkInput}
/>
) : (
<FormInputHelpText
key={index}
text={warning.errorMessage}
link={warning.infoLink}
tooltip={warning.detailedDescription}
text={warning.message}
isWarning={true}
isCheckInput={checkInput}
/>

View File

@@ -29,6 +29,8 @@ import HintedSelectInputOption from './HintedSelectInputOption';
import HintedSelectInputSelectedValue from './HintedSelectInputSelectedValue';
import styles from './EnhancedSelectInput.css';
const MINIMUM_DISTANCE_FROM_EDGE = 10;
function isArrowKey(keyCode: number) {
return keyCode === keyCodes.UP_ARROW || keyCode === keyCodes.DOWN_ARROW;
}
@@ -189,14 +191,9 @@ function EnhancedSelectInput<T extends EnhancedSelectInputValue<V>, V>(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const handleComputeMaxHeight = useCallback((data: any) => {
const { top, bottom } = data.offsets.reference;
const windowHeight = window.innerHeight;
if (/^bottom/.test(data.placement)) {
data.styles.maxHeight = windowHeight - bottom;
} else {
data.styles.maxHeight = top;
}
data.styles.maxHeight = windowHeight - MINIMUM_DISTANCE_FROM_EDGE;
return data;
}, []);
@@ -508,6 +505,10 @@ function EnhancedSelectInput<T extends EnhancedSelectInputValue<V>, V>(
enabled: true,
fn: handleComputeMaxHeight,
},
preventOverflow: {
enabled: true,
boundariesElement: 'viewport',
},
}}
>
{({ ref, style, scheduleUpdate }) => {

View File

@@ -19,6 +19,7 @@
.modal {
position: relative;
display: flex;
max-width: 90%;
max-height: 90%;
border-radius: 6px;
opacity: 1;

View File

@@ -1,5 +1,6 @@
import React, { useCallback } from 'react';
import { useDispatch } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import AppState from 'App/State/AppState';
import Modal from 'Components/Modal/Modal';
import { sizes } from 'Helpers/Props';
import { clearPendingChanges } from 'Store/Actions/baseActions';
@@ -7,7 +8,8 @@ import EditMetadataModalContent, {
EditMetadataModalContentProps,
} from './EditMetadataModalContent';
interface EditMetadataModalProps extends EditMetadataModalContentProps {
interface EditMetadataModalProps
extends Omit<EditMetadataModalContentProps, 'advancedSettings'> {
isOpen: boolean;
}
@@ -18,6 +20,10 @@ function EditMetadataModal({
}: EditMetadataModalProps) {
const dispatch = useDispatch();
const advancedSettings = useSelector(
(state: AppState) => state.settings.advancedSettings
);
const handleModalClose = useCallback(() => {
dispatch(clearPendingChanges({ section: 'metadata' }));
onModalClose();
@@ -27,6 +33,7 @@ function EditMetadataModal({
<Modal size={sizes.MEDIUM} isOpen={isOpen} onModalClose={handleModalClose}>
<EditMetadataModalContent
{...otherProps}
advancedSettings={advancedSettings}
onModalClose={handleModalClose}
/>
</Modal>

View File

@@ -95,7 +95,6 @@ function Metadata({ id, name, enable, fields }: MetadataProps) {
) : null}
<EditMetadataModal
advancedSettings={false}
id={id}
isOpen={isEditMetadataModalOpen}
onModalClose={handleModalClose}

View File

@@ -23,12 +23,13 @@ const error = console.error;
function logError(...parameters: any[]) {
const filter = parameters.find((parameter) => {
return (
parameter.includes(
typeof parameter === 'string' &&
(parameter.includes(
'Support for defaultProps will be removed from function components in a future major release'
) ||
parameter.includes(
'findDOMNode is deprecated and will be removed in the next major release'
)
parameter.includes(
'findDOMNode is deprecated and will be removed in the next major release'
))
);
});

View File

@@ -42,17 +42,18 @@ namespace NzbDrone.Common
public void CreateZip(string path, IEnumerable<string> files)
{
using (var zipFile = ZipFile.Create(path))
_logger.Debug("Creating archive {0}", path);
using var zipFile = ZipFile.Create(path);
zipFile.BeginUpdate();
foreach (var file in files)
{
zipFile.BeginUpdate();
foreach (var file in files)
{
zipFile.Add(file, Path.GetFileName(file));
}
zipFile.CommitUpdate();
zipFile.Add(file, Path.GetFileName(file));
}
zipFile.CommitUpdate();
}
private void ExtractZip(string compressedFile, string destination)

View File

@@ -341,10 +341,11 @@ namespace NzbDrone.Common.Disk
var isCifs = targetDriveFormat == "cifs";
var isBtrfs = sourceDriveFormat == "btrfs" && targetDriveFormat == "btrfs";
var isZfs = sourceDriveFormat == "zfs" && targetDriveFormat == "zfs";
if (mode.HasFlag(TransferMode.Copy))
{
if (isBtrfs)
if (isBtrfs || isZfs)
{
if (_diskProvider.TryCreateRefLink(sourcePath, targetPath))
{
@@ -358,7 +359,7 @@ namespace NzbDrone.Common.Disk
if (mode.HasFlag(TransferMode.Move))
{
if (isBtrfs)
if (isBtrfs || isZfs)
{
if (isSameMount && _diskProvider.TryRenameFile(sourcePath, targetPath))
{

View File

@@ -390,5 +390,12 @@ namespace NzbDrone.Common.Http
return this;
}
public virtual HttpRequestBuilder AllowRedirect(bool allowAutoRedirect = true)
{
AllowAutoRedirect = allowAutoRedirect;
return this;
}
}
}

View File

@@ -110,7 +110,7 @@ namespace NzbDrone.Common.Instrumentation.Sentry
o.Environment = BuildInfo.Branch;
// Crash free run statistics (sends a ping for healthy and for crashes sessions)
o.AutoSessionTracking = true;
o.AutoSessionTracking = false;
// Caches files in the event device is offline
// Sentry creates a 'sentry' sub directory, no need to concat here

View File

@@ -0,0 +1,9 @@
using System.IO;
using System.Text;
namespace NzbDrone.Common;
public class Utf8StringWriter : StringWriter
{
public override Encoding Encoding => Encoding.UTF8;
}

View File

@@ -168,6 +168,50 @@ namespace NzbDrone.Core.Test.Download.Aggregation.Aggregators
Mocker.GetMock<IIndexerFactory>().VerifyNoOtherCalls();
}
[Test]
public void should_return_multi_languages_when_release_as_specified_language_and_indexer_has_multi_languages_configuration()
{
var releaseTitle = "Series.Title.S01E01.MULTi.VFF.VFQ.1080p.BluRay.DTS.HDMA.x264-RlsGroup";
var indexerDefinition = new IndexerDefinition
{
Id = 1,
Settings = new TorrentRssIndexerSettings { MultiLanguages = new List<int> { Language.Original.Id, Language.French.Id } }
};
Mocker.GetMock<IIndexerFactory>()
.Setup(v => v.Find(1))
.Returns(indexerDefinition);
_remoteEpisode.ParsedEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.French }, releaseTitle);
_remoteEpisode.Release.IndexerId = 1;
_remoteEpisode.Release.Title = releaseTitle;
Subject.Aggregate(_remoteEpisode).Languages.Should().BeEquivalentTo(new List<Language> { _series.OriginalLanguage, Language.French });
Mocker.GetMock<IIndexerFactory>().Verify(c => c.Find(1), Times.Once());
Mocker.GetMock<IIndexerFactory>().VerifyNoOtherCalls();
}
[Test]
public void should_return_multi_languages_when_release_as_other_language_and_indexer_has_multi_languages_configuration()
{
var releaseTitle = "Series.Title.S01E01.MULTi.GERMAN.1080p.BluRay.DTS.HDMA.x264-RlsGroup";
var indexerDefinition = new IndexerDefinition
{
Id = 1,
Settings = new TorrentRssIndexerSettings { MultiLanguages = new List<int> { Language.Original.Id, Language.French.Id } }
};
Mocker.GetMock<IIndexerFactory>()
.Setup(v => v.Find(1))
.Returns(indexerDefinition);
_remoteEpisode.ParsedEpisodeInfo = GetParsedEpisodeInfo(new List<Language> { Language.German }, releaseTitle);
_remoteEpisode.Release.IndexerId = 1;
_remoteEpisode.Release.Title = releaseTitle;
Subject.Aggregate(_remoteEpisode).Languages.Should().BeEquivalentTo(new List<Language> { _series.OriginalLanguage, Language.French, Language.German });
Mocker.GetMock<IIndexerFactory>().Verify(c => c.Find(1), Times.Once());
Mocker.GetMock<IIndexerFactory>().VerifyNoOtherCalls();
}
[Test]
public void should_return_original_when_indexer_has_no_multi_languages_configuration()
{

View File

@@ -712,6 +712,30 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
item.CanMoveFiles.Should().BeTrue();
}
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_max_ratio_reached_after_rounding_and_paused(string state)
{
GivenGlobalSeedLimits(1.0f);
GivenCompletedTorrent(state, ratio: 1.1006066990976857f);
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue();
}
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_just_under_max_ratio_reached_after_rounding_and_paused(string state)
{
GivenGlobalSeedLimits(1.0f);
GivenCompletedTorrent(state, ratio: 0.9999f);
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue();
}
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_overridden_max_ratio_reached_and_paused(string state)
@@ -724,6 +748,30 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.QBittorrentTests
item.CanMoveFiles.Should().BeTrue();
}
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_overridden_max_ratio_reached_after_rounding_and_paused(string state)
{
GivenGlobalSeedLimits(2.0f);
GivenCompletedTorrent(state, ratio: 1.1006066990976857f, ratioLimit: 1.1f);
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue();
}
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_be_removable_and_should_allow_move_files_if_just_under_overridden_max_ratio_reached_after_rounding_and_paused(string state)
{
GivenGlobalSeedLimits(2.0f);
GivenCompletedTorrent(state, ratio: 0.9999f, ratioLimit: 1.0f);
var item = Subject.GetItems().Single();
item.CanBeRemoved.Should().BeTrue();
item.CanMoveFiles.Should().BeTrue();
}
[TestCase("pausedUP")]
[TestCase("stoppedUP")]
public void should_not_be_removable_if_overridden_max_ratio_not_reached_and_paused(string state)

View File

@@ -12,46 +12,256 @@ namespace NzbDrone.Core.Test.ImportListTests
{
public class ImportListItemServiceFixture : CoreTest<ImportListItemService>
{
[SetUp]
public void SetUp()
private void GivenExisting(List<ImportListItemInfo> existing)
{
var existing = Builder<ImportListItemInfo>.CreateListOfSize(3)
.TheFirst(1)
.With(s => s.TvdbId = 6)
.With(s => s.ImdbId = "6")
.TheNext(1)
.With(s => s.TvdbId = 7)
.With(s => s.ImdbId = "7")
.TheNext(1)
.With(s => s.TvdbId = 8)
.With(s => s.ImdbId = "8")
.Build().ToList();
Mocker.GetMock<IImportListItemInfoRepository>()
Mocker.GetMock<IImportListItemRepository>()
.Setup(v => v.GetAllForLists(It.IsAny<List<int>>()))
.Returns(existing);
}
[Test]
public void should_insert_new_update_existing_and_delete_missing()
public void should_insert_new_update_existing_and_delete_missing_based_on_tvdb_id()
{
var newItems = Builder<ImportListItemInfo>.CreateListOfSize(3)
var existing = Builder<ImportListItemInfo>.CreateListOfSize(2)
.All()
.With(s => s.TvdbId = 0)
.With(s => s.ImdbId = null)
.With(s => s.TmdbId = 0)
.With(s => s.MalId = 0)
.With(s => s.AniListId = 0)
.TheFirst(1)
.With(s => s.TvdbId = 5)
.TheNext(1)
.With(s => s.TvdbId = 6)
.TheNext(1)
.With(s => s.TvdbId = 7)
.Build().ToList();
var newItem = Builder<ImportListItemInfo>.CreateNew()
.With(s => s.TvdbId = 5)
.With(s => s.ImdbId = null)
.With(s => s.TmdbId = 0)
.With(s => s.MalId = 0)
.With(s => s.AniListId = 0)
.Build();
var updatedItem = Builder<ImportListItemInfo>.CreateNew()
.With(s => s.TvdbId = 6)
.With(s => s.ImdbId = null)
.With(s => s.TmdbId = 0)
.With(s => s.MalId = 0)
.With(s => s.AniListId = 0)
.Build();
GivenExisting(existing);
var newItems = new List<ImportListItemInfo> { newItem, updatedItem };
var numDeleted = Subject.SyncSeriesForList(newItems, 1);
numDeleted.Should().Be(1);
Mocker.GetMock<IImportListItemInfoRepository>()
.Verify(v => v.InsertMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].TvdbId == 5)), Times.Once());
Mocker.GetMock<IImportListItemInfoRepository>()
.Verify(v => v.UpdateMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 2 && s[0].TvdbId == 6 && s[1].TvdbId == 7)), Times.Once());
Mocker.GetMock<IImportListItemInfoRepository>()
.Verify(v => v.DeleteMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].TvdbId == 8)), Times.Once());
Mocker.GetMock<IImportListItemRepository>()
.Verify(v => v.InsertMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].TvdbId == newItem.TvdbId)), Times.Once());
Mocker.GetMock<IImportListItemRepository>()
.Verify(v => v.UpdateMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].TvdbId == updatedItem.TvdbId)), Times.Once());
Mocker.GetMock<IImportListItemRepository>()
.Verify(v => v.DeleteMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].TvdbId != newItem.TvdbId && s[0].TvdbId != updatedItem.TvdbId)), Times.Once());
}
[Test]
public void should_insert_new_update_existing_and_delete_missing_based_on_imdb_id()
{
var existing = Builder<ImportListItemInfo>.CreateListOfSize(2)
.All()
.With(s => s.TvdbId = 0)
.With(s => s.ImdbId = null)
.With(s => s.TmdbId = 0)
.With(s => s.MalId = 0)
.With(s => s.AniListId = 0)
.TheFirst(1)
.With(s => s.ImdbId = "6")
.TheNext(1)
.With(s => s.ImdbId = "7")
.Build().ToList();
var newItem = Builder<ImportListItemInfo>.CreateNew()
.With(s => s.TvdbId = 0)
.With(s => s.ImdbId = "5")
.With(s => s.TmdbId = 0)
.With(s => s.MalId = 0)
.With(s => s.AniListId = 0)
.Build();
var updatedItem = Builder<ImportListItemInfo>.CreateNew()
.With(s => s.TvdbId = 0)
.With(s => s.ImdbId = "6")
.With(s => s.TmdbId = 6)
.With(s => s.MalId = 0)
.With(s => s.AniListId = 0)
.Build();
GivenExisting(existing);
var newItems = new List<ImportListItemInfo> { newItem, updatedItem };
var numDeleted = Subject.SyncSeriesForList(newItems, 1);
numDeleted.Should().Be(1);
Mocker.GetMock<IImportListItemRepository>()
.Verify(v => v.InsertMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].ImdbId == newItem.ImdbId)), Times.Once());
Mocker.GetMock<IImportListItemRepository>()
.Verify(v => v.UpdateMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].ImdbId == updatedItem.ImdbId)), Times.Once());
Mocker.GetMock<IImportListItemRepository>()
.Verify(v => v.DeleteMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].ImdbId != newItem.ImdbId && s[0].ImdbId != updatedItem.ImdbId)), Times.Once());
}
[Test]
public void should_insert_new_update_existing_and_delete_missing_based_on_tmdb_id()
{
var existing = Builder<ImportListItemInfo>.CreateListOfSize(2)
.All()
.With(s => s.TvdbId = 0)
.With(s => s.ImdbId = null)
.With(s => s.TmdbId = 0)
.With(s => s.MalId = 0)
.With(s => s.AniListId = 0)
.TheFirst(1)
.With(s => s.TmdbId = 6)
.TheNext(1)
.With(s => s.TmdbId = 7)
.Build().ToList();
var newItem = Builder<ImportListItemInfo>.CreateNew()
.With(s => s.TvdbId = 0)
.With(s => s.ImdbId = null)
.With(s => s.TmdbId = 5)
.With(s => s.MalId = 0)
.With(s => s.AniListId = 0)
.Build();
var updatedItem = Builder<ImportListItemInfo>.CreateNew()
.With(s => s.TvdbId = 0)
.With(s => s.ImdbId = null)
.With(s => s.TmdbId = 6)
.With(s => s.MalId = 0)
.With(s => s.AniListId = 0)
.Build();
GivenExisting(existing);
var newItems = new List<ImportListItemInfo> { newItem, updatedItem };
var numDeleted = Subject.SyncSeriesForList(newItems, 1);
numDeleted.Should().Be(1);
Mocker.GetMock<IImportListItemRepository>()
.Verify(v => v.InsertMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].TmdbId == newItem.TmdbId)), Times.Once());
Mocker.GetMock<IImportListItemRepository>()
.Verify(v => v.UpdateMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].TmdbId == updatedItem.TmdbId)), Times.Once());
Mocker.GetMock<IImportListItemRepository>()
.Verify(v => v.DeleteMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].TmdbId != newItem.TmdbId && s[0].TmdbId != updatedItem.TmdbId)), Times.Once());
}
[Test]
public void should_insert_new_update_existing_and_delete_missing_based_on_mal_id()
{
var existing = Builder<ImportListItemInfo>.CreateListOfSize(2)
.All()
.With(s => s.TvdbId = 0)
.With(s => s.ImdbId = null)
.With(s => s.TmdbId = 0)
.With(s => s.MalId = 0)
.With(s => s.AniListId = 0)
.TheFirst(1)
.With(s => s.MalId = 6)
.TheNext(1)
.With(s => s.MalId = 7)
.Build().ToList();
var newItem = Builder<ImportListItemInfo>.CreateNew()
.With(s => s.TvdbId = 0)
.With(s => s.ImdbId = null)
.With(s => s.TmdbId = 0)
.With(s => s.MalId = 5)
.With(s => s.AniListId = 0)
.Build();
var updatedItem = Builder<ImportListItemInfo>.CreateNew()
.With(s => s.TvdbId = 0)
.With(s => s.ImdbId = null)
.With(s => s.TmdbId = 0)
.With(s => s.MalId = 6)
.With(s => s.AniListId = 0)
.Build();
GivenExisting(existing);
var newItems = new List<ImportListItemInfo> { newItem, updatedItem };
var numDeleted = Subject.SyncSeriesForList(newItems, 1);
numDeleted.Should().Be(1);
Mocker.GetMock<IImportListItemRepository>()
.Verify(v => v.InsertMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].MalId == newItem.MalId)), Times.Once());
Mocker.GetMock<IImportListItemRepository>()
.Verify(v => v.UpdateMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].MalId == updatedItem.MalId)), Times.Once());
Mocker.GetMock<IImportListItemRepository>()
.Verify(v => v.DeleteMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].MalId != newItem.MalId && s[0].MalId != updatedItem.MalId)), Times.Once());
}
[Test]
public void should_insert_new_update_existing_and_delete_missing_based_on_anilist_id()
{
var existing = Builder<ImportListItemInfo>.CreateListOfSize(2)
.All()
.With(s => s.TvdbId = 0)
.With(s => s.ImdbId = null)
.With(s => s.TmdbId = 0)
.With(s => s.MalId = 0)
.With(s => s.AniListId = 0)
.TheFirst(1)
.With(s => s.AniListId = 6)
.TheNext(1)
.With(s => s.AniListId = 7)
.Build().ToList();
var newItem = Builder<ImportListItemInfo>.CreateNew()
.With(s => s.TvdbId = 0)
.With(s => s.ImdbId = null)
.With(s => s.TmdbId = 0)
.With(s => s.MalId = 0)
.With(s => s.AniListId = 5)
.Build();
var updatedItem = Builder<ImportListItemInfo>.CreateNew()
.With(s => s.TvdbId = 0)
.With(s => s.ImdbId = null)
.With(s => s.TmdbId = 0)
.With(s => s.MalId = 0)
.With(s => s.AniListId = 6)
.Build();
GivenExisting(existing);
var newItems = new List<ImportListItemInfo> { newItem, updatedItem };
var numDeleted = Subject.SyncSeriesForList(newItems, 1);
numDeleted.Should().Be(1);
Mocker.GetMock<IImportListItemRepository>()
.Verify(v => v.InsertMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].AniListId == newItem.AniListId)), Times.Once());
Mocker.GetMock<IImportListItemRepository>()
.Verify(v => v.UpdateMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].AniListId == updatedItem.AniListId)), Times.Once());
Mocker.GetMock<IImportListItemRepository>()
.Verify(v => v.DeleteMany(It.Is<List<ImportListItemInfo>>(s => s.Count == 1 && s[0].AniListId != newItem.AniListId && s[0].AniListId != updatedItem.AniListId)), Times.Once());
}
}
}

View File

@@ -42,24 +42,45 @@ namespace NzbDrone.Core.Test.ImportListTests
.TheFirst(1)
.With(s => s.TvdbId = 6)
.With(s => s.ImdbId = "6")
.With(s => s.TmdbId = 6)
.With(s => s.MalIds = new HashSet<int> { 6 })
.With(s => s.AniListIds = new HashSet<int> { 6 })
.With(s => s.Monitored = true)
.TheNext(1)
.With(s => s.TvdbId = 7)
.With(s => s.ImdbId = "7")
.With(s => s.TmdbId = 7)
.With(s => s.MalIds = new HashSet<int> { 7 })
.With(s => s.AniListIds = new HashSet<int> { 7 })
.With(s => s.Monitored = true)
.TheNext(1)
.With(s => s.TvdbId = 8)
.With(s => s.ImdbId = "8")
.With(s => s.TmdbId = 8)
.With(s => s.MalIds = new HashSet<int> { 8 })
.With(s => s.AniListIds = new HashSet<int> { 8 })
.With(s => s.Monitored = true)
.Build().ToList();
_list2Series = Builder<ImportListItemInfo>.CreateListOfSize(3)
.TheFirst(1)
.With(s => s.TvdbId = 6)
.With(s => s.ImdbId = "6")
.With(s => s.TmdbId = 6)
.With(s => s.MalId = 6)
.With(s => s.AniListId = 6)
.TheNext(1)
.With(s => s.TvdbId = 7)
.With(s => s.ImdbId = "7")
.With(s => s.TmdbId = 7)
.With(s => s.MalId = 7)
.With(s => s.AniListId = 7)
.TheNext(1)
.With(s => s.TvdbId = 8)
.With(s => s.ImdbId = "8")
.With(s => s.TmdbId = 8)
.With(s => s.MalId = 8)
.With(s => s.AniListId = 8)
.Build().ToList();
_importListFetch = new ImportListFetchResult(_list1Series, false);
@@ -110,6 +131,10 @@ namespace NzbDrone.Core.Test.ImportListTests
Mocker.GetMock<IImportListExclusionService>()
.Setup(v => v.All())
.Returns(new List<ImportListExclusion>());
Mocker.GetMock<IImportListItemService>()
.Setup(s => s.All())
.Returns(new List<ImportListItemInfo>());
}
private void WithTvdbId()
@@ -153,6 +178,19 @@ namespace NzbDrone.Core.Test.ImportListTests
});
}
private List<ImportListItemInfo> WithImportListItems(int count)
{
var importListItems = Builder<ImportListItemInfo>.CreateListOfSize(count)
.Build()
.ToList();
Mocker.GetMock<IImportListItemService>()
.Setup(s => s.All())
.Returns(importListItems);
return importListItems;
}
private void WithMonitorType(MonitorTypes monitor)
{
_importLists.ForEach(li => (li.Definition as ImportListDefinition).ShouldMonitor = monitor);
@@ -285,16 +323,18 @@ namespace NzbDrone.Core.Test.ImportListTests
{
WithList(1, true);
WithCleanLevel(ListSyncLevelType.KeepAndUnmonitor);
var importListItems = WithImportListItems(_existingSeries.Count - 1);
_importListFetch.Series.ForEach(m => m.ImportListId = 1);
Mocker.GetMock<IImportListItemService>()
.Setup(v => v.Exists(6, It.IsAny<string>()))
.Returns(true);
for (var i = 0; i < importListItems.Count; i++)
{
importListItems[i].TvdbId = _existingSeries[i].TvdbId;
}
Subject.Execute(_commandAll);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.UpdateSeries(It.Is<List<Series>>(s => s.Count > 0 && s.All(m => !m.Monitored)), true), Times.Once());
.Verify(v => v.UpdateSeries(It.Is<List<Series>>(s => s.Count == 1 && s.All(m => !m.Monitored)), true), Times.Once());
}
[Test]
@@ -302,18 +342,75 @@ namespace NzbDrone.Core.Test.ImportListTests
{
WithList(1, true);
WithCleanLevel(ListSyncLevelType.KeepAndUnmonitor);
var importListItems = WithImportListItems(_existingSeries.Count - 1);
_importListFetch.Series.ForEach(m => m.ImportListId = 1);
var x = _importLists;
Mocker.GetMock<IImportListItemService>()
.Setup(v => v.Exists(It.IsAny<int>(), "6"))
.Returns(true);
for (var i = 0; i < importListItems.Count; i++)
{
importListItems[i].ImdbId = _existingSeries[i].ImdbId;
}
Subject.Execute(_commandAll);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.UpdateSeries(It.Is<List<Series>>(s => s.Count > 0 && s.All(m => !m.Monitored)), true), Times.Once());
.Verify(v => v.UpdateSeries(It.Is<List<Series>>(s => s.Count == 1 && s.All(m => !m.Monitored)), true), Times.Once());
}
[Test]
public void should_not_clean_on_clean_library_if_tmdb_match()
{
WithList(1, true);
WithCleanLevel(ListSyncLevelType.KeepAndUnmonitor);
var importListItems = WithImportListItems(_existingSeries.Count - 1);
_importListFetch.Series.ForEach(m => m.ImportListId = 1);
for (var i = 0; i < importListItems.Count; i++)
{
importListItems[i].TmdbId = _existingSeries[i].TmdbId;
}
Subject.Execute(_commandAll);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.UpdateSeries(It.Is<List<Series>>(s => s.Count == 1 && s.All(m => !m.Monitored)), true), Times.Once());
}
[Test]
public void should_not_clean_on_clean_library_if_malid_match()
{
WithList(1, true);
WithCleanLevel(ListSyncLevelType.KeepAndUnmonitor);
var importListItems = WithImportListItems(_existingSeries.Count - 1);
_importListFetch.Series.ForEach(m => m.ImportListId = 1);
for (var i = 0; i < importListItems.Count; i++)
{
importListItems[i].MalId = _existingSeries[i].MalIds.First();
}
Subject.Execute(_commandAll);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.UpdateSeries(It.Is<List<Series>>(s => s.Count == 1 && s.All(m => !m.Monitored)), true), Times.Once());
}
[Test]
public void should_not_clean_on_clean_library_if_anilistid_match()
{
WithList(1, true);
WithCleanLevel(ListSyncLevelType.KeepAndUnmonitor);
var importListItems = WithImportListItems(_existingSeries.Count - 1);
_importListFetch.Series.ForEach(m => m.ImportListId = 1);
for (var i = 0; i < importListItems.Count; i++)
{
importListItems[i].AniListId = _existingSeries[i].AniListIds.First();
}
Subject.Execute(_commandAll);
Mocker.GetMock<ISeriesService>()
.Verify(v => v.UpdateSeries(It.Is<List<Series>>(s => s.Count == 1 && s.All(m => !m.Monitored)), true), Times.Once());
}
[Test]
@@ -345,6 +442,7 @@ namespace NzbDrone.Core.Test.ImportListTests
Mocker.GetMock<ISeriesService>()
.Verify(v => v.UpdateSeries(It.IsAny<List<Series>>(), It.IsAny<bool>()), Times.Never());
Mocker.GetMock<ISeriesService>()
.Verify(v => v.DeleteSeries(It.IsAny<List<int>>(), It.IsAny<bool>(), It.IsAny<bool>()), Times.Never());
}

View File

@@ -213,5 +213,16 @@ namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport
Subject.IsSample(_localEpisode).Should().Be(DetectSampleResult.Sample);
}
[Test]
public void should_default_to_45_minutes_if_runtime_is_zero()
{
GivenRuntime(120);
_localEpisode.Series.Runtime = 0;
_localEpisode.Episodes.First().Runtime = 0;
Subject.IsSample(_localEpisode).Should().Be(DetectSampleResult.Sample);
}
}
}

View File

@@ -96,6 +96,8 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Босх: Спадок (S2E1) / Series: Legacy (S2E1) (2023) WEB-DL 1080p Ukr/Eng | sub Eng", "Босх: Спадок", "Series: Legacy")]
[TestCase("Босх: Спадок / Series: Legacy / S2E1-4 of 10 (2023) WEB-DL 1080p Ukr/Eng | sub Eng", "Босх: Спадок", "Series: Legacy")]
[TestCase("Босх: Спадок AKA Series: Legacy S02 1080p NF WEB-DL Dual- Audio DD+ 5.1 Atmos H.264-APEX", "Босх: Спадок", "Series: Legacy")]
[TestCase("Босх.Спадок.AKA.Series.Legacy.S02.1080p.NF.WEB-DL.DUAL.DDP5.1.Atmos.H.264-APEX", "Босх Спадок", "Series Legacy")]
public void should_parse_multiple_series_titles(string postTitle, params string[] titles)
{
var seriesTitleInfo = Parser.Parser.ParseTitle(postTitle).SeriesTitleInfo;

View File

@@ -35,7 +35,8 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Series Title / S2E1-16 of 16 [2022, WEB-DL] RUS", "Series Title", 2)]
[TestCase("[hchcsen] Mobile Series 00 S01 [BD Remux Dual Audio 1080p AVC 2xFLAC] (Kidou Senshi Gundam 00 Season 1)", "Mobile Series 00", 1)]
[TestCase("[HorribleRips] Mobile Series 00 S1 [1080p]", "Mobile Series 00", 1)]
[TestCase("[Zoombie] Zom 100: Bucket List of the Dead S01 [Web][MKV][h265 10-bit][1080p][AC3 2.0][Softsubs (Zoombie)]", "Zom 100: Bucket List of the Dead", 1)]
[TestCase("[Zoombie] Series 100: Bucket List S01 [Web][MKV][h265 10-bit][1080p][AC3 2.0][Softsubs (Zoombie)]", "Series 100: Bucket List", 1)]
[TestCase("Seriesless (2016/S01/WEB-DL/1080p/AC3 5.1/DUAL/SUB)", "Seriesless (2016)", 1)]
public void should_parse_full_season_release(string postTitle, string title, int season)
{
var result = Parser.Parser.ParseTitle(postTitle);

View File

@@ -175,6 +175,8 @@ namespace NzbDrone.Core.Test.ParserTests
[TestCase("Series - Temporada 1 - [HDTV 1080p][Cap.101](wolfmax4k.com)", "Series", 1, 1)]
[TestCase("Series [HDTV 1080p][Cap.101](wolfmax4k.com)", "Series", 1, 1)]
[TestCase("Series [HDTV 1080p][Cap. 101](wolfmax4k.com).mkv", "Series", 1, 1)]
[TestCase("Amazing Title (2024/S01E07/DSNP/WEB-DL/1080p/ESP/EAC3 5.1/ING/EAC3 5.1 Atmos/SUBS) SPWEB", "Amazing Title (2024)", 1, 7)]
[TestCase("Mini Title (Miniserie) (2024/S01E07/DSNP/WEB-DL/1080p/ESP/EAC3 5.1/ING/EAC3 5.1 Atmos/SUBS) SPWEB", "Mini Title (2024)", 1, 7)]
// [TestCase("", "", 0, 0)]
public void should_parse_single_episode(string postTitle, string title, int seasonNumber, int episodeNumber)

View File

@@ -66,12 +66,19 @@ namespace NzbDrone.Core.Backup
{
_logger.ProgressInfo("Starting Backup");
var backupFolder = GetBackupFolder(backupType);
_diskProvider.EnsureFolder(_backupTempFolder);
_diskProvider.EnsureFolder(GetBackupFolder(backupType));
_diskProvider.EnsureFolder(backupFolder);
if (!_diskProvider.FolderWritable(backupFolder))
{
throw new UnauthorizedAccessException($"Backup folder {backupFolder} is not writable");
}
var dateNow = DateTime.Now;
var backupFilename = $"sonarr_backup_v{BuildInfo.Version}_{dateNow:yyyy.MM.dd_HH.mm.ss}.zip";
var backupPath = Path.Combine(GetBackupFolder(backupType), backupFilename);
var backupPath = Path.Combine(backupFolder, backupFilename);
Cleanup();

View File

@@ -0,0 +1,15 @@
using FluentMigrator;
using NzbDrone.Core.Datastore.Migration.Framework;
namespace NzbDrone.Core.Datastore.Migration
{
[Migration(217)]
public class add_mal_and_anilist_ids : NzbDroneMigrationBase
{
protected override void MainDbUpgrade()
{
Alter.Table("Series").AddColumn("MalIds").AsString().WithDefaultValue("[]");
Alter.Table("Series").AddColumn("AniListIds").AsString().WithDefaultValue("[]");
}
}
}

View File

@@ -117,6 +117,8 @@ namespace NzbDrone.Core.DecisionEngine
remoteEpisode.CustomFormats = _formatCalculator.ParseCustomFormat(remoteEpisode, remoteEpisode.Release.Size);
remoteEpisode.CustomFormatScore = remoteEpisode?.Series?.QualityProfile?.Value.CalculateCustomFormatScore(remoteEpisode.CustomFormats) ?? 0;
_logger.Trace("Custom Format Score of '{0}' [{1}] calculated for '{2}'", remoteEpisode.CustomFormatScore, remoteEpisode.CustomFormats?.ConcatToString(), report.Title);
remoteEpisode.DownloadAllowed = remoteEpisode.Episodes.Any();
decision = GetDecisionForReport(remoteEpisode, searchCriteria);
}

View File

@@ -1,3 +1,4 @@
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Parser.Model;
@@ -6,6 +7,13 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
{
public class CustomFormatAllowedbyProfileSpecification : IDownloadDecisionEngineSpecification
{
private readonly Logger _logger;
public CustomFormatAllowedbyProfileSpecification(Logger logger)
{
_logger = logger;
}
public SpecificationPriority Priority => SpecificationPriority.Default;
public RejectionType Type => RejectionType.Permanent;
@@ -19,6 +27,8 @@ namespace NzbDrone.Core.DecisionEngine.Specifications
return DownloadSpecDecision.Reject(DownloadRejectionReason.CustomFormatMinimumScore, "Custom Formats {0} have score {1} below Series profile minimum {2}", subject.CustomFormats.ConcatToString(), score, minScore);
}
_logger.Trace("Custom Format Score of {0} [{1}] above Series profile minimum {2}", score, subject.CustomFormats.ConcatToString(), minScore);
return DownloadSpecDecision.Accept();
}
}

View File

@@ -41,10 +41,12 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
if (delay == 0)
{
_logger.Debug("QualityProfile does not require a waiting period before download for {0}.", subject.Release.DownloadProtocol);
_logger.Debug("Delay Profile does not require a waiting period before download for {0}.", subject.Release.DownloadProtocol);
return DownloadSpecDecision.Accept();
}
_logger.Debug("Delay Profile requires a waiting period of {0} minutes for {1}", delay, subject.Release.DownloadProtocol);
var qualityComparer = new QualityModelComparer(qualityProfile);
if (isPreferredProtocol)
@@ -95,6 +97,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync
if (oldest != null && oldest.Release.AgeMinutes > delay)
{
_logger.Debug("Oldest pending release {0} has been delayed for {1}, longer than the set delay of {2}. Release will be accepted", oldest.Release.Title, oldest.Release.AgeMinutes, delay);
return DownloadSpecDecision.Accept();
}

View File

@@ -76,7 +76,7 @@ namespace NzbDrone.Core.Download.Aggregation.Aggregators
languages = languages.Except(languagesToRemove).ToList();
}
if ((languages.Count == 0 || (languages.Count == 1 && languages.First() == Language.Unknown)) && releaseInfo?.Title?.IsNotNullOrWhiteSpace() == true)
if (releaseInfo?.Title?.IsNotNullOrWhiteSpace() == true)
{
IndexerDefinition indexer = null;
@@ -93,7 +93,14 @@ namespace NzbDrone.Core.Download.Aggregation.Aggregators
if (indexer?.Settings is IIndexerSettings settings && settings.MultiLanguages.Any() && Parser.Parser.HasMultipleLanguages(releaseInfo.Title))
{
// Use indexer setting for Multi-languages
languages = settings.MultiLanguages.Select(i => (Language)i).ToList();
if (languages.Count == 0 || (languages.Count == 1 && languages.First() == Language.Unknown))
{
languages = settings.MultiLanguages.Select(i => (Language)i).ToList();
}
else
{
languages.AddRange(settings.MultiLanguages.Select(i => (Language)i).Except(languages).ToList());
}
}
}

View File

@@ -630,14 +630,14 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
{
if (torrent.RatioLimit >= 0)
{
if (torrent.Ratio >= torrent.RatioLimit)
if (torrent.RatioLimit - torrent.Ratio <= 0.001f)
{
return true;
}
}
else if (torrent.RatioLimit == -2 && config.MaxRatioEnabled)
{
if (Math.Round(torrent.Ratio, 2) >= config.MaxRatio)
if (config.MaxRatio - torrent.Ratio <= 0.001f)
{
return true;
}

View File

@@ -425,8 +425,8 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
}
catch (HttpException ex)
{
_logger.Debug("qbitTorrent authentication failed.");
if (ex.Response.StatusCode == HttpStatusCode.Forbidden)
_logger.Debug(ex, "qbitTorrent authentication failed.");
if (ex.Response.StatusCode is HttpStatusCode.Unauthorized or HttpStatusCode.Forbidden)
{
throw new DownloadClientAuthenticationException("Failed to authenticate with qBittorrent.", ex);
}
@@ -438,7 +438,7 @@ namespace NzbDrone.Core.Download.Clients.QBittorrent
throw new DownloadClientUnavailableException("Failed to connect to qBittorrent, please check your settings.", ex);
}
if (response.Content != "Ok.")
if (response.Content.IsNotNullOrWhiteSpace() && response.Content != "Ok.")
{
// returns "Fails." on bad login
_logger.Debug("qbitTorrent authentication failed.");

View File

@@ -7,6 +7,7 @@ using System.Net;
using Newtonsoft.Json.Linq;
using NLog;
using NzbDrone.Common.Cache;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http;
using NzbDrone.Common.Serializer;
@@ -261,7 +262,7 @@ namespace NzbDrone.Core.Download.Clients.Transmission
private void AuthenticateClient(HttpRequestBuilder requestBuilder, TransmissionSettings settings, bool reauthenticate = false)
{
var authKey = string.Format("{0}:{1}", requestBuilder.BaseUrl, settings.Password);
var authKey = $"{requestBuilder.BaseUrl}:{settings.Password}";
var sessionId = _authSessionIdCache.Find(authKey);
@@ -273,24 +274,26 @@ namespace NzbDrone.Core.Download.Clients.Transmission
authLoginRequest.SuppressHttpError = true;
var response = _httpClient.Execute(authLoginRequest);
if (response.StatusCode == HttpStatusCode.MovedPermanently)
{
var url = response.Headers.GetSingleValue("Location");
throw new DownloadClientException("Remote site redirected to " + url);
}
else if (response.StatusCode == HttpStatusCode.Conflict)
switch (response.StatusCode)
{
sessionId = response.Headers.GetSingleValue("X-Transmission-Session-Id");
case HttpStatusCode.MovedPermanently:
var url = response.Headers.GetSingleValue("Location");
if (sessionId == null)
{
throw new DownloadClientException("Remote host did not return a Session Id.");
}
}
else
{
throw new DownloadClientAuthenticationException("Failed to authenticate with Transmission.");
throw new DownloadClientException("Remote site redirected to " + url);
case HttpStatusCode.Forbidden:
throw new DownloadClientException($"Failed to authenticate with Transmission. It may be necessary to add {BuildInfo.AppName}'s IP address to RPC whitelist.");
case HttpStatusCode.Conflict:
sessionId = response.Headers.GetSingleValue("X-Transmission-Session-Id");
if (sessionId == null)
{
throw new DownloadClientException("Remote host did not return a Session Id.");
}
break;
default:
throw new DownloadClientAuthenticationException("Failed to authenticate with Transmission.");
}
_logger.Debug("Transmission authentication succeeded.");

View File

@@ -1,5 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Core.Download.TrackedDownloads;
using NzbDrone.Core.Indexers;
using NzbDrone.Core.MediaFiles.EpisodeImport;
@@ -14,15 +14,17 @@ public interface IRejectedImportService
public class RejectedImportService : IRejectedImportService
{
private readonly ICachedIndexerSettingsProvider _cachedIndexerSettingsProvider;
private readonly Logger _logger;
public RejectedImportService(ICachedIndexerSettingsProvider cachedIndexerSettingsProvider)
public RejectedImportService(ICachedIndexerSettingsProvider cachedIndexerSettingsProvider, Logger logger)
{
_cachedIndexerSettingsProvider = cachedIndexerSettingsProvider;
_logger = logger;
}
public bool Process(TrackedDownload trackedDownload, ImportResult importResult)
{
if (importResult.Result != ImportResultType.Rejected || importResult.ImportDecision.LocalEpisode != null)
if (importResult.Result != ImportResultType.Rejected || trackedDownload.RemoteEpisode?.Release == null)
{
return false;
}
@@ -30,19 +32,27 @@ public class RejectedImportService : IRejectedImportService
var indexerSettings = _cachedIndexerSettingsProvider.GetSettings(trackedDownload.RemoteEpisode.Release.IndexerId);
var rejectionReason = importResult.ImportDecision.Rejections.FirstOrDefault()?.Reason;
if (indexerSettings == null)
{
trackedDownload.Warn(new TrackedDownloadStatusMessage(trackedDownload.DownloadItem.Title, importResult.Errors));
return true;
}
if (rejectionReason == ImportRejectionReason.DangerousFile &&
indexerSettings.FailDownloads.Contains(FailDownloads.PotentiallyDangerous))
{
_logger.Trace("Download '{0}' contains potentially dangerous file, marking as failed", trackedDownload.DownloadItem.Title);
trackedDownload.Fail();
}
else if (rejectionReason == ImportRejectionReason.ExecutableFile &&
indexerSettings.FailDownloads.Contains(FailDownloads.Executables))
{
_logger.Trace("Download '{0}' contains executable file, marking as failed", trackedDownload.DownloadItem.Title);
trackedDownload.Fail();
}
else
{
trackedDownload.Warn(new TrackedDownloadStatusMessage(importResult.Errors.First(), new List<string>()));
trackedDownload.Warn(new TrackedDownloadStatusMessage(trackedDownload.DownloadItem.Title, importResult.Errors));
}
return true;

View File

@@ -40,6 +40,9 @@ namespace NzbDrone.Core.Download.TrackedDownloads
{
Status = TrackedDownloadStatus.Error;
State = TrackedDownloadState.FailedPending;
// Set CanBeRemoved to allow the failed item to be removed from the client
DownloadItem.CanBeRemoved = true;
}
}

View File

@@ -73,7 +73,7 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Plex
if (episodeFile.SeasonNumber == 0)
{
episodeFormat = $"SP{episodesInFile.First():00}";
episodeFormat = $"SP{episodesInFile.First().EpisodeNumber:00}";
}
content.AppendLine($"Episode: {episodeFormat}: {episodeFile.RelativePath}");

View File

@@ -8,6 +8,7 @@ using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;
using NLog;
using NzbDrone.Common;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Serializer;
@@ -149,110 +150,116 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
if (Settings.SeriesMetadata)
{
_logger.Debug("Generating Series Metadata for: {0}", series.Title);
var sb = new StringBuilder();
var xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;
xws.Indent = false;
using (var xw = XmlWriter.Create(sb, xws))
var tvShow = new XElement("tvshow");
tvShow.Add(new XElement("title", series.Title));
if (series.Ratings != null && series.Ratings.Votes > 0)
{
var tvShow = new XElement("tvshow");
tvShow.Add(new XElement("title", series.Title));
if (series.Ratings != null && series.Ratings.Votes > 0)
{
tvShow.Add(new XElement("rating", series.Ratings.Value));
}
tvShow.Add(new XElement("plot", series.Overview));
tvShow.Add(new XElement("mpaa", series.Certification));
tvShow.Add(new XElement("id", series.TvdbId));
var uniqueId = new XElement("uniqueid", series.TvdbId);
uniqueId.SetAttributeValue("type", "tvdb");
uniqueId.SetAttributeValue("default", true);
tvShow.Add(uniqueId);
if (series.ImdbId.IsNotNullOrWhiteSpace())
{
var imdbId = new XElement("uniqueid", series.ImdbId);
imdbId.SetAttributeValue("type", "imdb");
tvShow.Add(imdbId);
}
if (series.TmdbId > 0)
{
var tmdbId = new XElement("uniqueid", series.TmdbId);
tmdbId.SetAttributeValue("type", "tmdb");
tvShow.Add(tmdbId);
}
if (series.TvMazeId > 0)
{
var tvMazeId = new XElement("uniqueid", series.TvMazeId);
tvMazeId.SetAttributeValue("type", "tvmaze");
tvShow.Add(tvMazeId);
}
foreach (var genre in series.Genres)
{
tvShow.Add(new XElement("genre", genre));
}
if (series.Tags.Any())
{
var tags = _tagRepo.GetTags(series.Tags);
foreach (var tag in tags)
{
tvShow.Add(new XElement("tag", tag.Label));
}
}
tvShow.Add(new XElement("status", series.Status));
if (series.FirstAired.HasValue)
{
tvShow.Add(new XElement("premiered", series.FirstAired.Value.ToString("yyyy-MM-dd")));
}
// Add support for Jellyfin's "enddate" tag
if (series.Status == SeriesStatusType.Ended && series.LastAired.HasValue)
{
tvShow.Add(new XElement("enddate", series.LastAired.Value.ToString("yyyy-MM-dd")));
}
tvShow.Add(new XElement("studio", series.Network));
foreach (var actor in series.Actors)
{
var xmlActor = new XElement("actor",
new XElement("name", actor.Name),
new XElement("role", actor.Character));
if (actor.Images.Any())
{
xmlActor.Add(new XElement("thumb", actor.Images.First().RemoteUrl));
}
tvShow.Add(xmlActor);
}
if (Settings.SeriesMetadataEpisodeGuide)
{
var episodeGuide = new KodiEpisodeGuide(series);
var serializerSettings = STJson.GetSerializerSettings();
serializerSettings.WriteIndented = false;
tvShow.Add(new XElement("episodeguide", JsonSerializer.Serialize(episodeGuide, serializerSettings)));
}
var doc = new XDocument(tvShow);
doc.Save(xw);
xmlResult += doc.ToString();
tvShow.Add(new XElement("rating", series.Ratings.Value));
}
tvShow.Add(new XElement("plot", series.Overview));
tvShow.Add(new XElement("mpaa", series.Certification));
tvShow.Add(new XElement("id", series.TvdbId));
var uniqueId = new XElement("uniqueid", series.TvdbId);
uniqueId.SetAttributeValue("type", "tvdb");
uniqueId.SetAttributeValue("default", true);
tvShow.Add(uniqueId);
if (series.ImdbId.IsNotNullOrWhiteSpace())
{
var imdbId = new XElement("uniqueid", series.ImdbId);
imdbId.SetAttributeValue("type", "imdb");
tvShow.Add(imdbId);
}
if (series.TmdbId > 0)
{
var tmdbId = new XElement("uniqueid", series.TmdbId);
tmdbId.SetAttributeValue("type", "tmdb");
tvShow.Add(tmdbId);
}
if (series.TvMazeId > 0)
{
var tvMazeId = new XElement("uniqueid", series.TvMazeId);
tvMazeId.SetAttributeValue("type", "tvmaze");
tvShow.Add(tvMazeId);
}
foreach (var genre in series.Genres)
{
tvShow.Add(new XElement("genre", genre));
}
if (series.Tags.Any())
{
var tags = _tagRepo.GetTags(series.Tags);
foreach (var tag in tags)
{
tvShow.Add(new XElement("tag", tag.Label));
}
}
tvShow.Add(new XElement("status", series.Status));
if (series.FirstAired.HasValue)
{
tvShow.Add(new XElement("premiered", series.FirstAired.Value.ToString("yyyy-MM-dd")));
}
// Add support for Jellyfin's "enddate" tag
if (series.Status == SeriesStatusType.Ended && series.LastAired.HasValue)
{
tvShow.Add(new XElement("enddate", series.LastAired.Value.ToString("yyyy-MM-dd")));
}
tvShow.Add(new XElement("studio", series.Network));
foreach (var actor in series.Actors)
{
var xmlActor = new XElement("actor",
new XElement("name", actor.Name),
new XElement("role", actor.Character));
if (actor.Images.Any())
{
xmlActor.Add(new XElement("thumb", actor.Images.First().RemoteUrl));
}
tvShow.Add(xmlActor);
}
if (Settings.SeriesMetadataEpisodeGuide)
{
var episodeGuide = new KodiEpisodeGuide(series);
var serializerSettings = STJson.GetSerializerSettings();
serializerSettings.WriteIndented = false;
tvShow.Add(new XElement("episodeguide", JsonSerializer.Serialize(episodeGuide, serializerSettings)));
}
var doc = new XDocument(tvShow)
{
Declaration = new XDeclaration("1.0", "UTF-8", "yes"),
};
var sb = new StringBuilder();
using var sw = new Utf8StringWriter();
using var xw = XmlWriter.Create(sw, new XmlWriterSettings
{
Encoding = Encoding.UTF8,
Indent = true
});
doc.Save(xw);
xw.Flush();
xmlResult += sw.ToString();
}
if (Settings.SeriesMetadataUrl)
@@ -279,116 +286,117 @@ namespace NzbDrone.Core.Extras.Metadata.Consumers.Xbmc
var watched = GetExistingWatchedStatus(series, episodeFile.RelativePath);
var xmlResult = string.Empty;
var xws = new XmlWriterSettings
{
Encoding = Encoding.UTF8,
Indent = true,
ConformanceLevel = ConformanceLevel.Fragment
};
using var sw = new Utf8StringWriter();
using var xw = XmlWriter.Create(sw, xws);
xw.WriteProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"");
foreach (var episode in episodeFile.Episodes.Value)
{
var sb = new StringBuilder();
var xws = new XmlWriterSettings();
xws.OmitXmlDeclaration = true;
xws.Indent = false;
var image = episode.Images.SingleOrDefault(i => i.CoverType == MediaCoverTypes.Screenshot);
using (var xw = XmlWriter.Create(sb, xws))
var details = new XElement("episodedetails");
details.Add(new XElement("title", episode.Title));
details.Add(new XElement("season", episode.SeasonNumber));
details.Add(new XElement("episode", episode.EpisodeNumber));
details.Add(new XElement("aired", episode.AirDate));
details.Add(new XElement("plot", episode.Overview));
if (episode.SeasonNumber == 0 && episode.AiredAfterSeasonNumber.HasValue)
{
var doc = new XDocument();
var image = episode.Images.SingleOrDefault(i => i.CoverType == MediaCoverTypes.Screenshot);
var details = new XElement("episodedetails");
details.Add(new XElement("title", episode.Title));
details.Add(new XElement("season", episode.SeasonNumber));
details.Add(new XElement("episode", episode.EpisodeNumber));
details.Add(new XElement("aired", episode.AirDate));
details.Add(new XElement("plot", episode.Overview));
if (episode.SeasonNumber == 0 && episode.AiredAfterSeasonNumber.HasValue)
{
details.Add(new XElement("displayafterseason", episode.AiredAfterSeasonNumber));
}
else if (episode.SeasonNumber == 0 && episode.AiredBeforeSeasonNumber.HasValue)
{
details.Add(new XElement("displayseason", episode.AiredBeforeSeasonNumber));
details.Add(new XElement("displayepisode", episode.AiredBeforeEpisodeNumber ?? -1));
}
var tvdbId = new XElement("uniqueid", episode.TvdbId);
tvdbId.SetAttributeValue("type", "tvdb");
tvdbId.SetAttributeValue("default", true);
details.Add(tvdbId);
var sonarrId = new XElement("uniqueid", episode.Id);
sonarrId.SetAttributeValue("type", "sonarr");
details.Add(sonarrId);
if (image == null)
{
details.Add(new XElement("thumb"));
}
else if (Settings.EpisodeImageThumb)
{
details.Add(new XElement("thumb", image.RemoteUrl));
}
details.Add(new XElement("watched", watched));
if (episode.Ratings != null && episode.Ratings.Votes > 0)
{
details.Add(new XElement("rating", episode.Ratings.Value));
}
if (episodeFile.MediaInfo != null)
{
var sceneName = episodeFile.GetSceneOrFileName();
var fileInfo = new XElement("fileinfo");
var streamDetails = new XElement("streamdetails");
var video = new XElement("video");
video.Add(new XElement("aspect", (float)episodeFile.MediaInfo.Width / (float)episodeFile.MediaInfo.Height));
video.Add(new XElement("bitrate", episodeFile.MediaInfo.VideoBitrate));
video.Add(new XElement("codec", MediaInfoFormatter.FormatVideoCodec(episodeFile.MediaInfo, sceneName)));
video.Add(new XElement("framerate", episodeFile.MediaInfo.VideoFps));
video.Add(new XElement("height", episodeFile.MediaInfo.Height));
video.Add(new XElement("scantype", episodeFile.MediaInfo.ScanType));
video.Add(new XElement("width", episodeFile.MediaInfo.Width));
video.Add(new XElement("duration", episodeFile.MediaInfo.RunTime.TotalMinutes));
video.Add(new XElement("durationinseconds", Math.Round(episodeFile.MediaInfo.RunTime.TotalSeconds)));
streamDetails.Add(video);
var audio = new XElement("audio");
var audioChannelCount = episodeFile.MediaInfo.AudioChannels;
audio.Add(new XElement("bitrate", episodeFile.MediaInfo.AudioBitrate));
audio.Add(new XElement("channels", audioChannelCount));
audio.Add(new XElement("codec", MediaInfoFormatter.FormatAudioCodec(episodeFile.MediaInfo, sceneName)));
audio.Add(new XElement("language", episodeFile.MediaInfo.AudioLanguages));
streamDetails.Add(audio);
if (episodeFile.MediaInfo.Subtitles != null && episodeFile.MediaInfo.Subtitles.Count > 0)
{
foreach (var s in episodeFile.MediaInfo.Subtitles)
{
var subtitle = new XElement("subtitle");
subtitle.Add(new XElement("language", s));
streamDetails.Add(subtitle);
}
}
fileInfo.Add(streamDetails);
details.Add(fileInfo);
}
// Todo: get guest stars, writer and director
// details.Add(new XElement("credits", tvdbEpisode.Writer.FirstOrDefault()));
// details.Add(new XElement("director", tvdbEpisode.Directors.FirstOrDefault()));
doc.Add(details);
doc.Save(xw);
xmlResult += doc.ToString();
xmlResult += Environment.NewLine;
details.Add(new XElement("displayafterseason", episode.AiredAfterSeasonNumber));
}
else if (episode.SeasonNumber == 0 && episode.AiredBeforeSeasonNumber.HasValue)
{
details.Add(new XElement("displayseason", episode.AiredBeforeSeasonNumber));
details.Add(new XElement("displayepisode", episode.AiredBeforeEpisodeNumber ?? -1));
}
var tvdbId = new XElement("uniqueid", episode.TvdbId);
tvdbId.SetAttributeValue("type", "tvdb");
tvdbId.SetAttributeValue("default", true);
details.Add(tvdbId);
var sonarrId = new XElement("uniqueid", episode.Id);
sonarrId.SetAttributeValue("type", "sonarr");
details.Add(sonarrId);
if (image == null)
{
details.Add(new XElement("thumb"));
}
else if (Settings.EpisodeImageThumb)
{
details.Add(new XElement("thumb", image.RemoteUrl));
}
details.Add(new XElement("watched", watched));
if (episode.Ratings != null && episode.Ratings.Votes > 0)
{
details.Add(new XElement("rating", episode.Ratings.Value));
}
if (episodeFile.MediaInfo != null)
{
var sceneName = episodeFile.GetSceneOrFileName();
var fileInfo = new XElement("fileinfo");
var streamDetails = new XElement("streamdetails");
var video = new XElement("video");
video.Add(new XElement("aspect", (float)episodeFile.MediaInfo.Width / (float)episodeFile.MediaInfo.Height));
video.Add(new XElement("bitrate", episodeFile.MediaInfo.VideoBitrate));
video.Add(new XElement("codec", MediaInfoFormatter.FormatVideoCodec(episodeFile.MediaInfo, sceneName)));
video.Add(new XElement("framerate", episodeFile.MediaInfo.VideoFps));
video.Add(new XElement("height", episodeFile.MediaInfo.Height));
video.Add(new XElement("scantype", episodeFile.MediaInfo.ScanType));
video.Add(new XElement("width", episodeFile.MediaInfo.Width));
video.Add(new XElement("duration", episodeFile.MediaInfo.RunTime.TotalMinutes));
video.Add(new XElement("durationinseconds", Math.Round(episodeFile.MediaInfo.RunTime.TotalSeconds)));
streamDetails.Add(video);
var audio = new XElement("audio");
var audioChannelCount = episodeFile.MediaInfo.AudioChannels;
audio.Add(new XElement("bitrate", episodeFile.MediaInfo.AudioBitrate));
audio.Add(new XElement("channels", audioChannelCount));
audio.Add(new XElement("codec", MediaInfoFormatter.FormatAudioCodec(episodeFile.MediaInfo, sceneName)));
audio.Add(new XElement("language", episodeFile.MediaInfo.AudioLanguages));
streamDetails.Add(audio);
if (episodeFile.MediaInfo.Subtitles != null && episodeFile.MediaInfo.Subtitles.Count > 0)
{
foreach (var s in episodeFile.MediaInfo.Subtitles)
{
var subtitle = new XElement("subtitle");
subtitle.Add(new XElement("language", s));
streamDetails.Add(subtitle);
}
}
fileInfo.Add(streamDetails);
details.Add(fileInfo);
}
// Todo: get guest stars, writer and director
// details.Add(new XElement("credits", tvdbEpisode.Writer.FirstOrDefault()));
// details.Add(new XElement("director", tvdbEpisode.Directors.FirstOrDefault()));
details.WriteTo(xw);
}
xw.Flush();
var xmlResult = sw.ToString();
return new MetadataFileResult(GetEpisodeMetadataFilename(episodeFile.RelativePath), xmlResult.Trim(Environment.NewLine.ToCharArray()));
}

View File

@@ -72,7 +72,7 @@ namespace NzbDrone.Core.ImportLists.Custom
}
var baseUrl = settings.BaseUrl.TrimEnd('/');
var request = new HttpRequestBuilder(baseUrl).Accept(HttpAccept.Json).Build();
var request = new HttpRequestBuilder(baseUrl).Accept(HttpAccept.Json).AllowRedirect().Build();
var response = _httpClient.Get(request);
var results = JsonConvert.DeserializeObject<List<TResource>>(response.Content);

View File

@@ -1,18 +1,16 @@
using System.Collections.Generic;
using System.Linq;
using NzbDrone.Core.Datastore;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.ImportLists.ImportListItems
{
public interface IImportListItemInfoRepository : IBasicRepository<ImportListItemInfo>
public interface IImportListItemRepository : IBasicRepository<ImportListItemInfo>
{
List<ImportListItemInfo> GetAllForLists(List<int> listIds);
bool Exists(int tvdbId, string imdbId);
}
public class ImportListItemRepository : BasicRepository<ImportListItemInfo>, IImportListItemInfoRepository
public class ImportListItemRepository : BasicRepository<ImportListItemInfo>, IImportListItemRepository
{
public ImportListItemRepository(IMainDatabase database, IEventAggregator eventAggregator)
: base(database, eventAggregator)
@@ -23,21 +21,5 @@ namespace NzbDrone.Core.ImportLists.ImportListItems
{
return Query(x => listIds.Contains(x.ImportListId));
}
public bool Exists(int tvdbId, string imdbId)
{
List<ImportListItemInfo> items;
if (string.IsNullOrWhiteSpace(imdbId))
{
items = Query(x => x.TvdbId == tvdbId);
}
else
{
items = Query(x => x.TvdbId == tvdbId || x.ImdbId == imdbId);
}
return items.Any();
}
}
}

View File

@@ -1,6 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.ThingiProvider.Events;
@@ -9,51 +9,105 @@ namespace NzbDrone.Core.ImportLists.ImportListItems
{
public interface IImportListItemService
{
List<ImportListItemInfo> All();
List<ImportListItemInfo> GetAllForLists(List<int> listIds);
int SyncSeriesForList(List<ImportListItemInfo> listSeries, int listId);
bool Exists(int tvdbId, string imdbId);
}
public class ImportListItemService : IImportListItemService, IHandleAsync<ProviderDeletedEvent<IImportList>>
{
private readonly IImportListItemInfoRepository _importListSeriesRepository;
private readonly Logger _logger;
private readonly IImportListItemRepository _importListItemRepository;
public ImportListItemService(IImportListItemInfoRepository importListSeriesRepository,
Logger logger)
public ImportListItemService(IImportListItemRepository importListItemRepository)
{
_importListSeriesRepository = importListSeriesRepository;
_logger = logger;
_importListItemRepository = importListItemRepository;
}
public int SyncSeriesForList(List<ImportListItemInfo> listSeries, int listId)
{
var existingListSeries = GetAllForLists(new List<int> { listId });
listSeries.ForEach(l => l.Id = existingListSeries.FirstOrDefault(e => e.TvdbId == l.TvdbId)?.Id ?? 0);
var toAdd = new List<ImportListItemInfo>();
var toUpdate = new List<ImportListItemInfo>();
_importListSeriesRepository.InsertMany(listSeries.Where(l => l.Id == 0).ToList());
_importListSeriesRepository.UpdateMany(listSeries.Where(l => l.Id > 0).ToList());
var toDelete = existingListSeries.Where(l => !listSeries.Any(x => x.TvdbId == l.TvdbId)).ToList();
_importListSeriesRepository.DeleteMany(toDelete);
listSeries.ForEach(item =>
{
var existingItem = FindItem(existingListSeries, item);
return toDelete.Count;
if (existingItem == null)
{
toAdd.Add(item);
return;
}
// Remove so we'll only be left with items to remove at the end
existingListSeries.Remove(existingItem);
toUpdate.Add(existingItem);
existingItem.Title = item.Title;
existingItem.Year = item.Year;
existingItem.TvdbId = item.TvdbId;
existingItem.ImdbId = item.ImdbId;
existingItem.TmdbId = item.TmdbId;
existingItem.MalId = item.MalId;
existingItem.AniListId = item.AniListId;
existingItem.ReleaseDate = item.ReleaseDate;
});
_importListItemRepository.InsertMany(toAdd);
_importListItemRepository.UpdateMany(toUpdate);
_importListItemRepository.DeleteMany(existingListSeries);
return existingListSeries.Count;
}
public List<ImportListItemInfo> All()
{
return _importListItemRepository.All().ToList();
}
public List<ImportListItemInfo> GetAllForLists(List<int> listIds)
{
return _importListSeriesRepository.GetAllForLists(listIds).ToList();
return _importListItemRepository.GetAllForLists(listIds).ToList();
}
public void HandleAsync(ProviderDeletedEvent<IImportList> message)
{
var seriesOnList = _importListSeriesRepository.GetAllForLists(new List<int> { message.ProviderId });
_importListSeriesRepository.DeleteMany(seriesOnList);
var seriesOnList = _importListItemRepository.GetAllForLists(new List<int> { message.ProviderId });
_importListItemRepository.DeleteMany(seriesOnList);
}
public bool Exists(int tvdbId, string imdbId)
private ImportListItemInfo FindItem(List<ImportListItemInfo> existingItems, ImportListItemInfo item)
{
return _importListSeriesRepository.Exists(tvdbId, imdbId);
return existingItems.FirstOrDefault(e =>
{
if (e.TvdbId > 0 && item.TvdbId > 0 && e.TvdbId == item.TvdbId)
{
return true;
}
if (e.ImdbId.IsNotNullOrWhiteSpace() && item.ImdbId.IsNotNullOrWhiteSpace() && e.ImdbId == item.ImdbId)
{
return true;
}
if (e.TmdbId > 0 && item.TmdbId > 0 && e.TmdbId == item.TmdbId)
{
return true;
}
if (e.MalId > 0 && item.MalId > 0 && e.MalId == item.MalId)
{
return true;
}
if (e.AniListId > 0 && item.AniListId > 0 && e.AniListId == item.AniListId)
{
return true;
}
return false;
});
}
}
}

View File

@@ -299,12 +299,18 @@ namespace NzbDrone.Core.ImportLists
var seriesToUpdate = new List<Series>();
var seriesInLibrary = _seriesService.GetAllSeries();
var allListItems = _importListItemService.All();
foreach (var series in seriesInLibrary)
{
var seriesExists = _importListItemService.Exists(series.TvdbId, series.ImdbId);
var seriesExists = allListItems.Where(l =>
l.TvdbId == series.TvdbId ||
(l.ImdbId.IsNotNullOrWhiteSpace() && series.ImdbId.IsNotNullOrWhiteSpace() && l.ImdbId == series.ImdbId) ||
l.TmdbId == series.TmdbId ||
series.MalIds.Contains(l.MalId) ||
series.AniListIds.Contains(l.AniListId)).ToList();
if (!seriesExists)
if (!seriesExists.Any())
{
switch (_configService.ListSyncLevel)
{

View File

@@ -1,5 +1,5 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Newtonsoft.Json;
namespace NzbDrone.Core.ImportLists.Trakt
{
@@ -17,7 +17,7 @@ namespace NzbDrone.Core.ImportLists.Trakt
public string Title { get; set; }
public int? Year { get; set; }
public TraktSeriesIdsResource Ids { get; set; }
[JsonPropertyName("aired_episodes")]
[JsonProperty("aired_episodes")]
public int AiredEpisodes { get; set; }
}
@@ -44,11 +44,11 @@ namespace NzbDrone.Core.ImportLists.Trakt
public class RefreshRequestResponse
{
[JsonPropertyName("access_token")]
[JsonProperty("access_token")]
public string AccessToken { get; set; }
[JsonPropertyName("expires_in")]
[JsonProperty("expires_in")]
public int ExpiresIn { get; set; }
[JsonPropertyName("refresh_token")]
[JsonProperty("refresh_token")]
public string RefreshToken { get; set; }
}

View File

@@ -367,7 +367,9 @@ namespace NzbDrone.Core.IndexerSearch
// build list of queries for each episode in the form: "<series> <episode-title>"
searchSpec.EpisodeQueryTitles = episodes.Where(e => !string.IsNullOrWhiteSpace(e.Title))
.Where(e => interactiveSearch || !monitoredOnly || e.Monitored)
.SelectMany(e => searchSpec.CleanSceneTitles.Select(title => title + " " + SearchCriteriaBase.GetCleanSceneTitle(e.Title)))
.Distinct(StringComparer.InvariantCultureIgnoreCase)
.ToArray();
downloadDecisions.AddRange(await Dispatch(indexer => indexer.Fetch(searchSpec), searchSpec));

View File

@@ -454,7 +454,7 @@ namespace NzbDrone.Core.Indexers.Newznab
searchCriteria,
$"&season={NewznabifySeasonNumber(searchCriteria.SeasonNumber)}");
var queryTitles = TextSearchEngine == "raw" ? searchCriteria.SceneTitles : searchCriteria.CleanSceneTitles;
var queryTitles = TextSearchEngine == "raw" ? searchCriteria.AllSceneTitles : searchCriteria.CleanSceneTitles;
foreach (var queryTitle in queryTitles)
{
@@ -582,7 +582,7 @@ namespace NzbDrone.Core.Indexers.Newznab
}
else if (SupportsTvQuerySearch)
{
var queryTitles = TvTextSearchEngine == "raw" ? searchCriteria.SceneTitles : searchCriteria.CleanSceneTitles;
var queryTitles = TvTextSearchEngine == "raw" ? searchCriteria.AllSceneTitles : searchCriteria.CleanSceneTitles;
foreach (var queryTitle in queryTitles)
{
chain.Add(GetPagedRequests(MaxPages,

View File

@@ -1 +1,143 @@
{}
{
"AddedDate": "Добавен: {date}",
"AddANewPath": "Добави нов път",
"AddCustomFilter": "Добави персонализиран филтър",
"AddDownloadClientImplementation": "Добави клиент за изтегляне - {implementationName}",
"AddExclusion": "Добави изключение",
"AddImportList": "Добави списък за импортиране",
"AddIndexer": "Добавете индексатор",
"AirsTomorrowOn": "Утре от {time} по {networkLabel}",
"AddedToDownloadQueue": "Добавен към опашката за изтегляне",
"AfterManualRefresh": "След ръчно опресняване",
"AirsDateAtTimeOn": "{date} в {time} по {networkLabel}",
"AirsTbaOn": "TBA по {networkLabel}",
"AirsTimeOn": "{time} по {networkLabel}",
"AllFiles": "Всички файлове",
"AlternateTitles": "Алтернативни заглавия",
"Any": "Всякакви",
"AddConditionImplementation": "Добави условие - {implementationName}",
"AddConnectionImplementation": "Добави връзка - {implementationName}",
"AddListExclusion": "Добавете изключение от списъка",
"AddImportListExclusion": "Добави изключение от списъка за импортиране",
"AddImportListExclusionError": "Не може да се добави ново изключение от списъка за импортиране, моля, опитайте отново.",
"AddListExclusionSeriesHelpText": "Предотвратете добавянето на сериали в {appName} чрез списъци",
"AnimeEpisodeTypeFormat": "Абсолютен номер на епизода ({format})",
"AddRootFolderError": "Не може да се добави основна папка, моля, опитайте отново",
"AnimeEpisodeTypeDescription": "Епизоди, издадени с абсолютен номер на епизод",
"AnalyseVideoFilesHelpText": "Извлича видео информация, като резолюция, продължителност и информация за кодека от файловете. Това изисква {appName} да прочете части от файла, което може да предизвика висока дискова или мрежова активност по време на сканирането.",
"AnalyticsEnabledHelpText": "Изпращайте анонимна информация за използването и грешките към сървърите на {appName}. Това включва информация за вашия браузър, кои страници на уеб интерфейса на {appName} използвате, докладваните грешки, както и версията на операционната система и изпълнителната среда. Ще използваме тази информация, за да приоритизираме нови функции и поправки на бъгове.",
"Anime": "Аниме",
"AddIndexerError": "Не може да се добави нов индексатор, моля, опитайте отново.",
"AddIndexerImplementation": "Добавете индексатор - {implementationName}",
"AddDelayProfileError": "Не може да се добави нов профил за забавяне, моля, опитайте отново.",
"AddNotificationError": "Не може да се добави ново известие, моля, опитайте отново.",
"AddImportListImplementation": "Добави списък за импортиране - {implementationName}",
"AddList": "Добавете списък",
"AddNewSeriesSearchForMissingEpisodes": "Започнете търсене на липсващи епизоди",
"AddRemotePathMapping": "Добавете мапиране към отдалечен път",
"AddRemotePathMappingError": "Не може да се добави ново мапиране към отдалечен път, моля, опитайте отново.",
"AddToDownloadQueue": "Добавете към опашката за изтегляне",
"AlreadyInYourLibrary": "Вече е във вашата библиотека",
"AnEpisodeIsDownloading": "Изтегля се епизод",
"AnimeEpisodeFormat": "Формат на Аниме епизодите",
"ApiKey": "API ключ",
"Added": "Добавен",
"ApiKeyValidationHealthCheckMessage": "Моля, актуализирайте вашия API ключ, за да бъде с дължина най-малко {length} знака. Може да направите това чрез настройките или конфигурационния файл",
"AddConditionError": "Не може да се добави новo условие, моля, опитайте отново.",
"AddAutoTagError": "Не може да се добави нов автоматичен таг, моля, опитайте отново.",
"AddConnection": "Добави връзка",
"AddCustomFormat": "Добавете персонализиран формат",
"AddCustomFormatError": "Не може да се добави нов персонализиран формат, моля, опитайте отново.",
"AddDelayProfile": "Добавете профил за забавяне",
"AddDownloadClient": "Добави клиент за изтегляне",
"AddDownloadClientError": "Не може да се добави нов клиент за изтегляне, моля, опитайте отново.",
"AddListExclusionError": "Не може да се добави ново изключение от списъка, моля, опитайте отново.",
"AddNewRestriction": "Добавете новo ограничение",
"AddListError": "Не може да се добави нов списък, моля, опитайте отново.",
"AddQualityProfile": "Добавете профил за качество",
"AddQualityProfileError": "Не може да се добави нов профил за качество, моля, опитайте отново.",
"AddReleaseProfile": "Добавете профил за издания",
"Always": "Винаги",
"AnalyseVideoFiles": "Анализирайте видео файловете",
"Analytics": "Анализ",
"AgeWhenGrabbed": "Възраст (при грабване)",
"AddAutoTag": "Добави автоматичен таг",
"AddCondition": "Добави условие",
"AirDate": "Ефирна дата",
"AllTitles": "Всички заглавия",
"AddRootFolder": "Добавете основна папка",
"Add": "Добавяне",
"AddingTag": "Добавяне на таг",
"Age": "Възраст",
"All": "Всички",
"Activity": "Дейност",
"AddNew": "Добавете нов",
"Actions": "Действия",
"About": "Относно",
"Agenda": "Агенда",
"AddNewSeries": "Добавете нов сериал",
"AddNewSeriesError": "Неуспешно зареждане на резултатите от търсенето, моля, опитайте отново.",
"AddNewSeriesHelpText": "Лесно е да добавите нов сериал, просто започнете да въвеждате името на сериала, който искате да добавите.",
"AddNewSeriesRootFolderHelpText": "Подпапката '{folder}' ще бъде създадена автоматично",
"AddNewSeriesSearchForCutoffUnmetEpisodes": "Започни търсене на епизоди, които не са достигнали максималното качество за надграждане",
"AddSeriesWithTitle": "Добавете {title}",
"Absolute": "Абсолютен",
"AllSeriesAreHiddenByTheAppliedFilter": "Всички резултати са скрити от приложения филтър",
"AllSeriesInRootFolderHaveBeenImported": "Всички сериали в {path} са импортирани",
"AbsoluteEpisodeNumber": "Абсолютен епизоден номер",
"AllResultsAreHiddenByTheAppliedFilter": "Всички резултати са скрити от приложения филтър",
"AppDataDirectory": "Директория на приложението",
"SeasonFolder": "Папка ( Сезони )",
"SeasonDetails": "Детайли за сезона",
"SeasonCount": "Брой сезони",
"SslPort": "SSL порт",
"AppDataLocationHealthCheckMessage": "Актуализирането няма да бъде възможно, за да се предотврати изтриването на папката на приложението по време на актуализацията",
"AppUpdated": "{appName} Актуализиран",
"ApplyTagsHelpTextReplace": "Замяна: Заменете таговете с въведените тагове (не въвеждайте тагове, за да изчистите всички тагове)",
"AudioLanguages": "Аудио езици",
"AuthBasic": "Основно (изскачащ прозорец на браузъра)",
"AuthForm": "Формуляри (Страница за вход)",
"AuthenticationMethodHelpText": "Изисквайте потребителско име и парола за достъп до {appName}",
"AuthenticationRequiredPasswordHelpTextWarning": "Въведете нова парола",
"ApplicationURL": "URL адрес на приложението",
"AuthenticationMethodHelpTextWarning": "Моля, изберете валиден метод за удостоверяване",
"AuthenticationRequiredUsernameHelpTextWarning": "Въведете ново потребителско име",
"AuthenticationRequiredWarning": "За да предотврати отдалечен достъп без удостоверяване, {appName} вече изисква удостоверяването да бъде активирано. По желание можете да деактивирате удостоверяването от локални адреси.",
"SeriesFolderFormat": "Формат на папката ( Сериали )",
"ApplyChanges": "Прилагане на промените",
"AutoTaggingLoadError": "Не може да се зареди автоматичното маркиране",
"SeasonFinale": "Финал на сезона",
"AppUpdatedVersion": "{appName} е актуализиран до версия `{version}`, за да получите най-новите промени, ще трябва да презаредите {appName} ",
"ApplicationUrlHelpText": "Външният URL на това приложение, включително http(s)://, порт и базов URL",
"AutoTagging": "Автоматично маркиране",
"Apply": "Приложете",
"ApplyTags": "Прилагане на тагове",
"AutoAdd": "Автоматично добавяне",
"ApplyTagsHelpTextHowToApplyImportLists": "Как да добавите тагове към избраните списъци за импортиране",
"ApplyTagsHelpTextHowToApplySeries": "Как да добавите тагове към избраните сериали",
"SeasonFolderFormat": "Формат на папката ( Сезони )",
"AudioInfo": "Аудио информация",
"Season": "Сезон",
"ApplyTagsHelpTextAdd": "Добавяне: Добавете маркерите към съществуващия списък с маркери",
"ApplyTagsHelpTextRemove": "Премахване: Премахнете въведените тагове",
"RenameEpisodesHelpText": "{appName} ще използва съществуващото име на файла, ако преименуването е деактивирано",
"ApplyTagsHelpTextHowToApplyDownloadClients": "Как да приложите тагове към избраните приложения за сваляне",
"Authentication": "Удостоверяване",
"AuthenticationRequiredHelpText": "Променете за кои заявки се изисква удостоверяване. Не променяйте, освен ако не разбирате рисковете.",
"AutoRedownloadFailed": "Неуспешно повторно изтегляне",
"AutoRedownloadFailedFromInteractiveSearchHelpText": "Автоматично търсене и опит за изтегляне на различна версия, когато неуспешната версия е била взета от интерактивно търсене",
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Потвърдете новата парола",
"AutoTaggingNegateHelpText": "Ако е отметнато, правилото за автоматично маркиране няма да се приложи, ако това условие {implementationName} съвпада.",
"AutoRedownloadFailedFromInteractiveSearch": "Неуспешно повторно изтегляне от интерактивното търсене",
"AutoRedownloadFailedHelpText": "Автоматично търсене и опит за сваляне на различна версия",
"AptUpdater": "Използвайте apt, за да инсталирате актуализацията",
"ApplyTagsHelpTextHowToApplyIndexers": "Как да добавите тагове към избраните индексатори",
"AuthenticationMethod": "Метод за удостоверяване",
"AuthenticationRequired": "Изисква се удостоверяване",
"RenameEpisodes": "Преименуване на епизоди",
"Standard": "Стандартен",
"StandardEpisodeFormat": "Формат на епизода ( Стандартен )",
"SslCertPathHelpText": "Път до \"pfx\" файл",
"EpisodeNaming": "Именуване на епизоди",
"Close": "Затвори"
}

View File

@@ -750,5 +750,13 @@
"Organize": "Organitza",
"Search": "Cerca",
"SelectDropdown": "Seleccioneu...",
"Shutdown": "Apaga"
"Shutdown": "Apaga",
"ClickToChangeReleaseType": "Feu clic per canviar el tipus de llançament",
"BlocklistFilterHasNoItems": "El filtre de la llista de bloqueig seleccionat no conté elements",
"CustomColonReplacement": "Reemplaçament personalitzat de dos punts",
"CountVotes": "{votes} vots",
"Completed": "Completat",
"ContinuingOnly": "Només en emissió",
"CleanLibraryLevel": "Neteja el nivell de la llibreria",
"CountCustomFormatsSelected": "{count} format(s) personalitzat(s) seleccionat(s)"
}

View File

@@ -7,19 +7,19 @@
"AnalyseVideoFiles": "Analyzovat video soubory",
"AnalyseVideoFilesHelpText": "Extrahujte ze souborů informace o videu, jako je rozlišení, doba běhu a informace o kodeku. To vyžaduje, aby {appName} četl části souboru, což může způsobit vysokou aktivitu disku nebo sítě během skenování.",
"ApplicationURL": "URL aplikace",
"ApplicationUrlHelpText": "Externí adresa URL této aplikace včetně http(s)://, portu a základní adresy URL",
"ApplicationUrlHelpText": "Externí adresa URL této aplikace včetně http(s)://, portu a základu URL",
"AuthenticationMethodHelpText": "Vyžadovat uživatelské jméno a heslo pro přístup k {appName}u",
"AuthenticationRequired": "Vyžadované ověření",
"AuthenticationRequiredHelpText": "Změnit, pro které požadavky je vyžadováno ověření. Pokud nerozumíte rizikům, neměňte je.",
"AuthenticationRequiredWarning": "Aby se zabránilo vzdálenému přístupu bez ověření, vyžaduje nyní {appName} povolení ověření. Ověřování z místních adres můžete volitelně zakázat.",
"AuthenticationRequired": "Vyžadováno ověření",
"AuthenticationRequiredHelpText": "Změnit, pro které požadavky je vyžadováno ověření. Neměňte, pokud nerozumíte rizikům.",
"AuthenticationRequiredWarning": "Aby se zabránilo vzdálenému přístupu bez ověření, vyžaduje nyní {appName}, aby bylo povoleno ověřování. Volitelně můžete zakázat ověřování z místních adres.",
"AutoRedownloadFailedHelpText": "Automatické vyhledání a pokus o stažení jiného vydání",
"AutoTaggingLoadError": "Nepodařilo se načíst automatické značky",
"AutomaticAdd": "Přidat automaticky",
"BackupIntervalHelpText": "Interval mezi automatickými zálohami",
"BackupRetentionHelpText": "Automatické zálohy starší než doba uchovávání budou automaticky vyčištěny",
"BackupsLoadError": "Nelze načíst zálohy",
"BranchUpdate": "Větev, která se použije k aktualizaci {appName}u",
"BranchUpdateMechanism": "Větev používaná externím aktualizačním mechanismem",
"BranchUpdate": "Větev použi k aktualizaci {appName}u",
"BranchUpdateMechanism": "Větev použitá externím aktualizačním mechanismem",
"BrowserReloadRequired": "Vyžaduje se opětovné načtení prohlížeče",
"BuiltIn": "Vestavěný",
"BypassDelayIfHighestQualityHelpText": "Obejít zpoždění, když má vydání nejvyšší povolenou kvalitu v profilu kvality s preferovaným protokolem",
@@ -37,7 +37,7 @@
"Connect": "Připojit",
"ConnectSettingsSummary": "Oznámení, připojení k mediálním serverům/přehrávačům a vlastní skripty",
"Connections": "Připojení",
"AbsoluteEpisodeNumber": "Úplné číslo dílu",
"AbsoluteEpisodeNumber": "Celkový počet epizod",
"AddAutoTagError": "Nepodařilo se přidat novou automatickou značku, zkuste to prosím znovu.",
"AddConditionError": "Nepodařilo se přidat novou podmínku, prosím, zkuste to znovu.",
"AddConnection": "Přidat spojení",
@@ -58,12 +58,12 @@
"Automatic": "Automatický",
"AutoTaggingNegateHelpText": "Pokud je zaškrtnuto, pravidlo automatického označování se nepoužije, pokud odpovídá této podmínce {implementationName}.",
"BindAddress": "Vázat adresu",
"BindAddressHelpText": "Platná IP adresa, localhost nebo '*' pro všechna rozhraní",
"BindAddressHelpText": "Platná IP adresa, localhost nebo * pro všechna rozhraní",
"BlocklistLoadError": "Nelze načíst černou listinu",
"BypassDelayIfHighestQuality": "Obejít v případě nejvyšší kvality",
"BypassDelayIfAboveCustomFormatScoreHelpText": "Povolit obcházení, pokud má vydání vyšší skóre, než je nakonfigurované minimální skóre vlastního formátu",
"BypassDelayIfAboveCustomFormatScoreMinimumScore": "Minimální skóre vlastního formátu",
"CertificateValidation": "Ověření certifikátu",
"CertificateValidation": "Ověřování certifikátu",
"CalendarLoadError": "Nelze načíst kalendář",
"CertificateValidationHelpText": "Změňte přísnost ověřování certifikátů HTTPS. Neměňte, pokud nerozumíte rizikům.",
"ChownGroupHelpText": "Název skupiny nebo gid. Použijte gid pro vzdálené systémy souborů.",
@@ -76,29 +76,29 @@
"CollectionsLoadError": "Nelze načíst sbírky",
"CompletedDownloadHandling": "Zpracování stahování bylo dokončeno",
"Condition": "Stav",
"UpdateMechanismHelpText": "Použijte vestavěný nástroj {appName}u pro aktualizaci nebo skript",
"UpdateMechanismHelpText": "Použij vestavěný nástroj {appName}u pro aktualizaci nebo skript",
"AddCondition": "Přidat podmínku",
"AutoTagging": "Automatické označování",
"AddAutoTag": "Přidat automatickou značku",
"AutoTaggingRequiredHelpText": "Tato podmínka {implementationName} musí odpovídat, aby se pravidlo automatického označování použilo. V opačném případě postačí jediná shoda s {implementationName}.",
"AirDate": "Datum vysílání",
"AllTitles": "Všechny názvy",
"AbsoluteEpisodeNumbers": "Úplné číslo dílu(ů)",
"AbsoluteEpisodeNumbers": "Celkový počet epizod",
"AddRootFolder": "Přidat kořenový adresář",
"Backups": "Zálohy",
"Clear": "Vyčistit",
"BeforeUpdate": "Před zálohováním",
"Clear": "Vymazat",
"BeforeUpdate": "Před aktualizací",
"CloneAutoTag": "Klonovat automatické značky",
"Conditions": "Podmínky",
"CancelPendingTask": "Opravdu chcete zrušit tento nevyřízený úkol?",
"CancelPendingTask": "Opravdu chcete zrušit tento úkol čekající na vyřízení?",
"Apply": "Použít",
"AddingTag": "Přidání značky",
"ApplyTags": "Použít značky",
"AddingTag": "Přidáštítku",
"ApplyTags": "Použít štítky",
"AutoAdd": "Přidat automaticky",
"Cancel": "Zrušit",
"ApplyTagsHelpTextHowToApplyDownloadClients": "Jak použít značky na vybrané klienty pro stahování",
"ApplyTagsHelpTextHowToApplyImportLists": "Jak použít značky na vybrané seznamy k importu",
"ApplyTagsHelpTextHowToApplyIndexers": "Jak použít značky na vybrané indexery",
"ApplyTagsHelpTextHowToApplyIndexers": "Jak použít štítky na vybrané indexery",
"AudioInfo": "Audio informace",
"Age": "Stáří",
"AudioLanguages": "Jazyky zvuku",
@@ -114,22 +114,22 @@
"AllResultsAreHiddenByTheAppliedFilter": "Všechny výsledky jsou schovány použitým filtrem",
"AddANewPath": "Přidat novou cestu",
"AddCustomFormatError": "Nebylo možné přidat nový vlastní formát, prosím zkuste to později.",
"AddDownloadClientImplementation": "Přidat klienta pro stahování - {implementationName}",
"AddDownloadClientImplementation": "Přidat klienta pro stahování {implementationName}",
"AddImportListExclusionError": "Nebylo možné přidat nové importované položky, prosím zkuste to později.",
"ApplyTagsHelpTextRemove": "Odebrat: Odebrat zadané značky",
"ApplyTagsHelpTextAdd": "Přidat: Přidá značky k již existujícímu seznamu",
"ApplyTagsHelpTextReplace": "Nahradit: Nahradit značky zadanými značkami (prázdné pole vymaže všechny značky)",
"ApplyTagsHelpTextRemove": "Odebrat: Odebrat zadané štítky",
"ApplyTagsHelpTextAdd": "Přidat: Přidat štítky do existujícího seznamu štítků",
"ApplyTagsHelpTextReplace": "Nahradit: Nahradit štítky zadanými štítky (prázdné pole vymaže všechny štítky)",
"Backup": "Záloha",
"Activity": "Aktivita",
"Blocklist": "Blocklist",
"AddNew": "Přidat nové",
"About": "O aplikaci",
"Actions": "Akce",
"AptUpdater": "K instalaci aktualizace použijte apt",
"BackupNow": "Ihned zálohovat",
"AppDataDirectory": "Adresář AppData",
"AptUpdater": "K instalaci aktualizace používat apt",
"BackupNow": "Zálohovat nyní",
"AppDataDirectory": "AppData Adresář",
"ApplyTagsHelpTextHowToApplySeries": "Jak použít značky na vybrané seriály",
"BackupFolderHelpText": "Relativní cesty se budou nacházet v adresáři AppData systému {appName}",
"BackupFolderHelpText": "Relativní cesty budou v adresáři AppData {appName}u",
"BlocklistReleases": "Blocklist pro vydání",
"Agenda": "Agenda",
"AnEpisodeIsDownloading": "Epizoda se stahuje",
@@ -138,7 +138,7 @@
"AddNewSeriesError": "Výsledky vyhledávání se nepodařilo načíst, zkuste to prosím znovu.",
"AddNewSeriesHelpText": "Přidání nového seriálu je snadné, stačí začít psát název seriálu, který chcete přidat.",
"AddNewSeriesRootFolderHelpText": "'{folder}' posdložka bude vytvořena automaticky",
"AddNewSeriesSearchForCutoffUnmetEpisodes": "Zahájit hledání vynechaných epizod",
"AddNewSeriesSearchForCutoffUnmetEpisodes": "Zahájit hledání Neodpovídajících vynechaných epizod",
"AddNewSeriesSearchForMissingEpisodes": "Zahájit hledání chybějících epizod",
"AddReleaseProfile": "Přidat profil vydání",
"AddRemotePathMapping": "Přidat mapování vzdálených cest",
@@ -150,7 +150,7 @@
"ClickToChangeSeries": "Kliknutím změníte seriál",
"AddNotificationError": "Nebylo možné přidat nové oznámení, prosím zkuste to později.",
"AddConditionImplementation": "Přidat podmínku - {implementationName}",
"AddConnectionImplementation": "Přidat spojení - {implementationName}",
"AddConnectionImplementation": "Přidat spojení {implementationName}",
"AddCustomFilter": "Přidat vlastní filtr",
"AddDownloadClient": "Přidat klienta pro stahování",
"AddDelayProfile": "Přidat profil zpoždění",
@@ -159,7 +159,7 @@
"AddImportListExclusion": "Přidat výjimku ze seznamu k importu",
"AddImportList": "Přidat importované položky",
"AddImportListImplementation": "Přidat seznam k importu - {implementationName}",
"AddIndexerImplementation": "Přidat indexer - {implementationName}",
"AddIndexerImplementation": "Přidat indexer {implementationName}",
"AddQualityProfileError": "Nebylo možné přidat nový profil kvality, prosím zkuste to později.",
"AddToDownloadQueue": "Přidat stahování do fronty",
"Airs": "Vysíláno",
@@ -170,7 +170,7 @@
"CalendarOptions": "Možnosti kalendáře",
"AllFiles": "Všechny soubory",
"Analytics": "Analýzy",
"AnalyticsEnabledHelpText": "Odesílání anonymních informací o používání a chybách na servery společnosti {appName}. To zahrnuje informace o vašem prohlížeči, o tom, které stránky webového rozhraní {appName} používáte, hlášení chyb a také informace o verzi operačního systému a běhového prostředí. Tyto informace použijeme k určení priorit funkcí a oprav chyb.",
"AnalyticsEnabledHelpText": "Odesílejte anonymní informace o použití a chybách na servery {appName}u. To zahrnuje informace o vašem prohlížeči, které stránky webového rozhraní {appName}u používáte, hlášení chyb a také verzi operačního systému a běhového prostředí. Tyto informace použijeme k určení priorit funkcí a oprav chyb.",
"Anime": "Anime",
"AnimeEpisodeFormat": "Formát epizod pro Anime",
"AnimeEpisodeTypeDescription": "Epizody vydané s použitím absolutního čísla epizody",
@@ -182,7 +182,7 @@
"ChooseImportMode": "Vyberte mód importu",
"ClickToChangeEpisode": "Kliknutím změníte epizodu",
"ClickToChangeLanguage": "Kliknutím změníte jazyk",
"AutomaticSearch": "Vyhledat automaticky",
"AutomaticSearch": "Automatické vyhledávání",
"AutomaticUpdatesDisabledDocker": "Automatické aktualizace nejsou při použití aktualizačního mechanismu Docker přímo podporovány. Obraz kontejneru je nutné aktualizovat mimo {appName} nebo použít skript",
"Branch": "Větev",
"BypassDelayIfAboveCustomFormatScore": "Obejít, pokud je vyšší než skóre vlastního formátu",
@@ -202,9 +202,9 @@
"CloneProfile": "Klonovat profil",
"CollapseMultipleEpisodes": "Sbalení více epizod",
"CollapseMultipleEpisodesHelpText": "Sbalení více epizod vysílaných ve stejný den",
"ConnectionLost": "Spojení ztraceno",
"ConnectionLost": "Ztráta spojení",
"ConnectionLostReconnect": "{appName} se pokusí připojit automaticky, nebo můžete kliknout na tlačítko znovunačtení níže.",
"ConnectionLostToBackend": "{appName} ztratil spojení s backendem a pro obnovení funkčnosti bude třebaho znovu načíst.",
"ConnectionLostToBackend": "{appName} ztratil spojení s backendem a pro obnovení funkčnosti bude potřeba ho znovu načíst.",
"Continuing": "Pokračující",
"CountSeasons": "{count} Řad",
"CustomFormat": "Vlastní formát",
@@ -229,7 +229,7 @@
"CurrentlyInstalled": "Aktuálně nainstalováno",
"CountImportListsSelected": "{count} vybraných seznamů pro import",
"CustomFormatScore": "Skóre vlastního formátu",
"CountDownloadClientsSelected": "{count} vybraných klientů ke stahování",
"CountDownloadClientsSelected": "{count} vybraných klientů pro stahování",
"CouldNotFindResults": "Nepodařilo se najít žádné výsledky pro '{term}'",
"CustomFormatsSettings": "Nastavení vlastních formátů",
"CopyToClipboard": "Zkopírovat do schránky",
@@ -266,12 +266,12 @@
"Dash": "Pomlčka",
"Database": "Databáze",
"Date": "Datum",
"Dates": "Termíny",
"Dates": "Data",
"DefaultCase": "Výchozí případ",
"DailyEpisodeTypeFormat": "Datum ({format})",
"Default": "Výchozí",
"IndexerDownloadClientHelpText": "Zvolte, který klient pro stahování bude použit pro zachytávání z toho indexeru",
"DeletedReasonManual": "Soubor byl smazán pomocí UI",
"DeletedReasonManual": "Soubor byl odstraněn pomocí {appName}, a to buď ručně, nebo jiným nástrojem prostřednictvím rozhraní API",
"DeletedReasonUpgrade": "Soubor byl odstraněn pro import lepší verze",
"EditConditionImplementation": "Upravit sbírku - {implementationName}",
"ClearBlocklist": "Vyčistit blocklist",
@@ -303,10 +303,10 @@
"FormatAgeHour": "hodina",
"FormatAgeHours": "hodin",
"AuthenticationMethod": "Metoda ověřování",
"AuthenticationMethodHelpTextWarning": "Prosím vyberte platnou metodu ověřování",
"AuthenticationRequiredPasswordHelpTextWarning": "Vložte nové heslo",
"AuthenticationMethodHelpTextWarning": "Vyberte platnou metodu ověřování",
"AuthenticationRequiredPasswordHelpTextWarning": "Zadejte nové heslo",
"EditSelectedIndexers": "Upravit vybrané indexery",
"AuthenticationRequiredUsernameHelpTextWarning": "Vložte nové uživatelské jméno",
"AuthenticationRequiredUsernameHelpTextWarning": "Zadejte nové uživatelské jméno",
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Potvrďte nové heslo",
"AutoRedownloadFailedFromInteractiveSearchHelpText": "Automaticky vyhledat a pokusit se o stažení jiného vydání, pokud bylo neúspěšné vydání zachyceno z interaktivního vyhledávání",
"AutoRedownloadFailed": "Opětovné stažení se nezdařilo",
@@ -321,8 +321,8 @@
"DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Klient stahování {downloadClientName} je nastaven na odstranění dokončených stahování. To může vést k tomu, že stahování budou z klienta odstraněna dříve, než je bude moci importovat {appName}.",
"ConnectionSettingsUrlBaseHelpText": "Přidá předponu do {connectionName} url, jako např. {url}",
"CustomFormatsSpecificationRegularExpressionHelpText": "Vlastní formát RegEx nerozlišuje velká a malá písmena",
"CustomFormatsSpecificationFlag": "Vlajka",
"BlackholeFolderHelpText": "Složka do které {appName} uloží {extension} soubor",
"CustomFormatsSpecificationFlag": "Značka",
"BlackholeFolderHelpText": "Složka, do které {appName} uloží soubor {extension}",
"BlackholeWatchFolder": "Složka sledování",
"Category": "Kategorie",
"BlocklistAndSearch": "Seznam blokovaných a vyhledávání",
@@ -330,5 +330,190 @@
"BlocklistReleaseHelpText": "Zabránit {appName} v opětovném sebrání tohoto vydání pomocí RSS nebo automatického vyhledávání",
"BlocklistMultipleOnlyHint": "Blokovat a nehledat náhradu",
"CustomFormatsSettingsTriggerInfo": "Vlastní formát se použije na vydání nebo soubor, pokud odpovídá alespoň jednomu z různých typů zvolených podmínek.",
"ChangeCategory": "Změnit kategorii"
"ChangeCategory": "Změnit kategorii",
"CustomFilter": "Vlastní filtr",
"ClickToChangeIndexerFlags": "Kliknutím změníte značky indexeru",
"QualityProfile": "Profil Kvality",
"ContinuingSeriesDescription": "Očekává se více dílů/další sezóna",
"DeleteReleaseProfile": "Smazat profil vydání",
"DownloadClientDelugeSettingsUrlBaseHelpText": "Přidá prefix do url adresy json deluge, viz {url}",
"DownloadClientQbittorrentSettingsFirstAndLastFirst": "Nejprve první a poslední",
"DownloadClientRTorrentSettingsAddStopped": "Přidat zastavené",
"DownloadClientRTorrentSettingsUrlPathHelpText": "Cesta ke koncovému bodu XMLRPC, viz {url}. Při použití ruTorrentu je to obvykle RPC2 nebo [cesta k ruTorrentu]{url2}.",
"AddListExclusion": "Přidej Seznam Výjimek",
"DeleteSelectedSeries": "Smazat vybrané seriály",
"AllSeriesAreHiddenByTheAppliedFilter": "Všechny výsledky jsou skryté použitým filtrem",
"DeleteSeriesFoldersHelpText": "Smazat složky seriálu a všechno v nich",
"DownloadClientNzbgetSettingsAddPausedHelpText": "Tato volba vyžaduje NzbGet verze alespoň 16.0",
"Priority": "Přednost",
"ProxyBadRequestHealthCheckMessage": "Nepodařilo se otestovat proxy. Kód Stavu: {statusCode}",
"DownloadClientFreeboxSettingsPortHelpText": "Port použitý pro přístup k rozhraní Freeboxu, výchozí hodnota je {port}",
"CountSeriesSelected": "{count} vybrané seriály",
"CleanLibraryLevel": "Vyčistit Úroveň Knihovny",
"DeleteSeriesFolders": "Smazat složky seriálu",
"DoNotPrefer": "Neupřednostňovat",
"Destination": "Cesta",
"AddListExclusionSeriesHelpText": "„Zamezit přidávání Seriálu do {appName} prostřednictvím seznamů“",
"CountCustomFormatsSelected": "{count} vybraný vlastní formát(y)",
"DeleteQualityProfile": "Smazat profil kvality",
"DeleteSpecification": "Smaž specifikace",
"MappedNetworkDrivesWindowsService": "Mapované síťové jednotky nejsou k dispozici, když běží jako služba Windows. Další informace najdete v [FAQ]({url}).",
"DeletedSeriesDescription": "Seriál byl smazán z TheTVDB",
"RecycleBinUnableToWriteHealthCheckMessage": "Nelze zapisovat do nakonfigurované složky koše: {path}. Ujistěte se, že tato cesta existuje a že do ní může zapisovat uživatel se spuštěnou {appName}",
"DeleteSelectedImportListExclusionsMessageText": "Opravdu smazat vybraný importovaný seznam vyjímek?",
"DoNotUpgradeAutomatically": "Neupgradovat automaticky",
"DownloadClientQbittorrentSettingsInitialStateHelpText": "Počáteční stav torrentů přidaných do qBittorrentu. Pamatujte, že vynucené torrenty nedodržují omezení týkající se seedů",
"DeleteSelectedCustomFormats": "Smazat vlastní formát(y)",
"ClickToChangeReleaseType": "Kliknutím změníte typ verze",
"CollapseAll": "Sbal Všechno",
"CutoffUnmetNoItems": "Žádné neodpovídající nesplněné položky",
"CutoffUnmetLoadError": "Chybné načítání nesplněných položek",
"AddDelayProfileError": "Nelze přidat nový profil zpoždění, zkuste to prosím znovu.",
"AddedDate": "Přidáno: {date}",
"AlternateTitles": "Střídej tituly",
"BlocklistAndSearchHint": "Začne hledat náhradu po blokaci",
"BlocklistAndSearchMultipleHint": "Začne vyhledávat náhrady po blokaci",
"BlocklistFilterHasNoItems": "Vybraný filtr blokování neobsahuje žádné položky",
"BlocklistOnly": "Pouze seznam blokování",
"BlocklistOnlyHint": "Přidat do seznamu blokování bez náhrady",
"DeleteRemotePathMapping": "Smazat externí cestu k souboru",
"AutoTaggingSpecificationTag": "Značka",
"ChangeCategoryHint": "Změní stahování do kategorie „Post-Import“ z aplikace Download Client",
"ChangeCategoryMultipleHint": "Změní stahování do kategorie „Post-Import“ z aplikace Download Client",
"DeleteSelected": "Smazat vybrané",
"DownloadClientDelugeValidationLabelPluginFailureDetail": "{appName} nemohl(a) přidat etiketu k {clientName}.",
"DayOfWeekAt": "{day} v {time}",
"CountVotes": "{votes} hlasy",
"CustomColonReplacementFormatHint": "Platný znak souborového systému, například dvojtečka (písmeno)",
"ProxyFailedToTestHealthCheckMessage": "Nepodařilo se otestovat proxy: {url}",
"Completed": "Hotovo",
"DockerUpdater": "Aby jsi získal aktualizaci proveď update docker kontejneru",
"CustomFormatsSpecificationExceptLanguage": "Vyjma jazyka",
"CustomFormatsSpecificationExceptLanguageHelpText": "Odpovídá, pokud je přítomen jiný jazyk než vybraný",
"CustomFormatsSpecificationMaximumSize": "Maximální velikost",
"CustomFormatsSpecificationReleaseGroup": "Vydávající Skupina",
"CutoffNotMet": "Mezní hodnota není splněna",
"DeleteEpisodeFile": "Smazat Soubor Epizody",
"DeleteEpisodeFileMessage": "Opravdu chceš smazat '{path}'?",
"DeleteEpisodeFromDisk": "Smazat Epizodu z disku",
"DeleteIndexer": "Smazat Indexer",
"DeleteRemotePathMappingMessageText": "Opravdu chceš smazat tohle externí cestu k souboru?",
"Directory": "Adresář",
"DoNotBlocklist": "Nepřidávat do Seznamu blokování",
"DoneEditingGroups": "Úpravy skupin dokončeny",
"DeleteSeriesModalHeader": "Smazat - {title}",
"DeleteSelectedCustomFormatsMessageText": "Opravdu odstranit {count} vybraný vlastní formát(y)?",
"DownloadClientCheckNoneAvailableHealthCheckMessage": "Nedostupný klient pro stahování",
"DownloadClientCheckUnableToCommunicateWithHealthCheckMessage": "Nelze komunikovat s {downloadClientName}. {errorMessage}",
"DownloadClientFreeboxSettingsAppTokenHelpText": "Token aplikace získaný při vytváření přístupu k Freebox API (tj. app_token)",
"DownloadClientFreeboxSettingsAppToken": "Token aplikace",
"Enable": "Povolit",
"Episode": "Epizoda",
"DestinationPath": "Cesta Destinace",
"EnableAutomaticSearchHelpText": "Použije se při automatickém vyhledávání prostřednictvím uživatelského rozhraní nebo pomocí {appName}",
"CustomColonReplacement": "Vlastní Náhrada znaku dvojtečky",
"CustomColonReplacementFormatHelpText": "Znaky které nahradí dvojtečky",
"DeleteEpisodesFiles": "Smazat{episodeFileCount} Soubory Epizody",
"DeleteEpisodesFilesHelpText": "Smazat soubory epizody a složku seriálu",
"DeleteImportListExclusionMessageText": "Opravdu chceš smazat tento import Seznamu Vyjímek?",
"DeleteSelectedEpisodeFiles": "Smazat soubory vybrané epizody",
"DeleteSelectedEpisodeFilesHelpText": "Opravdu smazat soubory vybrané epizody?",
"DeleteSeriesFolderConfirmation": "Složka seriálu `{path}` a veškerý její obsah bude smazán.",
"DeleteSeriesFolderEpisodeCount": "{episodeFileCount} celkově souborů epizody {size}",
"Details": "Detaily",
"DetailedProgressBar": "Podrobný ukazatel průběhu",
"DeleteSeriesFolderHelpText": "Smazat složku seriálu a její obsah",
"DoNotBlocklistHint": "Odstraň bez přidání do seznamu blokování",
"Donate": "Daruj",
"DownloadClientAriaSettingsDirectoryHelpText": "Volitelné umístění pro stahování, pokud chcete použít výchozí umístění Aria2, ponechte prázdné",
"DownloadClientDelugeValidationLabelPluginFailure": "Konfigurace etikety selhala",
"DownloadClientFloodSettingsAdditionalTagsHelpText": "Přidá vlastnosti médií jako značky. Nápovědy jsou příklady.",
"DownloadClientFreeboxSettingsApiUrl": "API URL",
"DownloadClientFreeboxSettingsApiUrlHelpText": "Definuj základní adresu URL rozhraní Freebox API s verzí rozhraní API, např. {url}, výchozí hodnota je {defaultApiUrl}",
"DownloadClientFreeboxSettingsAppId": "ID aplikace",
"DownloadClientFreeboxSettingsAppIdHelpText": "ID aplikace zadané při vytváření přístupu k Freebox API (tj. app_id)",
"DownloadClientQbittorrentSettingsContentLayout": "Rozvržení obsahu",
"DownloadClientQbittorrentSettingsSequentialOrder": "Postupné pořadí",
"DownloadClientRTorrentSettingsAddStoppedHelpText": "Povolení přidá torrenty a magnety do rTorrentu v zastaveném stavu. To může způsobit poškození souborů magnet.",
"DownloadClientRTorrentSettingsDirectoryHelpText": "Volitelné umístění pro stahování, ponechte prázdné pro použití výchozího umístění rTorrentu",
"Donations": "Dary",
"Connection": "Spojení",
"DeleteSeriesFolder": "Smazat složku seriálu",
"DeleteNotification": "Smazat Oznámení",
"DownloadClientFloodSettingsAdditionalTags": "Další Značky",
"DownloadClientFloodSettingsUrlBaseHelpText": "Přidá prefix do Flood API, viz {url}",
"DownloadClientDownloadStationSettingsDirectoryHelpText": "Volitelná sdílená složka, do které se mají stahované soubory ukládat, pokud chcete použít výchozí umístění Download Station, ponechte prázdné",
"DownloadClientFreeboxSettingsHostHelpText": "Název hostitele nebo IP adresa hostitele Freeboxu, výchozí hodnota je {url} (funguje pouze ve stejné síti)",
"DownloadClientQbittorrentSettingsFirstAndLastFirstHelpText": "Stahovat nejprve první a poslední kusy (qBittorrent 4.1.0+)",
"DownloadClientQbittorrentSettingsSequentialOrderHelpText": "Stahovat v postupném pořadí (qBittorrent 4.1.0+)",
"DownloadClientQbittorrentSettingsUseSslHelpText": "Používat zabezpečené připojení. Viz Možnosti -> WebUI -> Webové uživatelské rozhraní -> Použít HTTPS místo HTTP v qBittorrentu.",
"DownloadClientTransmissionSettingsDirectoryHelpText": "Volitelné umístění pro stahování, ponechte prázdné pro použití výchozího umístění Transmission",
"DownloadClients": "Klienti pro stahování",
"HealthMessagesInfoBox": "Další informace o příčině těchto zpráv o kontrole zdraví najdete kliknutím na odkaz wiki (ikona knihy) na konci řádku nebo kontrolou [logů]({link}). Pokud máte potíže s interpretací těchto zpráv, můžete se obrátit na naši podporu, a to na níže uvedených odkazech.",
"GrabRelease": "Získat vydání",
"DownloadClientRTorrentSettingsUrlPath": "Cesta URL",
"Indexer": "Indexer",
"CustomFormatsSpecificationMaximumSizeHelpText": "Vydání musí odpovídat nebo být menší než tato velikost",
"CustomFormatsSpecificationMinimumSize": "Minimální velikost",
"Deleted": "Smazáno",
"DeletedReasonEpisodeMissingFromDisk": "{appName} nenalezen soubor na disku, Došlo k odvázání souboru na epizodu v databázi",
"DeleteSeriesFolderCountConfirmation": "Opravdu smazat {count} vybraný seriál?",
"DetailedProgressBarHelpText": "Zobrazit text na Ukazateli průběhu",
"Disabled": "Zakázáno",
"DownloadClientFloodSettingsTagsHelpText": "Počáteční značky stahování. Aby bylo stahování rozpoznáno, musí mít všechny počáteční značky. Tím se zabrání konfliktům s nesouvisejícími stahováními.",
"Filters": "Filtry",
"Implementation": "Implementace",
"DownloadClientPneumaticSettingsStrmFolderHelpText": "Soubory .strm v této složce budou importovány pomocí drone",
"History": "Historie",
"Discord": "Discord",
"DotNetVersion": ".NET",
"Download": "Stáhnout",
"DownloadClient": "Download klient",
"DownloadClientSettingsInitialStateHelpText": "Počáteční stav pro torrenty přidané do {clientName}",
"DownloadClientSettingsInitialState": "Počáteční stav",
"DownloadClientSettingsDestinationHelpText": "Ručně určuje cíl stahování, pro použití výchozího nastavení nechte prázdné",
"DownloadClientSettingsUseSslHelpText": "Při připojení k {clientName} použít zabezpečené připojení",
"EditConnectionImplementation": "Upravit připojení - {implementationName}",
"EnableInteractiveSearchHelpText": "Použije se při interaktivním vyhledávání",
"Ended": "Ukončeno",
"External": "Externí",
"General": "Obecné",
"AutoTaggingSpecificationGenre": "Žánr(y)",
"AutoTaggingSpecificationMaximumYear": "Maximální Rok",
"AutoTaggingSpecificationMinimumYear": "Minimální Rok",
"AutoTaggingSpecificationOriginalLanguage": "Jazyk",
"AutoTaggingSpecificationQualityProfile": "Profil Kvality",
"AutoTaggingSpecificationRootFolder": "Kořenová Složka",
"AutoTaggingSpecificationSeriesType": "Typ seriálu",
"AutoTaggingSpecificationStatus": "Status",
"CustomFormatsSpecificationLanguage": "Jazyk",
"CustomFormatsSpecificationRegularExpression": "Běžný výraz",
"CustomFormatsSpecificationMinimumSizeHelpText": "Vydání musí být větší než tato velikost",
"CustomFormatsSpecificationResolution": "Rozlišení",
"CustomFormatsSpecificationSource": "Zdroj",
"DeleteImportListExclusion": "Smazat import Seznamu Vyjímek",
"DiskSpace": "Místo na disku",
"DeleteReleaseProfileMessageText": "Opravdu smazat profil vydání '{name}'?",
"Docker": "Docker",
"DownloadClientQbittorrentSettingsContentLayoutHelpText": "Zda použít rozvržení obsahu nakonfigurované v qBittorrentu, původní rozvržení z torrentu nebo vždy vytvořit podsložku (qBittorrent 4.3.2+)",
"DownloadClientSettingsAddPaused": "Přidat pozastavené",
"DownloadClientSettingsUrlBaseHelpText": "Přidá prefix k {clientName}, například {url}",
"ExistingTag": "Stávající značka",
"ProxyResolveIpHealthCheckMessage": "Nepodařilo se vyřešit adresu IP konfigurovaného hostitele proxy {proxyHostName}",
"DownloadClientDelugeSettingsDirectory": "Adresář stahování",
"DownloadClientPneumaticSettingsNzbFolder": "Složka Nzb",
"FailedToFetchSettings": "Nepodařilo se načíst nastavení",
"DownloadClientSettings": "Nastavení klienta pro stahování",
"Grabbed": "Získáno",
"DatabaseMigration": "Migrace databáze",
"Delay": "Zpoždění",
"DeleteEmptyFolders": "Vymazat prázdné složky",
"DeleteEmptySeriesFoldersHelpText": "Smazat Složky prázdného Seriálu a Sezóny Během skenování a pokud jsou soubory epizody vymazány",
"DeleteTag": "Smazat štítek",
"DeleteTagMessageText": "Opravdu chceš smazat štítek \"{label}\"?",
"DestinationRelativePath": "Relativní cesta Destinace",
"DeleteSpecificationHelpText": "Opravdu smazat specifikaci '{name}'?",
"DownloadClientStatusAllClientHealthCheckMessage": "Všichni klienti pro stahování jsou nedostupní z důvodu selhání",
"DownloadClientStatusSingleClientHealthCheckMessage": "Klienti pro stahování jsou nedostupní z důvodu selhání: {downloadClientNames}",
"DownloadClientTransmissionSettingsUrlBaseHelpText": "Přidá předponu k url {clientName} rpc, např. {url}, výchozí hodnota je {defaultUrl}"
}

View File

@@ -103,5 +103,20 @@
"DeleteReleaseProfileMessageText": "Er du sikker på, at du vil slette udgivelsesprofilen »{name}«?",
"MinutesSixty": "60 minutter: {sixty}",
"NegateHelpText": "Hvis dette er markeret, gælder det tilpassede format ikke, hvis denne {implementationName}-betingelse stemmer overens.",
"RemoveSelectedItemsQueueMessageText": "Er du sikker på, at du vil fjerne {selectedCount} elementer fra køen?"
"RemoveSelectedItemsQueueMessageText": "Er du sikker på, at du vil fjerne {selectedCount} elementer fra køen?",
"AddNewSeriesSearchForCutoffUnmetEpisodes": "Start søgning efter uopfyldte cutoff epsioder",
"AddNewSeriesRootFolderHelpText": "'{folder}' undermappen vil blive oprettet automatisk",
"AddNewSeriesSearchForMissingEpisodes": "Start søgning efter manglende episoder",
"AddListExclusionSeriesHelpText": "Forhindre serie fra at blive tilføjet til {appName} af lister",
"AddQualityProfile": "Tilføj Kvalitetsprofil",
"AddReleaseProfile": "Tilføj udgivelsesprofil",
"AddNewSeriesError": "Kunne ikke indlæse søgeresultater, prøv igen.",
"AddNewSeriesHelpText": "Det er nemt at tilføje en ny serie, bare start med at skrive navnet på serien du gerne vil tilføje.",
"AddQualityProfileError": "Kunne ikke tilføje ny kvalitetsprofil, prøv igen.",
"AddListExclusionError": "Kunne ikke tilføje den nye liste eksklusion, prøv igen.",
"AddNewRestriction": "Tilføj ny restriktion",
"AddNotificationError": "Kunne ikke tilføje ny notifikation, prøv igen.",
"AddRemotePathMapping": "Tilføj Sammenkædning med fjernsti",
"AddNew": "Tilføj ny",
"AddNewSeries": "Tilføj ny serie"
}

View File

@@ -22,7 +22,7 @@
"Language": "Sprache",
"CloneCondition": "Bedingung klonen",
"DeleteCondition": "Bedingung löschen",
"DeleteConditionMessageText": "Bist du sicher, dass du die Bedingung '{0}' löschen willst?",
"DeleteConditionMessageText": "Bist du sicher, dass du die Bedingung '{name}' löschen willst?",
"DeleteCustomFormatMessageText": "Bist du sicher, dass du das benutzerdefinierte Format '{name}' wirklich löschen willst?",
"RemoveSelectedItemQueueMessageText": "Bist du sicher, dass du ein Eintrag aus der Warteschlange entfernen willst?",
"RemoveSelectedItemsQueueMessageText": "Bist du sicher, dass du {selectedCount} Einträge aus der Warteschlange entfernen willst?",
@@ -162,7 +162,7 @@
"SelectEpisodesModalTitle": "{modalTitle} Episode(n) auswählen",
"SeasonPassTruncated": "Es werden nur die letzten 25 Staffeln gezeigt. Gehen Sie zu den Details, um alle Staffeln zu sehen",
"RestartReloadNote": "Hinweis: {appName} startet während des Wiederherstellungsvorgangs automatisch neu und lädt die Benutzeroberfläche neu.",
"AutoRedownloadFailedHelpText": "Suchen Sie automatisch nach einer anderen Version und versuchen Sie, sie herunterzuladen",
"AutoRedownloadFailedHelpText": "Automatisch nach einem anderen Release suchen und versuchen es herunterzuladen",
"AirDate": "Ausstrahlungsdatum",
"AgeWhenGrabbed": "Alter (bei Erfassung)",
"ApplyTagsHelpTextHowToApplySeries": "So wenden Sie Tags auf die ausgewählte Serie an",
@@ -229,7 +229,7 @@
"UiLanguageHelpText": "Sprache, die {appName} für die Benutzeroberfläche verwendet",
"UsenetBlackhole": "Usenet Blackhole",
"YesCancel": "Ja Abbrechen",
"AutoRedownloadFailedFromInteractiveSearchHelpText": "Suchen Sie automatisch nach einer anderen Version und versuchen Sie, sie herunterzuladen, wenn eine fehlerhafte Version aus der interaktiven Suche ausgewählt wurde",
"AutoRedownloadFailedFromInteractiveSearchHelpText": "Falls ein Release aus der interaktiven Suche fehlschlägt, automatisch nach einer alternativen Version suchen und versuchen, sie herunterzuladen",
"DownloadClientQbittorrentSettingsSequentialOrder": "Fortlaufende Reihenfolge",
"AutoTagging": "Automatisches Tagging",
"AddRootFolder": "Stammverzeichnis hinzufügen",
@@ -486,7 +486,7 @@
"StartImport": "Import starten",
"StartProcessing": "Verarbeitung starten",
"Tasks": "Aufgaben",
"ThemeHelpText": "Ändern Sie das Benutzeroberflächen-Design der Anwendung. Das „Auto“-Design verwendet Ihr Betriebssystemdesign, um den Hell- oder Dunkelmodus festzulegen. Inspiriert vom Theme.Park",
"ThemeHelpText": "UI-Design ändern: Der 'Auto'-Modus übernimmt das Betriebssystem-Theme, um automatisch zwischen Light- und Dark-Modus zu wechseln. Inspiriert von Theme.Park",
"Theme": "Design",
"TestAllLists": "Prüfe alle Listen",
"Titles": "Titel",
@@ -2138,5 +2138,14 @@
"UpgradeUntilCustomFormatScoreEpisodeHelpText": "Sobald dieser benutzerdefinierte Formatwert erreicht ist, wird {appName} keine Episoden-Releases mehr herunterladen",
"UpgradesAllowedHelpText": "Wenn deaktiviert, werden Qualitäten nicht aktualisiert.",
"VideoDynamicRange": "Video-Dynamikbereich",
"Warning": "Warnung"
"Warning": "Warnung",
"ReleasePush": "Veröffentlichung-Push",
"ReleaseSource": "Veröffentlichungsquelle",
"MetadataKometaDeprecatedSetting": "Veraltet",
"MetadataKometaDeprecated": "Kometa-Dateien werden nicht mehr erstellt, die Unterstützung wird in Version 5 vollständig entfernt",
"NotificationsTelegramSettingsIncludeInstanceName": "Instanzname im Titel einfügen",
"NotificationsTelegramSettingsIncludeInstanceNameHelpText": "Optional den Instanznamen in die Benachrichtigung einfügen",
"IndexerSettingsFailDownloadsHelpText": "Beim Verarbeiten abgeschlossener Downloads behandelt {appName} diese ausgewählten Dateitypen als fehlgeschlagene Downloads.",
"UserInvokedSearch": "Benutzerinitiierte Suche",
"IndexerSettingsFailDownloads": "Fehlgeschlagene Downloads"
}

View File

@@ -1667,12 +1667,14 @@
"ReleaseProfiles": "Release Profiles",
"ReleaseProfilesLoadError": "Unable to load Release Profiles",
"ReleaseRejected": "Release Rejected",
"ReleasePush": "Release Push",
"ReleaseSceneIndicatorAssumingScene": "Assuming Scene numbering.",
"ReleaseSceneIndicatorAssumingTvdb": "Assuming TVDB numbering.",
"ReleaseSceneIndicatorMappedNotRequested": "Mapped episode wasn't requested in this search.",
"ReleaseSceneIndicatorSourceMessage": "{message} releases exist with ambiguous numbering, unable to reliably identify episode.",
"ReleaseSceneIndicatorUnknownMessage": "Numbering varies for this episode and release does not match any known mappings.",
"ReleaseSceneIndicatorUnknownSeries": "Unknown episode or series.",
"ReleaseSource": "Release Source",
"ReleaseTitle": "Release Title",
"ReleaseType": "Release Type",
"Reload": "Reload",
@@ -2118,6 +2120,7 @@
"UsenetDelayTime": "Usenet Delay: {usenetDelay}",
"UsenetDisabled": "Usenet Disabled",
"Username": "Username",
"UserInvokedSearch": "User Invoked Search",
"UtcAirDate": "UTC Air Date",
"Version": "Version",
"VersionNumber": "Version {version}",

File diff suppressed because it is too large Load Diff

View File

@@ -294,7 +294,7 @@
"Restart": "Redémarrer",
"RestartNow": "Redémarrer maintenant",
"SaveSettings": "Enregistrer les paramètres",
"ShowMonitoredHelpText": "Afficher l'état de surveillance sous le poster",
"ShowMonitoredHelpText": "Affiche l'état de surveillance sous le poster",
"SkipFreeSpaceCheck": "Ignorer la vérification de l'espace libre",
"Sunday": "Dimanche",
"TorrentDelay": "Retard du torrent",
@@ -401,7 +401,7 @@
"SearchForMissing": "Rechercher les manquants",
"SearchAll": "Tout rechercher",
"Series": "Série",
"ShowSearchHelpText": "Afficher le bouton de recherche au survol",
"ShowSearchHelpText": "Affiche le bouton de recherche au survol",
"SmartReplace": "Remplacement intelligent",
"SmartReplaceHint": "Dash ou Space Dash selon le nom",
"Space": "Espace",
@@ -435,7 +435,7 @@
"EditDownloadClientImplementation": "Modifier le client de téléchargement - {implementationName}",
"External": "Externe",
"Monday": "Lundi",
"ShowQualityProfileHelpText": "Afficher le profil de qualité sous l'affiche",
"ShowQualityProfileHelpText": "Affiche le profil de qualité sous l'affiche",
"IncludeCustomFormatWhenRenamingHelpText": "Inclure dans le format de renommage {Formats personnalisés}",
"SelectDropdown": "Sélectionner...",
"InteractiveImportNoFilesFound": "Aucun fichier vidéo n'a été trouvé dans le dossier sélectionné",
@@ -728,7 +728,7 @@
"ShowEpisodeInformation": "Afficher les informations sur l'épisode",
"ShowEpisodeInformationHelpText": "Afficher le titre et le numéro de l'épisode",
"ShowEpisodes": "Afficher les épisodes",
"ShowMonitored": "Afficher le chemin",
"ShowMonitored": "Afficher l'état de surveillance",
"ShowNetwork": "Afficher le réseau",
"ShowPath": "Afficher le chemin",
"ShowPreviousAiring": "Afficher la diffusion précédente",
@@ -737,7 +737,7 @@
"ShowSearch": "Afficher la recherche",
"ShowSeasonCount": "Afficher le nombre de saisons",
"ShowSizeOnDisk": "Afficher la taille sur le disque",
"ShowTitle": "Montrer le titre",
"ShowTitle": "Afficher le titre",
"ShowSeriesTitleHelpText": "Afficher le titre de la série sous l'affiche",
"ShowUnknownSeriesItems": "Afficher les éléments de série inconnus",
"ShowUnknownSeriesItemsHelpText": "Afficher les éléments sans série dans la file d'attente. Cela peut inclure des séries, des films ou tout autre élément supprimé dans la catégorie de {appName}",
@@ -1047,7 +1047,7 @@
"IncludeCustomFormatWhenRenaming": "Inclure un format personnalisé lors du changement de nom",
"InteractiveImportNoSeries": "Les séries doivent être choisies pour chaque fichier sélectionné",
"Level": "Niveau",
"LibraryImport": "Importer biblio.",
"LibraryImport": "Importer bibliothèque",
"ListExclusionsLoadError": "Impossible de charger les exclusions de liste",
"ListQualityProfileHelpText": "Les éléments de la liste du profil de qualité seront ajoutés avec",
"ListTagsHelpText": "Balises qui seront ajoutées lors de l'importation à partir de cette liste",
@@ -2075,7 +2075,7 @@
"DayOfWeekAt": "{day} à {time}",
"TomorrowAt": "Demain à {time}",
"TodayAt": "Aujourd'hui à {time}",
"ShowTagsHelpText": "Afficher les labels sous l'affiche",
"ShowTagsHelpText": "Affiche les labels sous l'affiche",
"ShowTags": "Afficher les labels",
"CountVotes": "{votes} votes",
"NoBlocklistItems": "Aucun élément de la liste de blocage",
@@ -2104,5 +2104,31 @@
"LogSizeLimit": "Limite de taille du journal",
"DeleteSelectedImportListExclusionsMessageText": "Êtes-vous sûr de vouloir supprimer les exclusions de la liste d'importation sélectionnée ?",
"CustomFormatsSpecificationExceptLanguage": "Excepté Langue",
"CustomFormatsSpecificationExceptLanguageHelpText": "Corresponf si l'autre langue que celle sélectionné est présente"
"CustomFormatsSpecificationExceptLanguageHelpText": "Correspond si l'autre langue que celle sélectionné est présente",
"IndexerSettingsFailDownloadsHelpText": "Lors du traitement des téléchargements terminés, {appName} traitera ces types de fichiers sélectionnés comme des téléchargements ayant échoué.",
"IndexerSettingsFailDownloads": "Échec des téléchargements",
"Completed": "Complété",
"CutoffNotMet": "Seuil non atteint",
"DownloadClientUnavailable": "Client de téléchargement indisponible",
"CountCustomFormatsSelected": "{count} format(s) personnalisé(s) sélectionné(s)",
"Delay": "Retard",
"NotificationsGotifySettingsMetadataLinks": "Liens de métadonnées",
"NotificationsGotifySettingsMetadataLinksHelpText": "Ajouter un lien vers les métadonnées de la série lors de l'envoi de notifications",
"MetadataKometaDeprecated": "Les fichiers Kometa ne seront plus créés, le support sera complètement supprimé dans la v5",
"Premiere": "Première",
"RecentFolders": "Dossiers récents",
"UpdatePath": "Chemin de mise à jour",
"UpdateSeriesPath": "Mettre à jour le chemin de la série",
"NoCustomFormatsFound": "Aucun format personnalisé trouvé",
"EditSelectedCustomFormats": "Modifier les formats personnalisés sélectionnés",
"SkipFreeSpaceCheckHelpText": "À utiliser lorsque {appName} ne parvient pas à détecter l'espace libre de votre dossier racine",
"MetadataPlexSettingsEpisodeMappings": "Mappages des épisodes",
"MetadataPlexSettingsEpisodeMappingsHelpText": "Inclure les mappages d'épisodes pour tous les fichiers dans le fichier .plexmatch",
"FailedToFetchSettings": "Impossible de récupérer les paramètres",
"DeleteSelectedCustomFormats": "Supprimer les format(s) personnalisé(s)",
"DeleteSelectedCustomFormatsMessageText": "Êtes-vous sûr de vouloir supprimer {count} format(s) personnalisé(s) sélectionné(s) ?",
"LastSearched": "Dernière recherche",
"FolderNameTokens": "Jetons de nom de dossier",
"ManageCustomFormats": "Gérer les formats personnalisés",
"Menu": "Menu"
}

View File

@@ -250,7 +250,7 @@
"AutoRedownloadFailed": "Download fallito",
"AddDelayProfileError": "Impossibile aggiungere un nuovo profilo di ritardo, riprova.",
"Cutoff": "Taglio",
"AddListExclusion": "Aggiungi Lista esclusioni",
"AddListExclusion": "Aggiungi elenco esclusioni",
"DownloadClientValidationApiKeyRequired": "API Key Richiesta",
"Donate": "Dona",
"DownloadClientDownloadStationValidationNoDefaultDestination": "Nessuna destinazione predefinita",

View File

@@ -55,5 +55,207 @@
"AddCondition": "조건 추가",
"AddIndexerError": "새 인덱서를 추가 할 수 없습니다. 다시 시도해주세요.",
"TorrentBlackholeTorrentFolder": "토렌트 폴더",
"UseSsl": "SSL 사용"
"UseSsl": "SSL 사용",
"AddListExclusion": "목록 예외 추가",
"BeforeUpdate": "업데이트 전",
"BindAddress": "바인드 주소",
"RemotePathMappingsInfo": "원격 경로 매핑은 거의 필요하지 않습니다. {appName}와(과) 다운로드 클라이언트가 동일한 시스템에 있는 경우 경로를 일치시키는 것이 좋습니다. 상세 내용은 [위키]({wikiLink})를 참조하세요.",
"RemoveSelectedBlocklistMessageText": "블랙리스트에서 선택한 항목을 제거 하시겠습니까?",
"RemoveSelectedItemQueueMessageText": "대기열에서 {0} 항목 {1}을 제거하시겠습니까?",
"RssSync": "RSS 동기화",
"RssSyncInterval": "RSS 동기화 간격",
"SelectLanguages": "언어 선택",
"SizeOnDisk": "디스크 상 크기",
"SslCertPassword": "SSL 인증서 비밀번호",
"SslCertPasswordHelpText": "pfx 파일의 비밀번호",
"SslCertPath": "SSL 인증서 경로",
"SupportedIndexersMoreInfo": "개별 인덱서에 대한 상세 내용을 보려면 정보 버튼을 클릭하세요.",
"SupportedListsMoreInfo": "개별 가져오기 목록에 대한 상세 내용을 보려면 정보 버튼을 클릭하세요.",
"UiLanguage": "UI 언어",
"UiSettings": "UI 설정",
"UpgradeUntil": "품질까지 업그레이드",
"Uppercase": "대문자",
"AutoTaggingSpecificationStatus": "상태",
"BuiltIn": "내장",
"ChangeFileDate": "파일 날짜 변경",
"Delete": "삭제",
"DeleteSelectedIndexers": "인덱서 삭제",
"DownloadClientSettings": "클라이언트 설정 다운로드",
"GrabId": "ID 잡아",
"ImportLists": "기울기",
"LocalPath": "로컬 경로",
"AnalyticsEnabledHelpText": "익명의 사용 및 오류 정보를 {appName}의 서버에 보냅니다. 여기에는 브라우저에 대한 정보, 사용하는 {appName} WebUI 페이지, 오류 보고, OS 및 런타임 버전이 포함됩니다. 이 정보를 사용하여 기능 및 버그 수정의 우선 순위를 지정합니다.",
"Connection": "연결",
"Dates": "날짜",
"DownloadClientSettingsRecentPriority": "클라이언트 우선 순위",
"Day": "일",
"Debug": "디버그",
"EditIndexerImplementation": "인덱서 추가 - {implementationName}",
"Clone": "닫기",
"CleanLibraryLevel": "정리 라이브러리 수준",
"ClickToChangeQuality": "품질을 변경하려면 클릭",
"ClientPriority": "클라이언트 우선 순위",
"Component": "구성 요소",
"DeleteEmptyFolders": "빈 폴더 삭제",
"MinimumCustomFormatScore": "최소 사용자 정의 형식 점수",
"MinimumFreeSpaceHelpText": "사용 가능한 디스크 공간을 이보다 적게 남겨 둘 경우 가져오기 방지",
"MoveAutomatically": "빠른 가져오기",
"No": "아니",
"IndexerSettingsRejectBlocklistedTorrentHashes": "동기화 중 차단 목록에 있는 토렌트 해시 거부",
"NotificationsSimplepushSettingsEvent": "이벤트",
"AutomaticSearch": "자동 검색",
"CustomFormat": "사용자 정의 형식",
"DelayProfile": "지연 프로필",
"DelayProfiles": "지연 프로필",
"EnableRss": "RSS 활성화",
"ChangeFileDateHelpText": "가져오기 / 재검색시 파일 날짜 변경",
"CreateGroup": "그룹 만들기",
"RecyclingBinHelpText": "영화 파일은 영구적으로 삭제되지 않고 삭제되면 여기로 이동합니다",
"IconForCutoffUnmetHelpText": "컷오프가 충족되지 않은 경우 파일 아이콘 표시",
"RemotePath": "원격 경로",
"ChmodFolder": "chmod 폴더",
"RemotePathMappingHostHelpText": "원격 다운로드 클라이언트에 지정한 것과 동일한 호스트",
"RemotePathMappingRemotePathHelpText": "다운로드 클라이언트가 액세스하는 디렉토리의 루트 경로",
"RemoveFromBlocklist": "블랙리스트에서 제거",
"RequiredHelpText": "이 {implementationName} 조건은 적용 할 맞춤 형식에 대해 일치해야합니다. 그렇지 않으면 단일 {implementationName} 일치로 충분합니다.",
"ShowRelativeDates": "상대 날짜 표시",
"ShowRelativeDatesHelpText": "상대 (오늘 / 어제 / 기타) 또는 절대 날짜 표시",
"TablePageSize": "페이지 크기",
"TablePageSizeHelpText": "각 페이지에 표시 할 항목 수",
"TagCannotBeDeletedWhileInUse": "사용 중에는 삭제할 수 없습니다",
"AddImportListExclusionError": "새 목록 제외를 추가 할 수 없음 재시도해주세요.",
"AddQualityProfile": "품질 프로필 추가",
"AddReleaseProfile": "지연 프로필 편집",
"AutoRedownloadFailedHelpText": "다른 출시를 자동으로 검색하고 다운로드 시도",
"BypassProxyForLocalAddresses": "로컬 주소에 대한 프록시 우회",
"CancelPendingTask": "이 보류 중인 작업을 취소하시겠습니까?",
"CancelProcessing": "처리 취소",
"Certification": "인증",
"SslPort": "SSL 포트",
"CustomFormatsSettings": "사용자 정의 형식 설정",
"CustomFormatsSpecificationReleaseGroup": "출시 그룹",
"DownloadClientPneumaticSettingsNzbFolder": "Nzb 폴더",
"CopyToClipboard": "클립 보드에 복사",
"DeleteQualityProfile": "품질 프로필 삭제",
"DetailedProgressBarHelpText": "진행률 표시줄에 텍스트 표시",
"Disabled": "비활성화됨",
"DisabledForLocalAddresses": "로컬 주소에 대해 비활성화됨",
"DiskSpace": "디스크 공간",
"Filters": "필터",
"ImportListExclusions": "제외 목록",
"AddRemotePathMapping": "원격 경로 매핑 추가",
"AppUpdatedVersion": "{appName}이 버전 `{version}`으로 업데이트되었습니다. 최신 변경 사항을 받으려면 {appName}을 재로드해야 합니다 ",
"BackupIntervalHelpText": "자동 백업 간격",
"BackupNow": "지금 백업",
"Backups": "백업",
"ChmodFolderHelpText": "8 진수, 미디어 폴더 및 파일로 가져오기 / 이름 변경 중에 적용됨 (실행 비트 없음)",
"ChooseAnotherFolder": "다른 폴더 선택",
"CompletedDownloadHandling": "완료된 다운로드 처리",
"CopyUsingHardlinksHelpTextWarning": "간혹 파일 잠금으로 인해 시드중인 파일의 이름을 바꾸지 못할 수 있습니다. 일시적으로 시드를 비활성화하고 {appName}의 이름 바꾸기 기능을 해결 방법으로 사용할 수 있습니다.",
"CurrentlyInstalled": "현재 설치됨",
"CustomFormatsSettingsSummary": "사용자 정의 형식 및 설정",
"DeleteIndexer": "인덱서 삭제",
"DeleteNotification": "알림 삭제",
"DeleteRemotePathMapping": "원격 경로 매핑 편집",
"DeleteTag": "태그 삭제",
"Download": "다운로드",
"DownloadClientRootFolderHealthCheckMessage": "다운로드 클라이언트 {downloadClientName} 은(는) 루트 폴더 {rootFolderPath}에 다운로드를 저장합니다. 루트 폴더에 다운로드해서는 안됩니다.",
"IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "해시에 의해 토렌트가 차단된 경우 일부 인덱서의 RSS/검색 중에 토렌트가 제대로 거부되지 않을 수 있습니다. 이 기능을 활성화하면 토렌트를 가져온 후 클라이언트로 전송하기 전에 토렌트를 거부할 수 있습니다.",
"DoneEditingGroups": "그룹 편집 완료",
"DotNetVersion": ".NET",
"EditImportListExclusion": "목록 제외 편집",
"EnableSsl": "SSL 활성화",
"Conditions": "조건",
"ConnectSettings": "연결 설정",
"AddImportListExclusion": "목록 예외 추가",
"AllFiles": "모든 파일",
"Always": "항상",
"Connect": "연결",
"ConnectionLostReconnect": "Radarr가 자동으로 연결을 시도하거나 아래에서 새로고침을 클릭할 수 있습니다.",
"CustomFormats": "사용자 정의 형식",
"Ui": "UI",
"DockerUpdater": "Docker 컨테이너를 업데이트하여 업데이트를 받으세요",
"EditConnectionImplementation": "애플리케이션 추가 - {implementationName}",
"From": "부터",
"BranchUpdate": "{appName} 업데이트에 사용할 파생 버전",
"DeleteBackup": "백업 삭제",
"DeleteSelectedDownloadClients": "다운로드 클라이언트 삭제",
"AgeWhenGrabbed": "연령 (잡았을 때)",
"AnalyseVideoFiles": "비디오 파일 분석",
"ApiKey": "API 키",
"AptUpdater": "apt를 사용하여 업데이트 설치",
"BranchUpdateMechanism": "외부 업데이트 메커니즘에서 사용하는 파생 버전",
"DeleteSpecification": "알림 삭제",
"Deleted": "삭제됨",
"Clear": "지우기",
"CloneProfile": "프로필 복제",
"CloneIndexer": "인덱서 복제",
"Cutoff": "중단점",
"Date": "날짜",
"DeleteDelayProfileMessageText": "이 지연 프로필을 삭제하시겠습니까?",
"DoNotBlocklistHint": "차단 목록에 추가하지 않고 제거",
"DoNotPrefer": "선호하지 않음",
"EnableHelpText": "이 메타데이터 유형에 대한 메타데이터 파일 생성 활성화",
"Docker": "Docker",
"Donations": "기부",
"ImportList": "기울기",
"ImportListSettings": "목록 설정",
"Add": "추가",
"Apply": "적용",
"ApplyTags": "태그 적용",
"Cancel": "취소",
"EditDownloadClientImplementation": "다운로드 클라이언트 추가 - {implementationName}",
"EditReleaseProfile": "지연 프로필 편집",
"AddRootFolder": "루트 폴더 추가",
"ExtraFileExtensionsHelpText": "가져올 추가 파일의 쉼표로 구분 된 목록 (.nfo는 .nfo-orig로 가져옴)",
"AddDelayProfile": "지연 프로필 추가",
"AddDownloadClient": "다운로드 클라이언트 추가",
"AddExclusion": "예외 추가",
"AddNewRestriction": "새로운 제한 추가",
"AuthForm": "양식 (로그인 페이지)",
"AuthBasic": "기본 (브라우저 팝업)",
"Authentication": "인증",
"Automatic": "자동",
"CertificateValidation": "인증서 검증",
"Close": "닫기",
"Connections": "연결",
"DeleteImportListExclusion": "가져오기 목록 제외 삭제",
"DoNotUpgradeAutomatically": "자동 업그레이드 안함",
"DownloadPropersAndRepacksHelpText": "Propers / Repacks로 자동 업그레이드할지 여부",
"NoIssuesWithYourConfiguration": "구성에 문제 없음",
"IncludeHealthWarnings": "건강 경고 포함",
"DownloadClientsSettingsSummary": "클라이언트 다운로드, 다운로드 처리 및 원격 경로 매핑",
"DownloadFailed": "다운로드 실패함",
"Downloaded": "다운로드됨",
"Downloading": "다운로드 중",
"ICalShowAsAllDayEvents": "종일 이벤트로 표시",
"Rating": "등급",
"RegularExpression": "일반 표현",
"Activity": "활동",
"Backup": "백업",
"AudioInfo": "오디오 정보",
"DownloadClient": "클라이언트 다운로드",
"ShortDateFormat": "짧은 날짜 형식",
"Yes": "예",
"Actions": "동작",
"About": "정보",
"EditConditionImplementation": "연결 추가 - {implementationName}",
"ICalLink": "iCal 링크",
"Agenda": "일정",
"DownloadClients": "클라이언트 다운로드",
"QualityProfile": "품질 프로필",
"Rss": "RSS",
"WhatsNew": "새로운 소식?",
"MaximumSize": "최대 크기",
"DeleteDownloadClient": "다운로드 클라이언트 삭제",
"DeleteImportListExclusionMessageText": "이 가져오기 목록 제외를 삭제하시겠습니까?",
"DeleteDelayProfile": "지연 프로필 삭제",
"DestinationRelativePath": "대상 상대 경로",
"File": "파일",
"ImportListsTraktSettingsGenres": "장르",
"InteractiveSearchModalHeader": "대화형 검색",
"ManualImportItemsLoadError": "수동 가져오기 항목을 로드할 수 없습니다",
"LongDateFormat": "긴 날짜 형식",
"Lowercase": "소문자",
"KeyboardShortcutsSaveSettings": "설정 저장"
}

View File

@@ -18,5 +18,42 @@
"Actions": "Handlinger",
"AddCustomFilter": "Legg til eget filter",
"AddConnection": "Legg til tilkobling",
"AddDelayProfile": "Legg til forsinkelsesprofil"
"AddDelayProfile": "Legg til forsinkelsesprofil",
"AddRootFolderError": "Kunne ikke legge til rotmappe",
"AddDelayProfileError": "Kunne ikke legge til ny forsinkelsesprofil, vennligst prøv igjen.",
"AddIndexerError": "Kunne ikke legge til ny indekser, vennligst prøv igjen.",
"AddList": "Legg til liste",
"AddListError": "Kunne ikke legge til ny liste, vennligst prøv igjen.",
"AddRootFolder": "Legg til Rotmappe",
"AddConnectionImplementation": "Legg til tilkobling - {implementationName}",
"AddDownloadClientImplementation": "Ny Nedlastingsklient - {implementationName}",
"AddImportListImplementation": "Legg til importliste - {implementationName}",
"AddIndexerImplementation": "Legg til indekser - {implementationName}",
"AddToDownloadQueue": "Legg til nedlastningskø",
"AddedToDownloadQueue": "Lagt til nedlastningskø",
"AfterManualRefresh": "Etter manuell oppdatering",
"AddCustomFormat": "Nytt Egendefinert format",
"AddCustomFormatError": "Kunne ikke legge til nytt egendefinert format, vennligst prøv på nytt.",
"AddDownloadClient": "Ny Nedlastingsklient",
"AddDownloadClientError": "Kunne ikke legge til ny Nedlastingsklient, vennligst prøv igjen.",
"AddImportList": "Ny Importliste",
"AddIndexer": "Legg til indekser",
"AddNewRestriction": "Legg til ny begrensning",
"AddNotificationError": "Kunne ikke legge til ny varsling, vennligst prøv igjen.",
"AddQualityProfile": "Legg til kvalitetsprofil",
"AddQualityProfileError": "Kunne ikke legge til ny kvalitetsprofil, vennligst prøv igjen.",
"AddReleaseProfile": "Legg til utgivelsesprofil",
"AddNew": "Legg til ny",
"Age": "Alder",
"Agenda": "Agenda",
"AddNewSeries": "Legg til ny serie",
"AddNewSeriesError": "Kunne ikke laste søkeresultat, vennligst prøv igjen.",
"AddNewSeriesHelpText": "Det er enkelt å legge til en ny serie. Bare begynn å taste navnet på serien du vil legge til.",
"AddNewSeriesRootFolderHelpText": "Undermappa \"{folder}\" vil bli automatisk laget",
"AddNewSeriesSearchForMissingEpisodes": "Søk etter manglende episoder",
"AddRemotePathMapping": "Legg til ekstern stimapping",
"AddRemotePathMappingError": "Kunne ikke legge til ny ekstern stimapping, vennligst prøv igjen.",
"AddSeriesWithTitle": "Legg til {title}",
"Added": "Lagt til",
"AddedDate": "Lagt til: {date}"
}

File diff suppressed because it is too large Load Diff

View File

@@ -209,5 +209,8 @@
"CloneIndexer": "Clonează Indexer",
"CloneProfile": "Clonează Profil",
"DownloadClientUnavailable": "Client de descărcare indisponibil",
"Clone": "Clonează"
"Clone": "Clonează",
"DownloadClientSettingsOlderPriority": "Prioritate mai vechi",
"DownloadClientSettingsRecentPriority": "Prioritate recente",
"Absolute": "Absolut"
}

View File

@@ -2061,7 +2061,7 @@
"Umask770Description": "{octal} - Владелец и группа - запись",
"UiSettings": "Настройки пользовательского интерфейса",
"UiLanguage": "Язык пользовательского интерфейса",
"Ui": "Пользовательский интерфейс",
"Ui": "Интерфейс",
"ShowSeriesTitleHelpText": "Показать название сериала под постером",
"ShowSeasonCount": "Показать количество сезонов",
"TorrentBlackholeSaveMagnetFilesExtension": "Сохранить магнет-файлы с расширением",
@@ -2089,5 +2089,9 @@
"LogSizeLimit": "Ограничение размера журнала",
"LogSizeLimitHelpText": "Максимальный размер файла журнала в МБ перед архивированием. По умолчанию - 1 МБ.",
"IndexerHDBitsSettingsMediums": "Mediums",
"CountCustomFormatsSelected": "{count} пользовательских форматов выбрано"
"CountCustomFormatsSelected": "{count} пользовательских форматов выбрано",
"Completed": "Завершено",
"CutoffNotMet": "Порог не достигнут",
"CustomFormatsSpecificationExceptLanguage": "Кроме языка",
"CustomFormatsSpecificationExceptLanguageHelpText": "Подходит, если есть любой язык кроме указанного"
}

View File

@@ -7,7 +7,7 @@
"AddConditionImplementation": "Koşul Ekle - {implementationName}",
"EditConnectionImplementation": "Bildirimi Düzenle - {implementationName}",
"AddConnectionImplementation": "Bağlantı Ekle - {implementationName}",
"AddIndexerImplementation": "Yeni Dizinleyici Ekle - {implementationName}",
"AddIndexerImplementation": "Yeni İndeksleyici Ekle - {implementationName}",
"EditIndexerImplementation": "Koşul Ekle - {implementationName}",
"AddToDownloadQueue": "İndirme kuyruğuna ekleyin",
"AddedToDownloadQueue": "İndirme kuyruğuna eklendi",
@@ -31,7 +31,7 @@
"AddImportListExclusion": "İçe Aktarma Listesi Hariç Tutma Ekle",
"AddImportListExclusionError": "Yeni bir liste dışlaması eklenemiyor, lütfen tekrar deneyin.",
"AddImportListImplementation": "İçe Aktarım Listesi Ekle -{implementationName}",
"AddIndexer": "Dizinleyici Ekle",
"AddIndexer": "İndeksleyici Ekle",
"AddNewSeriesSearchForMissingEpisodes": "Kayıp bölümleri aramaya başlayın",
"AddNotificationError": "Yeni bir bildirim eklenemiyor, lütfen tekrar deneyin.",
"AddReleaseProfile": "Yayın Profili Ekle",
@@ -40,7 +40,7 @@
"AddSeriesWithTitle": "{title} Ekleyin",
"Agenda": "Ajanda",
"Airs": "Yayınlar",
"AddIndexerError": "Yeni dizinleyici eklenemiyor, lütfen tekrar deneyin.",
"AddIndexerError": "Yeni indeksleyici eklenemiyor, lütfen tekrar deneyin.",
"AddNewSeriesSearchForCutoffUnmetEpisodes": "Karşılanmamış bölümleri aramaya başlayın",
"AddQualityProfileError": "Yeni kalite profili eklenemiyor, lütfen tekrar deneyin.",
"AddRemotePathMappingError": "Yeni bir uzak yol eşlemesi eklenemiyor, lütfen tekrar deneyin.",
@@ -68,7 +68,7 @@
"AddRootFolderError": "Kök klasör eklenemiyor",
"CountImportListsSelected": "{count} içe aktarma listesi seçildi",
"CustomFormatsSpecificationFlag": "Bayrak",
"ClickToChangeIndexerFlags": "Dizinleyici bayraklarını değiştirmek için tıklayın",
"ClickToChangeIndexerFlags": "İndeksleyici bayraklarını değiştirmek için tıklayın",
"ClickToChangeReleaseGroup": "Yayım grubunu değiştirmek için tıklayın",
"AppUpdated": "{appName} Güncellendi",
"ApplicationURL": "Uygulama URL'si",
@@ -127,7 +127,7 @@
"Category": "Kategori",
"CertificateValidationHelpText": "HTTPS sertifika doğrulamasının sıkılığını değiştirin. Riskleri anlamadığınız sürece değişmeyin.",
"CloneCondition": "Klon Durumu",
"CountIndexersSelected": "{count} dizinleyici seçildi",
"CountIndexersSelected": "{count} indeksleyici seçildi",
"CustomFormatsSpecificationRegularExpressionHelpText": "Özel Format RegEx Büyük/Küçük Harfe Duyarsızdır",
"AutoRedownloadFailed": "Başarısız İndirmeleri Yenile",
"AutoRedownloadFailedFromInteractiveSearch": "Etkileşimli Arama'dan Başarısız İndirmeleri Yenile",
@@ -155,7 +155,7 @@
"DelayMinutes": "{delay} Dakika",
"DeleteImportListMessageText": "'{name}' listesini silmek istediğinizden emin misiniz?",
"DeleteReleaseProfile": "Yayımlama Profilini Sil",
"DeleteSelectedIndexers": "Dizinleyicileri Sil",
"DeleteSelectedIndexers": "İndeksleyicileri Sil",
"Directory": "Dizin",
"Donate": "Bağış yap",
"DownloadClientDownloadStationValidationFolderMissing": "Klasör mevcut değil",
@@ -176,11 +176,11 @@
"DeleteConditionMessageText": "'{name}' koşulunu silmek istediğinizden emin misiniz?",
"DeleteImportListExclusionMessageText": "Bu içe aktarma listesi hariç tutma işlemini silmek istediğinizden emin misiniz?",
"DeleteQualityProfileMessageText": "'{name}' kalite profilini silmek istediğinizden emin misiniz?",
"DeleteSelectedIndexersMessageText": "Seçilen {count} dizinleyiciyi silmek istediğinizden emin misiniz?",
"DeleteSelectedIndexersMessageText": "Seçilen {count} indeksleyiciyi silmek istediğinizden emin misiniz?",
"DownloadClientDelugeValidationLabelPluginFailureDetail": "{appName}, etiketi {clientName} uygulamasına ekleyemedi.",
"DownloadClientDownloadStationProviderMessage": "DSM hesabınızda 2 Faktörlü Kimlik Doğrulama etkinleştirilmişse {appName}, Download Station'a bağlanamaz",
"DownloadClientDownloadStationValidationApiVersion": "Download Station API sürümü desteklenmiyor; en az {requiredVersion} olmalıdır. {minVersion}'dan {maxVersion}'a kadar destekler",
"DownloadClientDownloadStationValidationNoDefaultDestination": "Varsayılan hedef yok",
"DownloadClientDownloadStationValidationNoDefaultDestination": "Varsayılan hedef bulunamadı",
"DownloadClientFloodSettingsAdditionalTagsHelpText": "Medyanın özelliklerini etiket olarak ekler. İpuçları örnektir.",
"DownloadClientFloodSettingsPostImportTagsHelpText": "İndirmelere içe aktarıldıktan sonra etiket ekler.",
"DownloadClientFloodSettingsUrlBaseHelpText": "Flood API'sine {url} gibi bir önek ekler",
@@ -195,13 +195,13 @@
"DownloadClientDelugeValidationLabelPluginFailure": "Etiket yapılandırılması başarısız oldu",
"DownloadClientDownloadStationValidationSharedFolderMissing": "Paylaşılan klasör mevcut değil",
"DeleteImportList": "İçe Aktarma Listesini Sil",
"IndexerPriorityHelpText": "Dizinleyici Önceliği (En Yüksek) 1'den (En Düşük) 50'ye kadar. Varsayılan: 25'dir. Eşit olmayan yayınlar için eşitlik bozucu olarak yayınlar alınırken kullanılan {appName}, RSS Senkronizasyonu ve Arama için etkinleştirilmiş tüm dizin oluşturucuları kullanmaya devam edecek",
"IndexerPriorityHelpText": "İndeksleyici Önceliği (En Yüksek) 1'den (En Düşük) 50'ye kadar. Varsayılan: 25'dir. Eşit olmayan yayınlar için eşitlik bozucu olarak yayınlar alınırken kullanılan {appName}, RSS Senkronizasyonu ve Arama için etkinleştirilmiş tüm indeksleyicileri kullanmaya devam edecek",
"DisabledForLocalAddresses": "Yerel Adreslerde Devre Dışı Bırak",
"DownloadClientDelugeValidationLabelPluginInactive": "Etiket eklentisi etkinleştirilmedi",
"DownloadClientDelugeValidationLabelPluginInactiveDetail": "Kategorileri kullanmak için {clientName} uygulamasında Etiket eklentisini etkinleştirmiş olmanız gerekir.",
"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.",
"DownloadClientDownloadStationValidationSharedFolderMissingDetail": "Diskstation'da '{sharedFolder}' adında bir Paylaşımlı Klasör yok, bunu doğru belirttiğinizden emin misiniz?",
"DownloadClientFloodSettingsRemovalInfo": "{appName}, Ayarlar -> Dizinleyiciler'deki geçerli başlangıç ölçütlerine göre torrentlerin otomatik olarak kaldırılmasını sağlar",
"DownloadClientFloodSettingsRemovalInfo": "{appName}, Ayarlar -> İndeksleyiciler'deki geçerli başlangıç ölçütlerine göre torrentlerin otomatik olarak kaldırılmasını sağlar",
"Database": "Veri tabanı",
"DelayProfileProtocol": "Protokol: {preferredProtocol}",
"DownloadClientDownloadStationValidationFolderMissingDetail": "'{downloadDir}' klasörü mevcut değil, '{sharedFolder}' Paylaşımlı Klasöründe manuel olarak oluşturulması gerekiyor.",
@@ -321,7 +321,7 @@
"DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "{downloadClientName} indirme istemcisi, tamamlanan indirmeleri kaldıracak şekilde ayarlandı. Bu, indirilenlerin {appName} içe aktarılmadan önce istemcinizden kaldırılmasına neden olabilir.",
"DownloadClientQbittorrentTorrentStatePathError": "İçe Aktarılamıyor. Yol, istemci tabanlı indirme dizini ile eşleşiyor, bu torrent için 'Üst düzey klasörü tut' seçeneği devre dışı bırakılmış olabilir veya 'Torrent İçerik Düzeni' 'Orijinal' veya 'Alt Klasör Oluştur' olarak ayarlanmamış olabilir mi?",
"DownloadClientQbittorrentValidationRemovesAtRatioLimit": "qBittorrent, Torrentleri Paylaşım Oranı Sınırına ulaştıklarında kaldıracak şekilde yapılandırılmıştır",
"DownloadClientRTorrentProviderMessage": "rTorrent, başlangıç kriterlerini karşılayan torrentleri duraklatmaz. {appName}, torrentlerin otomatik olarak kaldırılmasını Ayarlar->Dizinleyiciler'deki geçerli tohum kriterlerine göre yalnızca Tamamlandı Kaldırma etkinleştirildiğinde gerçekleştirecektir. İçe aktardıktan sonra, davranışı özelleştirmek için rTorrent komut dosyalarında kullanılabilen {importedView}'ı bir rTorrent görünümü olarak ayarlayacaktır.",
"DownloadClientRTorrentProviderMessage": "rTorrent, başlangıç kriterlerini karşılayan torrentleri duraklatmaz. {appName}, torrentlerin otomatik olarak kaldırılmasını Ayarlar->İndeksleyiciler'deki geçerli tohum kriterlerine göre yalnızca Tamamlandı Kaldırma etkinleştirildiğinde gerçekleştirecektir. İçe aktardıktan sonra, davranışı özelleştirmek için rTorrent komut dosyalarında kullanılabilen {importedView}'ı bir rTorrent görünümü olarak ayarlayacaktır.",
"DownloadClientValidationAuthenticationFailureDetail": "Kullanıcı adınızı ve şifrenizi kontrol edin. Ayrıca, {appName} çalıştıran ana bilgisayarın, {clientName} yapılandırmasındaki WhiteList sınırlamaları nedeniyle {clientName} erişiminin engellenip engellenmediğini de doğrulayın.",
"DownloadStationStatusExtracting": ıkarılıyor: %{progress}",
"DownloadClientNzbVortexMultipleFilesMessage": "İndirme birden fazla dosya içeriyor ve bir iş klasöründe değil: {outputPath}",
@@ -392,7 +392,7 @@
"MoveAutomatically": "Otomatik Olarak Taşı",
"MustContainHelpText": "Yayın, bu terimlerden en az birini içermelidir (büyük / küçük harfe duyarsız)",
"NotificationStatusAllClientHealthCheckMessage": "Arızalar nedeniyle tüm bildirimler kullanılamıyor",
"EditSelectedIndexers": "Seçili Dizinleyicileri Düzenle",
"EditSelectedIndexers": "Seçili İndeksleyicileri Düzenle",
"EnableProfileHelpText": "Yayımlama profilini etkinleştirmek için işaretleyin",
"EnableRssHelpText": "{appName}, RSS Senkronizasyonu aracılığıyla düzenli periyotlarda yayın değişikliği aradığında kullanacak",
"FormatTimeSpanDays": "{days}g {time}",
@@ -407,7 +407,7 @@
"FormatRuntimeHours": "{hours}s",
"LanguagesLoadError": "Diller yüklenemiyor",
"ListWillRefreshEveryInterval": "Liste yenileme periyodu {refreshInterval}dır",
"ManageIndexers": "Dizinleyicileri Yönet",
"ManageIndexers": "İndeksleyicileri Yönet",
"ManualGrab": "Manuel Alımlarda",
"DownloadClientsSettingsSummary": "İndirme İstemcileri, indirme işlemleri ve uzaktan yol eşlemeleri",
"DownloadClients": "İndirme İstemcileri",
@@ -445,7 +445,7 @@
"ManageLists": "Listeleri Yönet",
"MediaInfoFootNote": "Full/AudioLanguages/SubtitleLanguages, dosya adında yer alan dilleri filtrelemenize olanak tanıyan bir `:EN+DE` son ekini destekler. Belirli dilleri hariç tutmak için '-DE'yi kullanın. `+` (örneğin `:EN+`) eklenmesi, hariç tutulan dillere bağlı olarak `[EN]`/`[EN+--]`/`[--]` sonucunu verecektir. Örneğin `{MediaInfo Full:EN+DE}`.",
"Never": "Asla",
"NoIndexersFound": "Dizinleyici bulunamadı",
"NoIndexersFound": "İndeksleyici bulunamadı",
"NotificationsAppriseSettingsConfigurationKeyHelpText": "Kalıcı Depolama Çözümü için Yapılandırma Anahtarı. Durum Bilgisi Olmayan URL'ler kullanılıyorsa boş bırakın.",
"NotificationsAppriseSettingsPasswordHelpText": "HTTP Temel Kimlik Doğrulama Parolası",
"NotificationsAppriseSettingsUsernameHelpText": "HTTP Temel Kimlik Doğrulama Kullanıcı Adı",
@@ -486,14 +486,14 @@
"Test": "Test Et",
"HealthMessagesInfoBox": "Satırın sonundaki wiki bağlantısını (kitap simgesi) tıklayarak veya [log kayıtlarınızı]({link}) kontrol ederek bu durum kontrolü mesajlarının nedeni hakkında daha fazla bilgi bulabilirsiniz. Bu mesajları yorumlamakta zorluk yaşıyorsanız aşağıdaki bağlantılardan destek ekibimize ulaşabilirsiniz.",
"IndexerSettingsRejectBlocklistedTorrentHashes": "Alırken Engellenen Torrent Karmalarını Reddet",
"IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Bir torrent hash tarafından engellenirse, bazı dizinleyiciler için RSS / Arama sırasında düzgün bir şekilde reddedilmeyebilir, bunun etkinleştirilmesi, torrent alındıktan sonra, ancak istemciye gönderilmeden önce reddedilmesine izin verecektir.",
"IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Bir torrent hash tarafından engellenirse, bazı indeksleyiciler için RSS / Arama sırasında düzgün bir şekilde reddedilmeyebilir, bunun etkinleştirilmesi, torrent alındıktan sonra, ancak istemciye gönderilmeden önce reddedilmesine izin verecektir.",
"NotificationsAppriseSettingsConfigurationKey": "Apprise Yapılandırma Anahtarı",
"NotificationsAppriseSettingsNotificationType": "Apprise Bildirim Türü",
"NotificationsGotifySettingsServerHelpText": "Gerekiyorsa http(s):// ve bağlantı noktası dahil olmak üzere Gotify sunucu URL'si",
"NotificationsJoinSettingsApiKeyHelpText": "Katıl hesap ayarlarınızdaki API Anahtarı (API'ye Katıl düğmesine tıklayın).",
"ImportScriptPathHelpText": "İçe aktarma için kullanılacak komut dosyasının yolu",
"Label": "Etiket",
"NoDelay": "Gecikme yok",
"NoDelay": "Gecikmesiz",
"NoImportListsFound": "İçe aktarma listesi bulunamadı",
"FormatAgeMinute": "dakika",
"FormatAgeMinutes": "dakika",
@@ -504,7 +504,7 @@
"NotificationsKodiSettingsUpdateLibraryHelpText": "İçe Aktarma ve Yeniden Adlandırmada kitaplık güncellensin mi?",
"NotificationsNtfySettingsServerUrlHelpText": "Genel sunucuyu ({url}) kullanmak için boş bırakın",
"InteractiveImportLoadError": "Manuel içe aktarma öğeleri yüklenemiyor",
"IndexerDownloadClientHelpText": "Bu dizinleyiciden almak için hangi indirme istemcisinin kullanılacağını belirtin",
"IndexerDownloadClientHelpText": "Bu indeksleyiciden almak için hangi indirme istemcisinin kullanılacağını belirtin",
"DeleteRemotePathMapping": "Uzak Yol Eşlemeyi Sil",
"LastDuration": "Yürütme Süresi",
"NotificationsSettingsUpdateMapPathsToSeriesHelpText": "{serviceName}, kitaplık yolu konumunu {appName}'den farklı gördüğünde seri yollarını değiştirmek için kullanılan {serviceName} yolu ('Kütüphaneyi Güncelle' gerektirir)",
@@ -526,7 +526,7 @@
"BlocklistRelease": "Kara Liste Sürümü",
"CustomFormats": "Özel Formatlar",
"DeleteDownloadClientMessageText": "'{name}' indirme istemcisini silmek istediğinizden emin misiniz?",
"DeleteIndexerMessageText": "'{name}' dizinleyicisini silmek istediğinizden emin misiniz?",
"DeleteIndexerMessageText": "'{name}' indeksleyicisini silmek istediğinizden emin misiniz?",
"OneMinute": "1 dakika",
"TaskUserAgentTooltip": "API'yi çağıran uygulama tarafından sağlanan Kullanıcı Aracısı",
"SkipRedownload": "Yeniden İndirmeyi Atla",
@@ -555,9 +555,9 @@
"RemoveFailedDownloads": "Başarısız İndirmeleri Kaldır",
"Scheduled": "Planlı",
"Underscore": "Vurgula",
"SetIndexerFlags": "Dizinleyici Bayraklarını Ayarla",
"SetIndexerFlags": "İndeksleyici Bayraklarını Ayarla",
"SetReleaseGroup": "Yayımlama Grubunu Ayarla",
"SetIndexerFlagsModalTitle": "{modalTitle} - Dizinleyici Bayraklarını Ayarla",
"SetIndexerFlagsModalTitle": "{modalTitle} - İndeksleyici Bayraklarını Ayarla",
"SslCertPassword": "SSL Sertifika Parolası",
"Rating": "Puan",
"GrabRelease": "Yayın Alma",
@@ -615,7 +615,7 @@
"DeleteNotificationMessageText": "'{name}' bildirimini silmek istediğinizden emin misiniz?",
"Or": "veya",
"OverrideGrabModalTitle": "Geçersiz Kıl ve Al - {title}",
"PreferProtocol": "{preferredProtocol}'u tercih edin",
"PreferProtocol": "{preferredProtocol} Tercih Edin",
"PreferredProtocol": "Tercih Edilen Protokol",
"PublishedDate": "Yayınlanma Tarihi",
"RemoveQueueItem": "Kaldır - {sourceTitle}",
@@ -704,7 +704,7 @@
"PreviouslyInstalled": "Daha Önce Kurulmuş",
"QualityCutoffNotMet": "Kalite sınırı karşılanmadı",
"QueueIsEmpty": "Kuyruk boş",
"ReleaseProfileIndexerHelpTextWarning": "Bir sürüm profilinde belirli bir dizinleyicinin ayarlanması, bu profilin yalnızca söz konusu dizinleyicinin yayınlarına uygulanmasına neden olur.",
"ReleaseProfileIndexerHelpTextWarning": "Bir sürüm profilinde belirli bir indeksleyicinin ayarlanması, bu profilin yalnızca söz konusu indeksleyicinin yayınlarına uygulanmasına neden olur.",
"ResetDefinitionTitlesHelpText": "Değerlerin yanı sıra tanım başlıklarını da sıfırlayın",
"SecretToken": "Gizlilik Token'ı",
"SetReleaseGroupModalTitle": "{modalTitle} - Yayımlama Grubunu Ayarla",
@@ -720,7 +720,7 @@
"Uptime": "Çalışma süresi",
"RemotePath": "Uzak Yol",
"File": "Dosya",
"ReleaseProfileIndexerHelpText": "Profilin hangi dizinleyiciye uygulanacağını belirtin",
"ReleaseProfileIndexerHelpText": "Profilin hangi indeksleyiciye uygulanacağını belirtin",
"TablePageSize": "Sayfa Boyutu",
"NotificationsSynologyValidationTestFailed": "Synology veya synoındex mevcut değil",
"NotificationsTwitterSettingsAccessTokenSecret": "Erişim Token Gizliliği",
@@ -736,7 +736,7 @@
"RemoveQueueItemRemovalMethod": "Kaldırma Yöntemi",
"RemoveQueueItemRemovalMethodHelpTextWarning": "'İndirme İstemcisinden Kaldır', indirme işlemini ve dosyaları indirme istemcisinden kaldıracaktır.",
"RemoveSelectedItems": "Seçili öğeleri kaldır",
"SelectIndexerFlags": "Dizinleyici Bayraklarını Seçin",
"SelectIndexerFlags": "İndeksleyici Bayraklarını Seçin",
"Started": "Başlatıldı",
"Size": "Boyut",
"SupportedCustomConditions": "{appName}, aşağıdaki yayın özelliklerine göre özel koşulları destekler.",
@@ -784,22 +784,22 @@
"NotificationsSignalSettingsPasswordHelpText": "Signal-api'ye yönelik istekleri doğrulamak için kullanılan şifre",
"NotificationsSimplepushSettingsEventHelpText": "Anlık bildirimlerin davranışını özelleştirme",
"NotificationsSlackSettingsUsernameHelpText": "Slack'e gönderilecek kullanıcı adı",
"QueueFilterHasNoItems": "Seçilen kuyruk filtresinde hiç öğe yok",
"QueueFilterHasNoItems": "Seçilen kuyruk filtresinde hiç öğe bulunamadı",
"ReleaseGroups": "Yayımlama Grupları",
"IncludeCustomFormatWhenRenamingHelpText": "Özel formatları yeniden adlandırma formatına dahil et",
"Logging": "Loglama",
"MinutesSixty": "60 Dakika: {sixty}",
"SelectDownloadClientModalTitle": "{modalTitle} - İndirme İstemcisini Seçin",
"Repack": "Yeniden paketle",
"IndexerFlags": "Dizinleyici Bayrakları",
"Indexer": "Dizinleyici",
"Indexers": "Dizinleyiciler",
"IndexerPriority": "Dizinleyici Önceliği",
"IndexerOptionsLoadError": "Dizinleyici seçenekleri yüklenemiyor",
"IndexerSettings": "Dizinleyici Ayarları",
"IndexerFlags": "İndeksleyici Bayrakları",
"Indexer": "İndeksleyici",
"Indexers": "İndeksleyiciler",
"IndexerPriority": "İndeksleyici Önceliği",
"IndexerOptionsLoadError": "İndeksleyici seçenekleri yüklenemiyor",
"IndexerSettings": "İndeksleyici Ayarları",
"MustContain": "İçermeli",
"MustNotContain": "İçermemeli",
"RssSyncIntervalHelpTextWarning": "Bu, tüm dizinleyiciler için geçerli olacaktır, lütfen onlar tarafından belirlenen kurallara uyun",
"RssSyncIntervalHelpTextWarning": "Bu, tüm indeksleyiciler için geçerli olacaktır, lütfen onlar tarafından belirlenen kurallara uyun",
"DownloadClientQbittorrentTorrentStateMissingFiles": "qBittorrent eksik dosya raporluyor",
"ImportListExclusions": "İçe Aktarma Listesinden Hariç Bırakılan(lar)",
"UiLanguage": "Arayüz Dili",
@@ -820,7 +820,7 @@
"Monitored": "Takip Ediliyor",
"MonitoredOnly": "Sadece Takip Edilen",
"External": "Harici",
"MassSearchCancelWarning": "Bu işlem, {appName} yeniden başlatılmadan veya tüm dizin oluşturucularınız devre dışı bırakılmadan başlatılır ise iptal edilemez.",
"MassSearchCancelWarning": "Bu, {appName} uygulamasını yeniden başlatmadan veya tüm İndeksleyiciler devre dışı bırakılmadan başlatılır ise iptal edilemez.",
"IncludeUnmonitored": "Takip Edilmeyenleri Dahil Et",
"MonitorSelected": "Seçilenleri Bırak",
"MonitoredStatus": "Takip Edilen/Durum",
@@ -835,7 +835,7 @@
"UpdateAutomaticallyHelpText": "Güncelleştirmeleri otomatik olarak indirip yükleyin. Sistem: Güncellemeler'den yükleme yapmaya devam edebileceksiniz",
"Wanted": "Arananlar",
"Cutoff": "Kesinti",
"Required": "Gerekli",
"Required": "Zorunlu",
"AirsTbaOn": "Daha sonra duyurulacak {networkLabel}'de",
"AllFiles": "Tüm dosyalar",
"AllSeriesAreHiddenByTheAppliedFilter": "Tüm sonuçlar uygulanan filtre tarafından gizlendi",
@@ -864,7 +864,7 @@
"TomorrowAt": "Yarın {time}'da",
"NoBlocklistItems": "Engellenenler listesi öğesi yok",
"YesterdayAt": "Dün saat {time}'da",
"CustomFormatsSpecificationExceptLanguage": "Dil Dışında",
"CustomFormatsSpecificationExceptLanguage": "Dil Hariç",
"CustomFormatsSpecificationExceptLanguageHelpText": "Seçilen dil dışında herhangi bir dil mevcutsa eşleşir",
"LastSearched": "Son Aranan",
"Enable": "Etkinleştir",
@@ -958,7 +958,7 @@
"DownloadClientRootFolderHealthCheckMessage": "İndirme istemcisi {downloadClientName}, indirmeleri kök klasöre yerleştirir {rootFolderPath}. Bir kök klasöre indirmemelisiniz.",
"DeleteBackup": "Yedeklemeyi Sil",
"CustomColonReplacementFormatHelpText": "İki nokta üst üste yerine kullanılacak karakterler",
"CustomColonReplacement": "Özel Kolon Değişimi",
"CustomColonReplacement": "İki Nokta Üst Üste İşareti İçin Özel Değiştirme",
"CustomColonReplacementFormatHint": "İki Nokta (Harf) gibi geçerli dosya sistemi karakteri",
"CustomFormatsSpecificationReleaseGroup": "Yayın Grubu",
"CustomFormatsSpecificationResolution": "Çözünürlük",
@@ -968,7 +968,7 @@
"DeleteEmptySeriesFoldersHelpText": "Disk taraması sırasında ve bölüm dosyaları silindiğinde boş dizi ve sezon klasörlerini silin",
"DeleteEpisodesFiles": "{episodeFileCount} Bölüm Dosyasını Sil",
"DeleteImportListExclusion": "İçe Aktarma Listesi Hariç Tutmasını Sil",
"DeleteIndexer": "Dizinleyiciyi Sil",
"DeleteIndexer": "İndeksleyiciyi Sil",
"Docker": "Docker",
"DockerUpdater": "Güncellemeyi almak için docker konteynerini güncelleyin",
"DeleteSelectedSeries": "Seçili Serileri Sil",
@@ -1008,10 +1008,10 @@
"Debug": "Hata ayıklama",
"DailyEpisodeTypeFormat": "Tarih ({format})",
"DeleteSeriesFolders": "Dizi Klasörlerini Sil",
"Discord": "Uyuşmazlık",
"Discord": "Discord",
"DeleteSeriesFoldersHelpText": "Dizi klasörlerini ve tüm içeriklerini silin",
"QualitySettings": "Kalite Ayarları",
"ReplaceWithSpaceDashSpace": "Space Dash Space ile değiştirin",
"ReplaceWithSpaceDashSpace": "Boşluk, Tire ve Boşluk ile Değiştir",
"Continuing": "Devam Ediyor",
"CleanLibraryLevel": "Kütüphane Seviyesini Temizle",
"ClickToChangeSeason": "Sezonu değiştirmek için tıklayın",
@@ -1084,7 +1084,7 @@
"EditDelayProfile": "Gecikme Profilini Düzenle",
"EventType": "Etkinlik tipi",
"ImportedTo": "İçeri Aktarıldı",
"IndexerDownloadClientHealthCheckMessage": "Geçersiz indirme istemcilerine sahip dizinleyiciler: {indexerNames}.",
"IndexerDownloadClientHealthCheckMessage": "Geçersiz indirme istemcilerine sahip indeksleyiciler: {indexerNames}.",
"Component": "Bileşen",
"Connection": "Bağlantılar",
"Reorder": "Yeniden sırala",
@@ -1188,7 +1188,7 @@
"DeleteSeriesFolderEpisodeCount": "{episodeFileCount} bölüm dosyası toplamı {size}",
"DestinationPath": "Hedef yol",
"Disabled": "Devre dışı",
"ColonReplacementFormatHelpText": "{appName}'ın kolon değişimini nasıl işlediğini değiştirin",
"ColonReplacementFormatHelpText": "{appName} uygulamasının iki nokta üst üste işaretini değiştirme ayarı",
"DeleteTag": "Etiketi Sil",
"NamingSettingsLoadError": "Adlandırma ayarları yüklenemiyor",
"NotificationTriggers": "Bildirim Tetikleyicileri",
@@ -1296,7 +1296,7 @@
"DeleteSelectedEpisodeFilesHelpText": "Seçili bölüm dosyalarını silmek istediğinizden emin misiniz?",
"DownloadClientCheckUnableToCommunicateWithHealthCheckMessage": "{downloadClientName} ile iletişim kurulamıyor. {errorMessage}",
"DownloadClientSettingsRecentPriorityEpisodeHelpText": "Son 14 gün içinde yayınlanan bölümleri almaya öncelik verin",
"EnableInteractiveSearchHelpTextWarning": "Bu dizinleyici ile arama desteklenmiyor",
"EnableInteractiveSearchHelpTextWarning": "Bu indeksleyici ile arama desteklenmiyor",
"EpisodeAirDate": "Bölüm Yayın Tarihi",
"EnableColorImpairedModeHelpText": "Renk engelli kullanıcıların renkleri daha iyi ayırt edebilmelerini sağlamak için değiştirilmiş stil",
"EnableRss": "RSS'yi etkinleştir",
@@ -1318,8 +1318,8 @@
"ImportList": "Listeler",
"ImportListExclusionsLoadError": "Hariç Tutulanlar Listesi yüklenemiyor",
"ImportLists": "Listeler",
"IndexersLoadError": "Dizinleyiciler yüklenemiyor",
"IndexersSettingsSummary": "Dizinleyiciler ve yayımlama kısıtlamaları",
"IndexersLoadError": "İndeksleyiciler yüklenemiyor",
"IndexersSettingsSummary": "İndeksleyiciler ve indeksleyici seçenekleri",
"InteractiveImport": "Etkileşimli İçe Aktarma",
"InteractiveImportNoLanguage": "Seçilen her dosya için dil seçilmelidir",
"InteractiveSearch": "Etkileşimli Arama",
@@ -1360,12 +1360,12 @@
"NoLeaveIt": "Hayır, Bırak",
"NoLimitForAnyRuntime": "Herhangi bir çalışma zamanı için sınır yok",
"NoLinks": "Bağlantı Yok",
"NoLogFiles": "Log kayıt dosyası henüz yok",
"NoLogFiles": "Log kayıt dosyası henüz oluşturulmadı",
"NoMatchFound": "Eşleşme bulunamadı!",
"NoMinimumForAnyRuntime": "Herhangi bir çalışma süresi için minimum değer yok",
"NoResultsFound": "Sonuç bulunamadı",
"NoTagsHaveBeenAddedYet": "Henüz etiket eklenmedi",
"NoUpdatesAreAvailable": "Güncelleme yok",
"NoUpdatesAreAvailable": "Güncelleme bulunamadı",
"None": "Yok",
"NotificationsGotifySettingsPreferredMetadataLink": "Tercih Edilen Meta Veri Bağlantısı",
"NotificationsGotifySettingsPreferredMetadataLinkHelpText": "Yalnızca tek bir bağlantıyı destekleyen istemciler için meta veri bağlantısı",
@@ -1435,8 +1435,8 @@
"RenameFiles": "Yeniden Adlandır",
"Renamed": "Yeniden adlandırıldı",
"Replace": "Değiştir",
"ReplaceWithDash": "Dash ile değiştir",
"ReplaceWithSpaceDash": "Space Dash ile değiştirin",
"ReplaceWithDash": "Tire ile değiştir",
"ReplaceWithSpaceDash": "Tire ve Boşluk ile Değiştir",
"RequiredHelpText": "Özel formatın uygulanabilmesi için bu {implementationName} koşulunun eşleşmesi gerekir. Aksi takdirde tek bir {implementationName} eşleşmesi yeterlidir.",
"RestartRequiredHelpTextWarning": "Etkili olması için yeniden başlatma gerektirir",
"RetentionHelpText": "Yalnızca Usenet: Sınırsız saklamaya ayarlamak için sıfıra ayarlayın",
@@ -1495,7 +1495,7 @@
"Tasks": "Görevler",
"TestAll": "Tümünü Test Et",
"TestAllClients": "Tüm İstemcileri Test Et",
"TestAllIndexers": "Dizinleyicileri Test Et",
"TestAllIndexers": "İndeksleyicileri Test Et",
"TestAllLists": "Tüm Listeleri Test Et",
"Time": "Zaman",
"TimeFormat": "Zaman formatı",
@@ -1658,9 +1658,9 @@
"ImportListsSimklSettingsUserListTypeHold": "Tut",
"ImportListsSimklSettingsUserListTypeWatching": "İzlenen",
"ImportListsSonarrSettingsFullUrl": "Tam URL",
"IndexerJackettAllHealthCheckMessage": "Desteklenmeyen Jackett 'tümü' uç noktasını kullanan dizinleyiciler: {indexerNames}",
"IndexerLongTermStatusAllUnavailableHealthCheckMessage": "6 saatten uzun süren hatalar nedeniyle tüm dizinleyiciler kullanılamıyor",
"IndexerSearchNoInteractiveHealthCheckMessage": "Etkileşimli Arama etkinleştirildiğinde hiçbir dizinleyici kullanılamaz, {appName} herhangi bir etkileşimli arama sonucu sağlamayacaktır",
"IndexerJackettAllHealthCheckMessage": "Desteklenmeyen Jackett 'tümü' uç noktasını kullanan indeksleyiciler: {indexerNames}",
"IndexerLongTermStatusAllUnavailableHealthCheckMessage": "6 saatten uzun süren hatalar nedeniyle tüm indeksleyiciler kullanılamıyor",
"IndexerSearchNoInteractiveHealthCheckMessage": "Etkileşimli Arama etkinleştirildiğinde hiçbir indeksleyici kullanılamaz, {appName} herhangi bir etkileşimli arama sonucu sağlamayacaktır",
"IndexerSettingsAllowZeroSizeHelpText": "Bunu etkinleştirmek, sürüm boyutunu belirtmeyen beslemeleri kullanmanıza olanak tanır; ancak dikkatli olun, boyutla ilgili kontroller gerçekleştirilmeyecektir.",
"IndexerSettingsAnimeCategoriesHelpText": "Açılır listeyi boş bırakın, animeyi devre dışı bırakın",
"IndexerSettingsAnimeStandardFormatSearch": "Anime Standart Format Arama",
@@ -1679,7 +1679,7 @@
"IRCLinkText": "#sonarr Daima Özgür",
"EpisodeTitleRequiredHelpText": "Bölüm başlığı adlandırma biçimindeyse ve bölüm başlığı TBA ise 48 saate kadar içe aktarmayı önleyin",
"FullSeason": "Tam Sezon",
"IndexerLongTermStatusUnavailableHealthCheckMessage": "6 saatten uzun süren hatalar nedeniyle kullanılamayan dizinleyiciler: {indexerNames}",
"IndexerLongTermStatusUnavailableHealthCheckMessage": "6 saatten uzun süren hatalar nedeniyle kullanılamayan indeksleyiciler: {indexerNames}",
"IndexerSettingsAdditionalParametersNyaa": "Ek Parametreler",
"IndexerSettingsApiUrl": "API URL'si",
"IndexerSettingsCookieHelpText": "Sitenizin rss'e erişmek için bir giriş çerezine ihtiyacı varsa, bunu bir tarayıcı aracılığıyla almanız gerekecektir.",
@@ -1764,8 +1764,8 @@
"ImportListsTraktSettingsPopularListTypeTopYearShows": "Yıla Göre En Çok İzlenen Diziler",
"ImportListsValidationUnableToConnectException": "İçe aktarma listesine bağlanılamıyor: {exceptionMessage}. Ayrıntılar için bu hatayla ilgili günlüğü kontrol edin.",
"ImportMechanismHandlingDisabledHealthCheckMessage": "Tamamlanmış İndirme İşlemini Etkinleştir",
"IndexerRssNoIndexersAvailableHealthCheckMessage": "Son zamanlardaki dizinleyici hataları nedeniyle tüm rss uyumlu dizinleyiciler geçici olarak kullanılamıyor",
"IndexerRssNoIndexersEnabledHealthCheckMessage": "RSS senkronizasyonu etkinleştirildiğinde dizinleyiciler kullanılamaz, {appName} yeni sürümleri otomatik olarak almayacaktır",
"IndexerRssNoIndexersAvailableHealthCheckMessage": "Son zamanlardaki indeksleyici hataları nedeniyle tüm rss uyumlu indeksleyiciler geçici olarak kullanılamıyor",
"IndexerRssNoIndexersEnabledHealthCheckMessage": "RSS senkronizasyonu etkinleştirildiğinde tüm indeksleyiciler kullanılamaz, {appName} yeni sürümleri otomatik olarak almayacaktır",
"IndexerSettingsCategoriesHelpText": "Açılır listeyi boş bırakın, standart/günlük gösterileri devre dışı bırakın",
"EpisodeTitleFootNote": "İsteğe bağlı olarak kesmeyi üç nokta (`...`) dahil olarak maksimum bayt boyutuna göre kontrol edin. Sondan (örn. `{Episode Title:30}`) veya başlangıçtan (örn. `{Episode Title:-30}`) kesme her ikisi de desteklenmektedir. Bölüm başlıkları, gerekirse dosya sistemi sınırlamalarına göre otomatik olarak kesilecektir.",
"GrabReleaseUnknownSeriesOrEpisodeMessageText": "{appName} bu sürümün hangi dizi ve bölüm için olduğunu belirleyemedi. {appName} bu sürümü otomatik olarak içe aktaramayabilir. '{title}' öğesini almak ister misiniz?",
@@ -1773,8 +1773,8 @@
"ImportMechanismEnableCompletedDownloadHandlingIfPossibleMultiComputerHealthCheckMessage": "Mümkünse Tamamlanmış İndirme İşlemini Etkinleştirin (Çoklu Bilgisayar desteklenmiyor)",
"IndexerIPTorrentsSettingsFeedUrlHelpText": "IPTorrents tarafından yalnızca seçtiğiniz kategorileri (HD, SD, x264, vb.) kullanarak oluşturulan tam RSS besleme URL'si",
"IndexerSettingsAdditionalNewznabParametersHelpText": "Lütfen kategoriyi değiştirmeniz durumunda yabancı dil sürümlerini önlemek için alt gruplar hakkında zorunlu/kısıtlı kurallar eklemeniz gerekeceğini unutmayın.",
"IndexerValidationNoResultsInConfiguredCategories": "Sorgu başarılı, ancak dizinleyicinizden yapılandırılan kategorilerde hiçbir sonuç döndürülmedi. Bu, dizinleyici veya dizinleyici kategori ayarlarınızdaki bir sorun olabilir.",
"IndexerValidationQuerySeasonEpisodesNotSupported": "Dizinleyici geçerli sorguyu desteklemiyor. Kategorilerin ve/veya sezon/bölüm aramasının desteklenip desteklenmediğini kontrol edin. Daha fazla ayrıntı için günlüğü kontrol edin.",
"IndexerValidationNoResultsInConfiguredCategories": "Sorgu başarılı, ancak indeksleyicinizden yapılandırılan kategorilerde hiçbir sonuç döndürülmedi. Bu, indeksleyici veya indeksleyici kategori ayarlarınızdan kaynaklı bir sorun olabilir.",
"IndexerValidationQuerySeasonEpisodesNotSupported": "İndeksleyici geçerli sorguyu desteklemiyor. Kategorilerin ve/veya sezon/bölüm aramasının desteklenip desteklenmediğini kontrol edin. Daha fazla ayrıntı için günlüğü kontrol edin.",
"MarkAsFailedConfirmation": "'{sourceTitle}' öğesini başarısız olarak işaretlemek istediğinizden emin misiniz?",
"ErrorLoadingContent": "Bu içerik yüklenirken bir hata oluştu",
"FilterContains": "içerir",
@@ -1784,39 +1784,39 @@
"ImportListsTraktSettingsLimitHelpText": "Alınacak dizi sayısını sınırlayın",
"ImportListsTraktSettingsUsernameHelpText": "İçe aktarılacak Liste için Kullanıcı Adı",
"ImportListsTraktSettingsWatchedListSortingHelpText": "Liste Türü İzlenen ise, listeyi sıralamak için sırayı seçin",
"IndexerSearchNoAutomaticHealthCheckMessage": "Otomatik Arama etkinleştirildiğinde hiçbir dizinleyici kullanılamaz, {appName} herhangi bir otomatik arama sonucu sağlamayacaktır",
"IndexerSearchNoAutomaticHealthCheckMessage": "Otomatik Arama etkinleştirildiğinde hiçbir indeksleyici kullanılamaz, {appName} herhangi bir otomatik arama sonucu sağlamayacaktır",
"IndexerSettingsApiUrlHelpText": "Ne yaptığınızı bilmiyorsanız bunu değiştirmeyin. API anahtarınız ana sunucuya gönderilecektir.",
"IndexerSettingsSeasonPackSeedTimeHelpText": "Bir sezon paketi torrentinin durdurulmadan önce başlatılması gereken süre, boş bırakıldığında indirme istemcisinin varsayılanı kullanılır",
"IndexerValidationCloudFlareCaptchaRequired": "Site CloudFlare CAPTCHA tarafından korunmaktadır. Geçerli CAPTCHA belirteci gereklidir.",
"IndexerValidationUnableToConnectServerUnavailable": "Dizinleyiciye bağlanılamıyor, dizinleyicinin sunucusu kullanılamıyor. Daha sonra tekrar deneyin. {exceptionMessage}.",
"IndexerValidationUnableToConnectServerUnavailable": "İndeksleyiciye bağlanılamıyor, indeksleyicinin sunucusu kullanılamıyor. Daha sonra tekrar deneyin. {exceptionMessage}.",
"ImportListsTraktSettingsUserListUsernameHelpText": "İçe aktarılacak Liste için Kullanıcı Adı (Yetkili Kullanıcı için boş bırakın)",
"ImportListsTraktSettingsYearsHelpText": "Diziyi yıla veya yıl aralığına göre filtreleyin",
"IndexerHDBitsSettingsMediums": "Ortamlar",
"IndexerSearchNoAvailableIndexersHealthCheckMessage": "Son zamanlardaki dizinleyici hataları nedeniyle tüm arama yeteneğine sahip dizinleyiciler geçici olarak kullanılamıyor",
"IndexerSearchNoAvailableIndexersHealthCheckMessage": "Son zamanlardaki indeksleyici hataları nedeniyle tüm arama yeteneğine sahip indeksleyiciler geçici olarak kullanılamıyor",
"IndexerSettingsSeasonPackSeedTime": "Sezon Paketi Seed Süresi",
"IndexerValidationJackettAllNotSupportedHelpText": "Jackett'in tüm uç noktaları desteklenmiyor, lütfen dizinleyicileri tek tek ekleyin",
"IndexerValidationNoRssFeedQueryAvailable": "RSS besleme sorgusu mevcut değil. Bu, dizinleyici veya dizinleyici kategori ayarlarınızdaki bir sorun olabilir.",
"IndexerValidationUnableToConnectResolutionFailure": "Dizinleyiciye bağlanılamıyor bağlantı hatası. Dizinleyicinin sunucusuna ve DNS'ine olan bağlantınızı kontrol edin. {exceptionMessage}.",
"IndexerValidationJackettAllNotSupportedHelpText": "Jackett'in tüm uç noktaları desteklenmiyor, lütfen indeksleyicileri tek tek ekleyin",
"IndexerValidationNoRssFeedQueryAvailable": "RSS besleme sorgusu mevcut değil. Bu, indeksleyici veya indeksleyici kategori ayarlarınızdan kaynaklı bir sorun olabilir.",
"IndexerValidationUnableToConnectResolutionFailure": "İndeksleyiciye bağlanılamıyor bağlantı hatası. İndeksleyicinin sunucusuna ve DNS'ine olan bağlantınızı kontrol edin. {exceptionMessage}.",
"IndexerSettingsFailDownloads": "Başarısız İndirmeler",
"IndexerSettingsFailDownloadsHelpText": "Tamamlanan indirmeler işlenirken {appName} bu seçili dosya türlerini başarısız indirmeler olarak değerlendirecektir.",
"IndexerSettingsMinimumSeeders": "Minimum Seeder",
"IndexerSettingsRssUrl": "RSS URL",
"IndexerSettingsRssUrlHelpText": "{indexer} uyumlu bir RSS beslemesine URL girin",
"IndexerSettingsWebsiteUrl": "Web site URL'si",
"IndexerStatusAllUnavailableHealthCheckMessage": "Tüm dizinleyiciler hatalar nedeniyle kullanılamıyor",
"IndexerStatusUnavailableHealthCheckMessage": "Hatalar nedeniyle kullanılamayan dizinleyiciler: {indexerNames}",
"IndexerStatusAllUnavailableHealthCheckMessage": "Tüm indeksleyiciler hatalar nedeniyle kullanılamıyor",
"IndexerStatusUnavailableHealthCheckMessage": "Hatalar nedeniyle kullanılamayan indeksleyiciler: {indexerNames}",
"IndexerTagSeriesHelpText": "Bu indeksleyiciyi yalnızca en az bir eşleşen etiketi olan seriler için kullanın. Tüm serilerle kullanmak için boş bırakın.",
"IndexerValidationCloudFlareCaptchaExpired": "CloudFlare CAPTCHA token'ınızın süresi doldu, lütfen yenileyin.",
"IndexerValidationFeedNotSupported": "Dizinleyici beslemesi desteklenmiyor: {exceptionMessage}",
"IndexerValidationFeedNotSupported": "indeksleyici beslemesi desteklenmiyor: {exceptionMessage}",
"IndexerValidationInvalidApiKey": "Geçersiz API Anahtarı",
"IndexerValidationJackettAllNotSupported": "Jackett'in tüm uç noktaları desteklenmiyor, lütfen dizinleyicileri tek tek ekleyin",
"IndexerValidationJackettAllNotSupported": "Jackett'in tüm uç noktaları desteklenmiyor, lütfen indeksleyicileri tek tek ekleyin",
"IndexerValidationRequestLimitReached": "Talep sınırına ulaşıldı: {exceptionMessage}",
"IndexerValidationSearchParametersNotSupported": "Dizinleyici gerekli arama parametrelerini desteklemiyor",
"IndexerValidationSearchParametersNotSupported": "İndeksleyici gerekli arama parametrelerini desteklemiyor",
"IndexerValidationTestAbortedDueToError": "Test bir hata nedeniyle iptal edildi: {exceptionMessage}",
"IndexerValidationUnableToConnect": "Dizinleyiciye bağlanılamıyor: {exceptionMessage}. Ayrıntılar için bu hatayla ilgili günlüğü kontrol edin",
"IndexerValidationUnableToConnectHttpError": "Dizinleyiciye bağlanılamıyor, lütfen DNS ayarlarınızı kontrol edin ve IPv6'nın çalıştığından veya devre dışı olduğundan emin olun. {exceptionMessage}.",
"IndexerValidationUnableToConnectInvalidCredentials": "Dizinleyiciye bağlanılamıyor, geçersiz kimlik bilgileri. {exceptionMessage}.",
"IndexerValidationUnableToConnectTimeout": "Dizinleyiciye bağlanılamıyor, muhtemelen zaman aşımı nedeniyle. Tekrar deneyin veya ağ ayarlarınızı kontrol edin. {exceptionMessage}.",
"IndexerValidationUnableToConnect": "İndeksleyiciye bağlanılamıyor: {exceptionMessage}. Ayrıntılar için bu hatayla ilgili günlüğü kontrol edin",
"IndexerValidationUnableToConnectHttpError": "İndeksleyiciye bağlanılamıyor, lütfen DNS ayarlarınızı kontrol edin ve IPv6'nın çalıştığından veya devre dışı olduğundan emin olun. {exceptionMessage}.",
"IndexerValidationUnableToConnectInvalidCredentials": "İndeksleyiciye bağlanılamıyor, geçersiz kimlik bilgileri. {exceptionMessage}.",
"IndexerValidationUnableToConnectTimeout": "İndeksleyiciye bağlanılamıyor, muhtemelen zaman aşımı nedeniyle. Tekrar deneyin veya ağ ayarlarınızı kontrol edin. {exceptionMessage}.",
"InteractiveImportNoEpisode": "Her seçili dosya için bir veya daha fazla bölüm seçilmelidir",
"InteractiveImportNoSeason": "Her seçilen dosya için sezon seçilmelidir",
"InteractiveImportNoSeries": "Her seçilen dosya için dizi seçilmelidir",
@@ -1968,7 +1968,7 @@
"ReleaseSceneIndicatorUnknownMessage": "Bu bölüm için numaralandırma değişiklik göstermektedir ve sürüm bilinen hiçbir eşleştirmeyle uyuşmamaktadır.",
"ReleaseSceneIndicatorUnknownSeries": "Bilinmeyen bölüm veya dizi.",
"ReleaseType": "Sürüm Türü",
"RemotePathMappingDockerFolderMissingHealthCheckMessage": "Docker kullanıyorsunuz; indirme istemcisi {downloadClientName} indirmeleri {path} dizinine yerleştiriyor ancak bu dizin konteynerin içinde görünmüyor. Uzak yol eşlemelerinizi ve konteyner hacmi ayarlarınızı inceleyin.",
"RemotePathMappingDockerFolderMissingHealthCheckMessage": "Docker kullanıyorsunuz; indirme istemcisi {downloadClientName} indirmeleri {path} dizinine yerleştiriyor ancak bu dizin konteynerin içinde görünmüyor. Uzak yol eşlemelerinizi ve konteyner bağlama ayarlarınızı inceleyin.",
"RemotePathMappingDownloadPermissionsEpisodeHealthCheckMessage": "{appName} indirilen bölümü {path} görebiliyor ancak erişemiyor. Muhtemelen izin hatası.",
"RemotePathMappingFileRemovedHealthCheckMessage": "{path} dosyası işleme sırasında kaldırıldı.",
"RemotePathMappingFilesGenericPermissionsHealthCheckMessage": "{downloadClientName} indirme istemcisi {path} dizinindeki dosyaları raporladı ancak {appName} bu dizini göremiyor. Klasörün izinlerini ayarlamanız gerekebilir.",

View File

@@ -52,5 +52,20 @@
"AddNewRestriction": "加入新的限制",
"AuthenticationRequiredWarning": "為防止未經認證的遠程訪問,{appName} 現需要啟用身份認證。您可以選擇禁用本地地址的身份認證。",
"AddRemotePathMappingError": "無法加入新的遠程路徑對應,請重試。",
"AnalyseVideoFilesHelpText": "從文件中提取影像資訊,如解析度、運行環境和編解碼器資訊。這需要 {appName} 在掃描期間讀取文件並可能導致高磁盤或網絡佔用。"
"AnalyseVideoFilesHelpText": "從文件中提取影像資訊,如解析度、運行環境和編解碼器資訊。這需要 {appName} 在掃描期間讀取文件並可能導致高磁盤或網絡佔用。",
"AddDelayProfileError": "無法加入新的延遲配置,請重新嘗試。",
"AddImportListExclusionError": "無法加入新的導入列表排除,請重試。",
"AddIndexerError": "無法加入新的索引器,請重試。",
"AddList": "加入清單",
"AddListError": "無法加入新的清單,請重試。",
"AddANewPath": "新增新的路徑",
"AddCustomFormat": "加入自訂格式",
"AddCustomFormatError": "無法加入自訂格式,請重試。",
"AddDownloadClient": "加入下載用戶端",
"AddDownloadClientError": "無法加入下載用戶端,請重試。",
"AddExclusion": "加入排除",
"AbsoluteEpisodeNumbers": "絕對集數",
"AbsoluteEpisodeNumber": "絕對集數",
"AddListExclusionError": "無法加入新的清單排除,請重試。",
"AddNew": "加入新的"
}

View File

@@ -260,6 +260,26 @@ namespace NzbDrone.Core.MediaFiles
var extension = Path.GetExtension(fileInfo.Name);
if (FileExtensions.DangerousExtensions.Contains(extension))
{
return new List<ImportResult>
{
new ImportResult(new ImportDecision(new LocalEpisode { Path = fileInfo.FullName },
new ImportRejection(ImportRejectionReason.DangerousFile, $"Caution: Found potentially dangerous file with extension: {extension}")),
$"Caution: Found potentially dangerous file with extension: {extension}")
};
}
if (FileExtensions.ExecutableExtensions.Contains(extension))
{
return new List<ImportResult>
{
new ImportResult(new ImportDecision(new LocalEpisode { Path = fileInfo.FullName },
new ImportRejection(ImportRejectionReason.ExecutableFile, $"Caution: Found executable file with extension: '{extension}'")),
$"Caution: Found executable file with extension: '{extension}'")
};
}
if (extension.IsNullOrWhiteSpace() || !MediaFileExtensions.Extensions.Contains(extension))
{
_logger.Debug("[{0}] has an unsupported extension: '{1}'", fileInfo.FullName, extension);

View File

@@ -66,6 +66,12 @@ namespace NzbDrone.Core.MediaFiles.EpisodeImport
return DetectSampleResult.Indeterminate;
}
if (runtime == 0)
{
_logger.Debug("Series runtime is 0, defaulting runtime to 45 minutes");
runtime = 45;
}
return IsSample(localEpisode.Path, localEpisode.MediaInfo.RunTime, runtime);
}

View File

@@ -23,8 +23,11 @@ namespace NzbDrone.Core.MediaFiles
private static List<string> _dangerousExtensions = new List<string>
{
".arj",
".lnk",
".lzh",
".ps1",
".scr",
".vbs",
".zipx"
};

View File

@@ -24,7 +24,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
public int? TvRageId { get; set; }
public int? TvMazeId { get; set; }
public int? TmdbId { get; set; }
public HashSet<int> MalIds { get; set; }
public HashSet<int> AniListIds { get; set; }
public string Status { get; set; }
public int? Runtime { get; set; }
public TimeOfDayResource TimeOfDay { get; set; }

View File

@@ -194,6 +194,8 @@ namespace NzbDrone.Core.MetadataSource.SkyHook
}
series.ImdbId = show.ImdbId;
series.MalIds = show.MalIds;
series.AniListIds = show.AniListIds;
series.Title = show.Title;
series.CleanTitle = Parser.Parser.CleanSeriesTitle(show.Title);
series.SortTitle = SeriesTitleNormalizer.Normalize(show.Title, show.TvdbId);

View File

@@ -554,7 +554,7 @@ namespace NzbDrone.Core.Notifications.Discord
{
embed.Thumbnail = new DiscordImage
{
Url = series?.Images?.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Poster)?.Url
Url = series?.Images?.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Poster)?.RemoteUrl
};
}
@@ -562,7 +562,7 @@ namespace NzbDrone.Core.Notifications.Discord
{
embed.Image = new DiscordImage
{
Url = series?.Images?.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Fanart)?.Url
Url = series?.Images?.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Fanart)?.RemoteUrl
};
}

View File

@@ -51,6 +51,9 @@ namespace NzbDrone.Core.Parser
// Some Chinese anime releases contain both Chinese and English titles separated by | instead of /, remove the Chinese title and replace with normal anime pattern
new RegexReplace(@"^\[(?<subgroup>[^\]]+)\](?:\s)(?:(?<chinesetitle>(?=[^\]]*?[\u4E00-\u9FCC])[^\]]*?)(?:\s\|\s))(?<title>[^\]]+?)(?:[- ]+)(?<episode>[0-9]+(?:-[0-9]+)?(?![a-z]))话?(?:END|完)?", "[${subgroup}] ${title} - ${episode} ", RegexOptions.Compiled),
// Spanish releases with information in brackets
new RegexReplace(@"^(?<title>.+?(?=[ ._-]\()).+?\((?<year>\d{4})\/(?<info>S[^\/]+)", "${title} (${year}) - ${info} ", RegexOptions.Compiled),
};
private static readonly Regex[] ReportTitleRegex = new[]
@@ -572,7 +575,7 @@ namespace NzbDrone.Core.Parser
private static readonly Regex YearInTitleRegex = new Regex(@"^(?<title>.+?)[-_. ]+?[\(\[]?(?<year>\d{4})[\]\)]?",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex TitleComponentsRegex = new Regex(@"^(?:(?<title>.+?) \((?<title>.+?)\)|(?<title>.+?) \| (?<title>.+?))$",
private static readonly Regex TitleComponentsRegex = new Regex(@"^(?:(?<title>.+?) \((?<title>.+?)\)|(?<title>.+?) \| (?<title>.+?)|(?<title>.+?) AKA (?<title>.+?))$",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex PartRegex = new Regex(@"\(\d+\)$", RegexOptions.Compiled);

View File

@@ -20,7 +20,7 @@
<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.6" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.7" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="5.3.4" />
<PackageReference Include="MonoTorrent" Version="2.0.7" />

View File

@@ -94,6 +94,8 @@ namespace NzbDrone.Core.Tv
series.TvMazeId = seriesInfo.TvMazeId;
series.TmdbId = seriesInfo.TmdbId;
series.ImdbId = seriesInfo.ImdbId;
series.MalIds = seriesInfo.MalIds;
series.AniListIds = seriesInfo.AniListIds;
series.AirTime = seriesInfo.AirTime;
series.Overview = seriesInfo.Overview;
series.OriginalLanguage = seriesInfo.OriginalLanguage;

View File

@@ -17,6 +17,8 @@ namespace NzbDrone.Core.Tv
Seasons = new List<Season>();
Tags = new HashSet<int>();
OriginalLanguage = Language.English;
MalIds = new HashSet<int>();
AniListIds = new HashSet<int>();
}
public int TvdbId { get; set; }
@@ -24,6 +26,8 @@ namespace NzbDrone.Core.Tv
public int TvMazeId { get; set; }
public string ImdbId { get; set; }
public int TmdbId { get; set; }
public HashSet<int> MalIds { get; set; }
public HashSet<int> AniListIds { get; set; }
public string Title { get; set; }
public string CleanTitle { get; set; }
public string SortTitle { get; set; }

View File

@@ -1,5 +1,4 @@
using FluentValidation;
using FluentValidation.Validators;
using NzbDrone.Common.Extensions;
namespace NzbDrone.Core.Validation
@@ -10,10 +9,5 @@ namespace NzbDrone.Core.Validation
{
return ruleBuilder.Must(x => x.IsValidIpAddress()).WithMessage("Must contain wildcard (*) or a valid IP Address");
}
public static IRuleBuilderOptions<T, string> NotListenAllIp4Address<T>(this IRuleBuilder<T, string> ruleBuilder)
{
return ruleBuilder.SetValidator(new RegularExpressionValidator(@"^(?!0\.0\.0\.0)")).WithMessage("Use * instead of 0.0.0.0");
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using DryIoc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
@@ -59,8 +60,11 @@ namespace NzbDrone.Host
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("10.0.0.0"), 8));
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("172.16.0.0"), 12));
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("192.168.0.0"), 16));
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("fc00::"), 7));
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("fe80::"), 10));
});
services.AddRouting(options => options.LowercaseUrls = true);

View File

@@ -33,7 +33,6 @@ namespace Sonarr.Api.V3.Config
SharedValidator.RuleFor(c => c.BindAddress)
.ValidIpAddress()
.NotListenAllIp4Address()
.When(c => c.BindAddress != "*" && c.BindAddress != "localhost");
SharedValidator.RuleFor(c => c.Port).ValidPort();

View File

@@ -329,7 +329,7 @@ namespace Sonarr.Api.V3.Series
{
foreach (var series in message.Series)
{
BroadcastResourceChange(ModelAction.Deleted, series.ToResource());
BroadcastResourceChange(ModelAction.Deleted, GetSeriesResource(series, false));
}
}
@@ -344,7 +344,7 @@ namespace Sonarr.Api.V3.Series
{
foreach (var series in message.Series)
{
BroadcastResourceChange(ModelAction.Updated, series.ToResource());
BroadcastResourceChange(ModelAction.Updated, GetSeriesResource(series, false));
}
}