2020-02-09 02:35:16 +00:00
|
|
|
using System;
|
2017-04-15 08:45:10 +00:00
|
|
|
using System.Collections.Generic;
|
2017-10-29 06:50:47 +00:00
|
|
|
using System.Collections.Specialized;
|
2020-05-03 23:35:52 +00:00
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2017-04-15 08:45:10 +00:00
|
|
|
using System.Text;
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
using System.Threading.Tasks;
|
2019-01-20 00:09:27 +00:00
|
|
|
using AngleSharp.Html.Parser;
|
2018-03-10 08:05:56 +00:00
|
|
|
using Jackett.Common.Models;
|
|
|
|
using Jackett.Common.Models.IndexerConfig;
|
|
|
|
using Jackett.Common.Services.Interfaces;
|
|
|
|
using Jackett.Common.Utils;
|
|
|
|
using Jackett.Common.Utils.Clients;
|
2017-10-29 06:50:47 +00:00
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
using NLog;
|
2017-04-15 08:45:10 +00:00
|
|
|
|
2018-03-10 08:05:56 +00:00
|
|
|
namespace Jackett.Common.Indexers
|
2017-04-15 08:45:10 +00:00
|
|
|
{
|
2020-05-03 23:35:52 +00:00
|
|
|
[ExcludeFromCodeCoverage]
|
2020-05-11 22:58:10 +00:00
|
|
|
public class PixelHD : BaseWebIndexer
|
2017-04-15 08:45:10 +00:00
|
|
|
{
|
2020-02-25 16:08:03 +00:00
|
|
|
private string LoginUrl => SiteLink + "login.php";
|
|
|
|
private string BrowseUrl => SiteLink + "torrents.php";
|
2017-04-15 08:45:10 +00:00
|
|
|
|
2017-10-29 06:50:47 +00:00
|
|
|
private new ConfigurationDataCaptchaLogin configData
|
2017-01-17 18:47:47 +00:00
|
|
|
{
|
2020-02-25 16:08:03 +00:00
|
|
|
get => (ConfigurationDataCaptchaLogin)base.configData;
|
|
|
|
set => base.configData = value;
|
2017-04-15 08:45:10 +00:00
|
|
|
}
|
|
|
|
|
2017-10-29 06:50:47 +00:00
|
|
|
private string input_captcha = null;
|
|
|
|
private string input_username = null;
|
|
|
|
private string input_password = null;
|
2017-04-15 08:45:10 +00:00
|
|
|
|
2020-05-11 22:58:10 +00:00
|
|
|
public PixelHD(IIndexerConfigurationService configService, WebClient webClient, Logger logger, IProtectionService protectionService)
|
2020-05-11 19:59:28 +00:00
|
|
|
: base(id: "pixelhd",
|
|
|
|
name: "PiXELHD",
|
|
|
|
description: "PixelHD (PxHD) is a Private Torrent Tracker for HD .MP4 MOVIES / TV",
|
|
|
|
link: "https://pixelhd.me/",
|
|
|
|
caps: new TorznabCapabilities
|
|
|
|
{
|
|
|
|
SupportsImdbMovieSearch = true
|
|
|
|
},
|
|
|
|
configService: configService,
|
|
|
|
logger: logger,
|
|
|
|
p: protectionService,
|
|
|
|
client: webClient,
|
|
|
|
configData: new ConfigurationDataCaptchaLogin()
|
2017-01-17 18:47:47 +00:00
|
|
|
)
|
2017-04-15 08:45:10 +00:00
|
|
|
{
|
2017-11-05 09:42:03 +00:00
|
|
|
Encoding = Encoding.UTF8;
|
2017-04-15 08:45:10 +00:00
|
|
|
Language = "en-us";
|
|
|
|
Type = "private";
|
|
|
|
|
|
|
|
AddCategoryMapping(1, TorznabCatType.MoviesHD);
|
|
|
|
}
|
|
|
|
|
|
|
|
public override async Task<ConfigurationData> GetConfigurationForSetup()
|
|
|
|
{
|
2020-09-21 06:02:53 +00:00
|
|
|
var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
|
2017-04-15 08:45:10 +00:00
|
|
|
var LoginParser = new HtmlParser();
|
2020-06-09 17:36:57 +00:00
|
|
|
var LoginDocument = LoginParser.ParseDocument(loginPage.ContentString);
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
|
|
configData.CaptchaCookie.Value = loginPage.Cookies;
|
|
|
|
|
|
|
|
var catchaImg = LoginDocument.QuerySelector("img[alt=\"FuckOff Image\"]");
|
|
|
|
if (catchaImg != null)
|
|
|
|
{
|
|
|
|
var catchaInput = LoginDocument.QuerySelector("input[maxlength=\"6\"]");
|
|
|
|
input_captcha = catchaInput.GetAttribute("name");
|
|
|
|
|
2020-09-21 06:02:53 +00:00
|
|
|
var captchaImage = await RequestBytesWithCookies(SiteLink + catchaImg.GetAttribute("src"), loginPage.Cookies, RequestType.GET, LoginUrl);
|
2020-03-14 23:58:50 +00:00
|
|
|
configData.CaptchaImage.Value = captchaImage.ContentBytes;
|
2017-04-15 08:45:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
input_captcha = null;
|
|
|
|
configData.CaptchaImage.Value = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
var usernameInput = LoginDocument.QuerySelector("input[maxlength=\"20\"]");
|
|
|
|
input_username = usernameInput.GetAttribute("name");
|
|
|
|
|
|
|
|
var passwordInput = LoginDocument.QuerySelector("input[maxlength=\"40\"]");
|
|
|
|
input_password = passwordInput.GetAttribute("name");
|
2017-10-29 06:50:47 +00:00
|
|
|
|
2017-04-15 08:45:10 +00:00
|
|
|
return configData;
|
|
|
|
}
|
|
|
|
|
2017-06-28 05:31:38 +00:00
|
|
|
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
|
2017-04-15 08:45:10 +00:00
|
|
|
{
|
2017-01-17 18:47:47 +00:00
|
|
|
configData.LoadValuesFromJson(configJson);
|
|
|
|
|
|
|
|
var pairs = new Dictionary<string, string>
|
|
|
|
{
|
|
|
|
{ input_username, configData.Username.Value },
|
|
|
|
{ input_password, configData.Password.Value },
|
|
|
|
{ "keeplogged", "1" }
|
2017-04-15 08:45:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
if (input_captcha != null)
|
|
|
|
pairs.Add(input_captcha, configData.CaptchaText.Value);
|
|
|
|
|
|
|
|
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, configData.CaptchaCookie.Value, true);
|
|
|
|
|
2020-06-09 17:36:57 +00:00
|
|
|
await ConfigureIfOK(result.Cookies, result.ContentString.Contains("logout.php"), () =>
|
2017-04-15 08:45:10 +00:00
|
|
|
{
|
|
|
|
var LoginParser = new HtmlParser();
|
2020-06-09 17:36:57 +00:00
|
|
|
var LoginDocument = LoginParser.ParseDocument(result.ContentString);
|
2018-01-05 17:56:54 +00:00
|
|
|
var errorMessage = LoginDocument.QuerySelector("span.warning[id!=\"no-cookies\"]:has(br)").TextContent;
|
2017-04-15 08:45:10 +00:00
|
|
|
throw new ExceptionWithConfigData(errorMessage, configData);
|
|
|
|
});
|
|
|
|
|
|
|
|
return IndexerConfigurationStatus.RequiresTesting;
|
|
|
|
}
|
|
|
|
|
2017-07-03 05:15:47 +00:00
|
|
|
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
|
2017-04-15 08:45:10 +00:00
|
|
|
{
|
|
|
|
var releases = new List<ReleaseInfo>();
|
|
|
|
var searchString = query.GetQueryString();
|
2020-03-26 22:15:28 +00:00
|
|
|
var queryCollection = new NameValueCollection
|
|
|
|
{
|
|
|
|
{ "order_by", "time" },
|
|
|
|
{ "order_way", "desc" }
|
|
|
|
};
|
2017-04-15 08:45:10 +00:00
|
|
|
|
2017-01-17 18:47:47 +00:00
|
|
|
if (!string.IsNullOrWhiteSpace(query.ImdbID))
|
|
|
|
{
|
|
|
|
queryCollection.Add("imdbid", query.ImdbID);
|
|
|
|
}
|
|
|
|
else if (!string.IsNullOrWhiteSpace(searchString))
|
|
|
|
{
|
|
|
|
queryCollection.Add("groupname", searchString);
|
2017-04-15 08:45:10 +00:00
|
|
|
}
|
2020-03-26 22:15:28 +00:00
|
|
|
//Add anyway after checking above?
|
2017-04-15 08:45:10 +00:00
|
|
|
queryCollection.Add("groupname", searchString);
|
|
|
|
|
|
|
|
var searchUrl = BrowseUrl + "?" + queryCollection.GetQueryString();
|
|
|
|
|
2020-09-21 06:02:53 +00:00
|
|
|
var results = await RequestStringWithCookies(searchUrl);
|
2017-04-15 08:45:10 +00:00
|
|
|
if (results.IsRedirect)
|
|
|
|
{
|
|
|
|
// re login
|
|
|
|
await GetConfigurationForSetup();
|
|
|
|
await ApplyConfiguration(null);
|
2020-09-21 06:02:53 +00:00
|
|
|
results = await RequestStringWithCookies(searchUrl);
|
2017-04-15 08:45:10 +00:00
|
|
|
}
|
|
|
|
|
2020-02-10 22:16:19 +00:00
|
|
|
var IMDBRegEx = new Regex(@"tt(\d+)", RegexOptions.Compiled);
|
2017-04-15 08:45:10 +00:00
|
|
|
var hParser = new HtmlParser();
|
2020-06-09 17:36:57 +00:00
|
|
|
var ResultDocument = hParser.ParseDocument(results.ContentString);
|
2017-01-17 18:47:47 +00:00
|
|
|
try
|
|
|
|
{
|
|
|
|
var Groups = ResultDocument.QuerySelectorAll("div.browsePoster");
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
|
|
foreach (var Group in Groups)
|
|
|
|
{
|
|
|
|
var groupPoster = Group.QuerySelector("img.classBrowsePoster");
|
|
|
|
var bannerURL = new Uri(SiteLink + groupPoster.GetAttribute("src"));
|
|
|
|
|
|
|
|
long? IMDBId = null;
|
2019-10-06 21:56:47 +00:00
|
|
|
var imdbLink = Group.QuerySelector("a[href*=\"www.imdb.com/title/tt\"]");
|
2017-04-15 08:45:10 +00:00
|
|
|
if (imdbLink != null)
|
|
|
|
{
|
|
|
|
var IMDBMatch = IMDBRegEx.Match(imdbLink.GetAttribute("href"));
|
|
|
|
IMDBId = ParseUtil.CoerceLong(IMDBMatch.Groups[1].Value);
|
2017-01-17 18:47:47 +00:00
|
|
|
}
|
2017-04-15 08:45:10 +00:00
|
|
|
|
2020-03-26 22:15:28 +00:00
|
|
|
var group = Group.QuerySelector("strong:has(a[title=\"View Torrent\"])").TextContent.Replace(" ]", "]");
|
2017-04-15 08:45:10 +00:00
|
|
|
|
|
|
|
var Rows = Group.QuerySelectorAll("tr.group_torrent:has(a[href^=\"torrents.php?id=\"])");
|
|
|
|
foreach (var Row in Rows)
|
|
|
|
{
|
|
|
|
var title = Row.QuerySelector("a[href^=\"torrents.php?id=\"]");
|
|
|
|
var added = Row.QuerySelector("td:nth-child(3)");
|
|
|
|
var Size = Row.QuerySelector("td:nth-child(4)");
|
|
|
|
var Grabs = Row.QuerySelector("td:nth-child(6)");
|
|
|
|
var Seeders = Row.QuerySelector("td:nth-child(7)");
|
|
|
|
var Leechers = Row.QuerySelector("td:nth-child(8)");
|
2020-03-26 22:15:28 +00:00
|
|
|
var link = new Uri(SiteLink + Row.QuerySelector("a[href^=\"torrents.php?action=download\"]").GetAttribute("href"));
|
|
|
|
var seeders = ParseUtil.CoerceInt(Seeders.TextContent);
|
|
|
|
var comments = new Uri(SiteLink + title.GetAttribute("href"));
|
|
|
|
var size = ReleaseInfo.GetBytes(Size.TextContent);
|
|
|
|
var leechers = ParseUtil.CoerceInt(Leechers.TextContent);
|
|
|
|
var grabs = ParseUtil.CoerceLong(Grabs.TextContent);
|
|
|
|
var publishDate = DateTimeUtil.FromTimeAgo(added.TextContent);
|
|
|
|
var release = new ReleaseInfo
|
|
|
|
{
|
|
|
|
MinimumRatio = 1,
|
|
|
|
MinimumSeedTime = 72 * 60 * 60,
|
|
|
|
Title = group + " " + title.TextContent,
|
2020-04-07 16:17:17 +00:00
|
|
|
Category = new List<int> { TorznabCatType.MoviesHD.ID },
|
2020-03-26 22:15:28 +00:00
|
|
|
Link = link,
|
|
|
|
Comments = comments,
|
|
|
|
Guid = link,
|
|
|
|
Size = size,
|
|
|
|
Seeders = seeders,
|
|
|
|
Peers = leechers + seeders,
|
|
|
|
Grabs = grabs,
|
|
|
|
PublishDate = publishDate,
|
|
|
|
BannerUrl = bannerURL,
|
|
|
|
Imdb = IMDBId
|
|
|
|
};
|
2017-04-15 08:45:10 +00:00
|
|
|
releases.Add(release);
|
|
|
|
}
|
|
|
|
}
|
2017-01-17 18:47:47 +00:00
|
|
|
}
|
|
|
|
catch (Exception ex)
|
2017-04-15 08:45:10 +00:00
|
|
|
{
|
2020-06-09 17:36:57 +00:00
|
|
|
OnParseError(results.ContentString, ex);
|
2017-01-17 18:47:47 +00:00
|
|
|
}
|
|
|
|
|
2017-04-15 08:45:10 +00:00
|
|
|
return releases;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|