|
|
|
@ -7,10 +7,9 @@ using System.Text;
|
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using AngleSharp.Html.Parser;
|
|
|
|
|
using FluentValidation;
|
|
|
|
|
using NLog;
|
|
|
|
|
using NzbDrone.Common.Extensions;
|
|
|
|
|
using NzbDrone.Common.Http;
|
|
|
|
|
using NzbDrone.Core.Annotations;
|
|
|
|
|
using NzbDrone.Core.Configuration;
|
|
|
|
|
using NzbDrone.Core.Indexers.Exceptions;
|
|
|
|
|
using NzbDrone.Core.Indexers.Settings;
|
|
|
|
@ -18,21 +17,20 @@ using NzbDrone.Core.IndexerSearch.Definitions;
|
|
|
|
|
using NzbDrone.Core.Messaging.Events;
|
|
|
|
|
using NzbDrone.Core.Parser;
|
|
|
|
|
using NzbDrone.Core.Parser.Model;
|
|
|
|
|
using NzbDrone.Core.Validation;
|
|
|
|
|
|
|
|
|
|
namespace NzbDrone.Core.Indexers.Definitions
|
|
|
|
|
{
|
|
|
|
|
public class HDSpace : TorrentIndexerBase<UserPassTorrentBaseSettings>
|
|
|
|
|
{
|
|
|
|
|
public override string Name => "HD-Space";
|
|
|
|
|
public override string[] IndexerUrls => new string[] { "https://hd-space.org/" };
|
|
|
|
|
private string LoginUrl => Settings.BaseUrl + "index.php?page=login";
|
|
|
|
|
public override string[] IndexerUrls => new[] { "https://hd-space.org/" };
|
|
|
|
|
public override string Description => "HD-Space (HDS) is a Private Torrent Tracker for HD MOVIES / TV";
|
|
|
|
|
public override string Language => "en-US";
|
|
|
|
|
public override Encoding Encoding => Encoding.UTF8;
|
|
|
|
|
public override DownloadProtocol Protocol => DownloadProtocol.Torrent;
|
|
|
|
|
public override IndexerPrivacy Privacy => IndexerPrivacy.Private;
|
|
|
|
|
public override IndexerCapabilities Capabilities => SetCapabilities();
|
|
|
|
|
private string LoginUrl => Settings.BaseUrl + "index.php?page=login";
|
|
|
|
|
|
|
|
|
|
public HDSpace(IIndexerHttpClient httpClient, IEventAggregator eventAggregator, IIndexerStatusService indexerStatusService, IConfigService configService, Logger logger)
|
|
|
|
|
: base(httpClient, eventAggregator, indexerStatusService, configService, logger)
|
|
|
|
@ -41,7 +39,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|
|
|
|
|
|
|
|
|
public override IIndexerRequestGenerator GetRequestGenerator()
|
|
|
|
|
{
|
|
|
|
|
return new HDSpaceRequestGenerator() { Settings = Settings, Capabilities = Capabilities };
|
|
|
|
|
return new HDSpaceRequestGenerator { Settings = Settings, Capabilities = Capabilities };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override IParseIndexerResponse GetParser()
|
|
|
|
@ -56,10 +54,10 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|
|
|
|
var requestBuilder = new HttpRequestBuilder(LoginUrl)
|
|
|
|
|
{
|
|
|
|
|
LogResponseContent = true,
|
|
|
|
|
AllowAutoRedirect = true
|
|
|
|
|
AllowAutoRedirect = true,
|
|
|
|
|
Method = HttpMethod.Post
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
requestBuilder.Method = HttpMethod.Post;
|
|
|
|
|
requestBuilder.PostProcess += r => r.RequestTimeout = TimeSpan.FromSeconds(15);
|
|
|
|
|
|
|
|
|
|
var cookies = Cookies;
|
|
|
|
@ -70,7 +68,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|
|
|
|
.AddFormParameter("uid", Settings.Username)
|
|
|
|
|
.AddFormParameter("pwd", Settings.Password)
|
|
|
|
|
.SetCookies(loginPage.GetCookies())
|
|
|
|
|
.SetHeader("Content-Type", "multipart/form-data")
|
|
|
|
|
.SetHeader("Content-Type", "application/x-www-form-urlencoded")
|
|
|
|
|
.SetHeader("Referer", LoginUrl)
|
|
|
|
|
.Build();
|
|
|
|
|
|
|
|
|
@ -108,17 +106,17 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|
|
|
|
var caps = new IndexerCapabilities
|
|
|
|
|
{
|
|
|
|
|
TvSearchParams = new List<TvSearchParam>
|
|
|
|
|
{
|
|
|
|
|
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep, TvSearchParam.ImdbId
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
TvSearchParam.Q, TvSearchParam.Season, TvSearchParam.Ep, TvSearchParam.ImdbId
|
|
|
|
|
},
|
|
|
|
|
MovieSearchParams = new List<MovieSearchParam>
|
|
|
|
|
{
|
|
|
|
|
MovieSearchParam.Q, MovieSearchParam.ImdbId
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
MovieSearchParam.Q, MovieSearchParam.ImdbId
|
|
|
|
|
},
|
|
|
|
|
MusicSearchParams = new List<MusicSearchParam>
|
|
|
|
|
{
|
|
|
|
|
MusicSearchParam.Q
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
MusicSearchParam.Q
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
caps.Categories.AddCategoryMapping(15, NewznabStandardCategory.MoviesBluRay, "Movie / Blu-ray");
|
|
|
|
@ -155,10 +153,6 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|
|
|
|
public UserPassTorrentBaseSettings Settings { get; set; }
|
|
|
|
|
public IndexerCapabilities Capabilities { get; set; }
|
|
|
|
|
|
|
|
|
|
public HDSpaceRequestGenerator()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IEnumerable<IndexerRequest> GetPagedRequests(string term, int[] categories, string imdb = null)
|
|
|
|
|
{
|
|
|
|
|
var searchUrl = string.Format("{0}/index.php?page=torrents&", Settings.BaseUrl.TrimEnd('/'));
|
|
|
|
@ -249,7 +243,7 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|
|
|
|
|
|
|
|
|
var resultParser = new HtmlParser();
|
|
|
|
|
var searchResultDocument = resultParser.ParseDocument(indexerResponse.Content);
|
|
|
|
|
var rows = searchResultDocument.QuerySelectorAll("table.lista > tbody > tr");
|
|
|
|
|
var rows = searchResultDocument.QuerySelectorAll("div#bodyarea table.lista:not(:contains(\"Our Team Recommend\")) > tbody > tr:has(a[href^=\"index.php?page=torrent-details&id=\"])");
|
|
|
|
|
|
|
|
|
|
foreach (var row in rows)
|
|
|
|
|
{
|
|
|
|
@ -264,12 +258,27 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|
|
|
|
release.MinimumRatio = 1;
|
|
|
|
|
release.MinimumSeedTime = 86400; // 24 hours
|
|
|
|
|
|
|
|
|
|
var qLink = row.Children[1].FirstElementChild;
|
|
|
|
|
release.Title = qLink.TextContent.Trim();
|
|
|
|
|
release.InfoUrl = _settings.BaseUrl + qLink.GetAttribute("href");
|
|
|
|
|
var qLink = row.QuerySelector("td:nth-child(2) a[href^=\"index.php?page=torrent-details&id=\"]");
|
|
|
|
|
release.Title = qLink?.TextContent.Trim();
|
|
|
|
|
release.InfoUrl = _settings.BaseUrl + qLink?.GetAttribute("href");
|
|
|
|
|
release.Guid = release.InfoUrl;
|
|
|
|
|
|
|
|
|
|
var qGenres = row.QuerySelector("span[style=\"color: #000000 \"]");
|
|
|
|
|
var downloadUrl = row.QuerySelector("td:nth-child(4) a[href^=\"download.php?id=\"]")?.GetAttribute("href");
|
|
|
|
|
release.DownloadUrl = _settings.BaseUrl + downloadUrl;
|
|
|
|
|
|
|
|
|
|
// Use the torrent filename as release title
|
|
|
|
|
var torrentTitle = ParseUtil.GetArgumentFromQueryString(downloadUrl, "f")?
|
|
|
|
|
.Replace("&", "&")
|
|
|
|
|
.Replace("'", "'")
|
|
|
|
|
.Replace(".torrent", "")
|
|
|
|
|
.Trim();
|
|
|
|
|
|
|
|
|
|
if (torrentTitle.IsNotNullOrWhiteSpace())
|
|
|
|
|
{
|
|
|
|
|
release.Title = torrentTitle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var qGenres = row.QuerySelector("td:nth-child(2) span[style=\"color: #000000 \"]");
|
|
|
|
|
if (qGenres != null)
|
|
|
|
|
{
|
|
|
|
|
var description = qGenres.TextContent.Split('\xA0').Last().Replace(" ", "");
|
|
|
|
@ -277,25 +286,18 @@ namespace NzbDrone.Core.Indexers.Definitions
|
|
|
|
|
release.Genres = description.Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var imdbLink = row.Children[1].QuerySelector("a[href*=imdb]");
|
|
|
|
|
var imdbLink = row.QuerySelector("td:nth-child(2) a[href*=imdb]");
|
|
|
|
|
if (imdbLink != null)
|
|
|
|
|
{
|
|
|
|
|
release.ImdbId = ParseUtil.GetImdbID(imdbLink.GetAttribute("href").Split('/').Last()).GetValueOrDefault();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var qDownload = row.Children[3].FirstElementChild;
|
|
|
|
|
release.DownloadUrl = _settings.BaseUrl + qDownload.GetAttribute("href");
|
|
|
|
|
|
|
|
|
|
var dateStr = row.Children[4].TextContent.Trim();
|
|
|
|
|
|
|
|
|
|
//"July 11, 2015, 13:34:09", "Today|Yesterday at 20:04:23"
|
|
|
|
|
release.PublishDate = DateTimeUtil.FromUnknown(dateStr);
|
|
|
|
|
var sizeStr = row.Children[5].TextContent;
|
|
|
|
|
release.Size = ParseUtil.GetBytes(sizeStr);
|
|
|
|
|
release.Seeders = ParseUtil.CoerceInt(row.Children[7].TextContent);
|
|
|
|
|
release.Peers = ParseUtil.CoerceInt(row.Children[8].TextContent) + release.Seeders;
|
|
|
|
|
var grabs = row.QuerySelector("td:nth-child(10)").TextContent;
|
|
|
|
|
grabs = grabs.Replace("---", "0");
|
|
|
|
|
release.PublishDate = DateTimeUtil.FromUnknown(row.QuerySelector("td:nth-child(5)")?.TextContent.Trim());
|
|
|
|
|
release.Size = ParseUtil.GetBytes(row.QuerySelector("td:nth-child(6)")?.TextContent.Trim());
|
|
|
|
|
release.Seeders = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(8)")?.TextContent);
|
|
|
|
|
release.Peers = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(9)")?.TextContent) + release.Seeders;
|
|
|
|
|
var grabs = row.QuerySelector("td:nth-child(10)")?.TextContent.Trim().Replace("---", "0");
|
|
|
|
|
release.Grabs = ParseUtil.CoerceInt(grabs);
|
|
|
|
|
|
|
|
|
|
if (row.QuerySelector("img[title=\"FreeLeech\"]") != null)
|
|
|
|
|