mirror of
https://github.com/lidarr/lidarr.git
synced 2025-08-22 22:43:31 -07:00
initial awesomeHD support
This commit is contained in:
parent
abf4b137f1
commit
b93a9719fe
6 changed files with 305 additions and 0 deletions
30
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHD.cs
Normal file
30
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHD.cs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Core.Configuration;
|
||||||
|
using NzbDrone.Core.Parser;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Indexers.AwesomeHD
|
||||||
|
{
|
||||||
|
public class AwesomeHD : HttpIndexerBase<AwesomeHDSettings>
|
||||||
|
{
|
||||||
|
public override string Name => "AwesomeHD";
|
||||||
|
public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
|
||||||
|
public override bool SupportsRss => false;
|
||||||
|
public override bool SupportsSearch => true;
|
||||||
|
public override int PageSize => 50;
|
||||||
|
|
||||||
|
public AwesomeHD(IHttpClient httpClient, IIndexerStatusService indexerStatusService, IConfigService configService, IParsingService parsingService, Logger logger)
|
||||||
|
: base(httpClient, indexerStatusService, configService, parsingService, logger)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public override IIndexerRequestGenerator GetRequestGenerator()
|
||||||
|
{
|
||||||
|
return new AwesomeHDRequestGenerator() { Settings = Settings };
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IParseIndexerResponse GetParser()
|
||||||
|
{
|
||||||
|
return new AwesomeHDRssParser(Settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
80
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDApi.cs
Normal file
80
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDApi.cs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
using System;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Indexers.AwesomeHD
|
||||||
|
{
|
||||||
|
public class Torrent
|
||||||
|
{
|
||||||
|
[XmlElement(ElementName = "id")]
|
||||||
|
public string Id { get; set; }
|
||||||
|
[XmlElement(ElementName = "groupid")]
|
||||||
|
public string GroupId { get; set; }
|
||||||
|
[XmlElement(ElementName = "time")]
|
||||||
|
public DateTime Time { get; set; }
|
||||||
|
[XmlElement(ElementName = "userid")]
|
||||||
|
public string Userid { get; set; }
|
||||||
|
[XmlElement(ElementName = "size")]
|
||||||
|
public long Size { get; set; }
|
||||||
|
[XmlElement(ElementName = "snatched")]
|
||||||
|
public string Snatched { get; set; }
|
||||||
|
[XmlElement(ElementName = "seeders")]
|
||||||
|
public string Seeders { get; set; }
|
||||||
|
[XmlElement(ElementName = "leechers")]
|
||||||
|
public string Leechers { get; set; }
|
||||||
|
[XmlElement(ElementName = "releasegroup")]
|
||||||
|
public string Releasegroup { get; set; }
|
||||||
|
[XmlElement(ElementName = "resolution")]
|
||||||
|
public string Resolution { get; set; }
|
||||||
|
[XmlElement(ElementName = "media")]
|
||||||
|
public string Media { get; set; }
|
||||||
|
[XmlElement(ElementName = "format")]
|
||||||
|
public string Format { get; set; }
|
||||||
|
[XmlElement(ElementName = "encoding")]
|
||||||
|
public string Encoding { get; set; }
|
||||||
|
[XmlElement(ElementName = "audioformat")]
|
||||||
|
public string Audioformat { get; set; }
|
||||||
|
[XmlElement(ElementName = "audiobitrate")]
|
||||||
|
public string Audiobitrate { get; set; }
|
||||||
|
[XmlElement(ElementName = "audiochannels")]
|
||||||
|
public string Audiochannels { get; set; }
|
||||||
|
[XmlElement(ElementName = "subtitles")]
|
||||||
|
public string Subtitles { get; set; }
|
||||||
|
[XmlElement(ElementName = "encodestatus")]
|
||||||
|
public string Encodestatus { get; set; }
|
||||||
|
[XmlElement(ElementName = "freeleech")]
|
||||||
|
public string Freeleech { get; set; }
|
||||||
|
[XmlElement(ElementName = "cover")]
|
||||||
|
public string Cover { get; set; }
|
||||||
|
[XmlElement(ElementName = "smallcover")]
|
||||||
|
public string Smallcover { get; set; }
|
||||||
|
[XmlElement(ElementName = "year")]
|
||||||
|
public string Year { get; set; }
|
||||||
|
[XmlElement(ElementName = "name")]
|
||||||
|
public string Name { get; set; }
|
||||||
|
[XmlElement(ElementName = "imdb")]
|
||||||
|
public string Imdb { get; set; }
|
||||||
|
[XmlElement(ElementName = "type")]
|
||||||
|
public string Type { get; set; }
|
||||||
|
[XmlElement(ElementName = "plotoutline")]
|
||||||
|
public string Plotoutline { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SearchResults
|
||||||
|
{
|
||||||
|
[XmlElement(ElementName = "authkey")]
|
||||||
|
public string AuthKey { get; set; }
|
||||||
|
[XmlElement(ElementName = "torrent")]
|
||||||
|
public List<Torrent> Torrent { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AwesomeHDSearchResponse
|
||||||
|
{
|
||||||
|
[XmlElement(ElementName = "?xml")]
|
||||||
|
public string Xml { get; set; }
|
||||||
|
[XmlElement(ElementName = "searchresults")]
|
||||||
|
public SearchResults SearchResults { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Common.Serializer;
|
||||||
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Indexers.AwesomeHD
|
||||||
|
{
|
||||||
|
public class AwesomeHDRequestGenerator : IIndexerRequestGenerator
|
||||||
|
{
|
||||||
|
public AwesomeHDSettings Settings { get; set; }
|
||||||
|
|
||||||
|
public virtual IndexerPageableRequestChain GetRecentRequests()
|
||||||
|
{
|
||||||
|
var pageableRequests = new IndexerPageableRequestChain();
|
||||||
|
|
||||||
|
pageableRequests.Add(GetRequest("tt2488496"));
|
||||||
|
|
||||||
|
return pageableRequests;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual IndexerPageableRequestChain GetSearchRequests(SingleEpisodeSearchCriteria searchCriteria)
|
||||||
|
{
|
||||||
|
return new IndexerPageableRequestChain();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual IndexerPageableRequestChain GetSearchRequests(AnimeEpisodeSearchCriteria searchCriteria)
|
||||||
|
{
|
||||||
|
return new IndexerPageableRequestChain();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual IndexerPageableRequestChain GetSearchRequests(SpecialEpisodeSearchCriteria searchCriteria)
|
||||||
|
{
|
||||||
|
return new IndexerPageableRequestChain();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual IndexerPageableRequestChain GetSearchRequests(DailyEpisodeSearchCriteria searchCriteria)
|
||||||
|
{
|
||||||
|
return new IndexerPageableRequestChain();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual IndexerPageableRequestChain GetSearchRequests(SeasonSearchCriteria searchCriteria)
|
||||||
|
{
|
||||||
|
return new IndexerPageableRequestChain();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria searchCriteria)
|
||||||
|
{
|
||||||
|
var pageableRequests = new IndexerPageableRequestChain();
|
||||||
|
pageableRequests.Add(GetRequest(searchCriteria.Movie.ImdbId));
|
||||||
|
return pageableRequests;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<IndexerRequest> GetRequest(string searchParameters)
|
||||||
|
{
|
||||||
|
var request = new IndexerRequest(string.Format("{0}/searchapi.php?action=imdbsearch&passkey={1}&imdb={2}", Settings.BaseUrl.Trim().TrimEnd('/'), Settings.Passkey.Trim(), searchParameters), HttpAccept.Rss);
|
||||||
|
yield return request;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
92
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDRssParser.cs
Normal file
92
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDRssParser.cs
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using NzbDrone.Common.Http;
|
||||||
|
using NzbDrone.Core.Indexers.Exceptions;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Indexers.AwesomeHD
|
||||||
|
{
|
||||||
|
public class AwesomeHDRssParser : IParseIndexerResponse
|
||||||
|
{
|
||||||
|
private readonly AwesomeHDSettings _settings;
|
||||||
|
|
||||||
|
public AwesomeHDRssParser(AwesomeHDSettings settings)
|
||||||
|
{
|
||||||
|
_settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IList<ReleaseInfo> ParseResponse(IndexerResponse indexerResponse)
|
||||||
|
{
|
||||||
|
var torrentInfos = new List<ReleaseInfo>();
|
||||||
|
|
||||||
|
if (indexerResponse.HttpResponse.StatusCode != HttpStatusCode.OK)
|
||||||
|
{
|
||||||
|
throw new IndexerException(indexerResponse,
|
||||||
|
"Unexpected response status {0} code from API request",
|
||||||
|
indexerResponse.HttpResponse.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hacky ¯\_(ツ)_/¯
|
||||||
|
XmlDocument doc = new XmlDocument();
|
||||||
|
doc.LoadXml(indexerResponse.Content);
|
||||||
|
|
||||||
|
var json = JsonConvert.SerializeXmlNode(doc);
|
||||||
|
|
||||||
|
Console.WriteLine(json);
|
||||||
|
|
||||||
|
var jsonResponse = JsonConvert.DeserializeObject<AwesomeHDSearchResponse>(json);
|
||||||
|
|
||||||
|
if (jsonResponse == null)
|
||||||
|
{
|
||||||
|
throw new IndexerException(indexerResponse, "Unexpected response from request");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var torrent in jsonResponse.SearchResults.Torrent)
|
||||||
|
{
|
||||||
|
var id = torrent.Id;
|
||||||
|
var title = $"{torrent.Name}.{torrent.Year}.{torrent.Resolution}.{torrent.Media}.{torrent.Encoding}.{torrent.Audioformat}-{torrent.Releasegroup}";
|
||||||
|
|
||||||
|
torrentInfos.Add(new TorrentInfo()
|
||||||
|
{
|
||||||
|
Guid = string.Format("AwesomeHD-{0}", id),
|
||||||
|
Title = title,
|
||||||
|
Size = torrent.Size,
|
||||||
|
DownloadUrl = GetDownloadUrl(id, jsonResponse.SearchResults.AuthKey, _settings.Passkey),
|
||||||
|
InfoUrl = GetInfoUrl(torrent.GroupId, id),
|
||||||
|
Seeders = int.Parse(torrent.Seeders),
|
||||||
|
Peers = int.Parse(torrent.Leechers) + int.Parse(torrent.Seeders),
|
||||||
|
PublishDate = torrent.Time.ToUniversalTime()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return torrentInfos.OrderByDescending(o => ((dynamic)o).Seeders).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetDownloadUrl(string torrentId, string authKey, string passKey)
|
||||||
|
{
|
||||||
|
var url = new HttpUri(_settings.BaseUrl)
|
||||||
|
.CombinePath("/torrents.php")
|
||||||
|
.AddQueryParam("action", "download")
|
||||||
|
.AddQueryParam("id", torrentId)
|
||||||
|
.AddQueryParam("authkey", authKey)
|
||||||
|
.AddQueryParam("torrent_pass", passKey);
|
||||||
|
|
||||||
|
return url.FullUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetInfoUrl(string groupId, string torrentId)
|
||||||
|
{
|
||||||
|
var url = new HttpUri(_settings.BaseUrl)
|
||||||
|
.CombinePath("/torrents.php")
|
||||||
|
.AddQueryParam("id", groupId)
|
||||||
|
.AddQueryParam("torrentid", torrentId);
|
||||||
|
|
||||||
|
return url.FullUri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
37
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDSettings.cs
Normal file
37
src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDSettings.cs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
using FluentValidation;
|
||||||
|
using NzbDrone.Core.Annotations;
|
||||||
|
using NzbDrone.Core.ThingiProvider;
|
||||||
|
using NzbDrone.Core.Validation;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Indexers.AwesomeHD
|
||||||
|
{
|
||||||
|
public class AwesomeHDSettingsValidator : AbstractValidator<AwesomeHDSettings>
|
||||||
|
{
|
||||||
|
public AwesomeHDSettingsValidator()
|
||||||
|
{
|
||||||
|
RuleFor(c => c.BaseUrl).ValidRootUrl();
|
||||||
|
RuleFor(c => c.Passkey).NotEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AwesomeHDSettings : IProviderConfig
|
||||||
|
{
|
||||||
|
private static readonly AwesomeHDSettingsValidator Validator = new AwesomeHDSettingsValidator();
|
||||||
|
|
||||||
|
public AwesomeHDSettings()
|
||||||
|
{
|
||||||
|
BaseUrl = "https://awesome-hd.me";
|
||||||
|
}
|
||||||
|
|
||||||
|
[FieldDefinition(0, Label = "API URL", Advanced = true, HelpText = "Do not change this unless you know what you're doing. Since you Passkey will be sent to that host.")]
|
||||||
|
public string BaseUrl { get; set; }
|
||||||
|
|
||||||
|
[FieldDefinition(1, Label = "Passkey")]
|
||||||
|
public string Passkey { get; set; }
|
||||||
|
|
||||||
|
public NzbDroneValidationResult Validate()
|
||||||
|
{
|
||||||
|
return new NzbDroneValidationResult(Validator.Validate(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -578,6 +578,7 @@
|
||||||
<Compile Include="IndexerSearch\Definitions\MovieSearchCriteria.cs" />
|
<Compile Include="IndexerSearch\Definitions\MovieSearchCriteria.cs" />
|
||||||
<Compile Include="IndexerSearch\MoviesSearchCommand.cs" />
|
<Compile Include="IndexerSearch\MoviesSearchCommand.cs" />
|
||||||
<Compile Include="IndexerSearch\MoviesSearchService.cs" />
|
<Compile Include="IndexerSearch\MoviesSearchService.cs" />
|
||||||
|
<Compile Include="Indexers\AwesomeHD\AwesomeHDRssParser.cs" />
|
||||||
<Compile Include="Indexers\DownloadProtocol.cs" />
|
<Compile Include="Indexers\DownloadProtocol.cs" />
|
||||||
<Compile Include="Indexers\Exceptions\ApiKeyException.cs" />
|
<Compile Include="Indexers\Exceptions\ApiKeyException.cs" />
|
||||||
<Compile Include="Indexers\Exceptions\IndexerException.cs" />
|
<Compile Include="Indexers\Exceptions\IndexerException.cs" />
|
||||||
|
@ -585,6 +586,10 @@
|
||||||
<Compile Include="Indexers\Exceptions\UnsupportedFeedException.cs" />
|
<Compile Include="Indexers\Exceptions\UnsupportedFeedException.cs" />
|
||||||
<Compile Include="Indexers\EzrssTorrentRssParser.cs" />
|
<Compile Include="Indexers\EzrssTorrentRssParser.cs" />
|
||||||
<Compile Include="Indexers\FetchAndParseRssService.cs" />
|
<Compile Include="Indexers\FetchAndParseRssService.cs" />
|
||||||
|
<Compile Include="Indexers\AwesomeHD\AwesomeHD.cs" />
|
||||||
|
<Compile Include="Indexers\AwesomeHD\AwesomeHDApi.cs" />
|
||||||
|
<Compile Include="Indexers\AwesomeHD\AwesomeHDRequestGenerator.cs" />
|
||||||
|
<Compile Include="Indexers\AwesomeHD\AwesomeHDSettings.cs" />
|
||||||
<Compile Include="Indexers\PassThePopcorn\PassThePopcorn.cs" />
|
<Compile Include="Indexers\PassThePopcorn\PassThePopcorn.cs" />
|
||||||
<Compile Include="Indexers\PassThePopcorn\PassThePopcornApi.cs" />
|
<Compile Include="Indexers\PassThePopcorn\PassThePopcornApi.cs" />
|
||||||
<Compile Include="Indexers\PassThePopcorn\PassThePopcornInfo.cs" />
|
<Compile Include="Indexers\PassThePopcorn\PassThePopcornInfo.cs" />
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue