Merge branch 'develop' into NET8
This commit is contained in:
commit
fbbf33b64b
|
@ -0,0 +1,13 @@
|
|||
// This file is used to open the backend and frontend in the same workspace, which is necessary as
|
||||
// the frontend has vscode settings that are distinct from the backend
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": ".."
|
||||
},
|
||||
{
|
||||
"path": "../frontend"
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
|
@ -1,17 +1,23 @@
|
|||
'connection':
|
||||
- src/NzbDrone.Core/Notifications/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: src/NzbDrone.Core/Notifications/**/*
|
||||
|
||||
'db-migration':
|
||||
- src/NzbDrone.Core/Datastore/Migration/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: src/NzbDrone.Core/Datastore/Migration/*
|
||||
|
||||
'download-client':
|
||||
- src/NzbDrone.Core/Download/Clients/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: src/NzbDrone.Core/Download/Clients/**/*
|
||||
|
||||
'indexer':
|
||||
- src/NzbDrone.Core/Indexers/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: src/NzbDrone.Core/Indexers/**/*
|
||||
|
||||
'parsing':
|
||||
- src/NzbDrone.Core/Parser/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: src/NzbDrone.Core/Parser/**/*
|
||||
|
||||
'ui-only':
|
||||
- all: ['frontend/**/*']
|
||||
- changed-files:
|
||||
- any-glob-to-all-files: frontend/**/*
|
||||
|
|
|
@ -236,7 +236,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Notify
|
||||
uses: tsickert/discord-webhook@v5.3.0
|
||||
uses: tsickert/discord-webhook@v6.0.0
|
||||
with:
|
||||
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
username: 'GitHub Actions'
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
name: Merge Conflict Labeler
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
pull_request_target:
|
||||
branches:
|
||||
- develop
|
||||
types: [synchronize]
|
||||
|
||||
jobs:
|
||||
label:
|
||||
name: Labeling
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'Sonarr/Sonarr' }}
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Apply label
|
||||
uses: eps1lon/actions-label-merge-conflict@v3
|
||||
with:
|
||||
dirtyLabel: 'merge-conflict'
|
||||
repoToken: '${{ secrets.GITHUB_TOKEN }}'
|
||||
|
|
@ -9,4 +9,4 @@ jobs:
|
|||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v4
|
||||
- uses: actions/labeler@v5
|
||||
|
|
|
@ -9,13 +9,13 @@ jobs:
|
|||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v2
|
||||
- uses: dessant/lock-threads@v5
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-lock-inactive-days: '90'
|
||||
issue-exclude-created-before: ''
|
||||
issue-exclude-labels: 'one-day-maybe'
|
||||
issue-lock-labels: ''
|
||||
issue-lock-comment: ''
|
||||
issue-inactive-days: '90'
|
||||
exclude-issue-created-before: ''
|
||||
exclude-any-issue-labels: 'one-day-maybe'
|
||||
add-issue-labels: ''
|
||||
issue-comment: ''
|
||||
issue-lock-reason: 'resolved'
|
||||
process-only: ''
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import $ from 'jquery';
|
||||
import _ from 'lodash';
|
||||
import createAjaxRequest from 'Utilities/createAjaxRequest';
|
||||
import getProviderState from 'Utilities/State/getProviderState';
|
||||
import { set } from '../baseActions';
|
||||
|
||||
const abortCurrentRequests = {};
|
||||
let lastTestData = null;
|
||||
|
||||
export function createCancelTestProviderHandler(section) {
|
||||
return function(getState, payload, dispatch) {
|
||||
|
@ -17,10 +20,25 @@ function createTestProviderHandler(section, url) {
|
|||
return function(getState, payload, dispatch) {
|
||||
dispatch(set({ section, isTesting: true }));
|
||||
|
||||
const testData = getProviderState(payload, getState, section);
|
||||
const {
|
||||
queryParams = {},
|
||||
...otherPayload
|
||||
} = payload;
|
||||
|
||||
const testData = getProviderState({ ...otherPayload }, getState, section);
|
||||
const params = { ...queryParams };
|
||||
|
||||
// If the user is re-testing the same provider without changes
|
||||
// force it to be tested.
|
||||
|
||||
if (_.isEqual(testData, lastTestData)) {
|
||||
params.forceTest = true;
|
||||
}
|
||||
|
||||
lastTestData = testData;
|
||||
|
||||
const ajaxOptions = {
|
||||
url: `${url}/test`,
|
||||
url: `${url}/test?${$.param(params, true)}`,
|
||||
method: 'POST',
|
||||
contentType: 'application/json',
|
||||
dataType: 'json',
|
||||
|
@ -32,6 +50,8 @@ function createTestProviderHandler(section, url) {
|
|||
abortCurrentRequests[section] = abortRequest;
|
||||
|
||||
request.done((data) => {
|
||||
lastTestData = null;
|
||||
|
||||
dispatch(set({
|
||||
section,
|
||||
isTesting: false,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
|
@ -12,5 +13,7 @@ namespace NzbDrone.Core.Test.IndexerTests
|
|||
}
|
||||
|
||||
public string BaseUrl { get; set; }
|
||||
|
||||
public IEnumerable<int> MultiLanguages { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -429,6 +429,26 @@ namespace NzbDrone.Core.Test.ParserTests
|
|||
result.Languages.Should().Contain(Language.English);
|
||||
}
|
||||
|
||||
[TestCase("Остання серія (Сезон 1) / The Last Series (Season 1) (2024) WEB-DLRip-AVC 2xUkr/Eng | Sub Ukr/Eng")]
|
||||
[TestCase("Справжня серія (Сезон 1-3) / True Series (Season 1-3) (2014-2019) BDRip-AVC 3xUkr/Eng | Ukr/Eng")]
|
||||
[TestCase("Серія (Сезон 1-3) / The Series (Seasons 1-3) (2019-2022) BDRip-AVC 4xUkr/Eng | Sub 2xUkr/Eng")]
|
||||
public void should_parse_english_and_ukranian(string postTitle)
|
||||
{
|
||||
var result = Parser.Parser.ParseTitle(postTitle);
|
||||
result.Languages.Count.Should().Be(2);
|
||||
result.Languages.Should().Contain(Language.Ukrainian);
|
||||
result.Languages.Should().Contain(Language.English);
|
||||
}
|
||||
|
||||
[TestCase("Серія (Сезон 1, серії 01-26 із 51) / Seri (Season 1, episodes 01-26) (2018) WEBRip-AVC 2Ukr/Tur")]
|
||||
public void should_parse_turkish_and_ukranian(string postTitle)
|
||||
{
|
||||
var result = Parser.Parser.ParseTitle(postTitle);
|
||||
result.Languages.Count.Should().Be(2);
|
||||
result.Languages.Should().Contain(Language.Ukrainian);
|
||||
result.Languages.Should().Contain(Language.Turkish);
|
||||
}
|
||||
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].testtitle.default.eng.forced.ass", new[] { "default", "forced" }, "testtitle", "English")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].eng.default.testtitle.forced.ass", new[] { "default", "forced" }, "testtitle", "English")]
|
||||
[TestCase("Name (2020) - S01E20 - [AAC 2.0].default.eng.testtitle.forced.ass", new[] { "default", "forced" }, "testtitle", "English")]
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.BroadcastheNet
|
||||
|
@ -23,6 +26,7 @@ namespace NzbDrone.Core.Indexers.BroadcastheNet
|
|||
{
|
||||
BaseUrl = "https://api.broadcasthe.net/";
|
||||
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
||||
MultiLanguages = Array.Empty<int>();
|
||||
}
|
||||
|
||||
[FieldDefinition(0, Label = "IndexerSettingsApiUrl", Advanced = true, HelpText = "IndexerSettingsApiUrlHelpText")]
|
||||
|
@ -40,6 +44,9 @@ namespace NzbDrone.Core.Indexers.BroadcastheNet
|
|||
[FieldDefinition(4, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
|
||||
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
|
||||
|
||||
[FieldDefinition(5, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
|
||||
public IEnumerable<int> MultiLanguages { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.Fanzub
|
||||
|
@ -19,6 +22,7 @@ namespace NzbDrone.Core.Indexers.Fanzub
|
|||
public FanzubSettings()
|
||||
{
|
||||
BaseUrl = "http://fanzub.com/rss/";
|
||||
MultiLanguages = Array.Empty<int>();
|
||||
}
|
||||
|
||||
[FieldDefinition(0, Label = "IndexerSettingsRssUrl", HelpText = "IndexerSettingsRssUrlHelpText")]
|
||||
|
@ -28,6 +32,9 @@ namespace NzbDrone.Core.Indexers.Fanzub
|
|||
[FieldDefinition(1, Label = "IndexerSettingsAnimeStandardFormatSearch", Type = FieldType.Checkbox, HelpText = "IndexerSettingsAnimeStandardFormatSearchHelpText")]
|
||||
public bool AnimeStandardFormatSearch { get; set; }
|
||||
|
||||
[FieldDefinition(2, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
|
||||
public IEnumerable<int> MultiLanguages { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.FileList
|
||||
|
@ -35,6 +36,7 @@ namespace NzbDrone.Core.Indexers.FileList
|
|||
};
|
||||
|
||||
AnimeCategories = Array.Empty<int>();
|
||||
MultiLanguages = Array.Empty<int>();
|
||||
}
|
||||
|
||||
[FieldDefinition(0, Label = "Username", Privacy = PrivacyLevel.UserName)]
|
||||
|
@ -43,6 +45,9 @@ namespace NzbDrone.Core.Indexers.FileList
|
|||
[FieldDefinition(1, Label = "IndexerSettingsPasskey", Privacy = PrivacyLevel.ApiKey)]
|
||||
public string Passkey { get; set; }
|
||||
|
||||
[FieldDefinition(2, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
|
||||
public IEnumerable<int> MultiLanguages { get; set; }
|
||||
|
||||
[FieldDefinition(3, Label = "IndexerSettingsApiUrl", Advanced = true, HelpText = "IndexerSettingsApiUrlHelpText")]
|
||||
public string BaseUrl { get; set; }
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.HDBits
|
||||
|
@ -29,6 +30,7 @@ namespace NzbDrone.Core.Indexers.HDBits
|
|||
Categories = new[] { (int)HdBitsCategory.Tv, (int)HdBitsCategory.Documentary };
|
||||
Codecs = Array.Empty<int>();
|
||||
Mediums = Array.Empty<int>();
|
||||
MultiLanguages = Array.Empty<int>();
|
||||
}
|
||||
|
||||
[FieldDefinition(0, Label = "IndexerSettingsApiUrl", Advanced = true, HelpText = "IndexerSettingsApiUrlHelpText")]
|
||||
|
@ -58,6 +60,9 @@ namespace NzbDrone.Core.Indexers.HDBits
|
|||
[FieldDefinition(8, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
|
||||
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
|
||||
|
||||
[FieldDefinition(9, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
|
||||
public IEnumerable<int> MultiLanguages { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
using NzbDrone.Core.ThingiProvider;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
|
||||
namespace NzbDrone.Core.Indexers
|
||||
{
|
||||
public interface IIndexerSettings : IProviderConfig
|
||||
{
|
||||
string BaseUrl { get; set; }
|
||||
|
||||
IEnumerable<int> MultiLanguages { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.IPTorrents
|
||||
|
@ -29,6 +32,7 @@ namespace NzbDrone.Core.Indexers.IPTorrents
|
|||
public IPTorrentsSettings()
|
||||
{
|
||||
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
||||
MultiLanguages = Array.Empty<int>();
|
||||
}
|
||||
|
||||
[FieldDefinition(0, Label = "IndexerIPTorrentsSettingsFeedUrl", HelpText = "IndexerIPTorrentsSettingsFeedUrlHelpText")]
|
||||
|
@ -43,6 +47,9 @@ namespace NzbDrone.Core.Indexers.IPTorrents
|
|||
[FieldDefinition(3, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
|
||||
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
|
||||
|
||||
[FieldDefinition(4, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
|
||||
public IEnumerable<int> MultiLanguages { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using FluentValidation.Results;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Localization;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
@ -17,6 +20,8 @@ namespace NzbDrone.Core.Indexers
|
|||
public abstract class IndexerBase<TSettings> : IIndexer
|
||||
where TSettings : IIndexerSettings, new()
|
||||
{
|
||||
private static readonly Regex MultiRegex = new (@"[_. ](?<multi>multi)[_. ]", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
|
||||
protected readonly IIndexerStatusService _indexerStatusService;
|
||||
protected readonly IConfigService _configService;
|
||||
protected readonly IParsingService _parsingService;
|
||||
|
@ -84,9 +89,16 @@ namespace NzbDrone.Core.Indexers
|
|||
protected virtual IList<ReleaseInfo> CleanupReleases(IEnumerable<ReleaseInfo> releases)
|
||||
{
|
||||
var result = releases.DistinctBy(v => v.Guid).ToList();
|
||||
var settings = Definition.Settings as IIndexerSettings;
|
||||
|
||||
result.ForEach(c =>
|
||||
{
|
||||
// Use multi languages from setting if ReleaseInfo languages is empty
|
||||
if (c.Languages.Empty() && MultiRegex.IsMatch(c.Title) && settings.MultiLanguages.Any())
|
||||
{
|
||||
c.Languages = settings.MultiLanguages.Select(i => (Language)i).ToList();
|
||||
}
|
||||
|
||||
c.IndexerId = Definition.Id;
|
||||
c.Indexer = Definition.Name;
|
||||
c.DownloadProtocol = Protocol;
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.Newznab
|
||||
|
@ -55,6 +57,7 @@ namespace NzbDrone.Core.Indexers.Newznab
|
|||
ApiPath = "/api";
|
||||
Categories = new[] { 5030, 5040 };
|
||||
AnimeCategories = Enumerable.Empty<int>();
|
||||
MultiLanguages = Array.Empty<int>();
|
||||
}
|
||||
|
||||
[FieldDefinition(0, Label = "URL")]
|
||||
|
@ -79,7 +82,10 @@ namespace NzbDrone.Core.Indexers.Newznab
|
|||
[FieldDefinition(6, Label = "IndexerSettingsAdditionalParameters", HelpText = "IndexerSettingsAdditionalNewznabParametersHelpText", Advanced = true)]
|
||||
public string AdditionalParameters { get; set; }
|
||||
|
||||
// Field 7 is used by TorznabSettings MinimumSeeders
|
||||
[FieldDefinition(7, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
|
||||
public IEnumerable<int> MultiLanguages { get; set; }
|
||||
|
||||
// Field 8 is used by TorznabSettings MinimumSeeders
|
||||
// If you need to add another field here, update TorznabSettings as well and this comment
|
||||
|
||||
public virtual NzbDroneValidationResult Validate()
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.Nyaa
|
||||
|
@ -25,6 +28,7 @@ namespace NzbDrone.Core.Indexers.Nyaa
|
|||
BaseUrl = "";
|
||||
AdditionalParameters = "&cats=1_0&filter=1";
|
||||
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
||||
MultiLanguages = Array.Empty<int>();
|
||||
}
|
||||
|
||||
[FieldDefinition(0, Label = "IndexerSettingsWebsiteUrl")]
|
||||
|
@ -45,6 +49,9 @@ namespace NzbDrone.Core.Indexers.Nyaa
|
|||
[FieldDefinition(5, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
|
||||
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
|
||||
|
||||
[FieldDefinition(6, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
|
||||
public IEnumerable<int> MultiLanguages { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.TorrentRss
|
||||
|
@ -23,6 +26,7 @@ namespace NzbDrone.Core.Indexers.TorrentRss
|
|||
BaseUrl = string.Empty;
|
||||
AllowZeroSize = false;
|
||||
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
||||
MultiLanguages = Array.Empty<int>();
|
||||
}
|
||||
|
||||
[FieldDefinition(0, Label = "IndexerSettingsRssUrl")]
|
||||
|
@ -43,6 +47,9 @@ namespace NzbDrone.Core.Indexers.TorrentRss
|
|||
[FieldDefinition(5, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
|
||||
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
|
||||
|
||||
[FieldDefinition(6, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
|
||||
public IEnumerable<int> MultiLanguages { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.Torrentleech
|
||||
|
@ -23,6 +26,7 @@ namespace NzbDrone.Core.Indexers.Torrentleech
|
|||
{
|
||||
BaseUrl = "http://rss.torrentleech.org";
|
||||
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
||||
MultiLanguages = Array.Empty<int>();
|
||||
}
|
||||
|
||||
[FieldDefinition(0, Label = "IndexerSettingsWebsiteUrl")]
|
||||
|
@ -40,6 +44,9 @@ namespace NzbDrone.Core.Indexers.Torrentleech
|
|||
[FieldDefinition(4, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
|
||||
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
|
||||
|
||||
[FieldDefinition(5, Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Label = "IndexerSettingsMultiLanguageRelease", HelpText = "IndexerSettingsMultiLanguageReleaseHelpText", Advanced = true)]
|
||||
public IEnumerable<int> MultiLanguages { get; set; }
|
||||
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
|
|
|
@ -49,13 +49,13 @@ namespace NzbDrone.Core.Indexers.Torznab
|
|||
MinimumSeeders = IndexerDefaults.MINIMUM_SEEDERS;
|
||||
}
|
||||
|
||||
[FieldDefinition(7, Type = FieldType.Number, Label = "IndexerSettingsMinimumSeeders", HelpText = "IndexerSettingsMinimumSeedersHelpText", Advanced = true)]
|
||||
[FieldDefinition(8, Type = FieldType.Number, Label = "IndexerSettingsMinimumSeeders", HelpText = "IndexerSettingsMinimumSeedersHelpText", Advanced = true)]
|
||||
public int MinimumSeeders { get; set; }
|
||||
|
||||
[FieldDefinition(8)]
|
||||
[FieldDefinition(9)]
|
||||
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
|
||||
|
||||
[FieldDefinition(9, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
|
||||
[FieldDefinition(10, Type = FieldType.Checkbox, Label = "IndexerSettingsRejectBlocklistedTorrentHashes", HelpText = "IndexerSettingsRejectBlocklistedTorrentHashesHelpText", Advanced = true)]
|
||||
public bool RejectBlocklistedTorrentHashesWhileGrabbing { get; set; }
|
||||
|
||||
public override NzbDroneValidationResult Validate()
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NzbDrone.Core.Annotations;
|
||||
|
||||
namespace NzbDrone.Core.Languages
|
||||
{
|
||||
public class RealLanguageFieldConverter : ISelectOptionsConverter
|
||||
{
|
||||
public List<SelectOption> GetSelectOptions()
|
||||
{
|
||||
return Language.All
|
||||
.Where(l => l != Language.Unknown)
|
||||
.OrderBy(l => l.Id > 0).ThenBy(l => l.Name)
|
||||
.ToList()
|
||||
.ConvertAll(v => new SelectOption { Value = v.Id, Name = v.Name });
|
||||
}
|
||||
}
|
||||
}
|
|
@ -978,6 +978,8 @@
|
|||
"IndexerSettingsPasskey": "Passkey",
|
||||
"IndexerSettingsRejectBlocklistedTorrentHashes": "Reject Blocklisted Torrent Hashes While Grabbing",
|
||||
"IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "If a torrent is blocked by hash it may not properly be rejected during RSS/Search for some indexers, enabling this will allow it to be rejected after the torrent is grabbed, but before it is sent to the client.",
|
||||
"IndexerSettingsMultiLanguageRelease": "Multi Languages",
|
||||
"IndexerSettingsMultiLanguageReleaseHelpText": "What languages are normally in a multi release on this indexer?",
|
||||
"IndexerSettingsRssUrl": "RSS URL",
|
||||
"IndexerSettingsRssUrlHelpText": "Enter to URL to an {indexer} compatible RSS feed",
|
||||
"IndexerSettingsSeasonPackSeedTime": "Season-Pack Seed Time",
|
||||
|
|
|
@ -68,11 +68,11 @@
|
|||
"CancelPendingTask": "Êtes-vous sur de vouloir annuler cette tâche en attente ?",
|
||||
"Clear": "Effacer",
|
||||
"AddAutoTagError": "Impossible d'ajouter un nouveau tag automatique, veuillez réessayer.",
|
||||
"AddConditionError": "Impossible d'ajouter une nouvelle condition, Réessayer.",
|
||||
"AddConditionError": "Impossible d'ajouter une nouvelle condition, veuillez réessayer.",
|
||||
"AddCondition": "Ajouter une condition",
|
||||
"AddAutoTag": "Ajouter un tag automatique",
|
||||
"AddCustomFormatError": "Impossible d'ajouter un nouveau format personnalisé, veuillez réessayer.",
|
||||
"AddIndexerError": "Impossible d'ajouter un nouvelle indexeur, veuillez réessayer.",
|
||||
"AddIndexerError": "Impossible d'ajouter un nouvel indexeur, veuillez réessayer.",
|
||||
"AddNewRestriction": "Ajouter une nouvelle restriction",
|
||||
"AddListError": "Impossible d'ajouter une nouvelle liste, veuillez réessayer.",
|
||||
"AddDownloadClientError": "Impossible d'ajouter un nouveau client de téléchargement, veuillez réessayer.",
|
||||
|
@ -534,7 +534,7 @@
|
|||
"IndexerSearchNoInteractiveHealthCheckMessage": "Aucun indexeur n'est disponible avec la recherche interactive activée. {appName} ne fournira aucun résultat de recherche interactif",
|
||||
"IndexerStatusUnavailableHealthCheckMessage": "Indexeurs indisponibles en raison d'échecs : {indexerNames}",
|
||||
"Info": "Information",
|
||||
"InstallLatest": "Installer le dernier",
|
||||
"InstallLatest": "Installer la dernière",
|
||||
"InteractiveImportNoLanguage": "La ou les langues doivent être choisies pour chaque fichier sélectionné",
|
||||
"InteractiveImportNoQuality": "La qualité doit être choisie pour chaque fichier sélectionné",
|
||||
"InteractiveSearchModalHeader": "Recherche interactive",
|
||||
|
@ -2066,5 +2066,8 @@
|
|||
"EpisodeTitleFootNote": "Contrôlez éventuellement la troncature à un nombre maximum d'octets, y compris les points de suspension (`...`). La troncature de la fin (par exemple `{Episode Title:30}`) ou du début (par exemple `{Episode Title:-30}`) sont toutes deux prises en charge. Les titres des épisodes seront automatiquement tronqués en fonction des limitations du système de fichiers si nécessaire.",
|
||||
"SelectReleaseType": "Sélectionnez le type de version",
|
||||
"SeriesFootNote": "Contrôlez éventuellement la troncature à un nombre maximum d'octets, y compris les points de suspension (`...`). La troncature de la fin (par exemple `{Series Title:30}`) ou du début (par exemple `{Series Title:-30}`) sont toutes deux prises en charge.",
|
||||
"ReleaseGroupFootNote": "Contrôlez éventuellement la troncature à un nombre maximum d'octets, y compris les points de suspension (`...`). La troncature de la fin (par exemple `{Release Group:30}`) ou du début (par exemple `{Release Group:-30}`) sont toutes deux prises en charge.`)."
|
||||
"ReleaseGroupFootNote": "Contrôlez éventuellement la troncature à un nombre maximum d'octets, y compris les points de suspension (`...`). La troncature de la fin (par exemple `{Release Group:30}`) ou du début (par exemple `{Release Group:-30}`) sont toutes deux prises en charge.`).",
|
||||
"AutoTaggingSpecificationTag": "Étiquette",
|
||||
"NotificationsTelegramSettingsIncludeAppName": "Inclure {appName} dans le Titre",
|
||||
"NotificationsTelegramSettingsIncludeAppNameHelpText": "Préfixer éventuellement le titre du message par {appName} pour différencier les notifications des différentes applications"
|
||||
}
|
||||
|
|
|
@ -249,5 +249,6 @@
|
|||
"AnimeEpisodeTypeFormat": "Numero assoluto dell'episodio ({format})",
|
||||
"AutoRedownloadFailed": "Download fallito",
|
||||
"AddDelayProfileError": "Impossibile aggiungere un nuovo profilo di ritardo, riprova.",
|
||||
"Cutoff": "Taglio"
|
||||
"Cutoff": "Taglio",
|
||||
"AddListExclusion": "Aggiungi elenco esclusioni"
|
||||
}
|
||||
|
|
|
@ -136,12 +136,90 @@
|
|||
"AuthenticationMethod": "Kimlik Doğrulama Yöntemi",
|
||||
"AuthenticationRequired": "Kimlik Doğrulama Gerekli",
|
||||
"AuthenticationRequiredWarning": "Kimlik doğrulaması olmadan uzaktan erişimi engellemek için, {appName}'da artık kimlik doğrulamanın etkinleştirilmesini gerektiriyor. İsteğe bağlı olarak yerel adresler için kimlik doğrulamayı devre dışı bırakabilirsiniz.",
|
||||
"ApiKeyValidationHealthCheckMessage": "Lütfen API anahtarınızı en az {length} karakter uzunluğunda olacak şekilde güncelleyin. Bunu ayarlar veya yapılandırma dosyası aracılığıyla yapabilirsiniz",
|
||||
"ApiKeyValidationHealthCheckMessage": "Lütfen API anahtarınızı en az {length} karakter sayısı kadar güncelleyiniz. Bunu ayarlar veya yapılandırma dosyası üzerinden yapabilirsiniz",
|
||||
"ClearBlocklistMessageText": "Engellenenler listesindeki tüm öğeleri temizlemek istediğinizden emin misiniz?",
|
||||
"AutomaticUpdatesDisabledDocker": "Docker güncelleme mekanizması kullanıldığında otomatik güncellemeler doğrudan desteklenmez. Kapsayıcı görüntüsünü {appName} dışında güncellemeniz veya bir komut dosyası kullanmanız gerekecek",
|
||||
"ConnectionLostReconnect": "{appName} otomatik bağlanmayı deneyecek veya aşağıda yeniden yükle seçeneğini işaretleyebilirsiniz.",
|
||||
"BlackholeWatchFolderHelpText": "{appName} uygulamasının tamamlanmış indirmeleri içe aktaracağı klasör",
|
||||
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Yeni şifreyi onayla",
|
||||
"BindAddressHelpText": "Tüm arayüzler için geçerli IP adresi, localhost veya '*'",
|
||||
"CloneAutoTag": "Otomatik Etiketi Klonla"
|
||||
"CloneAutoTag": "Otomatik Etiketi Klonla",
|
||||
"Dash": "Çizgi",
|
||||
"DeleteReleaseProfileMessageText": "'{name}' bu sürüm profilini silmek istediğinizden emin misiniz?",
|
||||
"DownloadClientFreeboxApiError": "Freebox API'si şu hatayı döndürdü: {errorDescription}",
|
||||
"DeleteSelectedDownloadClients": "İndirme İstemcilerini Sil",
|
||||
"DeleteSelectedDownloadClientsMessageText": "Seçilen {count} indirme istemcisini silmek istediğinizden emin misiniz?",
|
||||
"DeleteRootFolderMessageText": "'{path}' kök klasörünü silmek istediğinizden emin misiniz?",
|
||||
"DeleteSpecificationHelpText": "'{name}' spesifikasyonunu silmek istediğinizden emin misiniz?",
|
||||
"DeletedReasonUpgrade": "Bir yükseltmeyi içe aktarmak için dosya silindi",
|
||||
"DelayMinutes": "{delay} Dakika",
|
||||
"DeleteImportListMessageText": "'{name}' listesini silmek istediğinizden emin misiniz?",
|
||||
"DeleteReleaseProfile": "Sürüm Profilini Sil",
|
||||
"DeleteSelectedIndexers": "Dizin Oluşturucuları Sil",
|
||||
"Directory": "Rehber",
|
||||
"Donate": "Bağış yap",
|
||||
"DownloadClientDownloadStationValidationFolderMissing": "Klasör mevcut değil",
|
||||
"DownloadClientFloodSettingsAdditionalTags": "Ek Etiketler",
|
||||
"DownloadClientFloodSettingsPostImportTags": "İçe Aktarma Sonrası Etiketler",
|
||||
"DownloadClientFloodSettingsStartOnAdd": "Eklemeye Başla",
|
||||
"DownloadClientFloodSettingsTagsHelpText": "Bir indirme işleminin başlangıç etiketleri. Bir indirmenin tanınabilmesi için tüm başlangıç etiketlerine sahip olması gerekir. Bu, ilgisiz indirmelerle çakışmaları önler.",
|
||||
"DownloadClientAriaSettingsDirectoryHelpText": "İndirilenlerin yerleştirileceği isteğe bağlı konum, varsayılan Aria2 konumunu kullanmak için boş bırakın",
|
||||
"DefaultNameCopiedProfile": "{name} - Kopyala",
|
||||
"DeleteAutoTag": "Etiketi Otomatik Sil",
|
||||
"DeleteCondition": "Koşulu Sil",
|
||||
"DeleteDelayProfileMessageText": "Bu gecikme profilini silmek istediğinizden emin misiniz?",
|
||||
"DeleteRootFolder": "Kök Klasörü Sil",
|
||||
"DeleteSpecification": "Spesifikasyonu Sil",
|
||||
"DeletedReasonManual": "Dosya, {appName} kullanılarak manuel olarak veya API aracılığıyla başka bir araçla silindi",
|
||||
"DeleteCustomFormatMessageText": "'{name}' özel biçimini silmek istediğinizden emin misiniz?",
|
||||
"DefaultNameCopiedSpecification": "{name} - Kopyala",
|
||||
"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} dizin oluşturucuyu 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",
|
||||
"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",
|
||||
"ReplaceIllegalCharactersHelpText": "Geçersiz karakterleri değiştirin. İşaretlenmezse bunun yerine {appName} bunları kaldıracak",
|
||||
"ConnectionSettingsUrlBaseHelpText": "{connectionName} URL'sine {url} gibi bir önek ekler",
|
||||
"DeleteSelectedImportLists": "İçe Aktarma Listelerini Sil",
|
||||
"DelayingDownloadUntil": "İndirme işlemi {date} tarihine, {time} tarihine kadar erteleniyor",
|
||||
"Destination": "Hedef",
|
||||
"DoNotBlocklist": "Engelleme Listesine Eklemeyin",
|
||||
"DoNotBlocklistHint": "Engellenenler listesine eklemeden kaldır",
|
||||
"DownloadClientDelugeTorrentStateError": "Deluge bir hata bildiriyor",
|
||||
"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": "Dizin Oluşturucu Önceliği (En Yüksek) 1'den (En Düşük) 50'ye kadar. Varsayılan: 25'dir. Eşit olmayan sürümler için eşitlik bozucu olarak sürümler alınırken kullanılan {appName}, RSS Senkronizasyonu ve Arama için etkinleştirilmiş tüm dizin oluşturucuları kullanmaya devam edecek",
|
||||
"DisabledForLocalAddresses": "Yerel Adresler için Devre Dışı Bırakıldı",
|
||||
"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 -> Dizin Oluşturucular'daki mevcut tohum kriterlerine göre torrentlerin otomatik olarak kaldırılmasını gerçekleştirecek",
|
||||
"Database": "Veri tabanı",
|
||||
"DelayProfileProtocol": "Protokol: {preferredProtocol}",
|
||||
"DownloadClientDownloadStationValidationFolderMissingDetail": "'{downloadDir}' klasörü mevcut değil, '{sharedFolder}' Paylaşımlı Klasöründe manuel olarak oluşturulması gerekiyor.",
|
||||
"DeleteAutoTagHelpText": "'{name}' etiketini otomatik silmek istediğinizden emin misiniz?",
|
||||
"DownloadClientDelugeSettingsUrlBaseHelpText": "Deluge json URL'sine bir önek ekler, bkz. {url}",
|
||||
"DownloadClientFreeboxSettingsPortHelpText": "Freebox arayüzüne erişim için kullanılan bağlantı noktası, varsayılan olarak '{port}' şeklindedir",
|
||||
"DownloadClientFreeboxUnableToReachFreebox": "Freebox API'sine ulaşılamıyor. 'Ana Bilgisayar', 'Bağlantı Noktası' veya 'SSL Kullan' ayarlarını doğrulayın. (Hata: {istisnaMessage})",
|
||||
"CustomFormatsSettingsTriggerInfo": "Bir yayına veya dosyaya, seçilen farklı koşul türlerinden en az biriyle eşleştiğinde Özel Format uygulanacaktır.",
|
||||
"Default": "Varsayılan",
|
||||
"DeleteSelectedImportListsMessageText": "Seçilen {count} içe aktarma listesini silmek istediğinizden emin misiniz?",
|
||||
"DownloadClientDelugeSettingsDirectory": "İndirme Dizini",
|
||||
"DownloadClientDelugeSettingsDirectoryCompleted": "Tamamlandığında Dizini Taşı",
|
||||
"DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Tamamlanan indirmelerin taşınacağı isteğe bağlı konum; varsayılan Deluge konumunu kullanmak için boş bırakın",
|
||||
"DownloadClientDelugeSettingsDirectoryHelpText": "İndirilenlerin yerleştirileceği isteğe bağlı konum; varsayılan Deluge konumunu kullanmak için boş bırakın",
|
||||
"DownloadClientDownloadStationSettingsDirectoryHelpText": "İndirilenlerin yerleştirileceği isteğe bağlı paylaşımlı klasör, varsayılan Download Station konumunu kullanmak için boş bırakın",
|
||||
"ApiKey": "API Anahtarı",
|
||||
"Analytics": "Analiz",
|
||||
"All": "Herşey",
|
||||
"AppDataLocationHealthCheckMessage": "Güncellemede AppData'nın silinmesini önlemek için güncelleme mümkün olmayacak",
|
||||
"AnalyticsEnabledHelpText": "Anonim kullanım ve hata bilgilerini {appName} sunucularına gönderin. Bu, tarayıcınızla ilgili bilgileri, kullandığınız {appName} Web arayüz sayfalarını, hata raporlamasının yanı sıra işletim sistemi ve çalışma zamanı sürümünü içerir. Bu bilgileri, özellikleri ve hata düzeltmelerini önceliklendirmek için kullanacağız."
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace NzbDrone.Core.Parser
|
|||
new RegexReplace(@".*?[_. ](S\d{2}(?:E\d{2,4})*[_. ].*)", "$1", RegexOptions.Compiled | RegexOptions.IgnoreCase)
|
||||
};
|
||||
|
||||
private static readonly Regex LanguageRegex = new Regex(@"(?:\W|_)(?<english>\b(?:ing|eng)\b)|(?<italian>\b(?:ita|italian)\b)|(?<german>german\b|videomann|ger[. ]dub)|(?<flemish>flemish)|(?<greek>greek)|(?<french>(?:\W|_)(?:FR|VF|VF2|VFF|VFQ|TRUEFRENCH)(?:\W|_))|(?<russian>\b(?:rus|ru)\b)|(?<hungarian>\b(?:HUNDUB|HUN)\b)|(?<hebrew>\bHebDub\b)|(?<polish>\b(?:PL\W?DUB|DUB\W?PL|LEK\W?PL|PL\W?LEK)\b)|(?<chinese>\[(?:CH[ST]|BIG5|GB)\]|简|繁|字幕)|(?<bulgarian>\bbgaudio\b)|(?<spanish>\b(?:español|castellano|esp|spa(?!\(Latino\)))\b)|(?<ukrainian>\b(?:ukr)\b)|(?<thai>\b(?:THAI)\b)|(?<romanian>\b(?:RoDubbed|ROMANIAN)\b)|(?<catalan>[-,. ]cat[. ](?:DD|subs)|\b(?:catalan|catalán)\b)|(?<latvian>\b(?:lat|lav|lv)\b)",
|
||||
private static readonly Regex LanguageRegex = new Regex(@"(?:\W|_)(?<english>\b(?:ing|eng)\b)|(?<italian>\b(?:ita|italian)\b)|(?<german>german\b|videomann|ger[. ]dub)|(?<flemish>flemish)|(?<greek>greek)|(?<french>(?:\W|_)(?:FR|VF|VF2|VFF|VFQ|TRUEFRENCH)(?:\W|_))|(?<russian>\b(?:rus|ru)\b)|(?<hungarian>\b(?:HUNDUB|HUN)\b)|(?<hebrew>\bHebDub\b)|(?<polish>\b(?:PL\W?DUB|DUB\W?PL|LEK\W?PL|PL\W?LEK)\b)|(?<chinese>\[(?:CH[ST]|BIG5|GB)\]|简|繁|字幕)|(?<bulgarian>\bbgaudio\b)|(?<spanish>\b(?:español|castellano|esp|spa(?!\(Latino\)))\b)|(?<ukrainian>\b(?:\dx?)?(?:ukr))|(?<thai>\b(?:THAI)\b)|(?<romanian>\b(?:RoDubbed|ROMANIAN)\b)|(?<catalan>[-,. ]cat[. ](?:DD|subs)|\b(?:catalan|catalán)\b)|(?<latvian>\b(?:lat|lav|lv)\b)|(?<turkish>\b(?:tur)\b)",
|
||||
RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
private static readonly Regex CaseSensitiveLanguageRegex = new Regex(@"(?:(?i)(?<!SUB[\W|_|^]))(?:(?<lithuanian>\bLT\b)|(?<czech>\bCZ\b)|(?<polish>\bPL\b)|(?<bulgarian>\bBG\b)|(?<slovak>\bSK\b))(?:(?i)(?![\W|_|^]SUB))",
|
||||
|
@ -470,6 +470,11 @@ namespace NzbDrone.Core.Parser
|
|||
{
|
||||
languages.Add(Language.Latvian);
|
||||
}
|
||||
|
||||
if (match.Groups["turkish"].Success)
|
||||
{
|
||||
languages.Add(Language.Turkish);
|
||||
}
|
||||
}
|
||||
|
||||
return languages;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<PackageReference Include="Diacritical.Net" Version="1.0.4" />
|
||||
<PackageReference Include="MailKit" Version="4.3.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="8.0.2" />
|
||||
<PackageReference Include="Polly" Version="8.3.0" />
|
||||
<PackageReference Include="Polly" Version="8.3.1" />
|
||||
<PackageReference Include="Servarr.FFMpegCore" Version="4.7.0-26" />
|
||||
<PackageReference Include="Servarr.FFprobe" Version="5.1.4.112" />
|
||||
<PackageReference Include="System.Memory" Version="4.5.5" />
|
||||
|
|
|
@ -205,10 +205,10 @@ namespace Sonarr.Api.V3
|
|||
[SkipValidation(true, false)]
|
||||
[HttpPost("test")]
|
||||
[Consumes("application/json")]
|
||||
public object Test([FromBody] TProviderResource providerResource)
|
||||
public object Test([FromBody] TProviderResource providerResource, [FromQuery] bool forceTest = false)
|
||||
{
|
||||
var existingDefinition = providerResource.Id > 0 ? _providerFactory.Find(providerResource.Id) : null;
|
||||
var providerDefinition = GetDefinition(providerResource, existingDefinition, true, true, true);
|
||||
var providerDefinition = GetDefinition(providerResource, existingDefinition, true, !forceTest, true);
|
||||
|
||||
Test(providerDefinition, true);
|
||||
|
||||
|
|
|
@ -1654,6 +1654,16 @@
|
|||
"tags": [
|
||||
"DownloadClient"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "forceTest",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
|
@ -2897,6 +2907,16 @@
|
|||
"tags": [
|
||||
"ImportList"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "forceTest",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
|
@ -3487,6 +3507,16 @@
|
|||
"tags": [
|
||||
"Indexer"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "forceTest",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
|
@ -4470,6 +4500,16 @@
|
|||
"tags": [
|
||||
"Metadata"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "forceTest",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
|
@ -5032,6 +5072,16 @@
|
|||
"tags": [
|
||||
"Notification"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "forceTest",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
|
|
Loading…
Reference in New Issue