mirror of
https://github.com/Radarr/Radarr
synced 2024-12-26 09:49:00 +00:00
Added TorrentPotato Indexer.
This commit is contained in:
parent
a63587bb19
commit
7a5fe59dbf
7 changed files with 321 additions and 0 deletions
64
src/NzbDrone.Core/Indexers/TorrentPotato/TorrentPotato.cs
Normal file
64
src/NzbDrone.Core/Indexers/TorrentPotato/TorrentPotato.cs
Normal file
|
@ -0,0 +1,64 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Exceptions;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Core.Http.CloudFlare;
|
||||
using NzbDrone.Core.Parser;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.TorrentPotato
|
||||
{
|
||||
public class TorrentPotato : HttpIndexerBase<TorrentPotatoSettings>
|
||||
{
|
||||
public override string Name => "TorrentPotato";
|
||||
|
||||
public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
|
||||
public override TimeSpan RateLimit => TimeSpan.FromSeconds(2);
|
||||
|
||||
public TorrentPotato(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
||||
: base(httpClient, indexerStatusService, configService, parsingService, logger)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override IEnumerable<ProviderDefinition> DefaultDefinitions
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return GetDefinition("Jackett", new TorrentPotatoSettings { BaseUrl = "http://localhost:9117/potato/YOURINDEXER"});
|
||||
}
|
||||
}
|
||||
|
||||
private IndexerDefinition GetDefinition(string name, TorrentPotatoSettings settings)
|
||||
{
|
||||
return new IndexerDefinition
|
||||
{
|
||||
EnableRss = false,
|
||||
EnableSearch = false,
|
||||
Name = name,
|
||||
Implementation = GetType().Name,
|
||||
Settings = settings,
|
||||
Protocol = DownloadProtocol.Torrent,
|
||||
SupportsRss = SupportsRss,
|
||||
SupportsSearch = SupportsSearch
|
||||
};
|
||||
}
|
||||
|
||||
public override IIndexerRequestGenerator GetRequestGenerator()
|
||||
{
|
||||
return new TorrentPotatoRequestGenerator() { Settings = Settings };
|
||||
}
|
||||
|
||||
public override IParseIndexerResponse GetParser()
|
||||
{
|
||||
return new TorrentPotatoParser();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.Indexers.Exceptions;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.TorrentPotato
|
||||
{
|
||||
public class TorrentPotatoParser : IParseIndexerResponse
|
||||
{
|
||||
private static readonly Regex RegexGuid = new Regex(@"^magnet:\?xt=urn:btih:([a-f0-9]+)", RegexOptions.Compiled);
|
||||
|
||||
public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
|
||||
{
|
||||
var results = new List<ReleaseInfo>();
|
||||
|
||||
switch (indexerResponse.HttpResponse.StatusCode)
|
||||
{
|
||||
default:
|
||||
if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
throw new IndexerException(indexerResponse, "Indexer API call returned an unexpected StatusCode [{0}]", indexerResponse.HttpResponse.StatusCode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var jsonResponse = new HttpResponse<TorrentPotatoResponse>(indexerResponse.HttpResponse);
|
||||
|
||||
foreach (var torrent in jsonResponse.Resource.results)
|
||||
{
|
||||
var torrentInfo = new TorrentInfo();
|
||||
|
||||
torrentInfo.Guid = GetGuid(torrent);
|
||||
torrentInfo.Title = torrent.release_name;
|
||||
torrentInfo.Size = (long)torrent.size*1000*1000;
|
||||
torrentInfo.DownloadUrl = torrent.download_url;
|
||||
torrentInfo.InfoUrl = torrent.details_url;
|
||||
torrentInfo.PublishDate = new System.DateTime();
|
||||
torrentInfo.Seeders = torrent.seeders;
|
||||
torrentInfo.Peers = torrent.leechers + torrent.seeders;
|
||||
torrentInfo.Freeleech = torrent.freeleech;
|
||||
|
||||
results.Add(torrentInfo);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private string GetGuid(Result torrent)
|
||||
{
|
||||
var match = RegexGuid.Match(torrent.download_url);
|
||||
|
||||
if (match.Success)
|
||||
{
|
||||
return string.Format("potato-{0}", match.Groups[1].Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Format("potato-{0}", torrent.download_url);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.TorrentPotato
|
||||
{
|
||||
public class TorrentPotatoRequestGenerator : IIndexerRequestGenerator
|
||||
{
|
||||
|
||||
public TorrentPotatoSettings Settings { get; set; }
|
||||
|
||||
public TorrentPotatoRequestGenerator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual IndexerPageableRequestChain GetRecentRequests()
|
||||
{
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
pageableRequests.Add(GetPagedRequests("list", null, null));
|
||||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
||||
public virtual IndexerPageableRequestChain GetSearchRequests(SingleEpisodeSearchCriteria searchCriteria)
|
||||
{
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
pageableRequests.Add(GetPagedRequests("search", searchCriteria.Series.TvdbId, "S{0:00}E{1:00}", searchCriteria.SeasonNumber, searchCriteria.EpisodeNumber));
|
||||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
||||
public virtual IndexerPageableRequestChain GetSearchRequests(SeasonSearchCriteria searchCriteria)
|
||||
{
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
pageableRequests.Add(GetPagedRequests("search", searchCriteria.Series.TvdbId, "S{0:00}", searchCriteria.SeasonNumber));
|
||||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
||||
public virtual IndexerPageableRequestChain GetSearchRequests(DailyEpisodeSearchCriteria searchCriteria)
|
||||
{
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
pageableRequests.Add(GetPagedRequests("search", searchCriteria.Series.TvdbId, "\"{0:yyyy MM dd}\"", searchCriteria.AirDate));
|
||||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
||||
public virtual IndexerPageableRequestChain GetSearchRequests(AnimeEpisodeSearchCriteria searchCriteria)
|
||||
{
|
||||
return new IndexerPageableRequestChain();
|
||||
}
|
||||
|
||||
public virtual IndexerPageableRequestChain GetSearchRequests(SpecialEpisodeSearchCriteria searchCriteria)
|
||||
{
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
foreach (var queryTitle in searchCriteria.EpisodeQueryTitles)
|
||||
{
|
||||
var query = queryTitle.Replace('+', ' ');
|
||||
query = System.Web.HttpUtility.UrlEncode(query);
|
||||
|
||||
pageableRequests.Add(GetPagedRequests("search", searchCriteria.Series.TvdbId, query));
|
||||
}
|
||||
|
||||
return pageableRequests;
|
||||
}
|
||||
|
||||
private IEnumerable<IndexerRequest> GetPagedRequests(string mode, int? tvdbId, string query, params object[] args)
|
||||
{
|
||||
var requestBuilder = new HttpRequestBuilder(Settings.BaseUrl)
|
||||
.Accept(HttpAccept.Json);
|
||||
|
||||
requestBuilder.AddQueryParam("passkey", Settings.Passkey);
|
||||
requestBuilder.AddQueryParam("user", Settings.User);
|
||||
requestBuilder.AddQueryParam("imdbid", "tt0076759"); //For now just search for Star Wars.
|
||||
|
||||
|
||||
|
||||
yield return new IndexerRequest(requestBuilder.Build());
|
||||
}
|
||||
|
||||
private IEnumerable<IndexerRequest> GetMovieRequest(MovieSearchCriteria searchCriteria)
|
||||
{
|
||||
var requestBuilder = new HttpRequestBuilder(Settings.BaseUrl)
|
||||
.Accept(HttpAccept.Json);
|
||||
|
||||
requestBuilder.AddQueryParam("passkey", Settings.Passkey);
|
||||
requestBuilder.AddQueryParam("user", Settings.User);
|
||||
|
||||
if (searchCriteria.Movie.ImdbId.IsNotNullOrWhiteSpace())
|
||||
{
|
||||
requestBuilder.AddQueryParam("imdbid", searchCriteria.Movie.ImdbId);
|
||||
}
|
||||
else
|
||||
{
|
||||
requestBuilder.AddQueryParam("search", searchCriteria.Movie.Title);
|
||||
}
|
||||
|
||||
yield return new IndexerRequest(requestBuilder.Build());
|
||||
}
|
||||
|
||||
public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria)
|
||||
{
|
||||
|
||||
|
||||
var pageableRequests = new IndexerPageableRequestChain();
|
||||
|
||||
pageableRequests.Add(GetMovieRequest(searchCriteria));
|
||||
|
||||
return pageableRequests;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.TorrentPotato
|
||||
{
|
||||
|
||||
public class TorrentPotatoResponse
|
||||
{
|
||||
public Result[] results { get; set; }
|
||||
public int total_results { get; set; }
|
||||
}
|
||||
|
||||
public class Result
|
||||
{
|
||||
public string release_name { get; set; }
|
||||
public string torrent_id { get; set; }
|
||||
public string details_url { get; set; }
|
||||
public string download_url { get; set; }
|
||||
public bool freeleech { get; set; }
|
||||
public string type { get; set; }
|
||||
public int size { get; set; }
|
||||
public int leechers { get; set; }
|
||||
public int seeders { get; set; }
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
using FluentValidation;
|
||||
using NzbDrone.Core.Annotations;
|
||||
using NzbDrone.Core.ThingiProvider;
|
||||
using NzbDrone.Core.Validation;
|
||||
|
||||
namespace NzbDrone.Core.Indexers.TorrentPotato
|
||||
{
|
||||
public class TorrentPotatoSettingsValidator : AbstractValidator<TorrentPotatoSettings>
|
||||
{
|
||||
public TorrentPotatoSettingsValidator()
|
||||
{
|
||||
RuleFor(c => c.BaseUrl).ValidRootUrl();
|
||||
}
|
||||
}
|
||||
|
||||
public class TorrentPotatoSettings : IProviderConfig
|
||||
{
|
||||
private static readonly TorrentPotatoSettingsValidator Validator = new TorrentPotatoSettingsValidator();
|
||||
|
||||
public TorrentPotatoSettings()
|
||||
{
|
||||
BaseUrl = "";
|
||||
}
|
||||
|
||||
[FieldDefinition(0, Label = "API URL", HelpText = "URL to TorrentPotato api.")]
|
||||
public string BaseUrl { get; set; }
|
||||
|
||||
[FieldDefinition(1, Label = "Username", HelpText = "The username you use at your indexer.")]
|
||||
public string User { get; set; }
|
||||
|
||||
[FieldDefinition(2, Label = "Passkey", HelpText = "The password you use at your Indexer,")]
|
||||
public string Passkey { get; set; }
|
||||
public NzbDroneValidationResult Validate()
|
||||
{
|
||||
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -633,6 +633,11 @@
|
|||
<Compile Include="Indexers\Omgwtfnzbs\OmgwtfnzbsRssParser.cs" />
|
||||
<Compile Include="Indexers\Omgwtfnzbs\OmgwtfnzbsSettings.cs" />
|
||||
<Compile Include="Indexers\HttpIndexerBase.cs" />
|
||||
<Compile Include="Indexers\TorrentPotato\TorrentPotato.cs" />
|
||||
<Compile Include="Indexers\TorrentPotato\TorrentPotatoParser.cs" />
|
||||
<Compile Include="Indexers\TorrentPotato\TorrentPotatoRequestGenerator.cs" />
|
||||
<Compile Include="Indexers\TorrentPotato\TorrentPotatoResponse.cs" />
|
||||
<Compile Include="Indexers\TorrentPotato\TorrentPotatoSettings.cs" />
|
||||
<Compile Include="Indexers\Rarbg\Rarbg.cs" />
|
||||
<Compile Include="Indexers\Rarbg\RarbgRequestGenerator.cs" />
|
||||
<Compile Include="Indexers\Rarbg\RarbgResponse.cs" />
|
||||
|
|
|
@ -8,6 +8,7 @@ public class TorrentInfo : ReleaseInfo
|
|||
public string InfoHash { get; set; }
|
||||
public int? Seeders { get; set; }
|
||||
public int? Peers { get; set; }
|
||||
public bool Freeleech { get; set; }
|
||||
|
||||
public static int? GetSeeders(ReleaseInfo release)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue