mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2026-04-17 21:44:48 -04:00
Compare commits
25 Commits
v1.10.2.40
...
v1.10.4.40
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
343d7088c9 | ||
|
|
709dfe453b | ||
|
|
3130fac106 | ||
|
|
28004dfae1 | ||
|
|
9b34c89bc8 | ||
|
|
28e90acd0d | ||
|
|
9d11d7e17f | ||
|
|
2cbdb5bcba | ||
|
|
118bfb8c28 | ||
|
|
942477ecf9 | ||
|
|
4b4589ed27 | ||
|
|
bd0609639e | ||
|
|
ccdad3a44c | ||
|
|
d99da0481b | ||
|
|
da1965b18e | ||
|
|
493114f4e8 | ||
|
|
6969326092 | ||
|
|
95f899131d | ||
|
|
0ba4f3e692 | ||
|
|
a7c00a0fd7 | ||
|
|
c84ff60ec9 | ||
|
|
b3f6f54e6e | ||
|
|
ed272aaf74 | ||
|
|
c0b10f889b | ||
|
|
bbfb92bbd8 |
@@ -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)'
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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."
|
||||
}
|
||||
|
||||
@@ -507,5 +507,14 @@
|
||||
"Clone": "Κλωνοποίηση",
|
||||
"DisabledForLocalAddresses": "Απενεργοποιήθηκε για τοπικές διευθύνσεις",
|
||||
"None": "Κανένας",
|
||||
"ResetAPIKeyMessageText": "Είστε βέβαιοι ότι θέλετε να επαναφέρετε το κλειδί API σας;"
|
||||
"ResetAPIKeyMessageText": "Είστε βέβαιοι ότι θέλετε να επαναφέρετε το κλειδί API σας;",
|
||||
"AppUpdated": "{appName} Ενημερώθηκε",
|
||||
"AppUpdatedVersion": "ξαναφορτωθεί",
|
||||
"EditIndexerImplementation": "Προσθήκη",
|
||||
"AddIndexerProxyImplementation": "Προσθήκη",
|
||||
"EditConnectionImplementation": "Προσθήκη",
|
||||
"EditApplicationImplementation": "Προσθήκη",
|
||||
"AddApplicationImplementation": "Προσθήκη",
|
||||
"AddConnectionImplementation": "Προσθήκη",
|
||||
"AddIndexerImplementation": "Προσθήκη"
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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}"
|
||||
}
|
||||
|
||||
@@ -351,5 +351,6 @@
|
||||
"AuthForm": "양식 (로그인 페이지)",
|
||||
"DisabledForLocalAddresses": "로컬 주소에 대해 비활성화됨",
|
||||
"None": "없음",
|
||||
"ResetAPIKeyMessageText": "API 키를 재설정하시겠습니까?"
|
||||
"ResetAPIKeyMessageText": "API 키를 재설정하시겠습니까?",
|
||||
"StopSelecting": "선택 취소"
|
||||
}
|
||||
|
||||
@@ -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}"
|
||||
}
|
||||
|
||||
@@ -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}"
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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}"
|
||||
}
|
||||
|
||||
@@ -415,5 +415,8 @@
|
||||
"ResetAPIKeyMessageText": "Вы уверены, что хотите сбросить Ваш API ключ?",
|
||||
"Categories": "Категории",
|
||||
"Album": "альбом",
|
||||
"AddCustomFilter": "Добавить специальный фильтр"
|
||||
"AddCustomFilter": "Добавить специальный фильтр",
|
||||
"AuthenticationMethod": "Способ авторизации",
|
||||
"AuthenticationRequiredPasswordHelpTextWarning": "Введите новый пароль",
|
||||
"AuthenticationRequiredUsernameHelpTextWarning": "Введите новое имя пользователя"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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 密钥吗?",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 =>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user