Jackett/src/Jackett/Indexers/HDTorrents.cs

220 lines
8.5 KiB
C#
Raw Normal View History

2015-07-11 19:27:57 +00:00
using CsQuery;
2015-07-19 00:27:41 +00:00
using Jackett.Models;
2015-07-19 17:18:54 +00:00
using Jackett.Services;
2015-07-19 00:27:41 +00:00
using Jackett.Utils;
2015-07-11 19:27:57 +00:00
using Newtonsoft.Json.Linq;
2015-07-19 00:27:41 +00:00
using NLog;
2015-07-11 19:27:57 +00:00
using System;
using System.Collections.Generic;
2015-07-12 15:48:37 +00:00
using System.Globalization;
2015-07-11 19:27:57 +00:00
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
2015-07-12 15:48:37 +00:00
using System.Web;
2015-07-11 19:27:57 +00:00
namespace Jackett.Indexers
{
2015-07-19 17:18:54 +00:00
public class HDTorrents : BaseIndexer, IIndexer
2015-07-11 19:27:57 +00:00
{
2015-07-19 17:18:54 +00:00
private readonly string SearchUrl = "";
private static string LoginUrl = "";
2015-07-12 15:48:37 +00:00
private const int MAXPAGES = 3;
2015-07-11 19:27:57 +00:00
CookieContainer cookies;
HttpClientHandler handler;
HttpClient client;
2015-07-19 17:18:54 +00:00
public HDTorrents(IIndexerManagerService i, Logger l) :
base(name: "HD-Torrents",
description: "HD-Torrents is a private torrent website with HD torrents and strict rules on their content.",
link: new Uri("http://hdts.ru"),// Of the accessible domains the .ru seems the most reliable. https://hdts.ru | https://hd-torrents.org | https://hd-torrents.net | https://hd-torrents.me
rageid: true,
manager: i,
logger: l)
2015-07-11 19:27:57 +00:00
{
2015-07-19 17:18:54 +00:00
SearchUrl = SiteLink + "/torrents.php?search={0}&active=1&options=0&category%5B%5D=59&category%5B%5D=60&category%5B%5D=30&category%5B%5D=38&page={1}";
LoginUrl = SiteLink + "/login.php";
2015-07-11 19:27:57 +00:00
cookies = new CookieContainer();
handler = new HttpClientHandler
{
CookieContainer = cookies,
AllowAutoRedirect = true,
UseCookies = true,
};
client = new HttpClient(handler);
}
2015-07-12 15:48:37 +00:00
public Task<ConfigurationData> GetConfigurationForSetup()
2015-07-11 19:27:57 +00:00
{
var config = new ConfigurationDataBasicLogin();
2015-07-12 15:48:37 +00:00
return Task.FromResult<ConfigurationData>(config);
2015-07-11 19:27:57 +00:00
}
2015-07-12 15:48:37 +00:00
HttpRequestMessage CreateHttpRequest(string url)
2015-07-11 19:27:57 +00:00
{
var message = new HttpRequestMessage();
message.Method = HttpMethod.Get;
2015-07-12 15:48:37 +00:00
message.RequestUri = new Uri(url);
2015-07-19 17:18:54 +00:00
message.Headers.UserAgent.ParseAdd(BrowserUtil.ChromeUserAgent);
2015-07-11 19:27:57 +00:00
return message;
}
public async Task ApplyConfiguration(JToken configJson)
{
var config = new ConfigurationDataBasicLogin();
config.LoadValuesFromJson(configJson);
2015-07-12 15:48:37 +00:00
var startMessage = CreateHttpRequest(LoginUrl);
var results = await (await client.SendAsync(startMessage)).Content.ReadAsStringAsync();
2015-07-11 19:27:57 +00:00
var pairs = new Dictionary<string, string> {
{ "uid", config.Username.Value },
{ "pwd", config.Password.Value }
};
2015-07-12 16:23:40 +00:00
2015-07-11 19:27:57 +00:00
var content = new FormUrlEncodedContent(pairs);
2015-07-12 16:23:40 +00:00
2015-07-12 15:48:37 +00:00
var loginRequest = CreateHttpRequest(LoginUrl);
loginRequest.Method = HttpMethod.Post;
loginRequest.Content = content;
loginRequest.Headers.Referrer = new Uri("https://hd-torrents.org/torrents.php");
2015-07-11 19:27:57 +00:00
2015-07-12 15:48:37 +00:00
var response = await client.SendAsync(loginRequest);
2015-07-11 19:27:57 +00:00
var responseContent = await response.Content.ReadAsStringAsync();
2015-07-12 15:48:37 +00:00
if (!responseContent.Contains("If your browser doesn't have javascript enabled"))
2015-07-11 19:27:57 +00:00
{
2015-07-12 15:48:37 +00:00
var errorMessage = "Couldn't login";
2015-07-11 19:27:57 +00:00
throw new ExceptionWithConfigData(errorMessage, (ConfigurationData)config);
}
else
{
var configSaveData = new JObject();
2015-07-12 16:23:40 +00:00
cookies.DumpToJson(SiteLink, configSaveData);
2015-07-19 17:18:54 +00:00
SaveConfig(configSaveData);
2015-07-11 19:27:57 +00:00
IsConfigured = true;
}
}
public void LoadFromSavedConfiguration(JToken jsonConfig)
{
2015-07-19 00:27:41 +00:00
cookies.FillFromJson(SiteLink, jsonConfig, logger);
2015-07-11 19:27:57 +00:00
IsConfigured = true;
}
2015-07-19 17:18:54 +00:00
async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query, Uri baseUrl)
2015-07-11 19:27:57 +00:00
{
List<ReleaseInfo> releases = new List<ReleaseInfo>();
2015-07-12 15:48:37 +00:00
List<string> searchurls = new List<string>();
var searchString = query.SanitizedSearchTerm + " " + query.GetEpisodeSearchString();
for (int page = 0; page < MAXPAGES; page++)
2015-07-12 15:48:37 +00:00
{
searchurls.Add(string.Format(SearchUrl, HttpUtility.UrlEncode(searchString.Trim()), page));
2015-07-12 15:48:37 +00:00
}
foreach (string SearchUrl in searchurls)
{
var results = await client.GetStringAsync(SearchUrl);
try
{
CQ dom = results;
ReleaseInfo release;
int rowCount = 0;
var rows = dom[".mainblockcontenttt > tbody > tr"];
foreach (var row in rows)
{
CQ qRow = row.Cq();
if (rowCount < 2 || qRow.Children().Count() != 12) //skip 2 rows because there's an empty row & a title/sort row
{
rowCount++;
continue;
}
release = new ReleaseInfo();
long? size;
release.Title = qRow.Find("td.mainblockcontent b a").Text();
release.Description = release.Title;
2015-07-12 17:58:46 +00:00
if (0 != qRow.Find("td.mainblockcontent u").Length)
2015-07-12 19:50:24 +00:00
{
var imdbStr = qRow.Find("td.mainblockcontent u").Parent().First().Attr("href").Replace("http://www.imdb.com/title/tt", "").Replace("/", "");
long imdb;
if (ParseUtil.TryCoerceLong(imdbStr, out imdb))
{
release.Imdb = imdb;
}
}
2015-07-12 15:48:37 +00:00
release.MinimumRatio = 1;
release.MinimumSeedTime = 172800;
2015-07-12 15:48:37 +00:00
2015-07-12 19:50:24 +00:00
int seeders, peers;
if (ParseUtil.TryCoerceInt(qRow.Find("td").Get(9).FirstChild.FirstChild.InnerText, out seeders))
{
release.Seeders = seeders;
if (ParseUtil.TryCoerceInt(qRow.Find("td").Get(10).FirstChild.FirstChild.InnerText, out peers))
{
release.Peers = peers + release.Seeders;
}
}
2015-07-12 15:48:37 +00:00
string fullSize = qRow.Find("td.mainblockcontent").Get(6).InnerText;
string[] sizeSplit = fullSize.Split(' ');
switch (sizeSplit[1].ToLower())
{
case "kb":
2015-07-12 17:52:32 +00:00
size = ReleaseInfo.BytesFromKB(ParseUtil.CoerceFloat(sizeSplit[0]));
2015-07-12 15:48:37 +00:00
break;
case "mb":
2015-07-12 17:52:32 +00:00
size = ReleaseInfo.BytesFromMB(ParseUtil.CoerceFloat(sizeSplit[0]));
2015-07-12 15:48:37 +00:00
break;
case "gb":
2015-07-12 17:52:32 +00:00
size = ReleaseInfo.BytesFromGB(ParseUtil.CoerceFloat(sizeSplit[0]));
2015-07-12 15:48:37 +00:00
break;
default:
size = null;
break;
}
release.Size = size;
2015-07-19 17:18:54 +00:00
release.Guid = new Uri(SiteLink + "/" + qRow.Find("td.mainblockcontent b a").Attr("href"));
release.Link = new Uri(SiteLink + "/" + qRow.Find("td.mainblockcontent").Get(3).FirstChild.GetAttribute("href"));
release.Comments = new Uri(SiteLink + "/" + qRow.Find("td.mainblockcontent b a").Attr("href") + "#comments");
2015-07-12 15:48:37 +00:00
string[] dateSplit = qRow.Find("td.mainblockcontent").Get(5).InnerHTML.Split(',');
string dateString = dateSplit[1].Substring(0, dateSplit[1].IndexOf('>'));
release.PublishDate = DateTime.Parse(dateString, CultureInfo.InvariantCulture);
2015-07-12 15:48:37 +00:00
releases.Add(release);
}
}
catch (Exception ex)
{
2015-07-19 17:18:54 +00:00
OnParseError( results, ex);
2015-07-12 15:48:37 +00:00
}
}
2015-07-11 19:27:57 +00:00
return releases.ToArray();
}
public async Task<ReleaseInfo[]> PerformQuery(TorznabQuery query)
{
2015-07-19 17:18:54 +00:00
return await PerformQuery(query, SiteLink);
2015-07-11 19:27:57 +00:00
}
public Task<byte[]> Download(Uri link)
{
return client.GetByteArrayAsync(link);
2015-07-11 19:27:57 +00:00
}
}
}