Compare commits

...

31 Commits

Author SHA1 Message Date
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
Bogdan
793de05e3d Fixed: (Beyond-HD) Types filtering 2023-11-04 17:36:01 +02:00
Bogdan
1b1f9d16be Remove default definitions for dead indexers 2023-11-04 16:30:40 +02:00
Bogdan
051dea30c2 Fixed: (Beyond-HD) Category filtering 2023-11-04 16:27:39 +02:00
Bogdan
75d8a3d1d0 Fixed: (FileList) Change TZ to account DST 2023-11-02 19:40:38 +02:00
Bogdan
edf41e2ead Bump version to 1.10.2 2023-10-29 10:35:43 +02:00
Bogdan
c15c71386d New: Set busy timeout for SQLite
(cherry picked from commit 192eb7b62ae60f300a9371ce3ed2e0056b5a1f4d)
2023-10-29 01:28:13 +03:00
Bogdan
71a19efd9a Improve appearance of info fields 2023-10-27 20:54:50 +03:00
Bogdan
2c6c0fcc81 Allow 0 as value in download client Id validation 2023-10-25 17:11:48 +03:00
Bogdan
203e2dbb10 Remove mandatory validation for download client in indexers 2023-10-25 16:24:30 +03:00
Bogdan
6169fc2fa3 New: Add Download Client validation for indexers 2023-10-25 15:55:38 +03:00
Bogdan
768ce14afb Fix integration tests for indexers 2023-10-25 14:17:22 +03:00
Servarr
31d32e8c30 Automated API Docs update 2023-10-25 13:38:07 +03:00
Bogdan
7a61761b2b Add schema endpoint for app profiles 2023-10-25 13:25:16 +03:00
Bogdan
3963807c96 New: Add App Profile validation for indexers
Fixes #1903
2023-10-25 13:04:02 +03:00
Bogdan
e0f6726a3d Fixed: Detect Raw search in Generic Torznab/Newznab feeds
Fixes #1895
2023-10-25 11:51:31 +03:00
Weblate
dd25bff3d6 Multiple Translations updated by Weblate
ignore-downstream

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: 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: 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/de/
Translate-URL: https://translate.servarr.com/projects/servarr/prowlarr/hu/
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/zh_CN/
Translation: Servarr/Prowlarr
2023-10-25 11:26:16 +03:00
Jordy
d834c4292e Update link to Docker instructions in readme (#1905) 2023-10-25 11:16:13 +03:00
Bogdan
7e8272ec2b Bump version to 1.10.1 2023-10-22 09:32:32 +03:00
Bogdan
62548f32fe Fixed: (FileList) Skip ID searches for daily episodes 2023-10-21 12:46:50 +03:00
Bogdan
db9f061564 Return TV category if season/episode detected in title for PTP 2023-10-20 00:13:55 +03:00
Bogdan
b37d8799a0 Add acronym for PrivateHD 2023-10-16 18:45:06 +03:00
DaftFuzz
4366530409 Fixed: Calculating value for peers filter (#1900)
Co-authored-by: Bogdan <mynameisbogdan@users.noreply.github.com>
2023-10-16 18:21:40 +03:00
Bogdan
c7959f735e Bump version to 1.10.0 2023-10-15 21:46:33 +03:00
33 changed files with 309 additions and 183 deletions

View File

@@ -2,7 +2,7 @@
[![Build Status](https://dev.azure.com/Prowlarr/Prowlarr/_apis/build/status/Prowlarr.Prowlarr?branchName=develop)](https://dev.azure.com/Prowlarr/Prowlarr/_build/latest?definitionId=1&branchName=develop)
[![Translated](https://translate.servarr.com/widgets/servarr/-/prowlarr/svg-badge.svg)](https://translate.servarr.com/engage/prowlarr/?utm_source=widget)
[![Docker Pulls](https://img.shields.io/docker/pulls/hotio/prowlarr.svg)](https://wiki.servarr.com/prowlarr/installation#docker)
[![Docker Pulls](https://img.shields.io/docker/pulls/hotio/prowlarr.svg)](https://wiki.servarr.com/prowlarr/installation/docker)
![Github Downloads](https://img.shields.io/github/downloads/Prowlarr/Prowlarr/total.svg)
[![Backers on Open Collective](https://opencollective.com/Prowlarr/backers/badge.svg)](#backers)
[![Sponsors on Open Collective](https://opencollective.com/Prowlarr/sponsors/badge.svg)](#sponsors)

View File

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

View File

@@ -1,5 +1,7 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Alert from 'Components/Alert';
import { kinds } from 'Helpers/Props';
class InfoInput extends Component {
@@ -7,12 +9,12 @@ class InfoInput extends Component {
// Render
render() {
const {
value
} = this.props;
const { value } = this.props;
return (
<span dangerouslySetInnerHTML={{ __html: value }} />
<Alert kind={kinds.INFO}>
<span dangerouslySetInnerHTML={{ __html: value }} />
</Alert>
);
}
}

View File

@@ -3,7 +3,7 @@ import React from 'react';
import { createAction } from 'redux-actions';
import { batchActions } from 'redux-batched-actions';
import Icon from 'Components/Icon';
import { filterBuilderTypes, filterBuilderValueTypes, icons, sortDirections } from 'Helpers/Props';
import { filterBuilderTypes, filterBuilderValueTypes, filterTypePredicates, icons, sortDirections } from 'Helpers/Props';
import { createThunk, handleThunks } from 'Store/thunks';
import createAjaxRequest from 'Utilities/createAjaxRequest';
import getSectionState from 'Utilities/State/getSectionState';
@@ -169,6 +169,18 @@ export const defaultState = {
}
],
filterPredicates: {
peers: function(item, filterValue, type) {
const predicate = filterTypePredicates[type];
const seeders = item.seeders || 0;
const leechers = item.leechers || 0;
const peers = seeders + leechers;
return predicate(peers, filterValue);
}
},
filterBuilderProps: [
{
name: 'title',

View File

@@ -55,7 +55,7 @@ namespace NzbDrone.Core.Test.IndexerTests.FileListTests
torrentInfo.InfoUrl.Should().Be("https://filelist.io/details.php?id=665873");
torrentInfo.CommentUrl.Should().BeNullOrEmpty();
torrentInfo.Indexer.Should().Be(Subject.Definition.Name);
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2020-01-25 19:20:19"));
torrentInfo.PublishDate.Should().Be(DateTime.Parse("2020-01-25 20:20:19"));
torrentInfo.Size.Should().Be(8300512414);
torrentInfo.InfoHash.Should().Be(null);
torrentInfo.MagnetUrl.Should().Be(null);

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

@@ -41,14 +41,16 @@ namespace NzbDrone.Core.Datastore
private static string GetConnectionString(string dbPath)
{
var connectionBuilder = new SQLiteConnectionStringBuilder();
connectionBuilder.DataSource = dbPath;
connectionBuilder.CacheSize = (int)-20000;
connectionBuilder.DateTimeKind = DateTimeKind.Utc;
connectionBuilder.JournalMode = OsInfo.IsOsx ? SQLiteJournalModeEnum.Truncate : SQLiteJournalModeEnum.Wal;
connectionBuilder.Pooling = true;
connectionBuilder.Version = 3;
var connectionBuilder = new SQLiteConnectionStringBuilder
{
DataSource = dbPath,
CacheSize = (int)-20000,
DateTimeKind = DateTimeKind.Utc,
JournalMode = OsInfo.IsOsx ? SQLiteJournalModeEnum.Truncate : SQLiteJournalModeEnum.Wal,
Pooling = true,
Version = 3,
BusyTimeout = 100
};
if (OsInfo.IsOsx)
{

View File

@@ -130,7 +130,7 @@ namespace NzbDrone.Core.Indexers.Definitions
if (cats.Count > 0)
{
body.Add("categories", string.Join(",", cats));
body.Add("categories", cats.Select(int.Parse).ToArray());
}
if (_settings.SearchTypes.Any())
@@ -143,7 +143,7 @@ namespace NzbDrone.Core.Indexers.Definitions
if (searchTypes.Any())
{
body.Add("types", string.Join(",", searchTypes));
body.Add("types", searchTypes.ToArray());
}
}

View File

@@ -72,7 +72,7 @@ public class FileListParser : IParseIndexerResponse
InfoUrl = GetInfoUrl(id),
Seeders = row.Seeders,
Peers = row.Leechers + row.Seeders,
PublishDate = DateTime.Parse(row.UploadDate + " +0300", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal),
PublishDate = DateTime.Parse(row.UploadDate + " +0200", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal),
Description = row.SmallDescription,
Genres = row.SmallDescription.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).ToList(),
ImdbId = imdbId,

View File

@@ -30,6 +30,12 @@ public class FileListRequestGenerator : IIndexerRequestGenerator
if (DateTime.TryParseExact($"{searchCriteria.Season} {searchCriteria.Episode}", "yyyy MM/dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var showDate))
{
if (searchCriteria.ImdbId.IsNotNullOrWhiteSpace())
{
// Skip ID searches for daily episodes
return pageableRequests;
}
searchQuery = $"{searchQuery} {showDate:yyyy.MM.dd}".Trim();
}
else

View File

@@ -103,10 +103,7 @@ namespace NzbDrone.Core.Indexers.Newznab
yield return GetDefinition("NzbPlanet", GetSettings("https://api.nzbplanet.net"));
yield return GetDefinition("NZBStars", GetSettings("https://nzbstars.com"));
yield return GetDefinition("OZnzb", GetSettings("https://api.oznzb.com"));
yield return GetDefinition("SimplyNZBs", GetSettings("https://simplynzbs.com"));
yield return GetDefinition("SpotNZB", GetSettings("https://spotnzb.xyz"));
yield return GetDefinition("Tabula Rasa", GetSettings("https://www.tabula-rasa.pw", apiPath: @"/api/v1/api"));
yield return GetDefinition("VeryCouch LazyMuch", GetSettings("https://api.verycouch.com"));
yield return GetDefinition("Generic Newznab", GetSettings(""));
}
}

View File

@@ -129,6 +129,8 @@ namespace NzbDrone.Core.Indexers.Newznab
capabilities.SearchParams.AddIfNotNull(searchParam);
}
}
capabilities.SupportsRawSearch = xmlBasicSearch.Attribute("searchEngine")?.Value == "raw";
}
else
{

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,12 +29,12 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
public override IIndexerRequestGenerator GetRequestGenerator()
{
return new PassThePopcornRequestGenerator(Settings);
return new PassThePopcornRequestGenerator(Settings, Capabilities);
}
public override IParseIndexerResponse GetParser()
{
return new PassThePopcornParser(Settings, _logger);
return new PassThePopcornParser(Settings);
}
private IndexerCapabilities SetCapabilities()
@@ -43,6 +43,10 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
{
LimitsDefault = PageSize,
LimitsMax = PageSize,
TvSearchParams = new List<TvSearchParam>
{
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep
},
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

@@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using NLog;
using System.Text.RegularExpressions;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Http;
using NzbDrone.Common.Serializer;
@@ -14,12 +14,12 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
public class PassThePopcornParser : IParseIndexerResponse
{
private readonly PassThePopcornSettings _settings;
private readonly Logger _logger;
public PassThePopcornParser(PassThePopcornSettings settings, Logger logger)
private static Regex SeasonRegex => new (@"\bS\d{2,3}(E\d{2,3})?\b", RegexOptions.Compiled);
public PassThePopcornParser(PassThePopcornSettings settings)
{
_settings = settings;
_logger = logger;
}
public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
@@ -57,6 +57,7 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
foreach (var torrent in result.Torrents)
{
var id = torrent.Id;
var title = torrent.ReleaseName;
var flags = new HashSet<IndexerFlag>();
@@ -70,14 +71,21 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
flags.Add(PassThePopcornFlag.Approved);
}
var categories = new List<IndexerCategory> { NewznabStandardCategory.Movies };
if (title != null && SeasonRegex.Match(title).Success)
{
categories.Add(NewznabStandardCategory.TV);
}
torrentInfos.Add(new TorrentInfo
{
Guid = $"PassThePopcorn-{id}",
Title = torrent.ReleaseName,
Title = title,
Year = int.Parse(result.Year),
InfoUrl = GetInfoUrl(result.GroupId, id),
DownloadUrl = GetDownloadUrl(id, jsonResponse.AuthKey, jsonResponse.PassKey),
Categories = new List<IndexerCategory> { NewznabStandardCategory.Movies },
Categories = categories,
Size = long.Parse(torrent.Size),
Grabs = int.Parse(torrent.Snatched),
Seeders = int.Parse(torrent.Seeders),

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,11 @@ namespace NzbDrone.Core.Indexers.Definitions.PassThePopcorn
public IndexerPageableRequestChain GetSearchRequests(TvSearchCriteria searchCriteria)
{
return new IndexerPageableRequestChain();
var pageableRequests = new IndexerPageableRequestChain();
pageableRequests.Add(GetRequest($"{searchCriteria.SanitizedTvSearchString}", searchCriteria));
return pageableRequests;
}
public IndexerPageableRequestChain GetSearchRequests(BookSearchCriteria searchCriteria)
@@ -52,32 +59,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

@@ -10,7 +10,7 @@ namespace NzbDrone.Core.Indexers.Definitions
{
public override string Name => "PrivateHD";
public override string[] IndexerUrls => new[] { "https://privatehd.to/" };
public override string Description => "PrivateHD is a Private Torrent Tracker for HD MOVIES / TV and the sister-site of AvistaZ, CinemaZ, ExoticaZ, and AnimeTorrents";
public override string Description => "PrivateHD (PHD) is a Private Torrent Tracker for HD MOVIES / TV and the sister-site of AvistaZ, CinemaZ, ExoticaZ, and AnimeTorrents";
public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
public PrivateHD(IIndexerRepository indexerRepository,

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

@@ -505,5 +505,7 @@
"DisabledForLocalAddresses": "Für Lokale Adressen deaktivieren",
"None": "Keine",
"ResetAPIKeyMessageText": "Bist du sicher, dass du den API-Schlüssel zurücksetzen willst?",
"AddCustomFilter": "Eigenen Filter hinzufügen"
"AddCustomFilter": "Eigenen Filter hinzufügen",
"AddApplication": "Application hinzufügen",
"AddCategory": "Kategorie hinzufügen"
}

View File

@@ -47,7 +47,7 @@
"CertificateValidationHelpText": "Módosítsa a HTTPS tanúsítás szigorúságát",
"CertificateValidation": "Tanúsítvány érvényesítése",
"CancelPendingTask": "Biztosan törlöd ezt a függőben lévő feladatot?",
"Cancel": "Vissza",
"Cancel": "Mégse",
"BypassProxyForLocalAddresses": "Proxy megkerülése a helyi hálózatos címekhez",
"BranchUpdateMechanism": "A külső frissítési mechanizmus által használt ágazat",
"BranchUpdate": "Ágazattípus a Prowlarr frissítéseihez",
@@ -55,19 +55,19 @@
"BindAddressHelpText": "Érvényes IP-cím, localhost vagy '*' minden interfészhez",
"BindAddress": "Kapcsolási Cím",
"BeforeUpdate": "Alkalmazásfrissítés előtt",
"Backups": "Biztonsági Mentés",
"Backups": "Biztonsági mentések",
"BackupRetentionHelpText": "A megőrzési időnél régebbi automatikus biztonsági másolatok automatikusan törlésre kerülnek",
"BackupNow": "Biztonsági Mentés Most",
"BackupIntervalHelpText": "Időeltérés a biztonsági mentések között",
"BackupFolderHelpText": "Az elérési útvonalak a Prowlarr AppData könyvtárában lesznek",
"Backup": "Biztonsági Mentés",
"AutomaticSearch": "Automatikus Keresés",
"AutomaticSearch": "Automatikus keresés",
"Automatic": "Automatikus",
"AnalyticsEnabledHelpText": "Küldjön névtelen használati és hibainformációkat a Prowlarr szervereire. Ez magában foglalja a böngészőjéről szóló információkat, mely Prowlarr WebUI oldalakat használja, a hibajelentést, valamint az operációs rendszer adatait. Ezeket az információkat a funkciók és a hibajavítások rangsorolására használjuk fel.",
"AuthenticationMethodHelpText": "Felhasználónév és Jelszó szükséges a Prowlarr-hoz való hozzáféréshez",
"Authentication": "Hitelesítés",
"ApplyTags": "Címkék alkalmazása",
"Age": "Kora",
"Age": "Kor",
"ApiKey": "API Kulcs",
"All": "Összes",
"AcceptConfirmationModal": "Változás Megerősítése",
@@ -459,7 +459,7 @@
"TheLatestVersionIsAlreadyInstalled": "A Prowlarr legújabb verziója már telepítva van",
"Remove": "Eltávolítás",
"Replace": "Kicserél",
"ApplicationURL": "Alkalmazás URL-je",
"ApplicationURL": "Alkalmazás URL",
"ApplicationUrlHelpText": "Az alkalmazás külső URL-címe, beleértve a http(s)://-t, a portot és az URL-alapot",
"More": "Több",
"Publisher": "Kiadó",
@@ -501,5 +501,7 @@
"AuthForm": "Felhasználó (Bejelentkezési oldal)",
"DisabledForLocalAddresses": "Letiltva a helyi címeknél",
"None": "Nincs",
"ResetAPIKeyMessageText": "Biztos hogy vissza szeretnéd állítani az API-Kulcsod?"
"ResetAPIKeyMessageText": "Biztos hogy vissza szeretnéd állítani az API-Kulcsod?",
"AuthenticationRequiredPasswordHelpTextWarning": "Adjon meg új jelszót",
"AuthenticationRequiredUsernameHelpTextWarning": "Adjon meg új felhasználónevet"
}

View File

@@ -444,5 +444,7 @@
"AuthForm": "Formulários (página de início de sessão)",
"DisabledForLocalAddresses": "Desativado para endereços locais",
"None": "Nenhum",
"ResetAPIKeyMessageText": "Tem a certeza que quer repor a Chave da API?"
"ResetAPIKeyMessageText": "Tem a certeza que quer repor a Chave da API?",
"ActiveApps": "Aplicações Ativadas",
"ActiveIndexers": "Indexadores ativados"
}

View File

@@ -4,10 +4,10 @@
"Actions": "Ações",
"Add": "Adicionar",
"AddApplication": "Adicionar Aplicativo",
"AddCustomFilter": "Adicionar Filtro Personalizado",
"AddDownloadClient": "Adicionar Cliente de Download",
"AddCustomFilter": "Adicionar filtro personalizado",
"AddDownloadClient": "Adicionar cliente de download",
"AddDownloadClientToProwlarr": "Adicionar um cliente de download possibilita que o Prowlarr envie lançamentos diretamente da interface ao executar uma pesquisa manual.",
"AddIndexer": "Adicionar Indexador",
"AddIndexer": "Adicionar indexador",
"AddIndexerProxy": "Adicionar Proxy ao Indexador",
"AddNewIndexer": "Adicionar novo indexador",
"AddRemoveOnly": "Adicionar e remover apenas",
@@ -16,13 +16,13 @@
"Added": "Adicionado",
"AddedToDownloadClient": "Lançamento adicionado ao cliente",
"AddingTag": "Adicionar tag",
"Age": "Idade",
"Age": "Tempo de vida",
"Album": "Álbum",
"All": "Todos",
"AllIndexersHiddenDueToFilter": "Todos os indexadores estão ocultos devido ao filtro aplicado.",
"Analytics": "Analítica",
"Analytics": "Análises",
"AnalyticsEnabledHelpText": "Envie informações anônimas de uso e erro para os servidores do Prowlarr. Isso inclui informações sobre seu navegador, quais páginas da interface Web do Prowlarr você usa, relatórios de erros, e a versão do sistema operacional e do tempo de execução. Usaremos essas informações para priorizar recursos e correções de bugs.",
"ApiKey": "Chave API",
"ApiKey": "Chave da API",
"ApiKeyValidationHealthCheckMessage": "Atualize sua chave de API para ter pelo menos {0} caracteres. Você pode fazer isso através das configurações ou do arquivo de configuração",
"AppDataDirectory": "Diretório AppData",
"AppDataLocationHealthCheckMessage": "A atualização não será possível para evitar a exclusão de AppData na atualização",
@@ -34,8 +34,8 @@
"ApplicationLongTermStatusCheckSingleClientMessage": "Aplicativos indisponíveis devido a falhas por mais de 6 horas: {0}",
"ApplicationStatusCheckAllClientMessage": "Não há aplicativos disponíveis devido a falhas",
"ApplicationStatusCheckSingleClientMessage": "Aplicativos indisponíveis devido a falhas: {0}",
"ApplicationURL": "URL do Aplicativo",
"ApplicationUrlHelpText": "A URL externa deste aplicativo, incluindo http(s)://, porta e base da URL",
"ApplicationURL": "URL do aplicativo",
"ApplicationUrlHelpText": "A URL externa deste aplicativo, incluindo http(s)://, porta e URL base",
"Applications": "Aplicativos",
"Apply": "Aplicar",
"ApplyTags": "Aplicar Tags",
@@ -45,13 +45,13 @@
"AudioSearch": "Pesquisar Áudio",
"Auth": "Autenticação",
"Authentication": "Autenticação",
"AuthenticationMethodHelpText": "Exigir nome de usuário e senha para acessar {appName}",
"AuthenticationRequired": "Autentificação Requerida",
"AuthenticationMethodHelpText": "Exigir nome de usuário e senha para acessar o {appName}",
"AuthenticationRequired": "Autenticação exigida",
"AuthenticationRequiredHelpText": "Altere para quais solicitações a autenticação é necessária. Não mude a menos que você entenda os riscos.",
"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.",
"Author": "Autor",
"Automatic": "Automático",
"AutomaticSearch": "Pesquisa Automática",
"AutomaticSearch": "Pesquisa automática",
"AverageResponseTimesMs": "Tempos Médios de Resposta do Indexador (ms)",
"Backup": "Backup",
"BackupFolderHelpText": "Os caminhos relativos estarão no diretório AppData do Prowlarr",
@@ -60,7 +60,7 @@
"BackupRetentionHelpText": "Backups automáticos anteriores ao período de retenção serão limpos automaticamente",
"Backups": "Backups",
"BeforeUpdate": "Antes da atualização",
"BindAddress": "Fixar Endereço",
"BindAddress": "Fixar endereço",
"BindAddressHelpText": "Endereço IP válido, localhost ou '*' para todas as interfaces",
"Book": "Livro",
"BookSearch": "Pesquisar Livro",
@@ -73,26 +73,26 @@
"CancelPendingTask": "Tem certeza de que deseja cancelar essa tarefa pendente?",
"Categories": "Categorias",
"Category": "Categoria",
"CertificateValidation": "Validação de Certificado",
"CertificateValidation": "Validação de certificado",
"CertificateValidationHelpText": "Alterar o quão estrita é a validação da certificação HTTPS",
"ChangeHasNotBeenSavedYet": "A alteração ainda não foi salva",
"Clear": "Limpar",
"ClearHistory": "Limpar histórico",
"ClearHistoryMessageText": "Tem certeza de que deseja limpar o histórico do Prowlarr?",
"ClientPriority": "Prioridade do Cliente",
"CloneProfile": "Clonar Perfil",
"ClientPriority": "Prioridade do cliente",
"CloneProfile": "Clonar perfil",
"Close": "Fechar",
"CloseCurrentModal": "Fechar modal atual",
"Columns": "Colunas",
"Component": "Componente",
"Connect": "Notificações",
"ConnectSettings": "Configurações de Conexão",
"ConnectSettings": "Configurações de conexão",
"ConnectSettingsSummary": "Notificações e scripts personalizados",
"ConnectionLost": "Conexão Perdida",
"ConnectionLost": "Conexão perdida",
"Connections": "Conexões",
"CouldNotConnectSignalR": "Não é possível conectar ao SignalR, a interface não atualizará",
"Custom": "Personalizar",
"CustomFilters": "Filtros Personalizados",
"Custom": "Personalizado",
"CustomFilters": "Filtros personalizados",
"DBMigration": "Migração de banco de dados",
"Database": "Banco de dados",
"Date": "Data",
@@ -104,11 +104,11 @@
"DeleteBackup": "Excluir Backup",
"DeleteBackupMessageText": "Tem certeza de que deseja excluir o backup '{name}'?",
"DeleteClientCategory": "Excluir Categoria de Cliente de Download",
"DeleteDownloadClient": "Excluir Cliente de Download",
"DeleteDownloadClient": "Excluir cliente de download",
"DeleteDownloadClientMessageText": "Tem certeza de que deseja excluir o cliente de download '{name}'?",
"DeleteIndexerProxy": "Apagar Proxy do Indexador",
"DeleteIndexerProxyMessageText": "Tem certeza de que deseja excluir o proxy do indexador '{name}'?",
"DeleteNotification": "Excluir Notificação",
"DeleteNotification": "Excluir notificação",
"DeleteNotificationMessageText": "Tem certeza de que deseja excluir a notificação '{name}'?",
"DeleteTag": "Excluir tag",
"DeleteTagMessageText": "Tem certeza de que deseja excluir a tag '{label}'?",
@@ -120,9 +120,9 @@
"Discord": "Discord",
"Docker": "Docker",
"Donations": "Doações",
"DownloadClient": "Cliente de Download",
"DownloadClient": "Cliente de download",
"DownloadClientCategory": "Categoria de Download do Cliente",
"DownloadClientSettings": "Configurações do Cliente de Download",
"DownloadClientSettings": "Configurações do cliente de download",
"DownloadClientStatusCheckAllClientMessage": "Todos os clientes de download estão indisponíveis devido a falhas",
"DownloadClientStatusCheckSingleClientMessage": "Clientes de download indisponíveis devido a falhas: {0}",
"DownloadClients": "Clientes de download",
@@ -137,7 +137,7 @@
"EnableAutomaticSearchHelpText": "Será usado ao realizar pesquisas automáticas pela interface ou pelo Prowlarr",
"EnableIndexer": "Habilitar indexador",
"EnableInteractiveSearch": "Ativar pesquisa interativa",
"EnableInteractiveSearchHelpText": "Será usado quando a pesquisa interativa for usada",
"EnableInteractiveSearchHelpText": "Será usado com a pesquisa interativa",
"EnableRss": "Habilitar RSS",
"EnableRssHelpText": "Habilitar feed RSS para o indexador",
"EnableSSL": "Habilitar SSL",
@@ -149,7 +149,7 @@
"Episode": "Episódio",
"Error": "Erro",
"ErrorLoadingContents": "Erro ao carregar o conteúdo",
"EventType": "Tipo de Evento",
"EventType": "Tipo de evento",
"Events": "Eventos",
"Exception": "Exceção",
"ExistingTag": "Etiqueta existente",
@@ -175,7 +175,7 @@
"Grabs": "Obtenções",
"Health": "Saúde",
"HealthNoIssues": "Nenhum problema com sua configuração",
"HideAdvanced": "Ocultar Avançado",
"HideAdvanced": "Ocultar opções avançadas",
"History": "Histórico",
"HistoryCleanup": "Histórico de Limpeza",
"HistoryCleanupDaysHelpText": "Defina como 0 para desabilitar a limpeza automática",
@@ -183,9 +183,9 @@
"HistoryDetails": "Detalhes do histórico",
"HomePage": "Página inicial",
"Host": "Host",
"Hostname": "Hostname",
"Hostname": "Nome do host",
"Id": "ID",
"IgnoredAddresses": "Endereços Ignorados",
"IgnoredAddresses": "Endereços ignorados",
"IllRestartLater": "Reiniciarei mais tarde",
"IncludeHealthWarningsHelpText": "Incluir avisos de integridade",
"IncludeManualGrabsHelpText": "Incluir Capturas Manuais feitas no Prowlarr",
@@ -203,7 +203,7 @@
"IndexerName": "Nome do Indexador",
"IndexerNoDefCheckMessage": "Os indexadores não têm definição e não funcionarão: {0}. Por favor, remova e (ou) adicione novamente ao Prowlarr",
"IndexerObsoleteCheckMessage": "Os seguintes indexadores são obsoletos ou foram atualizados: {0}. Remova-os e/ou adicione-os novamente ao Prowlarr",
"IndexerPriority": "Prioridade do Indexador",
"IndexerPriority": "Prioridade do indexador",
"IndexerPriorityHelpText": "Prioridade do Indexador de 1 (Mais Alta) a 50 (Mais Baixa). Padrão: 25.",
"IndexerProxies": "Proxies do Indexador",
"IndexerProxy": "Proxy do Indexador",
@@ -392,7 +392,7 @@
"SettingsShowRelativeDatesHelpText": "Mostrar datas absolutas ou relativas (Hoje, Ontem, etc.)",
"SettingsSqlLoggingHelpText": "Registrar todas as consultas de SQL do Prowlarr",
"SettingsTimeFormat": "Formato de hora",
"ShowAdvanced": "Mostrar Avançado",
"ShowAdvanced": "Mostrar opções avançadas",
"ShowSearch": "Mostrar pesquisa",
"ShowSearchHelpText": "Mostrar botão de pesquisa ao passar o mouse",
"Shutdown": "Desligar",
@@ -456,13 +456,13 @@
"URLBase": "URL base",
"UnableToAddANewAppProfilePleaseTryAgain": "Não foi possível adicionar um novo perfil de aplicativo, tente novamente.",
"UnableToAddANewApplicationPleaseTryAgain": "Não foi possível adicionar um novo aplicativo, tente novamente.",
"UnableToAddANewDownloadClientPleaseTryAgain": "Não foi possível adicionar um novo cliente de download, tente novamente.",
"UnableToAddANewIndexerPleaseTryAgain": "Não foi possível adicionar um novo indexador, tente novamente.",
"UnableToAddANewDownloadClientPleaseTryAgain": "Não foi possível adicionar um novo cliente de download. Tente novamente.",
"UnableToAddANewIndexerPleaseTryAgain": "Não foi possível adicionar um novo indexador. Tente novamente.",
"UnableToAddANewIndexerProxyPleaseTryAgain": "Não foi possível adicionar um novo proxy indexador, tente novamente.",
"UnableToAddANewNotificationPleaseTryAgain": "Não foi possível adicionar uma nova notificação, tente novamente.",
"UnableToAddANewNotificationPleaseTryAgain": "Não foi possível adicionar uma nova notificação. Tente novamente.",
"UnableToLoadAppProfiles": "Não foi possível carregar os perfis de aplicativos",
"UnableToLoadApplicationList": "Não é possível carregar a lista de aplicativos",
"UnableToLoadBackups": "Não é possível carregar backups",
"UnableToLoadBackups": "Não foi possível carregar os backups",
"UnableToLoadDevelopmentSettings": "Não foi possível carregar as configurações de desenvolvimento",
"UnableToLoadDownloadClients": "Não foi possível carregar os clientes de download",
"UnableToLoadGeneralSettings": "Não foi possível carregar as configurações gerais",
@@ -556,39 +556,39 @@
"days": "dias",
"IndexerDownloadClientHealthCheckMessage": "Indexadores com clientes de download inválidos: {0}.",
"DeleteAppProfileMessageText": "Tem certeza de que deseja excluir o perfil do aplicativo '{name}'?",
"AppUpdated": "{appName} Atualizado",
"AppUpdated": "{appName} atualizado",
"AppUpdatedVersion": "{appName} foi atualizado para a versão `{version}`, para obter as alterações mais recentes, você precisará recarregar {appName}",
"ConnectionLostToBackend": "{appName} perdeu sua conexão com o backend e precisará ser recarregado para restaurar a funcionalidade.",
"ConnectionLostToBackend": "{appName} perdeu a conexão com o backend e precisará ser recarregado para restaurar a funcionalidade.",
"RecentChanges": "Mudanças Recentes",
"WhatsNew": "O que há de novo?",
"ConnectionLostReconnect": "{appName} tentará se conectar automaticamente ou você pode clicar em recarregar abaixo.",
"AddApplicationImplementation": "Adicionar Aplicativo - {implementationName}",
"AddConnectionImplementation": "Adicionar Conexão - {implementationName}",
"AddConnectionImplementation": "Adicionar conexão - {implementationName}",
"EditApplicationImplementation": "Editar Aplicativo - {implementationName}",
"AddCategory": "Adicionar Categoria",
"AddConnection": "Adicionar Conexão",
"AddDownloadClientImplementation": "Adicionar Cliente de Download - {implementationName}",
"AddIndexerImplementation": "Adicionar Indexador - {implementationName}",
"AddConnection": "Adicionar conexão",
"AddDownloadClientImplementation": "Adicionar cliente de download - {implementationName}",
"AddIndexerImplementation": "Adicionar indexador - {implementationName}",
"AddIndexerProxyImplementation": "Adicionar Proxy do Indexador - {implementationName}",
"EditCategory": "Editar Categoria",
"EditConnectionImplementation": "Editar Conexão - {implementationName}",
"EditDownloadClientImplementation": "Editar Cliente de Download - {implementationName}",
"EditIndexerImplementation": "Editar Indexador - {implementationName}",
"EditConnectionImplementation": "Editar conexão - {implementationName}",
"EditDownloadClientImplementation": "Editar cliente de download - {implementationName}",
"EditIndexerImplementation": "Editar indexador - {implementationName}",
"EditIndexerProxyImplementation": "Editar Proxy do Indexador - {implementationName}",
"NotificationStatusAllClientHealthCheckMessage": "Todas as notificações estão indisponíveis devido a falhas",
"NotificationStatusSingleClientHealthCheckMessage": "Notificações indisponíveis devido a falhas: {0}",
"AuthForm": "Formulário (Página de login)",
"AuthenticationMethod": "Método de Autenticação",
"AuthForm": "Formulário (página de login)",
"AuthenticationMethod": "Método de autenticação",
"AuthenticationMethodHelpTextWarning": "Selecione um método de autenticação válido",
"AuthenticationRequiredPasswordHelpTextWarning": "Insira uma nova senha",
"AuthenticationRequiredPasswordHelpTextWarning": "Digite uma nova senha",
"AuthenticationRequiredUsernameHelpTextWarning": "Digite um novo nome de usuário",
"Clone": "Clonar",
"DefaultNameCopiedProfile": "{name} - Cópia",
"DisabledForLocalAddresses": "Desativado para Endereços Locais",
"DisabledForLocalAddresses": "Desabilitado para endereços locais",
"External": "Externo",
"None": "Vazio",
"ResetAPIKeyMessageText": "Tem certeza de que deseja redefinir sua chave de API?",
"AuthBasic": "Básico (Balão do Navegador)",
"AuthBasic": "Básico (pop-up do navegador)",
"ActiveIndexers": "Indexadores Ativos",
"ActiveApps": "Apps Ativos",
"IndexerHistoryLoadError": "Erro ao carregar o histórico do indexador",

View File

@@ -121,7 +121,7 @@
"SettingsEnableColorImpairedModeHelpText": "Stil modificat pentru a permite utilizatorilor cu deficiențe de culoare să distingă mai bine informațiile codificate prin culoare",
"SettingsLongDateFormat": "Format de dată lungă",
"SettingsShortDateFormat": "Format scurt de dată",
"SettingsTimeFormat": "Format de timp",
"SettingsTimeFormat": "Format ora",
"RSSIsNotSupportedWithThisIndexer": "RSS nu este suportat de acest indexator",
"ShowSearchHelpText": "Afișați butonul de căutare pe hover",
"UILanguageHelpText": "Limba pe care Prowlarr o va folosi pentru interfața de utilizare",
@@ -451,5 +451,6 @@
"AddDownloadClientImplementation": "Adăugați client de descărcare - {implementationName}",
"AddIndexerImplementation": "Adăugați Indexator - {implementationName}",
"AddIndexerProxyImplementation": "Adăugați proxy indexator - {implementationName}",
"Album": "Album"
"Album": "Album",
"AppUpdated": "{appName} actualizat"
}

View File

@@ -4,7 +4,7 @@
"Actions": "动作",
"Add": "添加",
"AddApplication": "添加应用程序",
"AddCustomFilter": "添加自定义过滤",
"AddCustomFilter": "添加自定义过滤",
"AddDownloadClient": "添加下载客户端",
"AddDownloadClientToProwlarr": "添加下载客户端允许 Prowlarr 在进行手动搜索时从 UI直接发送结果.",
"AddIndexer": "添加索引器",
@@ -91,7 +91,7 @@
"Connections": "连接",
"CouldNotConnectSignalR": "无法连接至SignalR不会升级UI",
"Custom": "自定义",
"CustomFilters": "自定义过滤",
"CustomFilters": "自定义过滤",
"DBMigration": "数据库迁移版本",
"Database": "数据库",
"Date": "日期",
@@ -108,7 +108,7 @@
"DeleteIndexerProxy": "删除搜刮器代理",
"DeleteIndexerProxyMessageText": "您确定要删除索引器代理“{name}”吗?",
"DeleteNotification": "删除消息推送",
"DeleteNotificationMessageText": "您确定要删除消息推送 “{name}” 吗?",
"DeleteNotificationMessageText": "您确定要删除通知“{name}”吗?",
"DeleteTag": "删除标签",
"DeleteTagMessageText": "您确定要删除标签 '{label}' 吗?",
"Description": "描述",
@@ -116,7 +116,7 @@
"DevelopmentSettings": "开发设置",
"Disabled": "禁用",
"DisabledUntil": "禁用Until",
"Discord": "冲突",
"Discord": "分歧",
"Docker": "Docker",
"Donations": "赞助",
"DownloadClient": "下载客户端",
@@ -147,7 +147,7 @@
"Ended": "已完结",
"Episode": "集",
"Error": "错误",
"ErrorLoadingContents": "读取内容错误",
"ErrorLoadingContents": "加载内容出错",
"EventType": "事件类型",
"Events": "事件",
"Exception": "例外",
@@ -224,7 +224,7 @@
"InstanceNameHelpText": "选项卡及日志应用名称",
"InteractiveSearch": "手动搜索",
"Interval": "间隔",
"KeyboardShortcuts": "键盘快捷键",
"KeyboardShortcuts": "快捷键",
"Label": "标签",
"Language": "语言",
"LastDuration": "上一次用时",
@@ -250,7 +250,7 @@
"MinimumSeeders": "最少播种量",
"MinimumSeedersHelpText": "用于索引器抓取的应用程序所需的最小播种量",
"Mode": "模式",
"More": "更多",
"More": "更多",
"MoreInfo": "更多信息",
"MovieIndexScrollBottom": "影片索引:滚动到底部",
"MovieIndexScrollTop": "影片索引:滚动到顶部",
@@ -334,7 +334,7 @@
"ReleaseStatus": "发布状态",
"Reload": "重新加载",
"Remove": "移除",
"RemoveFilter": "移除过滤条件",
"RemoveFilter": "移除过滤",
"RemovedFromTaskQueue": "从任务队列中移除",
"RemovingTag": "移除标签",
"RepeatSearch": "再次搜索",
@@ -480,7 +480,7 @@
"UserAgentProvidedByTheAppThatCalledTheAPI": "由调用API的应用程序提供的User-Agent",
"Username": "用户名",
"Version": "版本",
"View": "视图",
"View": "查看",
"VipExpiration": "VIP过期",
"Warn": "警告",
"Website": "‎网站‎",
@@ -557,16 +557,16 @@
"AddConnection": "添加连接",
"AddIndexerImplementation": "添加索引器 - {implementationName}",
"AddCategory": "添加目录",
"AddConnectionImplementation": "添加集合 - {implementationName}",
"AddDownloadClientImplementation": "添加下载客户端 - {implementationName}",
"AddConnectionImplementation": "添加连接- {implementationName}",
"AddDownloadClientImplementation": "添加下载客户端- {implementationName}",
"AddIndexerProxyImplementation": "添加搜刮器代理-{实体名称}",
"AppUpdated": "{appName} 升级",
"EditDownloadClientImplementation": "添加下载客户端 - {implementationName}",
"EditIndexerImplementation": "添加索引器 - {implementationName}",
"EditDownloadClientImplementation": "编辑下载客户端- {implementationName}",
"EditIndexerImplementation": "编辑索引器- {implementationName}",
"EditIndexerProxyImplementation": "添加搜刮器代理-{实体名称}",
"AppUpdatedVersion": "{appName} 已经更新到 {version} 版本,重新加载 {appName} 使更新生效",
"EditApplicationImplementation": "添加应用-{实体名称}",
"EditConnectionImplementation": "添加集合 - {implementationName}",
"EditConnectionImplementation": "编辑连接- {implementationName}",
"NotificationStatusAllClientHealthCheckMessage": "由于故障所用应用程序都不可用",
"NotificationStatusSingleClientHealthCheckMessage": "由于故障应用程序不可用",
"AuthBasic": "基础(浏览器弹出对话框)",

View File

@@ -7,7 +7,7 @@ using NzbDrone.Core.Messaging.Events;
namespace NzbDrone.Core.Profiles
{
public interface IProfileService
public interface IAppProfileService
{
AppSyncProfile Add(AppSyncProfile profile);
void Update(AppSyncProfile profile);
@@ -18,7 +18,7 @@ namespace NzbDrone.Core.Profiles
AppSyncProfile GetDefaultProfile(string name);
}
public class AppSyncProfileService : IProfileService,
public class AppSyncProfileService : IAppProfileService,
IHandle<ApplicationStartedEvent>
{
private readonly IAppProfileRepository _profileRepository;

View File

@@ -0,0 +1,22 @@
using FluentValidation.Validators;
using NzbDrone.Core.Profiles;
namespace NzbDrone.Core.Validation
{
public class AppProfileExistsValidator : PropertyValidator
{
private readonly IAppProfileService _appProfileService;
public AppProfileExistsValidator(IAppProfileService appProfileService)
{
_appProfileService = appProfileService;
}
protected override string GetDefaultMessageTemplate() => "App Profile does not exist";
protected override bool IsValid(PropertyValidatorContext context)
{
return context?.PropertyValue == null || _appProfileService.Exists((int)context.PropertyValue);
}
}
}

View File

@@ -0,0 +1,27 @@
using FluentValidation.Validators;
using NzbDrone.Core.Download;
namespace NzbDrone.Core.Validation
{
public class DownloadClientExistsValidator : PropertyValidator
{
private readonly IDownloadClientFactory _downloadClientFactory;
public DownloadClientExistsValidator(IDownloadClientFactory downloadClientFactory)
{
_downloadClientFactory = downloadClientFactory;
}
protected override string GetDefaultMessageTemplate() => "Download Client does not exist";
protected override bool IsValid(PropertyValidatorContext context)
{
if (context?.PropertyValue == null || (int)context.PropertyValue == 0)
{
return true;
}
return _downloadClientFactory.Exists((int)context.PropertyValue);
}
}
}

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
{
@@ -56,6 +56,7 @@ namespace NzbDrone.Integration.Test
Implementation = nameof(FileList),
Name = "NewznabTest",
Protocol = Core.Indexers.DownloadProtocol.Usenet,
AppProfileId = 1,
Fields = SchemaBuilder.ToSchema(new FileListSettings())
});

View File

@@ -1,4 +1,5 @@
using NzbDrone.Core.Indexers;
using NzbDrone.Core.Validation;
using Prowlarr.Http;
namespace Prowlarr.Api.V1.Indexers
@@ -6,9 +7,17 @@ namespace Prowlarr.Api.V1.Indexers
[V1ApiController]
public class IndexerController : ProviderControllerBase<IndexerResource, IndexerBulkResource, IIndexer, IndexerDefinition>
{
public IndexerController(IndexerFactory indexerFactory, IndexerResourceMapper resourceMapper, IndexerBulkResourceMapper bulkResourceMapper)
public IndexerController(IndexerFactory indexerFactory,
IndexerResourceMapper resourceMapper,
IndexerBulkResourceMapper bulkResourceMapper,
AppProfileExistsValidator appProfileExistsValidator,
DownloadClientExistsValidator downloadClientExistsValidator)
: base(indexerFactory, "indexer", resourceMapper, bulkResourceMapper)
{
Http.Validation.RuleBuilderExtensions.ValidId(SharedValidator.RuleFor(s => s.AppProfileId));
SharedValidator.RuleFor(c => c.AppProfileId).SetValidator(appProfileExistsValidator);
SharedValidator.RuleFor(c => c.DownloadClientId).SetValidator(downloadClientExistsValidator);
}
}
}

View File

@@ -11,11 +11,12 @@ namespace Prowlarr.Api.V1.Profiles.App
[V1ApiController]
public class AppProfileController : RestController<AppProfileResource>
{
private readonly IProfileService _profileService;
private readonly IAppProfileService _appProfileService;
public AppProfileController(IProfileService profileService)
public AppProfileController(IAppProfileService appProfileService)
{
_profileService = profileService;
_appProfileService = appProfileService;
SharedValidator.RuleFor(c => c.Name).NotEmpty();
}
@@ -25,7 +26,7 @@ namespace Prowlarr.Api.V1.Profiles.App
public ActionResult<AppProfileResource> Create(AppProfileResource resource)
{
var model = resource.ToModel();
model = _profileService.Add(model);
model = _appProfileService.Add(model);
return Created(model.Id);
}
@@ -33,7 +34,7 @@ namespace Prowlarr.Api.V1.Profiles.App
[Produces("application/json")]
public object DeleteProfile(int id)
{
_profileService.Delete(id);
_appProfileService.Delete(id);
return new { };
}
@@ -44,7 +45,7 @@ namespace Prowlarr.Api.V1.Profiles.App
{
var model = resource.ToModel();
_profileService.Update(model);
_appProfileService.Update(model);
return Accepted(model.Id);
}
@@ -55,14 +56,23 @@ namespace Prowlarr.Api.V1.Profiles.App
[ProducesResponseType(500)]
public override AppProfileResource GetResourceById(int id)
{
return _profileService.Get(id).ToResource();
return _appProfileService.Get(id).ToResource();
}
[HttpGet]
[Produces("application/json")]
public List<AppProfileResource> GetAll()
{
return _profileService.All().ToResource();
return _appProfileService.All().ToResource();
}
[HttpGet("schema")]
[Produces("application/json")]
public AppProfileResource GetTemplates()
{
var profile = _appProfileService.GetDefaultProfile(string.Empty);
return profile.ToResource();
}
}
}

View File

@@ -1,26 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using NzbDrone.Core.Profiles;
using Prowlarr.Http;
namespace Prowlarr.Api.V1.Profiles.App
{
[V1ApiController("appprofile/schema")]
public class QualityProfileSchemaController : Controller
{
private readonly IProfileService _profileService;
public QualityProfileSchemaController(IProfileService profileService)
{
_profileService = profileService;
}
[HttpGet]
[Produces("application/json")]
public AppProfileResource GetSchema()
{
var qualityProfile = _profileService.GetDefaultProfile(string.Empty);
return qualityProfile.ToResource();
}
}
}

View File

@@ -483,6 +483,25 @@
}
}
},
"/api/v1/appprofile/schema": {
"get": {
"tags": [
"AppProfile"
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AppProfileResource"
}
}
}
}
}
}
},
"/login": {
"post": {
"tags": [
@@ -3280,25 +3299,6 @@
}
}
},
"/api/v1/appprofile/schema": {
"get": {
"tags": [
"QualityProfileSchema"
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AppProfileResource"
}
}
}
}
}
}
},
"/api/v1/search": {
"post": {
"tags": [