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 > ( ) ;
2015-07-18 20:35:02 +00:00
var searchString = query . SanitizedSearchTerm + " " + query . GetEpisodeSearchString ( ) ;
for ( int page = 0 ; page < MAXPAGES ; page + + )
2015-07-12 15:48:37 +00:00
{
2015-07-18 20:35:02 +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-18 20:35:02 +00:00
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-18 20:35:02 +00:00
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 )
{
2015-07-18 08:52:26 +00:00
return client . GetByteArrayAsync ( link ) ;
2015-07-11 19:27:57 +00:00
}
}
}