Fixed: (FileList) Add alternative URL and return only FL results when fl-only is set

pull/1379/head v1.1.2.2453
Bogdan 2 years ago
parent 0685c2eb04
commit 0c0cbdac2f

@ -8,7 +8,7 @@ using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common.Http; using NzbDrone.Common.Http;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
using NzbDrone.Core.Indexers.FileList; using NzbDrone.Core.Indexers.Definitions.FileList;
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;

@ -3,7 +3,7 @@ using System.Linq;
using FluentAssertions; using FluentAssertions;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Core.Indexers; using NzbDrone.Core.Indexers;
using NzbDrone.Core.Indexers.FileList; using NzbDrone.Core.Indexers.Definitions.FileList;
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;

@ -3,95 +3,98 @@ using NLog;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Messaging.Events;
namespace NzbDrone.Core.Indexers.FileList namespace NzbDrone.Core.Indexers.Definitions.FileList;
public class FileList : TorrentIndexerBase<FileListSettings>
{ {
public class FileList : TorrentIndexerBase<FileListSettings> public override string Name => "FileList.io";
public override string[] IndexerUrls => new[]
{ {
public override string Name => "FileList.io"; "https://filelist.io/",
public override string[] IndexerUrls => new[] { "https://filelist.io/" }; "https://flro.org/"
public override string[] LegacyUrls => new[] { "https://filelist.io" }; };
public override string Description => "FileList (FL) is a ROMANIAN Private Torrent Tracker for 0DAY / GENERAL"; public override string[] LegacyUrls => new[] { "https://filelist.io" };
public override DownloadProtocol Protocol => DownloadProtocol.Torrent; public override string Description => "FileList (FL) is a ROMANIAN Private Torrent Tracker for 0DAY / GENERAL";
public override IndexerPrivacy Privacy => IndexerPrivacy.Private; public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
public override bool SupportsRss => true; public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
public override bool SupportsSearch => true; public override bool SupportsRss => true;
public override bool SupportsRedirect => true; public override bool SupportsSearch => true;
public override IndexerCapabilities Capabilities => SetCapabilities(); public override bool SupportsRedirect => true;
public override IndexerCapabilities Capabilities => SetCapabilities();
public FileList(IIndexerHttpClient httpClient, public FileList(IIndexerHttpClient httpClient,
IEventAggregator eventAggregator, IEventAggregator eventAggregator,
IIndexerStatusService indexerStatusService, IIndexerStatusService indexerStatusService,
IConfigService configService, IConfigService configService,
Logger logger) Logger logger)
: base(httpClient, eventAggregator, indexerStatusService, configService, logger) : base(httpClient, eventAggregator, indexerStatusService, configService, logger)
{ {
} }
public override IIndexerRequestGenerator GetRequestGenerator() public override IIndexerRequestGenerator GetRequestGenerator()
{ {
return new FileListRequestGenerator { Settings = Settings, Capabilities = Capabilities }; return new FileListRequestGenerator { Settings = Settings, Capabilities = Capabilities };
} }
public override IParseIndexerResponse GetParser() public override IParseIndexerResponse GetParser()
{ {
return new FileListParser(Settings, Capabilities.Categories); return new FileListParser(Settings, Capabilities.Categories);
} }
private IndexerCapabilities SetCapabilities() private IndexerCapabilities SetCapabilities()
{
var caps = new IndexerCapabilities
{ {
var caps = new IndexerCapabilities TvSearchParams = new List<TvSearchParam>
{
TvSearchParam.Q, TvSearchParam.ImdbId, TvSearchParam.Season, TvSearchParam.Ep
},
MovieSearchParams = new List<MovieSearchParam>
{
MovieSearchParam.Q, MovieSearchParam.ImdbId
},
MusicSearchParams = new List<MusicSearchParam>
{
MusicSearchParam.Q
},
BookSearchParams = new List<BookSearchParam>
{
BookSearchParam.Q
},
Flags = new List<IndexerFlag>
{ {
TvSearchParams = new List<TvSearchParam> IndexerFlag.Internal,
{ IndexerFlag.FreeLeech
TvSearchParam.Q, TvSearchParam.ImdbId, TvSearchParam.Season, TvSearchParam.Ep }
}, };
MovieSearchParams = new List<MovieSearchParam>
{
MovieSearchParam.Q, MovieSearchParam.ImdbId
},
MusicSearchParams = new List<MusicSearchParam>
{
MusicSearchParam.Q
},
BookSearchParams = new List<BookSearchParam>
{
BookSearchParam.Q
},
Flags = new List<IndexerFlag>
{
IndexerFlag.Internal,
IndexerFlag.FreeLeech
}
};
caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.MoviesSD, "Filme SD"); caps.Categories.AddCategoryMapping(1, NewznabStandardCategory.MoviesSD, "Filme SD");
caps.Categories.AddCategoryMapping(2, NewznabStandardCategory.MoviesDVD, "Filme DVD"); caps.Categories.AddCategoryMapping(2, NewznabStandardCategory.MoviesDVD, "Filme DVD");
caps.Categories.AddCategoryMapping(3, NewznabStandardCategory.MoviesForeign, "Filme DVD-RO"); caps.Categories.AddCategoryMapping(3, NewznabStandardCategory.MoviesForeign, "Filme DVD-RO");
caps.Categories.AddCategoryMapping(4, NewznabStandardCategory.MoviesHD, "Filme HD"); caps.Categories.AddCategoryMapping(4, NewznabStandardCategory.MoviesHD, "Filme HD");
caps.Categories.AddCategoryMapping(5, NewznabStandardCategory.AudioLossless, "FLAC"); caps.Categories.AddCategoryMapping(5, NewznabStandardCategory.AudioLossless, "FLAC");
caps.Categories.AddCategoryMapping(6, NewznabStandardCategory.MoviesUHD, "Filme 4K"); caps.Categories.AddCategoryMapping(6, NewznabStandardCategory.MoviesUHD, "Filme 4K");
caps.Categories.AddCategoryMapping(7, NewznabStandardCategory.XXX, "XXX"); caps.Categories.AddCategoryMapping(7, NewznabStandardCategory.XXX, "XXX");
caps.Categories.AddCategoryMapping(8, NewznabStandardCategory.PC, "Programe"); caps.Categories.AddCategoryMapping(8, NewznabStandardCategory.PC, "Programe");
caps.Categories.AddCategoryMapping(9, NewznabStandardCategory.PCGames, "Jocuri PC"); caps.Categories.AddCategoryMapping(9, NewznabStandardCategory.PCGames, "Jocuri PC");
caps.Categories.AddCategoryMapping(10, NewznabStandardCategory.Console, "Jocuri Console"); caps.Categories.AddCategoryMapping(10, NewznabStandardCategory.Console, "Jocuri Console");
caps.Categories.AddCategoryMapping(11, NewznabStandardCategory.Audio, "Audio"); caps.Categories.AddCategoryMapping(11, NewznabStandardCategory.Audio, "Audio");
caps.Categories.AddCategoryMapping(12, NewznabStandardCategory.AudioVideo, "Videoclip"); caps.Categories.AddCategoryMapping(12, NewznabStandardCategory.AudioVideo, "Videoclip");
caps.Categories.AddCategoryMapping(13, NewznabStandardCategory.TVSport, "Sport"); caps.Categories.AddCategoryMapping(13, NewznabStandardCategory.TVSport, "Sport");
caps.Categories.AddCategoryMapping(15, NewznabStandardCategory.TV, "Desene"); caps.Categories.AddCategoryMapping(15, NewznabStandardCategory.TV, "Desene");
caps.Categories.AddCategoryMapping(16, NewznabStandardCategory.Books, "Docs"); caps.Categories.AddCategoryMapping(16, NewznabStandardCategory.Books, "Docs");
caps.Categories.AddCategoryMapping(17, NewznabStandardCategory.PC, "Linux"); caps.Categories.AddCategoryMapping(17, NewznabStandardCategory.PC, "Linux");
caps.Categories.AddCategoryMapping(18, NewznabStandardCategory.Other, "Diverse"); caps.Categories.AddCategoryMapping(18, NewznabStandardCategory.Other, "Diverse");
caps.Categories.AddCategoryMapping(19, NewznabStandardCategory.MoviesForeign, "Filme HD-RO"); caps.Categories.AddCategoryMapping(19, NewznabStandardCategory.MoviesForeign, "Filme HD-RO");
caps.Categories.AddCategoryMapping(20, NewznabStandardCategory.MoviesBluRay, "Filme Blu-Ray"); caps.Categories.AddCategoryMapping(20, NewznabStandardCategory.MoviesBluRay, "Filme Blu-Ray");
caps.Categories.AddCategoryMapping(21, NewznabStandardCategory.TVHD, "Seriale HD"); caps.Categories.AddCategoryMapping(21, NewznabStandardCategory.TVHD, "Seriale HD");
caps.Categories.AddCategoryMapping(22, NewznabStandardCategory.PCMobileOther, "Mobile"); caps.Categories.AddCategoryMapping(22, NewznabStandardCategory.PCMobileOther, "Mobile");
caps.Categories.AddCategoryMapping(23, NewznabStandardCategory.TVSD, "Seriale SD"); caps.Categories.AddCategoryMapping(23, NewznabStandardCategory.TVSD, "Seriale SD");
caps.Categories.AddCategoryMapping(24, NewznabStandardCategory.TVAnime, "Anime"); caps.Categories.AddCategoryMapping(24, NewznabStandardCategory.TVAnime, "Anime");
caps.Categories.AddCategoryMapping(25, NewznabStandardCategory.Movies3D, "Filme 3D"); caps.Categories.AddCategoryMapping(25, NewznabStandardCategory.Movies3D, "Filme 3D");
caps.Categories.AddCategoryMapping(26, NewznabStandardCategory.MoviesBluRay, "Filme 4K Blu-Ray"); caps.Categories.AddCategoryMapping(26, NewznabStandardCategory.MoviesBluRay, "Filme 4K Blu-Ray");
caps.Categories.AddCategoryMapping(27, NewznabStandardCategory.TVUHD, "Seriale 4K"); caps.Categories.AddCategoryMapping(27, NewznabStandardCategory.TVUHD, "Seriale 4K");
return caps; return caps;
}
} }
} }

@ -1,29 +1,28 @@
using Newtonsoft.Json; using Newtonsoft.Json;
namespace NzbDrone.Core.Indexers.FileList namespace NzbDrone.Core.Indexers.Definitions.FileList;
public class FileListTorrent
{ {
public class FileListTorrent public string Id { get; set; }
{ public string Name { get; set; }
public string Id { get; set; } public long Size { get; set; }
public string Name { get; set; } public int Leechers { get; set; }
public long Size { get; set; } public int Seeders { get; set; }
public int Leechers { get; set; } [JsonProperty(PropertyName = "times_completed")]
public int Seeders { get; set; } public uint TimesCompleted { get; set; }
[JsonProperty(PropertyName = "times_completed")] public uint Comments { get; set; }
public uint TimesCompleted { get; set; } public uint Files { get; set; }
public uint Comments { get; set; } [JsonProperty(PropertyName = "imdb")]
public uint Files { get; set; } public string ImdbId { get; set; }
[JsonProperty(PropertyName = "imdb")] public bool Internal { get; set; }
public string ImdbId { get; set; } [JsonProperty(PropertyName = "freeleech")]
public bool Internal { get; set; } public bool FreeLeech { get; set; }
[JsonProperty(PropertyName = "freeleech")] [JsonProperty(PropertyName = "doubleup")]
public bool FreeLeech { get; set; } public bool DoubleUp { get; set; }
[JsonProperty(PropertyName = "doubleup")] [JsonProperty(PropertyName = "upload_date")]
public bool DoubleUp { get; set; } public string UploadDate { get; set; }
[JsonProperty(PropertyName = "upload_date")] public string Category { get; set; }
public string UploadDate { get; set; } [JsonProperty(PropertyName = "small_description")]
public string Category { get; set; } public string SmallDescription { get; set; }
[JsonProperty(PropertyName = "small_description")]
public string SmallDescription { get; set; }
}
} }

@ -8,101 +8,105 @@ using NzbDrone.Common.Http;
using NzbDrone.Core.Indexers.Exceptions; using NzbDrone.Core.Indexers.Exceptions;
using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Parser.Model;
namespace NzbDrone.Core.Indexers.FileList namespace NzbDrone.Core.Indexers.Definitions.FileList;
public class FileListParser : IParseIndexerResponse
{ {
public class FileListParser : IParseIndexerResponse private readonly FileListSettings _settings;
private readonly IndexerCapabilitiesCategories _categories;
public FileListParser(FileListSettings settings, IndexerCapabilitiesCategories categories)
{ {
private readonly FileListSettings _settings; _settings = settings;
private readonly IndexerCapabilitiesCategories _categories; _categories = categories;
}
public FileListParser(FileListSettings settings, IndexerCapabilitiesCategories categories) public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
{
if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
{ {
_settings = settings; throw new IndexerException(indexerResponse, "Unexpected response status {0} code from API request", indexerResponse.HttpResponse.StatusCode);
_categories = categories;
} }
public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse) if (!indexerResponse.HttpResponse.Headers.ContentType.Contains(HttpAccept.Json.Value))
{ {
var torrentInfos = new List<ReleaseInfo>(); throw new IndexerException(indexerResponse, $"Unexpected response header {indexerResponse.HttpResponse.Headers.ContentType} from API request, expected {HttpAccept.Json.Value}");
}
var releaseInfos = new List<ReleaseInfo>();
if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK) var results = JsonConvert.DeserializeObject<List<FileListTorrent>>(indexerResponse.Content);
foreach (var row in results)
{
// skip non-freeleech results when freeleech only is set
if (_settings.FreeleechOnly && !row.FreeLeech)
{ {
throw new IndexerException(indexerResponse, "Unexpected response status {0} code from API request", indexerResponse.HttpResponse.StatusCode); continue;
} }
if (!indexerResponse.HttpResponse.Headers.ContentType.Contains(HttpAccept.Json.Value)) var id = row.Id;
var flags = new HashSet<IndexerFlag>();
if (row.Internal)
{ {
throw new IndexerException(indexerResponse, $"Unexpected response header {indexerResponse.HttpResponse.Headers.ContentType} from API request, expected {HttpAccept.Json.Value}"); flags.Add(IndexerFlag.Internal);
} }
var queryResults = JsonConvert.DeserializeObject<List<FileListTorrent>>(indexerResponse.Content); var imdbId = 0;
if (row.ImdbId != null && row.ImdbId.Length > 2)
foreach (var result in queryResults)
{ {
var id = result.Id; imdbId = int.Parse(row.ImdbId.Substring(2));
var flags = new HashSet<IndexerFlag>();
if (result.Internal)
{
flags.Add(IndexerFlag.Internal);
}
var imdbId = 0;
if (result.ImdbId != null && result.ImdbId.Length > 2)
{
imdbId = int.Parse(result.ImdbId.Substring(2));
}
var downloadVolumeFactor = result.FreeLeech ? 0 : 1;
var uploadVolumeFactor = result.DoubleUp ? 2 : 1;
torrentInfos.Add(new TorrentInfo
{
Guid = string.Format("FileList-{0}", id),
Title = result.Name,
Size = result.Size,
Categories = _categories.MapTrackerCatDescToNewznab(result.Category),
DownloadUrl = GetDownloadUrl(id),
InfoUrl = GetInfoUrl(id),
Seeders = result.Seeders,
Peers = result.Leechers + result.Seeders,
PublishDate = DateTime.Parse(result.UploadDate + " +0200", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal),
Description = result.SmallDescription,
Genres = result.SmallDescription.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).ToList(),
ImdbId = imdbId,
IndexerFlags = flags,
Files = (int)result.Files,
Grabs = (int)result.TimesCompleted,
DownloadVolumeFactor = downloadVolumeFactor,
UploadVolumeFactor = uploadVolumeFactor,
MinimumRatio = 1,
MinimumSeedTime = 172800, // 48 hours
});
} }
return torrentInfos.ToArray(); var downloadVolumeFactor = row.FreeLeech ? 0 : 1;
var uploadVolumeFactor = row.DoubleUp ? 2 : 1;
releaseInfos.Add(new TorrentInfo
{
Guid = string.Format("FileList-{0}", id),
Title = row.Name,
Size = row.Size,
Categories = _categories.MapTrackerCatDescToNewznab(row.Category),
DownloadUrl = GetDownloadUrl(id),
InfoUrl = GetInfoUrl(id),
Seeders = row.Seeders,
Peers = row.Leechers + row.Seeders,
PublishDate = DateTime.Parse(row.UploadDate + " +0200", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal),
Description = row.SmallDescription,
Genres = row.SmallDescription.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).ToList(),
ImdbId = imdbId,
IndexerFlags = flags,
Files = (int)row.Files,
Grabs = (int)row.TimesCompleted,
DownloadVolumeFactor = downloadVolumeFactor,
UploadVolumeFactor = uploadVolumeFactor,
MinimumRatio = 1,
MinimumSeedTime = 172800, // 48 hours
});
} }
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; } return releaseInfos.ToArray();
}
private string GetDownloadUrl(string torrentId) public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
{
var url = new HttpUri(_settings.BaseUrl)
.CombinePath("/download.php")
.AddQueryParam("id", torrentId)
.AddQueryParam("passkey", _settings.Passkey);
return url.FullUri; private string GetDownloadUrl(string torrentId)
} {
var url = new HttpUri(_settings.BaseUrl)
.CombinePath("/download.php")
.AddQueryParam("id", torrentId)
.AddQueryParam("passkey", _settings.Passkey);
private string GetInfoUrl(string torrentId) return url.FullUri;
{ }
var url = new HttpUri(_settings.BaseUrl)
.CombinePath("/details.php")
.AddQueryParam("id", torrentId);
return url.FullUri; private string GetInfoUrl(string torrentId)
} {
var url = new HttpUri(_settings.BaseUrl)
.CombinePath("/details.php")
.AddQueryParam("id", torrentId);
return url.FullUri;
} }
} }

@ -6,149 +6,148 @@ using NzbDrone.Common.Http;
using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.Parser; using NzbDrone.Core.Parser;
namespace NzbDrone.Core.Indexers.FileList namespace NzbDrone.Core.Indexers.Definitions.FileList;
{
public class FileListRequestGenerator : IIndexerRequestGenerator
{
public FileListSettings Settings { get; set; }
public IndexerCapabilities Capabilities { get; set; }
public Func<IDictionary<string, string>> GetCookies { get; set; }
public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
public IndexerPageableRequestChain GetSearchRequests(TvSearchCriteria searchCriteria)
{
var pageableRequests = new IndexerPageableRequestChain();
var parameters = GetDefaultParameters();
if (searchCriteria.ImdbId.IsNotNullOrWhiteSpace() || searchCriteria.SearchTerm.IsNotNullOrWhiteSpace()) public class FileListRequestGenerator : IIndexerRequestGenerator
{ {
parameters.Add("action", "search-torrents"); public FileListSettings Settings { get; set; }
public IndexerCapabilities Capabilities { get; set; }
if (searchCriteria.ImdbId.IsNotNullOrWhiteSpace()) public Func<IDictionary<string, string>> GetCookies { get; set; }
{ public Action<IDictionary<string, string>, DateTime?> CookiesUpdater { get; set; }
parameters.Add("type", "imdb");
parameters.Add("query", searchCriteria.FullImdbId);
}
else if (searchCriteria.SearchTerm.IsNotNullOrWhiteSpace())
{
parameters.Add("type", "name");
parameters.Add("query", searchCriteria.SanitizedSearchTerm.Trim());
}
if (searchCriteria.Season.HasValue)
{
parameters.Add("season", searchCriteria.Season.ToString());
parameters.Add("episode", searchCriteria.Episode);
}
}
pageableRequests.Add(GetRequest(searchCriteria, parameters));
return pageableRequests; public IndexerPageableRequestChain GetSearchRequests(TvSearchCriteria searchCriteria)
} {
var pageableRequests = new IndexerPageableRequestChain();
var parameters = GetDefaultParameters();
public virtual IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria) if (searchCriteria.ImdbId.IsNotNullOrWhiteSpace() || searchCriteria.SearchTerm.IsNotNullOrWhiteSpace())
{ {
var pageableRequests = new IndexerPageableRequestChain(); parameters.Add("action", "search-torrents");
var parameters = GetDefaultParameters();
if (searchCriteria.ImdbId.IsNotNullOrWhiteSpace()) if (searchCriteria.ImdbId.IsNotNullOrWhiteSpace())
{ {
parameters.Add("action", "search-torrents");
parameters.Add("type", "imdb"); parameters.Add("type", "imdb");
parameters.Add("query", searchCriteria.FullImdbId); parameters.Add("query", searchCriteria.FullImdbId);
} }
else if (searchCriteria.SearchTerm.IsNotNullOrWhiteSpace()) else if (searchCriteria.SearchTerm.IsNotNullOrWhiteSpace())
{ {
parameters.Add("action", "search-torrents");
parameters.Add("type", "name"); parameters.Add("type", "name");
parameters.Add("query", searchCriteria.SanitizedSearchTerm.Trim()); parameters.Add("query", searchCriteria.SanitizedSearchTerm.Trim());
} }
pageableRequests.Add(GetRequest(searchCriteria, parameters)); if (searchCriteria.Season.HasValue)
{
return pageableRequests; parameters.Add("season", searchCriteria.Season.ToString());
parameters.Add("episode", searchCriteria.Episode);
}
} }
public IndexerPageableRequestChain GetSearchRequests(MusicSearchCriteria searchCriteria) pageableRequests.Add(GetRequest(searchCriteria, parameters));
{
var pageableRequests = new IndexerPageableRequestChain();
var parameters = GetDefaultParameters();
if (searchCriteria.SearchTerm.IsNotNullOrWhiteSpace()) return pageableRequests;
{ }
parameters.Add("action", "search-torrents");
parameters.Add("type", "name");
parameters.Add("query", searchCriteria.SanitizedSearchTerm.Trim());
}
pageableRequests.Add(GetRequest(searchCriteria, parameters)); public virtual IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria)
{
var pageableRequests = new IndexerPageableRequestChain();
var parameters = GetDefaultParameters();
return pageableRequests; if (searchCriteria.ImdbId.IsNotNullOrWhiteSpace())
{
parameters.Add("action", "search-torrents");
parameters.Add("type", "imdb");
parameters.Add("query", searchCriteria.FullImdbId);
} }
else if (searchCriteria.SearchTerm.IsNotNullOrWhiteSpace())
public IndexerPageableRequestChain GetSearchRequests(BookSearchCriteria searchCriteria)
{ {
var pageableRequests = new IndexerPageableRequestChain(); parameters.Add("action", "search-torrents");
var parameters = GetDefaultParameters(); parameters.Add("type", "name");
parameters.Add("query", searchCriteria.SanitizedSearchTerm.Trim());
}
if (searchCriteria.SearchTerm.IsNotNullOrWhiteSpace()) pageableRequests.Add(GetRequest(searchCriteria, parameters));
{
parameters.Add("action", "search-torrents");
parameters.Add("type", "name");
parameters.Add("query", searchCriteria.SanitizedSearchTerm.Trim());
}
pageableRequests.Add(GetRequest(searchCriteria, parameters)); return pageableRequests;
}
return pageableRequests; public IndexerPageableRequestChain GetSearchRequests(MusicSearchCriteria searchCriteria)
} {
var pageableRequests = new IndexerPageableRequestChain();
var parameters = GetDefaultParameters();
public IndexerPageableRequestChain GetSearchRequests(BasicSearchCriteria searchCriteria) if (searchCriteria.SearchTerm.IsNotNullOrWhiteSpace())
{ {
var pageableRequests = new IndexerPageableRequestChain(); parameters.Add("action", "search-torrents");
var parameters = GetDefaultParameters(); parameters.Add("type", "name");
parameters.Add("query", searchCriteria.SanitizedSearchTerm.Trim());
}
if (searchCriteria.SearchTerm.IsNotNullOrWhiteSpace()) pageableRequests.Add(GetRequest(searchCriteria, parameters));
{
parameters.Add("action", "search-torrents");
parameters.Add("type", "name");
parameters.Add("query", searchCriteria.SanitizedSearchTerm.Trim());
}
pageableRequests.Add(GetRequest(searchCriteria, parameters)); return pageableRequests;
}
return pageableRequests; public IndexerPageableRequestChain GetSearchRequests(BookSearchCriteria searchCriteria)
} {
var pageableRequests = new IndexerPageableRequestChain();
var parameters = GetDefaultParameters();
private IEnumerable<IndexerRequest> GetRequest(SearchCriteriaBase searchCriteria, NameValueCollection parameters) if (searchCriteria.SearchTerm.IsNotNullOrWhiteSpace())
{ {
if (parameters.Get("action") is null) parameters.Add("action", "search-torrents");
{ parameters.Add("type", "name");
parameters.Add("action", "latest-torrents"); parameters.Add("query", searchCriteria.SanitizedSearchTerm.Trim());
} }
parameters.Add("category", string.Join(",", Capabilities.Categories.MapTorznabCapsToTrackers(searchCriteria.Categories))); pageableRequests.Add(GetRequest(searchCriteria, parameters));
var searchUrl = $"{Settings.BaseUrl.TrimEnd('/')}/api.php?{parameters.GetQueryString()}"; return pageableRequests;
}
yield return new IndexerRequest(searchUrl, HttpAccept.Json); public IndexerPageableRequestChain GetSearchRequests(BasicSearchCriteria searchCriteria)
{
var pageableRequests = new IndexerPageableRequestChain();
var parameters = GetDefaultParameters();
if (searchCriteria.SearchTerm.IsNotNullOrWhiteSpace())
{
parameters.Add("action", "search-torrents");
parameters.Add("type", "name");
parameters.Add("query", searchCriteria.SanitizedSearchTerm.Trim());
} }
private NameValueCollection GetDefaultParameters() pageableRequests.Add(GetRequest(searchCriteria, parameters));
return pageableRequests;
}
private IEnumerable<IndexerRequest> GetRequest(SearchCriteriaBase searchCriteria, NameValueCollection parameters)
{
if (parameters.Get("action") is null)
{ {
var parameters = new NameValueCollection parameters.Add("action", "latest-torrents");
{ }
{ "username", Settings.Username.Trim() },
{ "passkey", Settings.Passkey.Trim() }
};
if (Settings.FreeleechOnly) parameters.Add("category", string.Join(",", Capabilities.Categories.MapTorznabCapsToTrackers(searchCriteria.Categories)));
{
parameters.Add("freeleech", "1"); var searchUrl = $"{Settings.BaseUrl.TrimEnd('/')}/api.php?{parameters.GetQueryString()}";
}
return parameters; yield return new IndexerRequest(searchUrl, HttpAccept.Json);
}
private NameValueCollection GetDefaultParameters()
{
var parameters = new NameValueCollection
{
{ "username", Settings.Username.Trim() },
{ "passkey", Settings.Passkey.Trim() }
};
if (Settings.FreeleechOnly)
{
parameters.Add("freeleech", "1");
} }
return parameters;
} }
} }

@ -3,33 +3,32 @@ using NzbDrone.Core.Annotations;
using NzbDrone.Core.Indexers.Settings; using NzbDrone.Core.Indexers.Settings;
using NzbDrone.Core.Validation; using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.FileList namespace NzbDrone.Core.Indexers.Definitions.FileList;
public class FileListSettingsValidator : NoAuthSettingsValidator<FileListSettings>
{ {
public class FileListSettingsValidator : NoAuthSettingsValidator<FileListSettings> public FileListSettingsValidator()
{ {
public FileListSettingsValidator() RuleFor(c => c.Username).NotEmpty();
{ RuleFor(c => c.Passkey).NotEmpty();
RuleFor(c => c.Username).NotEmpty();
RuleFor(c => c.Passkey).NotEmpty();
}
} }
}
public class FileListSettings : NoAuthTorrentBaseSettings public class FileListSettings : NoAuthTorrentBaseSettings
{ {
private static readonly FileListSettingsValidator Validator = new (); private static readonly FileListSettingsValidator Validator = new ();
[FieldDefinition(2, Label = "Username", HelpText = "Site Username", Privacy = PrivacyLevel.UserName)] [FieldDefinition(2, Label = "Username", HelpText = "Site Username", Privacy = PrivacyLevel.UserName)]
public string Username { get; set; } public string Username { get; set; }
[FieldDefinition(3, Label = "Passkey", HelpText = "Site Passkey (This is the alphanumeric string in the tracker url shown in your download client)", Privacy = PrivacyLevel.Password, Type = FieldType.Password)] [FieldDefinition(3, Label = "Passkey", HelpText = "Site Passkey (This is the alphanumeric string in the tracker url shown in your download client)", Privacy = PrivacyLevel.Password, Type = FieldType.Password)]
public string Passkey { get; set; } public string Passkey { get; set; }
[FieldDefinition(4, Label = "Freeleech Only", HelpText = "Search Freeleech torrents only", Type = FieldType.Checkbox)] [FieldDefinition(4, Label = "Freeleech Only", HelpText = "Search Freeleech torrents only", Type = FieldType.Checkbox)]
public bool FreeleechOnly { get; set; } public bool FreeleechOnly { get; set; }
public override NzbDroneValidationResult Validate() public override NzbDroneValidationResult Validate()
{ {
return new NzbDroneValidationResult(Validator.Validate(this)); return new NzbDroneValidationResult(Validator.Validate(this));
}
} }
} }

@ -1,13 +1,10 @@
using System.Collections.Generic;
using System.Threading; using System.Threading;
using Microsoft.Extensions.Configuration;
using NLog; using NLog;
using Npgsql;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Migration.Framework; using NzbDrone.Core.Datastore.Migration.Framework;
using NzbDrone.Core.Indexers.FileList; using NzbDrone.Core.Indexers.Definitions.FileList;
using NzbDrone.Test.Common; using NzbDrone.Test.Common;
using NzbDrone.Test.Common.Datastore; using NzbDrone.Test.Common.Datastore;
using Prowlarr.Http.ClientSchema; using Prowlarr.Http.ClientSchema;

Loading…
Cancel
Save