Compare commits

..

25 Commits

Author SHA1 Message Date
Bogdan
343d7088c9 Fixed: Don't die on info indexer when the definition is missing 2023-11-19 01:36:50 +02:00
Bogdan
709dfe453b Fix AB tests 2023-11-18 06:08:12 +02:00
Bogdan
3130fac106 New: (AnimeBytes) Filter old releases on RSS 2023-11-18 05:07:10 +02:00
Weblate
28004dfae1 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Dlgeri123 <bornemiszageri@gmail.com>
Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: Jhonata da Rocha <jhonata182@gmail.com>
Co-authored-by: Jordy <prive@jordyhoebergen.nl>
Co-authored-by: LandonLi <lxx4work@gmail.com>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: bai0012 <baicongrui@gmail.com>
Co-authored-by: hpoon <henry.yh.poon@gmail.com>
Co-authored-by: jianl <jianjianfengyun@126.com>
Co-authored-by: 宿命 <331874545@qq.com>
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/zh_CN/
Translation: Servarr/Prowlarr
2023-11-18 03:13:20 +02:00
Bogdan
9b34c89bc8 Fixed: Enforce validation warnings when testing providers
(cherry picked from commit c3b4126d0c4f449a41e2cf7ea438b20e25370995)
2023-11-17 05:26:04 +02:00
Mark McDowall
28e90acd0d Rename 'ReturnUrl' to 'returnUrl' for forms auth redirection
(cherry picked from commit 812712e2843a738054c065a6d5c1b7c81c5f8e7b)
2023-11-17 05:25:41 +02:00
Erik P
9d11d7e17f Fixed: (PTP) Add IMDb ID to TV Search capabilities (#1920)
Co-authored-by: Erik Persson <erik@erikpersson.me>
2023-11-16 19:33:53 +02:00
Bogdan
2cbdb5bcba New: (HDBits) Add Use Filenames option 2023-11-16 18:50:24 +02:00
Bogdan
118bfb8c28 Fixed: (AvistaZ) Increase rate limit to 5 seconds 2023-11-16 18:50:20 +02:00
Bogdan
942477ecf9 Fixed: (HDBits) Add labels for codecs and mediums 2023-11-14 17:21:07 +02:00
Bogdan
4b4589ed27 Improvements to download factor and show Freeleech only for HDB 2023-11-13 16:23:10 +02:00
Bogdan
bd0609639e New: (HDBits) Add pagination support 2023-11-13 02:54:28 +02:00
Bogdan
ccdad3a44c Bump version to 1.10.4 2023-11-12 16:49:35 +02:00
Bogdan
d99da0481b Fix AvistaZ tests 2023-11-12 15:22:35 +02:00
Bogdan
da1965b18e Fixed: (AvistaZ) Fix PublishDate timezone
Fixes #1917
2023-11-12 14:58:56 +02:00
Bogdan
493114f4e8 Fixed: Record status for notifications on tests 2023-11-10 05:34:15 +02:00
Mark McDowall
6969326092 Don't store status results for invalid providers
(cherry picked from commit de23182d593e2284972103d505e66dd8d812dfdb)
(cherry picked from commit 44d8dbaac81706691124ae5f8317289f0a3e5d73)
2023-11-10 04:01:04 +02:00
Bogdan
95f899131d Fix count in OrpheusFixture 2023-11-07 15:38:49 +02:00
Bogdan
0ba4f3e692 Fixed: (Orpheus) Filter old releases on RSS 2023-11-07 15:03:50 +02:00
Bogdan
a7c00a0fd7 Fixed: (Redacted) Filter old releases on RSS 2023-11-07 15:03:49 +02:00
Bogdan
c84ff60ec9 Fixed: (PTP) Add TV search capabilities 2023-11-05 21:00:24 +02:00
Bogdan
b3f6f54e6e Fixed: (PTP) Add support for TV searches 2023-11-05 20:53:21 +02:00
Bogdan
ed272aaf74 Increase the timeout for CheckHealth command 2023-11-05 20:17:02 +02:00
Bogdan
c0b10f889b Prevent NullRef on header assert 2023-11-05 19:58:30 +02:00
Bogdan
bbfb92bbd8 Bump version to 1.10.3 2023-11-05 11:10:44 +02:00
40 changed files with 427 additions and 209 deletions

View File

@@ -9,7 +9,7 @@ variables:
testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '1.10.2'
majorVersion: '1.10.4'
minorVersion: $[counter('minorVersion', 1)]
prowlarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(prowlarrVersion)'

View File

@@ -3,6 +3,7 @@ import React, { useCallback, useState } from 'react';
import { useSelector } from 'react-redux';
import { Tab, TabList, TabPanel, Tabs } from 'react-tabs';
import { createSelector } from 'reselect';
import Alert from 'Components/Alert';
import DescriptionList from 'Components/DescriptionList/DescriptionList';
import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem';
import DescriptionListItemDescription from 'Components/DescriptionList/DescriptionListItemDescription';
@@ -23,7 +24,7 @@ import TagListConnector from 'Components/TagListConnector';
import { kinds } from 'Helpers/Props';
import DeleteIndexerModal from 'Indexer/Delete/DeleteIndexerModal';
import EditIndexerModalConnector from 'Indexer/Edit/EditIndexerModalConnector';
import Indexer from 'Indexer/Indexer';
import Indexer, { IndexerCapabilities } from 'Indexer/Indexer';
import { createIndexerSelectorForHook } from 'Store/Selectors/createIndexerSelector';
import translate from 'Utilities/String/translate';
import IndexerHistory from './History/IndexerHistory';
@@ -63,7 +64,7 @@ function IndexerInfoModalContent(props: IndexerInfoModalContentProps) {
fields,
tags,
protocol,
capabilities,
capabilities = {} as IndexerCapabilities,
} = indexer as Indexer;
const { onModalClose } = props;
@@ -207,7 +208,7 @@ function IndexerInfoModalContent(props: IndexerInfoModalContentProps) {
descriptionClassName={styles.description}
title={translate('RawSearchSupported')}
data={
capabilities.supportsRawSearch
capabilities?.supportsRawSearch
? translate('Yes')
: translate('No')
}
@@ -216,12 +217,12 @@ function IndexerInfoModalContent(props: IndexerInfoModalContentProps) {
descriptionClassName={styles.description}
title={translate('SearchTypes')}
data={
capabilities.searchParams.length === 0 ? (
translate('NotSupported')
) : (
capabilities?.searchParams?.length > 0 ? (
<Label kind={kinds.PRIMARY}>
{capabilities.searchParams[0]}
</Label>
) : (
translate('NotSupported')
)
}
/>
@@ -229,60 +230,60 @@ function IndexerInfoModalContent(props: IndexerInfoModalContentProps) {
descriptionClassName={styles.description}
title={translate('TVSearchTypes')}
data={
capabilities.tvSearchParams.length === 0
? translate('NotSupported')
: capabilities.tvSearchParams.map((p) => {
capabilities?.tvSearchParams?.length > 0
? capabilities.tvSearchParams.map((p) => {
return (
<Label key={p} kind={kinds.PRIMARY}>
{p}
</Label>
);
})
: translate('NotSupported')
}
/>
<DescriptionListItem
descriptionClassName={styles.description}
title={translate('MovieSearchTypes')}
data={
capabilities.movieSearchParams.length === 0
? translate('NotSupported')
: capabilities.movieSearchParams.map((p) => {
capabilities?.movieSearchParams?.length > 0
? capabilities.movieSearchParams.map((p) => {
return (
<Label key={p} kind={kinds.PRIMARY}>
{p}
</Label>
);
})
: translate('NotSupported')
}
/>
<DescriptionListItem
descriptionClassName={styles.description}
title={translate('BookSearchTypes')}
data={
capabilities.bookSearchParams.length === 0
? translate('NotSupported')
: capabilities.bookSearchParams.map((p) => {
capabilities?.bookSearchParams?.length > 0
? capabilities.bookSearchParams.map((p) => {
return (
<Label key={p} kind={kinds.PRIMARY}>
{p}
</Label>
);
})
: translate('NotSupported')
}
/>
<DescriptionListItem
descriptionClassName={styles.description}
title={translate('MusicSearchTypes')}
data={
capabilities.musicSearchParams.length === 0
? translate('NotSupported')
: capabilities.musicSearchParams.map((p) => {
capabilities?.musicSearchParams?.length > 0
? capabilities.musicSearchParams.map((p) => {
return (
<Label key={p} kind={kinds.PRIMARY}>
{p}
</Label>
);
})
: translate('NotSupported')
}
/>
</DescriptionList>
@@ -338,7 +339,11 @@ function IndexerInfoModalContent(props: IndexerInfoModalContentProps) {
})}
</Table>
</FieldSet>
) : null}
) : (
<Alert kind={kinds.INFO}>
{translate('NoIndexerCategories')}
</Alert>
)}
</div>
</TabPanel>
<TabPanel>

View File

@@ -43,7 +43,7 @@ namespace NzbDrone.Core.Test.IndexerTests.AnimeBytesTests
.Setup(o => o.ExecuteProxiedAsync(It.Is<HttpRequest>(v => v.Method == HttpMethod.Get), Subject.Definition))
.Returns<HttpRequest, IndexerDefinition>((r, d) => Task.FromResult(new HttpResponse(r, new HttpHeader { { "Content-Type", "application/json" } }, new CookieCollection(), recentFeed)));
var releases = (await Subject.Fetch(new BasicSearchCriteria { Categories = new[] { 2000, 5000 } })).Releases;
var releases = (await Subject.Fetch(new BasicSearchCriteria { SearchTerm = "test", Categories = new[] { 2000, 5000 } })).Releases;
releases.Should().HaveCount(33);
releases.First().Should().BeOfType<TorrentInfo>();

View File

@@ -51,7 +51,7 @@ namespace NzbDrone.Core.Test.IndexerTests.AvistazTests
torrentInfo.InfoUrl.Should().Be("https://avistaz.to/torrent/187240-japan-sinks-people-of-hope-2021-s01e05-720p-nf-web-dl-ddp20-x264-seikel");
torrentInfo.CommentUrl.Should().BeNullOrEmpty();
torrentInfo.Indexer.Should().Be(Subject.Definition.Name);
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2021-11-14 21:26:21"));
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2021-11-14 22:26:21"));
torrentInfo.Size.Should().Be(935127615);
torrentInfo.InfoHash.Should().Be("a879261d4e6e792402f92401141a21de70d51bf2");
torrentInfo.MagnetUrl.Should().Be(null);

View File

@@ -51,7 +51,7 @@ namespace NzbDrone.Core.Test.IndexerTests.AvistazTests
torrentInfo.InfoUrl.Should().Be("https://exoticaz.to/torrent/64040-ssis-419-my-first-experience-is-yua-mikami-from-the-day-i-lost-my-virginity-i-was-devoted-to-sex");
torrentInfo.CommentUrl.Should().BeNullOrEmpty();
torrentInfo.Indexer.Should().Be(Subject.Definition.Name);
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2022-06-11 15:04:50"));
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2022-06-11 10:04:50"));
torrentInfo.Size.Should().Be(7085405541);
torrentInfo.InfoHash.Should().Be("asdjfiasdf54asd7f4a2sdf544asdf");
torrentInfo.MagnetUrl.Should().Be(null);

View File

@@ -51,7 +51,7 @@ namespace NzbDrone.Core.Test.IndexerTests.AvistazTests
torrentInfo.InfoUrl.Should().Be("https://privatehd.to/torrent/78506-godzilla-2014-2160p-uhd-bluray-remux-hdr-hevc-atmos-triton");
torrentInfo.CommentUrl.Should().BeNullOrEmpty();
torrentInfo.Indexer.Should().Be(Subject.Definition.Name);
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2021-03-21 04:24:49"));
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2021-03-21 05:24:49"));
torrentInfo.Size.Should().Be(69914591044);
torrentInfo.InfoHash.Should().Be("a879261d4e6e792402f92401141a21de70d51bf2");
torrentInfo.MagnetUrl.Should().Be(null);

View File

@@ -68,5 +68,16 @@ namespace NzbDrone.Core.Test.IndexerTests
VerifyNoUpdate();
}
[Test]
public void should_not_record_failure_for_unknown_provider()
{
Subject.RecordFailure(0);
Mocker.GetMock<IIndexerStatusRepository>()
.Verify(v => v.FindByProviderId(1), Times.Never);
VerifyNoUpdate();
}
}
}

View File

@@ -39,7 +39,7 @@ namespace NzbDrone.Core.Test.IndexerTests.OrpheusTests
var releases = (await Subject.Fetch(new BasicSearchCriteria { Categories = new[] { 3000 } })).Releases;
releases.Should().HaveCount(65);
releases.Should().HaveCount(50);
releases.First().Should().BeOfType<TorrentInfo>();
var torrentInfo = releases.First() as TorrentInfo;

View File

@@ -91,6 +91,11 @@ namespace NzbDrone.Core.Indexers.Definitions
{
var cleanReleases = base.CleanupReleases(releases, searchCriteria);
if (searchCriteria.IsRssSearch)
{
cleanReleases = cleanReleases.Where(r => r.PublishDate > DateTime.Now.AddDays(-1)).ToList();
}
return cleanReleases.Select(r => (ReleaseInfo)r.Clone()).ToList();
}

View File

@@ -84,6 +84,6 @@ namespace NzbDrone.Core.Indexers.Definitions
public class AvistaZParser : AvistazParserBase
{
protected override string TimezoneOffset => "+02:00";
protected override string TimezoneOffset => "+01:00";
}
}

View File

@@ -17,7 +17,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Avistaz
public override bool SupportsSearch => true;
public override bool SupportsPagination => true;
public override int PageSize => 50;
public override TimeSpan RateLimit => TimeSpan.FromSeconds(4);
public override TimeSpan RateLimit => TimeSpan.FromSeconds(5);
public override IndexerCapabilities Capabilities => SetCapabilities();
protected virtual string LoginUrl => Settings.BaseUrl + "api/v1/jackett/auth";
private IIndexerRepository _indexerRepository;

View File

@@ -14,7 +14,7 @@ namespace NzbDrone.Core.Indexers.Definitions.Avistaz
{
public class AvistazParserBase : IParseIndexerResponse
{
protected virtual string TimezoneOffset => "-04:00"; // Avistaz does not specify a timezone & returns server time
protected virtual string TimezoneOffset => "-05:00"; // Avistaz does not specify a timezone & returns server time
private readonly HashSet<string> _hdResolutions = new () { "1080p", "1080i", "720p" };
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }

View File

@@ -54,6 +54,8 @@ namespace NzbDrone.Core.Indexers.Definitions
{
private readonly IndexerCapabilitiesCategories _categories;
protected override string TimezoneOffset => "+01:00";
public ExoticaZParser(IndexerCapabilitiesCategories categories)
{
_categories = categories;

View File

@@ -12,9 +12,10 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
public override string[] LegacyUrls => new[] { "https://hdbits.org" };
public override string Description => "Best HD Tracker";
public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
public override IndexerCapabilities Capabilities => SetCapabilities();
public override bool SupportsRedirect => true;
public override int PageSize => 30;
public override bool SupportsPagination => true;
public override int PageSize => 100;
public override IndexerCapabilities Capabilities => SetCapabilities();
public HDBits(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger)
: base(httpClient, eventAggregator, indexerStatusService, configService, logger)
@@ -45,14 +46,14 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
}
};
caps.Categories.AddCategoryMapping(6, NewznabStandardCategory.Audio, "Audio Track");
caps.Categories.AddCategoryMapping(3, NewznabStandardCategory.TVDocumentary, "Documentary");
caps.Categories.AddCategoryMapping(8, NewznabStandardCategory.Other, "Misc/Demo");
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.Movies, "Movie");
caps.Categories.AddCategoryMapping(2, NewznabStandardCategory.TV, "TV");
caps.Categories.AddCategoryMapping(3, NewznabStandardCategory.TVDocumentary, "Documentary");
caps.Categories.AddCategoryMapping(4, NewznabStandardCategory.Audio, "Music");
caps.Categories.AddCategoryMapping(5, NewznabStandardCategory.TVSport, "Sport");
caps.Categories.AddCategoryMapping(2, NewznabStandardCategory.TV, "TV");
caps.Categories.AddCategoryMapping(6, NewznabStandardCategory.Audio, "Audio Track");
caps.Categories.AddCategoryMapping(7, NewznabStandardCategory.XXX, "XXX");
caps.Categories.AddCategoryMapping(8, NewznabStandardCategory.Other, "Misc/Demo");
return caps;
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace NzbDrone.Core.Indexers.Definitions.HDBits
@@ -7,19 +8,15 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
{
[JsonProperty(Required = Required.Always)]
public string Username { get; set; }
[JsonProperty(Required = Required.Always)]
public string Passkey { get; set; }
public string Hash { get; set; }
public string Search { get; set; }
public int[] Category { get; set; }
public int[] Codec { get; set; }
public int[] Medium { get; set; }
public IEnumerable<int> Category { get; set; }
public IEnumerable<int> Codec { get; set; }
public IEnumerable<int> Medium { get; set; }
public int? Origin { get; set; }
[JsonProperty(PropertyName = "imdb")]
@@ -33,13 +30,9 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
[JsonProperty(PropertyName = "snatched_only")]
public bool? SnatchedOnly { get; set; }
public int? Limit { get; set; }
public int? Page { get; set; }
public TorrentQuery Clone()
{
return MemberwiseClone() as TorrentQuery;
}
}
public class HDBitsResponse

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http;
using NzbDrone.Core.Indexers.Exceptions;
using NzbDrone.Core.Parser.Model;
@@ -14,6 +15,8 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
private readonly HDBitsSettings _settings;
private readonly IndexerCapabilitiesCategories _categories;
private readonly List<int> _halfLeechMediums = new () { (int)HdBitsMedium.Bluray, (int)HdBitsMedium.Remux, (int)HdBitsMedium.Capture };
public HDBitsParser(HDBitsSettings settings, IndexerCapabilitiesCategories categories)
{
_settings = settings;
@@ -22,7 +25,6 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
{
var torrentInfos = new List<ReleaseInfo>();
var indexerHttpResponse = indexerResponse.HttpResponse;
if (indexerHttpResponse.StatusCode == HttpStatusCode.Forbidden)
@@ -42,18 +44,25 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
throw new IndexerException(indexerResponse, "HDBits API request returned status code {0}: {1}", jsonResponse.Status, jsonResponse.Message ?? string.Empty);
}
var responseData = jsonResponse.Data as JArray;
if (responseData == null)
if (jsonResponse.Data is not JArray responseData)
{
throw new IndexerException(indexerResponse, "Indexer API call response missing result data");
}
var releaseInfos = new List<ReleaseInfo>();
var queryResults = responseData.ToObject<TorrentQueryResponse[]>();
foreach (var result in queryResults)
{
// Skip non-freeleech results when freeleech only is set
if (_settings.FreeleechOnly && result.FreeLeech != "yes")
{
continue;
}
var id = result.Id;
var internalRelease = result.TypeOrigin == 1 ? true : false;
var internalRelease = result.TypeOrigin == 1;
var flags = new HashSet<IndexerFlag>();
@@ -62,10 +71,10 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
flags.Add(IndexerFlag.Internal);
}
torrentInfos.Add(new HDBitsInfo()
releaseInfos.Add(new HDBitsInfo
{
Guid = string.Format("HDBits-{0}", id),
Title = result.Name,
Guid = $"HDBits-{id}",
Title = GetTitle(result),
Size = result.Size,
Categories = _categories.MapTrackerCatToNewznab(result.TypeCategory.ToString()),
InfoHash = result.Hash,
@@ -77,19 +86,55 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
Peers = result.Leechers + result.Seeders,
PublishDate = result.Added.ToUniversalTime(),
Internal = internalRelease,
Year = result.ImdbInfo?.Year ?? 0,
ImdbId = result.ImdbInfo?.Id ?? 0,
TvdbId = result.TvdbInfo?.Id ?? 0,
DownloadVolumeFactor = result.FreeLeech == "yes" ? 0 : 1,
UploadVolumeFactor = 1,
DownloadVolumeFactor = GetDownloadVolumeFactor(result),
UploadVolumeFactor = GetUploadVolumeFactor(result),
IndexerFlags = flags
});
}
return torrentInfos.ToArray();
return releaseInfos.ToArray();
}
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
private string GetTitle(TorrentQueryResponse item)
{
return _settings.UseFilenames && item.FileName.IsNotNullOrWhiteSpace()
? item.FileName.Replace(".torrent", "", StringComparison.InvariantCultureIgnoreCase)
: item.Name;
}
private double GetDownloadVolumeFactor(TorrentQueryResponse item)
{
if (item.FreeLeech == "yes")
{
return 0;
}
// 100% Neutral Leech: all XXX content.
if (item.TypeCategory == 7)
{
return 0;
}
// 50% Free Leech: all full discs, remuxes, captures and all internal encodes, also all TV and Documentary content.
if (_halfLeechMediums.Contains(item.TypeMedium) || item.TypeOrigin == 1 || item.TypeCategory is 2 or 3)
{
return 0.5;
}
return 1;
}
private static double GetUploadVolumeFactor(TorrentQueryResponse item)
{
// 100% Neutral Leech: all XXX content.
return item.TypeCategory == 7 ? 0 : 1;
}
private string GetDownloadUrl(string torrentId)
{
var url = new HttpUri(_settings.BaseUrl)

View File

@@ -21,12 +21,8 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
{
var pageableRequests = new IndexerPageableRequestChain();
var query = new TorrentQuery();
var imdbId = ParseUtil.GetImdbId(searchCriteria.ImdbId).GetValueOrDefault(0);
if (searchCriteria.Categories?.Length > 0)
{
query.Category = Capabilities.Categories.MapTorznabCapsToTrackers(searchCriteria.Categories).Select(int.Parse).ToArray();
}
var imdbId = ParseUtil.GetImdbId(searchCriteria.ImdbId).GetValueOrDefault(0);
if (imdbId == 0 && searchCriteria.SearchTerm.IsNotNullOrWhiteSpace())
{
@@ -39,37 +35,11 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
query.ImdbInfo.Id = imdbId;
}
pageableRequests.Add(GetRequest(query));
pageableRequests.Add(GetRequest(query, searchCriteria));
return pageableRequests;
}
public Func<IDictionary<string, string>> GetCookies { get; set; }
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
private IEnumerable<IndexerRequest> GetRequest(TorrentQuery query)
{
var request = new HttpRequestBuilder(Settings.BaseUrl)
.Resource("/api/torrents")
.Build();
request.Method = HttpMethod.Post;
const string appJson = "application/json";
request.Headers.Accept = appJson;
request.Headers.ContentType = appJson;
query.Username = Settings.Username;
query.Passkey = Settings.ApiKey;
query.Codec = Settings.Codecs.ToArray();
query.Medium = Settings.Mediums.ToArray();
request.SetContent(query.ToJson());
request.ContentSummary = query.ToJson(Formatting.None);
yield return new IndexerRequest(request);
}
public IndexerPageableRequestChain GetSearchRequests(MusicSearchCriteria searchCriteria)
{
return new IndexerPageableRequestChain();
@@ -79,14 +49,10 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
{
var pageableRequests = new IndexerPageableRequestChain();
var query = new TorrentQuery();
var tvdbId = searchCriteria.TvdbId.GetValueOrDefault(0);
var imdbId = ParseUtil.GetImdbId(searchCriteria.ImdbId).GetValueOrDefault(0);
if (searchCriteria.Categories?.Length > 0)
{
query.Category = Capabilities.Categories.MapTorznabCapsToTrackers(searchCriteria.Categories).Select(int.Parse).ToArray();
}
if (tvdbId == 0 && imdbId == 0 && searchCriteria.SearchTerm.IsNotNullOrWhiteSpace())
{
query.Search = searchCriteria.SanitizedTvSearchString;
@@ -114,7 +80,7 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
query.ImdbInfo.Id = imdbId;
}
pageableRequests.Add(GetRequest(query));
pageableRequests.Add(GetRequest(query, searchCriteria));
return pageableRequests;
}
@@ -129,19 +95,56 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
var pageableRequests = new IndexerPageableRequestChain();
var query = new TorrentQuery();
if (searchCriteria.Categories?.Length > 0)
{
query.Category = Capabilities.Categories.MapTorznabCapsToTrackers(searchCriteria.Categories).Select(int.Parse).ToArray();
}
if (searchCriteria.SearchTerm.IsNotNullOrWhiteSpace())
{
query.Search = searchCriteria.SanitizedSearchTerm;
}
pageableRequests.Add(GetRequest(query));
pageableRequests.Add(GetRequest(query, searchCriteria));
return pageableRequests;
}
public Func<IDictionary<string, string>> GetCookies { get; set; }
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
private IEnumerable<IndexerRequest> GetRequest(TorrentQuery query, SearchCriteriaBase searchCriteria)
{
var request = new HttpRequestBuilder(Settings.BaseUrl)
.Resource("/api/torrents")
.Build();
request.Method = HttpMethod.Post;
const string appJson = "application/json";
request.Headers.Accept = appJson;
request.Headers.ContentType = appJson;
query.Username = Settings.Username;
query.Passkey = Settings.ApiKey;
query.Codec = Settings.Codecs.ToArray();
query.Medium = Settings.Mediums.ToArray();
if (searchCriteria.Categories?.Length > 0)
{
query.Category = Capabilities.Categories
.MapTorznabCapsToTrackers(searchCriteria.Categories)
.Distinct()
.Select(int.Parse)
.ToArray();
}
query.Limit = 100;
if (searchCriteria.Limit is > 0 && searchCriteria.Offset is > 0)
{
query.Page = (int)(searchCriteria.Offset / searchCriteria.Limit);
}
request.SetContent(query.ToJson());
request.ContentSummary = query.ToJson(Formatting.None);
yield return new IndexerRequest(request);
}
}
}

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
@@ -10,6 +11,7 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
{
public HDBitsSettingsValidator()
{
RuleFor(c => c.Username).NotEmpty();
RuleFor(c => c.ApiKey).NotEmpty();
}
}
@@ -20,8 +22,10 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
public HDBitsSettings()
{
Codecs = System.Array.Empty<int>();
Mediums = System.Array.Empty<int>();
Codecs = Array.Empty<int>();
Mediums = Array.Empty<int>();
FreeleechOnly = false;
UseFilenames = false;
}
[FieldDefinition(2, Label = "Username", HelpText = "Site Username", Privacy = PrivacyLevel.UserName)]
@@ -30,45 +34,49 @@ namespace NzbDrone.Core.Indexers.Definitions.HDBits
[FieldDefinition(3, Label = "API Key", HelpText = "Site API Key", Privacy = PrivacyLevel.ApiKey)]
public string ApiKey { get; set; }
[FieldDefinition(4, Label = "Codecs", Type = FieldType.TagSelect, SelectOptions = typeof(HdBitsCodec), Advanced = true, HelpText = "Options: h264, Mpeg2, VC1, Xvid. If unspecified, all options are used.")]
[FieldDefinition(4, Label = "Codecs", Type = FieldType.Select, SelectOptions = typeof(HdBitsCodec), Advanced = true, HelpText = "If unspecified, all options are used.")]
public IEnumerable<int> Codecs { get; set; }
[FieldDefinition(5, Label = "Mediums", Type = FieldType.TagSelect, SelectOptions = typeof(HdBitsMedium), Advanced = true, HelpText = "Options: BluRay, Encode, Capture, Remux, WebDL. If unspecified, all options are used.")]
[FieldDefinition(5, Label = "Mediums", Type = FieldType.Select, SelectOptions = typeof(HdBitsMedium), Advanced = true, HelpText = "If unspecified, all options are used.")]
public IEnumerable<int> Mediums { get; set; }
[FieldDefinition(6, Label = "Freeleech Only", Type = FieldType.Checkbox, Advanced = true, HelpText = "Show freeleech releases only")]
public bool FreeleechOnly { get; set; }
[FieldDefinition(7, Label = "Use Filenames", Type = FieldType.Checkbox, HelpText = "Check this option if you want to use torrent filenames as release titles")]
public bool UseFilenames { get; set; }
public override NzbDroneValidationResult Validate()
{
return new NzbDroneValidationResult(Validator.Validate(this));
}
}
public enum HdBitsCategory
{
Movie = 1,
Tv = 2,
Documentary = 3,
Music = 4,
Sport = 5,
Audio = 6,
Xxx = 7,
MiscDemo = 8
}
public enum HdBitsCodec
{
[FieldOption("H.264")]
H264 = 1,
[FieldOption("MPEG-2")]
Mpeg2 = 2,
[FieldOption("VC-1")]
Vc1 = 3,
[FieldOption("XviD")]
Xvid = 4,
[FieldOption("HEVC")]
HEVC = 5
}
public enum HdBitsMedium
{
[FieldOption("Blu-ray/HD DVD")]
Bluray = 1,
[FieldOption("Encode")]
Encode = 3,
[FieldOption("Capture")]
Capture = 4,
[FieldOption("Remux")]
Remux = 5,
[FieldOption("WEB-DL")]
WebDl = 6
}
}

View File

@@ -29,6 +29,7 @@ namespace NzbDrone.Core.Indexers.Definitions
public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
public override IndexerCapabilities Capabilities => SetCapabilities();
public override bool SupportsRedirect => true;
public override TimeSpan RateLimit => TimeSpan.FromSeconds(3);
public Orpheus(IIndexerHttpClient httpClient,
IEventAggregator eventAggregator,
@@ -49,10 +50,24 @@ namespace NzbDrone.Core.Indexers.Definitions
return new OrpheusParser(Settings, Capabilities.Categories);
}
protected override IList<ReleaseInfo> CleanupReleases(IEnumerable<ReleaseInfo> releases, SearchCriteriaBase searchCriteria)
{
var cleanReleases = base.CleanupReleases(releases, searchCriteria);
if (searchCriteria.IsRssSearch)
{
cleanReleases = cleanReleases.Take(50).ToList();
}
return cleanReleases;
}
private IndexerCapabilities SetCapabilities()
{
var caps = new IndexerCapabilities
{
LimitsDefault = 50,
LimitsMax = 50,
MusicSearchParams = new List<MusicSearchParam>
{
MusicSearchParam.Q, MusicSearchParam.Artist, MusicSearchParam.Album, MusicSearchParam.Year
@@ -200,6 +215,7 @@ namespace NzbDrone.Core.Indexers.Definitions
}
var queryCats = _capabilities.Categories.MapTorznabCapsToTrackers(searchCriteria.Categories);
if (queryCats.Any())
{
queryCats.ForEach(cat => parameters.Set($"filter_cat[{cat}]", "1"));

View File

@@ -29,7 +29,7 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
public override IIndexerRequestGenerator GetRequestGenerator()
{
return new PassThePopcornRequestGenerator(Settings);
return new PassThePopcornRequestGenerator(Settings, Capabilities);
}
public override IParseIndexerResponse GetParser()
@@ -43,6 +43,10 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
{
LimitsDefault = PageSize,
LimitsMax = PageSize,
TvSearchParams = new List<TvSearchParam>
{
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep, TvSearchParam.ImdbId
},
MovieSearchParams = new List<MovieSearchParam>
{
MovieSearchParam.Q, MovieSearchParam.ImdbId
@@ -56,18 +60,11 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
};
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.Movies, "Feature Film");
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.MoviesForeign);
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.MoviesOther);
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.MoviesSD);
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.MoviesHD);
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.Movies3D);
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.MoviesBluRay);
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.MoviesDVD);
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.MoviesWEBDL);
caps.Categories.AddCategoryMapping(2, NewznabStandardCategory.Movies, "Short Film");
caps.Categories.AddCategoryMapping(3, NewznabStandardCategory.TV, "Miniseries");
caps.Categories.AddCategoryMapping(4, NewznabStandardCategory.TV, "Stand-up Comedy");
caps.Categories.AddCategoryMapping(5, NewznabStandardCategory.TV, "Live Performance");
caps.Categories.AddCategoryMapping(4, NewznabStandardCategory.Movies, "Stand-up Comedy");
caps.Categories.AddCategoryMapping(5, NewznabStandardCategory.Movies, "Live Performance");
caps.Categories.AddCategoryMapping(6, NewznabStandardCategory.Movies, "Movie Collection");
return caps;
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http;
using NzbDrone.Core.IndexerSearch.Definitions;
@@ -11,10 +12,12 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
public class PassThePopcornRequestGenerator : IIndexerRequestGenerator
{
private readonly PassThePopcornSettings _settings;
private readonly IndexerCapabilities _capabilities;
public PassThePopcornRequestGenerator(PassThePopcornSettings settings)
public PassThePopcornRequestGenerator(PassThePopcornSettings settings, IndexerCapabilities capabilities)
{
_settings = settings;
_capabilities = capabilities;
}
public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria)
@@ -27,7 +30,7 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
}
else
{
pageableRequests.Add(GetRequest($"{searchCriteria.SearchTerm}", searchCriteria));
pageableRequests.Add(GetRequest($"{searchCriteria.SanitizedSearchTerm}", searchCriteria));
}
return pageableRequests;
@@ -40,7 +43,18 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
public IndexerPageableRequestChain GetSearchRequests(TvSearchCriteria searchCriteria)
{
return new IndexerPageableRequestChain();
var pageableRequests = new IndexerPageableRequestChain();
if (searchCriteria.ImdbId.IsNotNullOrWhiteSpace())
{
pageableRequests.Add(GetRequest(searchCriteria.FullImdbId, searchCriteria));
}
else
{
pageableRequests.Add(GetRequest($"{searchCriteria.SanitizedTvSearchString}", searchCriteria));
}
return pageableRequests;
}
public IndexerPageableRequestChain GetSearchRequests(BookSearchCriteria searchCriteria)
@@ -52,32 +66,43 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
{
var pageableRequests = new IndexerPageableRequestChain();
pageableRequests.Add(GetRequest($"{searchCriteria.SearchTerm}", searchCriteria));
pageableRequests.Add(GetRequest($"{searchCriteria.SanitizedSearchTerm}", searchCriteria));
return pageableRequests;
}
private IEnumerable<IndexerRequest> GetRequest(string searchParameters, SearchCriteriaBase searchCriteria)
private IEnumerable<IndexerRequest> GetRequest(string searchTerm, SearchCriteriaBase searchCriteria)
{
var parameters = new NameValueCollection
{
{ "action", "advanced" },
{ "json", "noredirect" },
{ "grouping", "0" },
{ "searchstr", searchParameters }
{ "searchstr", searchTerm }
};
if (_settings.FreeleechOnly)
{
parameters.Set("freetorrent", "1");
}
var queryCats = _capabilities.Categories
.MapTorznabCapsToTrackers(searchCriteria.Categories)
.Select(int.Parse)
.Distinct()
.ToList();
if (searchCriteria.IsRssSearch && queryCats.Any())
{
queryCats.ForEach(cat => parameters.Set($"filter_cat[{cat}]", "1"));
}
if (searchCriteria.Limit is > 0 && searchCriteria.Offset is > 0)
{
var page = (int)(searchCriteria.Offset / searchCriteria.Limit) + 1;
parameters.Set("page", page.ToString());
}
if (_settings.FreeleechOnly)
{
parameters.Set("freetorrent", "1");
}
var searchUrl = $"{_settings.BaseUrl.Trim().TrimEnd('/')}/torrents.php?{parameters.GetQueryString()}";
var request = new IndexerRequest(searchUrl, HttpAccept.Json);

View File

@@ -29,6 +29,7 @@ namespace NzbDrone.Core.Indexers.Definitions
public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
public override IndexerCapabilities Capabilities => SetCapabilities();
public override bool SupportsRedirect => true;
public override TimeSpan RateLimit => TimeSpan.FromSeconds(3);
public Redacted(IIndexerHttpClient httpClient,
IEventAggregator eventAggregator,
@@ -63,10 +64,24 @@ namespace NzbDrone.Core.Indexers.Definitions
return Task.FromResult(request);
}
protected override IList<ReleaseInfo> CleanupReleases(IEnumerable<ReleaseInfo> releases, SearchCriteriaBase searchCriteria)
{
var cleanReleases = base.CleanupReleases(releases, searchCriteria);
if (searchCriteria.IsRssSearch)
{
cleanReleases = cleanReleases.Take(50).ToList();
}
return cleanReleases;
}
private IndexerCapabilities SetCapabilities()
{
var caps = new IndexerCapabilities
{
LimitsDefault = 50,
LimitsMax = 50,
MusicSearchParams = new List<MusicSearchParam>
{
MusicSearchParam.Q, MusicSearchParam.Artist, MusicSearchParam.Album, MusicSearchParam.Year
@@ -172,6 +187,7 @@ namespace NzbDrone.Core.Indexers.Definitions
}
var queryCats = _capabilities.Categories.MapTorznabCapsToTrackers(searchCriteria.Categories);
if (queryCats.Any())
{
queryCats.ForEach(cat => parameters.Set($"filter_cat[{cat}]", "1"));

View File

@@ -395,5 +395,6 @@
"CountDownloadClientsSelected": "{count} vybraných klientů ke stahování",
"CountIndexersSelected": "{count} vybraných indexátorů",
"EditIndexerProxyImplementation": "Přidat indexátor - {implementationName}",
"AuthBasic": "Základní (vyskakovací okno prohlížeče)"
"AuthBasic": "Základní (vyskakovací okno prohlížeče)",
"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."
}

View File

@@ -507,5 +507,14 @@
"Clone": "Κλωνοποίηση",
"DisabledForLocalAddresses": "Απενεργοποιήθηκε για τοπικές διευθύνσεις",
"None": "Κανένας",
"ResetAPIKeyMessageText": "Είστε βέβαιοι ότι θέλετε να επαναφέρετε το κλειδί API σας;"
"ResetAPIKeyMessageText": "Είστε βέβαιοι ότι θέλετε να επαναφέρετε το κλειδί API σας;",
"AppUpdated": "{appName} Ενημερώθηκε",
"AppUpdatedVersion": "ξαναφορτωθεί",
"EditIndexerImplementation": "Προσθήκη",
"AddIndexerProxyImplementation": "Προσθήκη",
"EditConnectionImplementation": "Προσθήκη",
"EditApplicationImplementation": "Προσθήκη",
"AddApplicationImplementation": "Προσθήκη",
"AddConnectionImplementation": "Προσθήκη",
"AddIndexerImplementation": "Προσθήκη"
}

View File

@@ -2,8 +2,8 @@
"About": "About",
"AcceptConfirmationModal": "Accept Confirmation Modal",
"Actions": "Actions",
"ActiveIndexers": "Active Indexers",
"ActiveApps": "Active Apps",
"ActiveIndexers": "Active Indexers",
"Add": "Add",
"AddApplication": "Add Application",
"AddApplicationImplementation": "Add Application - {implementationName}",
@@ -339,8 +339,9 @@
"NoChanges": "No Changes",
"NoDownloadClientsFound": "No download clients found",
"NoHistoryFound": "No history found",
"NoIndexersFound": "No indexers found",
"NoIndexerCategories": "No categories found for this indexer",
"NoIndexerHistory": "No history found for this indexer",
"NoIndexersFound": "No indexers found",
"NoLeaveIt": "No, Leave It",
"NoLinks": "No Links",
"NoLogFiles": "No log files",

View File

@@ -438,5 +438,6 @@
"AuthenticationRequiredHelpText": "Cambiar para que las solicitudes requieran autenticación. No lo cambie a menos que entienda los riesgos.",
"AuthenticationRequiredPasswordHelpTextWarning": "Introduzca una nueva contraseña",
"AuthenticationRequiredUsernameHelpTextWarning": "Introduzca un nuevo nombre de usuario",
"AuthenticationRequiredWarning": "Para evitar el acceso remoto sin autenticación, {appName} ahora requiere que la autenticación esté habilitada. Opcionalmente puede desactivar la autenticación desde una dirección local."
"AuthenticationRequiredWarning": "Para evitar el acceso remoto sin autenticación, {appName} ahora requiere que la autenticación esté habilitada. Opcionalmente puede desactivar la autenticación desde una dirección local.",
"EditDownloadClientImplementation": "Añadir Cliente de Descarga - {implementationName}"
}

View File

@@ -351,5 +351,6 @@
"AuthForm": "양식 (로그인 페이지)",
"DisabledForLocalAddresses": "로컬 주소에 대해 비활성화됨",
"None": "없음",
"ResetAPIKeyMessageText": "API 키를 재설정하시겠습니까?"
"ResetAPIKeyMessageText": "API 키를 재설정하시겠습니까?",
"StopSelecting": "선택 취소"
}

View File

@@ -459,5 +459,17 @@
"ResetAPIKeyMessageText": "Bent u zeker dat u uw API-sleutel wilt resetten?",
"AddConnectionImplementation": "Voeg connectie toe - {implementationName}",
"AddDownloadClientImplementation": "Voeg Downloadclient toe - {implementationName}",
"AddIndexerImplementation": "Indexeerder toevoegen - {implementationName}"
"AddIndexerImplementation": "Indexeerder toevoegen - {implementationName}",
"AdvancedSettingsHiddenClickToShow": "Geavanceerde instellingen zijn verborgen, klik om te tonen",
"AdvancedSettingsShownClickToHide": "Geavanceerde instellingen worden getoond, klik om te verbergen",
"AppUpdated": "{appName} is geüpdatet",
"AppUpdatedVersion": "{appName} is geüpdatet naar versie '{version}', om de laatste wijzigingen door te voeren moet je mogelijk {appName} herstarten",
"AddCategory": "Categorie toevoegen",
"ActiveIndexers": "Actieve indexeerders",
"ActiveApps": "Actieve Applicaties",
"EditConnectionImplementation": "Voeg connectie toe - {implementationName}",
"EditDownloadClientImplementation": "Voeg Downloadclient toe - {implementationName}",
"EditIndexerImplementation": "Indexeerder toevoegen - {implementationName}",
"AddApplicationImplementation": "Voeg connectie toe - {implementationName}",
"AddIndexerProxyImplementation": "Indexeerder toevoegen - {implementationName}"
}

View File

@@ -1,6 +1,6 @@
{
"Peers": "Elementos",
"AppDataLocationHealthCheckMessage": "Não foi possivél actualizar para prevenir apagar a AppData durante a actualização",
"AppDataLocationHealthCheckMessage": "Não foi possível actualizar para prevenir apagar a AppData durante a actualização",
"Warn": "Avisar",
"View": "Ver",
"Updates": "Atualizações",
@@ -89,7 +89,7 @@
"HealthNoIssues": "Não há problemas com suas definições",
"Health": "Estado de funcionamento",
"Grabbed": "Capturado",
"GeneralSettingsSummary": "Porta, SSL, utilizador/palavra-passe, proxy, análises e atualizações",
"GeneralSettingsSummary": "Porta, SSL, nome de utilizador/palavra-passe, proxy, análises e actualizações",
"General": "Geral",
"Folder": "Pasta",
"Filter": "Filtrar",
@@ -110,10 +110,10 @@
"Dates": "Datas",
"Date": "Data",
"CustomFilters": "Filtros personalizados",
"ConnectSettingsSummary": "Notificações, ligações para servidores/leitores de multimédia e scripts personalizados",
"ConnectSettingsSummary": "Notificações e scripts personalizados",
"Connections": "Ligações",
"ConnectionLost": "Ligação perdida",
"Connect": "Conexões",
"Connect": "Notificações",
"Component": "Componente",
"Columns": "Colunas",
"Close": "Fechar",
@@ -129,7 +129,7 @@
"Actions": "Ações",
"About": "Sobre",
"Automatic": "Automático",
"AuthenticationMethodHelpText": "Solicitar nome de utilizador e palavra-passe para acessar ao Prowlarr",
"AuthenticationMethodHelpText": "Solicitar nome de utilizador e palavra-passe para acessar ao {appName}",
"Authentication": "Autenticação",
"ApplyTags": "Aplicar etiquetas",
"AppDataDirectory": "Pasta AppData",
@@ -193,7 +193,7 @@
"AutomaticSearch": "Pesquisa automática",
"UnableToAddANewIndexerPleaseTryAgain": "Não foi possível adicionar um novo indexador, tenta novamente.",
"RSSIsNotSupportedWithThisIndexer": "RSS não é suportado por esse indexador",
"ProwlarrSupportsAnyIndexer": "O Prowlarr suporta qualquer indexador que usa o padrão Newznab, bem como os outros indexadores listados abaixo.",
"ProwlarrSupportsAnyIndexer": "O Prowlarr suporta vários indexadores, além de qualquer indexador que usa o padrão Newznab/Torznab como \"Newznab genérico\" (para Usenet) e \"Torznab genérico\" (para torrents). Pesquise e selecione os indexadores na listagem abaixo.",
"IndexerPriorityHelpText": "Prioridade do indexador de 1 (mais alta) a 50 (mais baixa). Padrão: 25.",
"IndexerPriority": "Prioridade do indexador",
"EditIndexer": "Editar indexador",
@@ -221,15 +221,15 @@
"ForMoreInformationOnTheIndividualDownloadClients": "Para obter mais informações sobre cada cliente de transferências, clique nos botões de informação.",
"FilterPlaceHolder": "Indexadores de pesquisa",
"ExistingTag": "Etiqueta existente",
"Exception": "Exceção",
"Exception": "Excepção",
"ErrorLoadingContents": "Erro ao carregar conteúdo",
"EnableInteractiveSearchHelpText": "Será utilizado ao realizar uma pesquisa interativa",
"EnableAutomaticSearchHelpText": "Será utilizado ao realizar pesquisas automáticas através da IU ou pelo Prowlarr",
"Disabled": "Desativado",
"DeleteTagMessageText": "Tem a certeza que quer eliminar a etiqueta \"{0}\"?",
"DeleteNotificationMessageText": "Tem a certeza que quer eliminar a notificação \"{0}\"?",
"DeleteDownloadClientMessageText": "Tem a certeza que quer eliminar o cliente de transferências \"{0}\"?",
"DeleteBackupMessageText": "Tem a certeza que quer eliminar a cópia de segurança \"{0}\"?",
"DeleteTagMessageText": "Tem a certeza que quer eliminar a etiqueta \"{label}\"?",
"DeleteNotificationMessageText": "Tem a certeza que quer eliminar a notificação \"{name}\"?",
"DeleteDownloadClientMessageText": "Tem a certeza que quer eliminar o cliente de transferências \"{name}\"?",
"DeleteBackupMessageText": "Tem a certeza que quer eliminar a cópia de segurança \"{name}\"?",
"UrlBaseHelpText": "Para suporte a proxy inverso, vazio por padrão",
"UpdateScriptPathHelpText": "Caminho para um script personalizado que toma um pacote de atualização extraído e lida com o restante do processo da atualização",
"UpdateMechanismHelpText": "Utilizar o atualizador do Prowlarr ou um script",
@@ -248,7 +248,7 @@
"ProxyUsernameHelpText": "Apenas insira o utilizador e a palavra-passe caso seja requerido. Caso contrário, deixe em branco.",
"ProxyPasswordHelpText": "Apenas insira o utilizador e a palavra-passe caso seja requerido. Caso contrário, deixe em branco.",
"ProxyBypassFilterHelpText": "Utilizar \",\" como separador e \"*.\" como caráter universal para subdomínios",
"MaintenanceRelease": "Versão de manutenção",
"MaintenanceRelease": "Versão de manutenção: reparações de erros e outras melhorias. Consulte o Histórico de Commits do Github para saber mais",
"RemovedFromTaskQueue": "Eliminado da fila de tarefas",
"LogLevelTraceHelpTextWarning": "O registo de rasteio somente deve ser ativado temporariamente",
"LaunchBrowserHelpText": " Abrir o browser e a home page do Prowlarr ao iniciar a aplicação.",
@@ -288,16 +288,16 @@
"SearchIndexers": "Pesquisar indexadores",
"IndexerRss": "RSS do indexador",
"IndexerQuery": "Consulta do indexador",
"IndexerObsoleteCheckMessage": "Os seguintes indexadores são obsoletos ou foram atualizados: {0}. Remova-os e/ou adicione-os novamente ao Prowlarr",
"IndexerObsoleteCheckMessage": "Os seguintes indexadores são obsoletos ou foram actualizados: {0}. Remova-os e/ou adicione-os novamente ao Prowlarr",
"IndexerLongTermStatusCheckSingleClientMessage": "Indexadores indisponíveis devido a erros por mais de 6 horas: {0}",
"IndexerLongTermStatusCheckAllClientMessage": "Todos os indexadores estão indisponíveis devido a erros por mais de 6 horas",
"IndexerHealthCheckNoIndexers": "Não há indexadores ativados, o Prowlarr não retornará resultados de pesquisa",
"IndexerHealthCheckNoIndexers": "Não há indexadores activados, o Prowlarr não retornará resultados de pesquisa",
"IndexerAuth": "Autenticação do indexador",
"EnableRssHelpText": "Ativar feed RSS para o indexador",
"EnableIndexer": "Ativar indexador",
"EnableRss": "Ativar RSS",
"EnableRssHelpText": "Activar feed RSS para o indexador",
"EnableIndexer": "Activar indexador",
"EnableRss": "Activar RSS",
"DevelopmentSettings": "Definições de desenvolvimento",
"DeleteApplicationMessageText": "Tem a certeza que deseja eliminar a aplicação \"{0}\"?",
"DeleteApplicationMessageText": "Tem a certeza que quer eliminar a aplicação \"{name}\"?",
"DeleteApplication": "Eliminar aplicação",
"ClearHistoryMessageText": "Tem a certeza que deseja limpar todo o histórico do Prowlarr?",
"ClearHistory": "Limpar histórico",
@@ -321,10 +321,10 @@
"SettingsLogRotate": "Rotação de logs",
"SettingsIndexerLoggingHelpText": "Registar dados adicionais do indexador, incluindo resposta",
"SettingsIndexerLogging": "Registo em log avançado do indexador",
"SettingsFilterSentryEvents": "Filtrar eventos de análises",
"SettingsFilterSentryEvents": "Filtrar eventos de análise",
"RSS": "RSS",
"RedirectHelpText": "Redirecionar as solicitações de transferência de entrada para o indexador, em vez de por proxy usando o Prowlarr",
"Redirect": "Redirecionar",
"RedirectHelpText": "Redireccionar as solicitações de transferência de entrada para o indexador e obter diretamente, em vez de por proxy usando o Prowlarr",
"Redirect": "Redireccionar",
"Reddit": "Reddit",
"HomePage": "Home Page",
"FeatureRequests": "Solicitações de funcionalidades",
@@ -352,7 +352,7 @@
"UnableToAddANewApplicationPleaseTryAgain": "Não é possível adicionar uma nova aplicação, tenta novamente.",
"Torrent": "Torrent",
"SyncLevelFull": "Sincronização completa: a aplicação estará sempre sincronizada. Mudanças feitas no Prowlar serão sincronizadas posteriormente com a aplicação. Qualquer mudança feita remotamente será substituída pelo Prowlarr na sincronização seguinte.",
"SyncLevelAddRemove": "Adicionar e remover apenas: esta aplicação remota será atualizada quando da adição e remoção do Prowlarr.",
"SyncLevelAddRemove": "Somente adicionar e eliminar: esta aplicação remota será actualizada ao adicionar ou eliminar indexadores do Prowlarr.",
"SyncLevel": "Nível da sincronização",
"Stats": "Estatísticas",
"Query": "Consulta",
@@ -362,7 +362,7 @@
"AddDownloadClientToProwlarr": "Adicionar um cliente de transferências possibilita ao Prowlarr enviar versões diretamente da IU ao realizar uma pesquisa manual.",
"Add": "Adicionar",
"DeleteIndexerProxy": "Apagar Proxy de Indexador",
"DeleteIndexerProxyMessageText": "Tem a certeza que quer apagar o proxy '{0}'?",
"DeleteIndexerProxyMessageText": "Tem a certeza que quer eliminar o proxy \"{name}\"?",
"IndexerProxy": "Proxy de Indexador",
"AddIndexerProxy": "Adicionar Proxy de Indexador",
"IndexerProxyStatusCheckSingleClientMessage": "Proxys indisponíveis devido a falhas: {0}",
@@ -372,7 +372,7 @@
"UnableToAddANewIndexerProxyPleaseTryAgain": "Não foi possível adicionar um novo indexador, tenta novamente.",
"Filters": "Filtros",
"HistoryCleanupDaysHelpText": "Defina como 0 para desativar a limpeza automática",
"OnGrab": "Ao capturar",
"OnGrab": "Ao capturar lançamento",
"OnHealthIssue": "Ao ter problemas no estado de funcionamento",
"TestAllIndexers": "Testar todos os indexadores",
"UserAgentProvidedByTheAppThatCalledTheAPI": "Par Utilizador-Agente fornecido pela aplicação que chamou a API",
@@ -419,9 +419,9 @@
"ApplyTagsHelpTextHowToApplyIndexers": "Como aplicar etiquetas aos indexadores selecionados",
"ApplyTagsHelpTextRemove": "Remover: eliminar as etiquetas adicionadas",
"DeleteSelectedDownloadClients": "Eliminar cliente de transferências",
"DeleteSelectedApplicationsMessageText": "Tem a certeza que quer eliminar o indexador \"{0}\"?",
"DeleteSelectedDownloadClientsMessageText": "Tem a certeza que quer eliminar o indexador \"{0}\"?",
"DeleteSelectedIndexersMessageText": "Tem a certeza que quer eliminar o indexador \"{0}\"?",
"DeleteSelectedApplicationsMessageText": "Tem a certeza que quer eliminar as {count} aplicações seleccionadas?",
"DeleteSelectedDownloadClientsMessageText": "Tem a certeza que quer eliminar os {count} clientes de transferência seleccionados?",
"DeleteSelectedIndexersMessageText": "Tem a certeza que quer eliminar os {count} indexadores seleccionados?",
"DownloadClientPriorityHelpText": "Priorizar múltiplos clientes de transferências. Utilizaremos round robin para clientes com a mesma prioridade.",
"More": "Mais",
"Year": "Ano",
@@ -445,6 +445,26 @@
"DisabledForLocalAddresses": "Desativado para endereços locais",
"None": "Nenhum",
"ResetAPIKeyMessageText": "Tem a certeza que quer repor a Chave da API?",
"ActiveApps": "Aplicações Ativadas",
"ActiveIndexers": "Indexadores ativados"
"ActiveApps": "Aplicações ativadas",
"ActiveIndexers": "Indexadores ativados",
"AuthenticationRequired": "Autenticação Necessária",
"Episode": "Episódio",
"AppUpdated": "{appName} Atualizado",
"AuthenticationRequiredHelpText": "Altere para quais solicitações a autenticação é necessária. Não mude a menos que você entenda os riscos.",
"EditIndexerProxyImplementation": "Adicionar Indexador - {implementationName}",
"AddApplicationImplementation": "Adicionar Condição - {implementationName}",
"AddConnectionImplementation": "Adicionar Conexão - {implementationName}",
"AddDownloadClientImplementation": "Adicionar Cliente de Download - {implementationName}",
"AddIndexerImplementation": "Adicionar Indexador - {implementationName}",
"AddIndexerProxyImplementation": "Adicionar Indexador - {implementationName}",
"AppUpdatedVersion": "{appName} foi atualizado para a versão `{version}`, para obter as alterações mais recentes, você precisará recarregar {appName}",
"AuthenticationRequiredWarning": "Para evitar o acesso remoto sem autenticação, {appName} agora exige que a autenticação esteja habilitada. Opcionalmente, você pode desabilitar a autenticação de endereços locais.",
"EditApplicationImplementation": "Adicionar Conexão - {implementationName}",
"EditConnectionImplementation": "Adicionar Conexão - {implementationName}",
"EditDownloadClientImplementation": "Adicionar Cliente de Download - {implementationName}",
"AuthenticationMethod": "Método de Autenticação",
"AuthenticationMethodHelpTextWarning": "Selecione um método de autenticação válido",
"AuthenticationRequiredPasswordHelpTextWarning": "Insira uma nova senha",
"AuthenticationRequiredUsernameHelpTextWarning": "Insira um novo Nome de Usuário",
"EditIndexerImplementation": "Adicionar Indexador - {implementationName}"
}

View File

@@ -82,7 +82,7 @@
"ClientPriority": "Prioridade do cliente",
"CloneProfile": "Clonar perfil",
"Close": "Fechar",
"CloseCurrentModal": "Fechar modal atual",
"CloseCurrentModal": "Fechar pop-up atual",
"Columns": "Colunas",
"Component": "Componente",
"Connect": "Notificações",
@@ -161,7 +161,7 @@
"FilterPlaceHolder": "Pesquisar indexadores",
"Filters": "Filtros",
"Fixed": "Corrigido",
"FocusSearchBox": "Selecionar caixa de pesquisa",
"FocusSearchBox": "Selecionar a caixa de pesquisa",
"Folder": "Pasta",
"ForMoreInformationOnTheIndividualDownloadClients": "Para saber mais sobre cada cliente de download, clique nos botões de informações.",
"FullSync": "Sincronização completa",
@@ -219,13 +219,13 @@
"IndexerVipCheckExpiredClientMessage": "Benefícios VIP do Indexador expiraram: {0}",
"IndexerVipCheckExpiringClientMessage": "Os benefícios VIPS do Indexador expirarão em breve: {0}",
"Indexers": "Indexadores",
"Info": "Info",
"Info": "Informações",
"InitialFailure": "Falha Inicial",
"InstanceName": "Nome da Instância",
"InstanceName": "Nome da instância",
"InstanceNameHelpText": "Nome da instância na aba e para o nome do aplicativo Syslog",
"InteractiveSearch": "Pesquisa Interativa",
"InteractiveSearch": "Pesquisa interativa",
"Interval": "Intervalo",
"KeyboardShortcuts": "Atalhos do Teclado",
"KeyboardShortcuts": "Atalhos de teclado",
"Label": "Rótulo",
"Language": "Idioma",
"LastDuration": "Última Duração",
@@ -236,9 +236,9 @@
"Level": "Nível",
"Link": "Link",
"LogFiles": "Arquivos de registro",
"LogLevel": "Nível de Registro",
"LogLevelTraceHelpTextWarning": "O registro de rastreamento deve ser ativado apenas temporariamente",
"Logging": "Registrando",
"LogLevel": "Nível de registro",
"LogLevelTraceHelpTextWarning": "O registro em log deve ser habilitado apenas temporariamente",
"Logging": "Registro em log",
"Logs": "Registros",
"MIA": "Desaparecidos",
"MaintenanceRelease": "Versão de manutenção: correções de bugs e outros aprimoramentos. Consulte o Histórico de Commit do Github para obter mais detalhes",
@@ -265,9 +265,9 @@
"No": "Não",
"NoBackupsAreAvailable": "Não há backups disponíveis",
"NoChange": "Sem alteração",
"NoChanges": "Sem Alterações",
"NoChanges": "Sem alterações",
"NoLeaveIt": "Não, deixe",
"NoLinks": "Sem Links",
"NoLinks": "Sem links",
"NoLogFiles": "Nenhum arquivo de registro",
"NoSearchResultsFound": "Nenhum resultado encontrado, tente fazer uma nova busca abaixo.",
"NoTagsHaveBeenAddedYet": "Nenhuma tag foi adicionada ainda",
@@ -288,7 +288,7 @@
"OnHealthRestored": "Com a Saúde Restaurada",
"OnHealthRestoredHelpText": "Com a Saúde Restaurada",
"OpenBrowserOnStart": "Abrir navegador ao iniciar",
"OpenThisModal": "Abrir este modal",
"OpenThisModal": "Abrir este pop-up",
"Options": "Opções",
"PackageVersion": "Versão do pacote",
"PageSize": "Tamanho da página",
@@ -360,7 +360,7 @@
"SSLPort": "Porta SSL",
"Save": "Salvar",
"SaveChanges": "Salvar Mudanças",
"SaveSettings": "Salvar Configurações",
"SaveSettings": "Salvar configurações",
"Scheduled": "Programado",
"ScriptPath": "Caminho do Script",
"Search": "Pesquisar",
@@ -386,7 +386,7 @@
"SettingsLogRotate": "Rotação de logs",
"SettingsLogRotateHelpText": "Quantidade máxima de arquivos de log a manter na pasta",
"SettingsLogSql": "Registrar SQL",
"SettingsLongDateFormat": "Formato longo da data",
"SettingsLongDateFormat": "Formato longo de data",
"SettingsShortDateFormat": "Formato curto da data",
"SettingsShowRelativeDates": "Mostrar datas relativas",
"SettingsShowRelativeDatesHelpText": "Mostrar datas absolutas ou relativas (Hoje, Ontem, etc.)",
@@ -586,7 +586,7 @@
"DefaultNameCopiedProfile": "{name} - Cópia",
"DisabledForLocalAddresses": "Desabilitado para endereços locais",
"External": "Externo",
"None": "Vazio",
"None": "Nenhum",
"ResetAPIKeyMessageText": "Tem certeza de que deseja redefinir sua chave de API?",
"AuthBasic": "Básico (pop-up do navegador)",
"ActiveIndexers": "Indexadores Ativos",

View File

@@ -452,5 +452,14 @@
"AddIndexerImplementation": "Adăugați Indexator - {implementationName}",
"AddIndexerProxyImplementation": "Adăugați proxy indexator - {implementationName}",
"Album": "Album",
"AppUpdated": "{appName} actualizat"
"AppUpdated": "{appName} actualizat",
"NoHistoryFound": "Nu s-a găsit istoric",
"AuthenticationRequiredPasswordHelpTextWarning": "Introduceți o parolă nouă",
"AuthenticationRequiredUsernameHelpTextWarning": "Introduceți un nou nume de utilizator",
"DefaultNameCopiedProfile": "{name} - Copie",
"EditConnectionImplementation": "Adăugați conexiune - {implementationName}",
"EditDownloadClientImplementation": "Adăugați client de descărcare - {implementationName}",
"EditIndexerImplementation": "Adăugați Indexator - {implementationName}",
"EditIndexerProxyImplementation": "Adăugați proxy indexator - {implementationName}",
"EditApplicationImplementation": "Adăugați aplicație - {implementareName}"
}

View File

@@ -415,5 +415,8 @@
"ResetAPIKeyMessageText": "Вы уверены, что хотите сбросить Ваш API ключ?",
"Categories": "Категории",
"Album": "альбом",
"AddCustomFilter": "Добавить специальный фильтр"
"AddCustomFilter": "Добавить специальный фильтр",
"AuthenticationMethod": "Способ авторизации",
"AuthenticationRequiredPasswordHelpTextWarning": "Введите новый пароль",
"AuthenticationRequiredUsernameHelpTextWarning": "Введите новое имя пользователя"
}

View File

@@ -353,5 +353,6 @@
"AuthForm": "Biểu mẫu (Trang đăng nhập)",
"DisabledForLocalAddresses": "Bị vô hiệu hóa đối với địa chỉ địa phương",
"None": "không ai",
"ResetAPIKeyMessageText": "Bạn có chắc chắn muốn đặt lại Khóa API của mình không?"
"ResetAPIKeyMessageText": "Bạn có chắc chắn muốn đặt lại Khóa API của mình không?",
"ApiKeyValidationHealthCheckMessage": "Hãy cập nhật mã API để dài ít nhất {length} kí tự. Bạn có thể làm điều này trong cài đặt hoặc trong tập config"
}

View File

@@ -44,10 +44,10 @@
"AudioSearch": "音频搜索",
"Auth": "认证",
"Authentication": "认证",
"AuthenticationMethodHelpText": "需要用户名和密码以访问{appName}",
"AuthenticationRequired": "需要证",
"AuthenticationRequiredHelpText": "更改需要身份验证的请求。除非您了解风险,否则请勿更改。",
"AuthenticationRequiredWarning": "为了防止未经身份验证的远程访问,{appName}现在需要启用身份验证。您可以选择禁用本地地址的身份验证。",
"AuthenticationMethodHelpText": "需要用户名和密码以访问 {appName}",
"AuthenticationRequired": "需要身份验证",
"AuthenticationRequiredHelpText": "更改身份验证的请求。除非您了解风险,否则请勿更改。",
"AuthenticationRequiredWarning": "为了防止未经身份验证的远程访问,{appName} 现在需要启用身份验证。您可以禁用本地地址的身份验证。",
"Author": "作者",
"Automatic": "自动化",
"AutomaticSearch": "自动搜索",
@@ -390,8 +390,8 @@
"SettingsSqlLoggingHelpText": "记录来自Prowlarr的所有SQL查询",
"SettingsTimeFormat": "时间格式",
"ShowAdvanced": "显示高级设置",
"ShowSearch": "显示搜索按钮",
"ShowSearchHelpText": "在选项中显示搜索",
"ShowSearch": "显示搜索",
"ShowSearchHelpText": "悬停时显示搜索按钮",
"Shutdown": "关机",
"Size": "大小",
"Sort": "排序",
@@ -401,7 +401,7 @@
"StartupDirectory": "启动目录",
"Stats": "统计数据",
"Status": "状态",
"StopSelecting": "停止选",
"StopSelecting": "停止选",
"Style": "类型",
"SuggestTranslationChange": "建议翻译改变 Suggest translation change",
"SyncAppIndexers": "同步应用索引",
@@ -463,7 +463,7 @@
"UnableToLoadTags": "无法加载标签",
"UnableToLoadUISettings": "无法加载UI设置",
"UnsavedChanges": "未保存更改",
"UnselectAll": "全不选",
"UnselectAll": "取消选择全部",
"UpdateAutomaticallyHelpText": "自动下载并安装更新。你还可以在“系统:更新”中安装",
"UpdateAvailable": "有新的更新可用",
"UpdateCheckStartupNotWritableMessage": "无法安装更新,因为用户“{1}”对于启动文件夹“{0}”没有写入权限。",
@@ -572,12 +572,12 @@
"AuthBasic": "基础(浏览器弹出对话框)",
"AuthForm": "表单(登陆页面)",
"AuthenticationMethod": "认证方式",
"AuthenticationMethodHelpTextWarning": "请选择有效的证方式",
"AuthenticationRequiredPasswordHelpTextWarning": "输入一个新的密码",
"AuthenticationRequiredUsernameHelpTextWarning": "输入一个新的用户名",
"AuthenticationMethodHelpTextWarning": "请选择一个有效的身份验证方式",
"AuthenticationRequiredPasswordHelpTextWarning": "输入密码",
"AuthenticationRequiredUsernameHelpTextWarning": "输入用户名",
"Clone": "复制",
"DefaultNameCopiedProfile": "{name} - 复制",
"DisabledForLocalAddresses": "对局域网内禁用",
"DisabledForLocalAddresses": "在本地地址上禁用",
"External": "外部的",
"None": "无",
"ResetAPIKeyMessageText": "您确定要重置您的 API 密钥吗?",

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FluentValidation.Results;
using NLog;
using NzbDrone.Core.Messaging.Events;
using NzbDrone.Core.ThingiProvider;
@@ -97,5 +98,26 @@ namespace NzbDrone.Core.Notifications
definition.SupportsOnHealthRestored = provider.SupportsOnHealthRestored;
definition.SupportsOnApplicationUpdate = provider.SupportsOnApplicationUpdate;
}
public override ValidationResult Test(NotificationDefinition definition)
{
var result = base.Test(definition);
if (definition.Id == 0)
{
return result;
}
if (result == null || result.IsValid)
{
_notificationStatusService.RecordSuccess(definition.Id);
}
else
{
_notificationStatusService.RecordFailure(definition.Id);
}
return result;
}
}
}

View File

@@ -59,6 +59,11 @@ namespace NzbDrone.Core.ThingiProvider.Status
public virtual void RecordSuccess(int providerId)
{
if (providerId <= 0)
{
return;
}
lock (_syncRoot)
{
var status = GetProviderStatus(providerId);
@@ -79,6 +84,11 @@ namespace NzbDrone.Core.ThingiProvider.Status
protected virtual void RecordFailure(int providerId, TimeSpan minimumBackOff, bool escalate)
{
if (providerId <= 0)
{
return;
}
lock (_syncRoot)
{
var status = GetProviderStatus(providerId);

View File

@@ -72,7 +72,7 @@ namespace NzbDrone.Integration.Test.Client
{
// cache control header gets reordered on net core
var headers = response.Headers;
((string)headers.Single(c => c.Name == "Cache-Control").Value).Split(',').Select(x => x.Trim())
((string)headers.SingleOrDefault(c => c.Name == "Cache-Control")?.Value ?? string.Empty).Split(',').Select(x => x.Trim())
.Should().BeEquivalentTo("no-store, no-cache".Split(',').Select(x => x.Trim()));
headers.Single(c => c.Name == "Pragma").Value.Should().Be("no-cache");
headers.Single(c => c.Name == "Expires").Value.Should().Be("-1");

View File

@@ -47,7 +47,7 @@ namespace NzbDrone.Integration.Test
protected override void InitializeTestTarget()
{
WaitForCompletion(() => Tasks.All().SelectList(x => x.TaskName).Contains("CheckHealth"));
WaitForCompletion(() => Tasks.All().SelectList(x => x.TaskName).Contains("CheckHealth"), 20000);
Indexers.Post(new Prowlarr.Api.V1.Indexers.IndexerResource
{

View File

@@ -73,7 +73,7 @@ namespace Prowlarr.Api.V1
if (providerDefinition.Enable)
{
Test(providerDefinition, false);
Test(providerDefinition, !forceSave);
}
providerDefinition = _providerFactory.Create(providerDefinition);
@@ -91,7 +91,7 @@ namespace Prowlarr.Api.V1
// Only test existing definitions if it is enabled and forceSave isn't set.
if (providerDefinition.Enable && !forceSave)
{
Test(providerDefinition, false);
Test(providerDefinition, true);
}
_providerFactory.Update(providerDefinition);

View File

@@ -40,6 +40,7 @@ namespace Prowlarr.Http.Authentication
options.LoginPath = "/login";
options.ExpireTimeSpan = TimeSpan.FromDays(7);
options.SlidingExpiration = true;
options.ReturnUrlParameter = "returnUrl";
})
.AddApiKey("API", options =>
{