2015-09-04 18:16:40 +00:00
using CsQuery ;
using Jackett.Models ;
using Jackett.Services ;
using Jackett.Utils ;
using Jackett.Utils.Clients ;
using Newtonsoft.Json.Linq ;
using NLog ;
using System ;
using System.Collections.Generic ;
using System.Globalization ;
using System.Linq ;
using System.Net ;
using System.Net.Http ;
using System.Text ;
using System.Threading.Tasks ;
using System.Web ;
using Jackett.Models.IndexerConfig ;
using System.Collections.Specialized ;
namespace Jackett.Indexers
{
public class TorrentDay : BaseIndexer , IIndexer
{
2016-10-26 02:25:51 +00:00
private string UseLink { get { return ( ! String . IsNullOrEmpty ( this . configData . AlternateLink . Value ) ? this . configData . AlternateLink . Value : SiteLink ) ; } }
private string StartPageUrl { get { return UseLink + "login.php" ; } }
private string LoginUrl { get { return UseLink + "tak3login.php" ; } }
private string SearchUrl { get { return UseLink + "browse.php" ; } }
private List < String > KnownURLs = new List < String > {
"https://tdonline.org/" ,
"https://secure.torrentday.com/" ,
"https://torrentday.eu/" ,
"https://torrentday.it/" ,
"https://classic.torrentday.com/" ,
"https://www.torrentday.com/" ,
"https://td-update.com/" ,
"https://www.torrentday.me/" ,
"https://www.torrentday.ru/" ,
"https://www.torrentday.com/" ,
"https://www.td.af/" ,
} ;
new ConfigurationDataRecaptchaLoginWithAlternateLink configData
2015-09-04 18:16:40 +00:00
{
2016-10-26 02:25:51 +00:00
get { return ( ConfigurationDataRecaptchaLoginWithAlternateLink ) base . configData ; }
2015-09-04 18:16:40 +00:00
set { base . configData = value ; }
}
public TorrentDay ( IIndexerManagerService i , Logger l , IWebClient wc , IProtectionService ps )
: base ( name : "TorrentDay" ,
description : "TorrentDay" ,
2016-10-25 17:04:55 +00:00
link : "https://torrentday.it/" ,
2015-09-04 18:16:40 +00:00
caps : TorznabUtil . CreateDefaultTorznabTVCaps ( ) ,
manager : i ,
client : wc ,
logger : l ,
p : ps ,
2016-10-26 02:25:51 +00:00
configData : new ConfigurationDataRecaptchaLoginWithAlternateLink ( ) )
2015-09-04 18:16:40 +00:00
{
2016-10-26 02:25:51 +00:00
this . configData . Instructions . Value = this . DisplayName + " has multiple URLs. The default (" + this . SiteLink + ") can be changed by entering a new value in the box below." ;
this . configData . Instructions . Value + = "The following are some known URLs for " + this . DisplayName ;
this . configData . Instructions . Value + = "<ul><li>" + String . Join ( "</li><li>" , this . KnownURLs . ToArray ( ) ) + "</li></ul>" ;
2015-09-04 18:16:40 +00:00
AddCategoryMapping ( 29 , TorznabCatType . TVAnime ) ;
AddCategoryMapping ( 28 , TorznabCatType . PC ) ;
AddCategoryMapping ( 28 , TorznabCatType . AudioAudiobook ) ;
AddCategoryMapping ( 20 , TorznabCatType . Books ) ;
AddCategoryMapping ( 30 , TorznabCatType . TVDocumentary ) ;
//Freelech
//Mac
AddCategoryMapping ( 25 , TorznabCatType . MoviesSD ) ;
AddCategoryMapping ( 11 , TorznabCatType . MoviesHD ) ;
AddCategoryMapping ( 5 , TorznabCatType . MoviesHD ) ;
2016-08-24 13:02:25 +00:00
AddCategoryMapping ( 48 , TorznabCatType . Movies ) ;
2015-09-04 18:16:40 +00:00
AddCategoryMapping ( 3 , TorznabCatType . MoviesSD ) ;
AddCategoryMapping ( 21 , TorznabCatType . MoviesSD ) ;
AddCategoryMapping ( 22 , TorznabCatType . MoviesForeign ) ;
// Movie packs
AddCategoryMapping ( 44 , TorznabCatType . MoviesSD ) ;
AddCategoryMapping ( 1 , TorznabCatType . MoviesSD ) ;
2016-05-28 09:40:16 +00:00
// Music
AddCategoryMapping ( 17 , TorznabCatType . AudioMP3 ) ;
AddCategoryMapping ( 44 , TorznabCatType . AudioLossless ) ;
AddCategoryMapping ( 23 , TorznabCatType . AudioForeign ) ;
AddCategoryMapping ( 41 , TorznabCatType . AudioOther ) ;
AddCategoryMapping ( 16 , TorznabCatType . AudioVideo ) ;
2015-09-04 18:16:40 +00:00
AddCategoryMapping ( 4 , TorznabCatType . PCGames ) ;
// ps3
// psp
// wii
// 360
AddCategoryMapping ( 24 , TorznabCatType . TVSD ) ;
AddCategoryMapping ( 32 , TorznabCatType . TVHD ) ;
AddCategoryMapping ( 31 , TorznabCatType . TVSD ) ;
AddCategoryMapping ( 33 , TorznabCatType . TVSD ) ;
AddCategoryMapping ( 14 , TorznabCatType . TVHD ) ;
AddCategoryMapping ( 26 , TorznabCatType . TVSD ) ;
AddCategoryMapping ( 7 , TorznabCatType . TVHD ) ;
AddCategoryMapping ( 2 , TorznabCatType . TVSD ) ;
2016-09-04 08:24:02 +00:00
AddCategoryMapping ( 34 , TorznabCatType . TV ) ;
2015-09-04 18:16:40 +00:00
AddCategoryMapping ( 6 , TorznabCatType . XXX ) ;
AddCategoryMapping ( 15 , TorznabCatType . XXX ) ;
}
public override async Task < ConfigurationData > GetConfigurationForSetup ( )
{
var loginPage = await RequestStringWithCookies ( StartPageUrl , string . Empty ) ;
CQ cq = loginPage . Content ;
2016-10-26 02:25:51 +00:00
var result = this . configData ;
2015-09-04 18:16:40 +00:00
result . CookieHeader . Value = loginPage . Cookies ;
result . Captcha . SiteKey = cq . Find ( ".g-recaptcha" ) . Attr ( "data-sitekey" ) ;
2016-10-26 02:25:51 +00:00
result . Captcha . Version = "2" ;
2015-09-04 18:16:40 +00:00
return result ;
}
public async Task < IndexerConfigurationStatus > ApplyConfiguration ( JToken configJson )
{
configData . LoadValuesFromJson ( configJson ) ;
var pairs = new Dictionary < string , string > {
{ "username" , configData . Username . Value } ,
{ "password" , configData . Password . Value } ,
{ "g-recaptcha-response" , configData . Captcha . Value }
} ;
if ( ! string . IsNullOrWhiteSpace ( configData . Captcha . Cookie ) )
{
// Cookie was manually supplied
CookieHeader = configData . Captcha . Cookie ;
try
{
var results = await PerformQuery ( new TorznabQuery ( ) ) ;
if ( results . Count ( ) = = 0 )
{
throw new Exception ( "Your cookie did not work" ) ;
}
SaveConfig ( ) ;
IsConfigured = true ;
return IndexerConfigurationStatus . Completed ;
}
catch ( Exception e )
{
IsConfigured = false ;
throw new Exception ( "Your cookie did not work: " + e . Message ) ;
}
}
2016-10-26 02:25:51 +00:00
var result = await RequestLoginAndFollowRedirect ( LoginUrl , pairs , configData . CookieHeader . Value , true , UseLink , LoginUrl ) ;
2015-09-04 18:16:40 +00:00
await ConfigureIfOK ( result . Cookies , result . Content ! = null & & result . Content . Contains ( "logout.php" ) , ( ) = >
{
CQ dom = result . Content ;
var messageEl = dom [ "#login" ] ;
messageEl . Children ( "form" ) . Remove ( ) ;
var errorMessage = messageEl . Text ( ) . Trim ( ) ;
if ( string . IsNullOrWhiteSpace ( errorMessage ) )
{
errorMessage = dom . Text ( ) ;
}
throw new ExceptionWithConfigData ( errorMessage , configData ) ;
} ) ;
return IndexerConfigurationStatus . RequiresTesting ;
}
public async Task < IEnumerable < ReleaseInfo > > PerformQuery ( TorznabQuery query )
{
var releases = new List < ReleaseInfo > ( ) ;
var searchString = query . GetQueryString ( ) ;
var queryUrl = SearchUrl ;
var queryCollection = new NameValueCollection ( ) ;
2016-08-24 13:02:25 +00:00
if ( query . QueryType = = "TorrentPotato" & & ! string . IsNullOrWhiteSpace ( query . ImdbID ) & & query . ImdbID . ToLower ( ) . StartsWith ( "tt" ) )
{
queryCollection . Add ( "search" , query . ImdbID ) ;
}
else
{
if ( ! string . IsNullOrWhiteSpace ( searchString ) )
queryCollection . Add ( "search" , searchString ) ;
}
2015-09-04 18:16:40 +00:00
foreach ( var cat in MapTorznabCapsToTrackers ( query ) )
queryCollection . Add ( "c" + cat , "1" ) ;
if ( queryCollection . Count > 0 )
queryUrl + = "?" + queryCollection . GetQueryString ( ) ;
var results = await RequestStringWithCookiesAndRetry ( queryUrl ) ;
// Check for being logged out
if ( results . IsRedirect )
throw new AuthenticationException ( ) ;
try
{
CQ dom = results . Content ;
var rows = dom [ "#torrentTable > tbody > tr.browse" ] ;
foreach ( var row in rows )
{
CQ qRow = row . Cq ( ) ;
var release = new ReleaseInfo ( ) ;
release . MinimumRatio = 1 ;
release . MinimumSeedTime = 172800 ;
release . Title = qRow . Find ( ".torrentName" ) . Text ( ) ;
release . Description = release . Title ;
2016-10-26 02:25:51 +00:00
release . Guid = new Uri ( UseLink + qRow . Find ( ".torrentName" ) . Attr ( "href" ) ) ;
2015-09-04 18:16:40 +00:00
release . Comments = release . Guid ;
2016-10-26 02:25:51 +00:00
release . Link = new Uri ( UseLink + qRow . Find ( ".dlLinksInfo > a" ) . Attr ( "href" ) ) ;
2015-09-04 18:16:40 +00:00
var sizeStr = qRow . Find ( ".sizeInfo" ) . Text ( ) ;
release . Size = ReleaseInfo . GetBytes ( sizeStr ) ;
var dateStr = qRow . Find ( ".ulInfo" ) . Text ( ) . Split ( '|' ) . Last ( ) . Trim ( ) ;
var agoIdx = dateStr . IndexOf ( "ago" ) ;
if ( agoIdx > - 1 )
{
dateStr = dateStr . Substring ( 0 , agoIdx ) ;
}
release . PublishDate = DateTimeUtil . FromTimeAgo ( dateStr ) ;
release . Seeders = ParseUtil . CoerceInt ( qRow . Find ( ".seedersInfo" ) . Text ( ) ) ;
release . Peers = ParseUtil . CoerceInt ( qRow . Find ( ".leechersInfo" ) . Text ( ) ) + release . Seeders ;
var cat = qRow . Find ( "td:eq(0) a" ) . First ( ) . Attr ( "href" ) . Substring ( 15 ) ; //browse.php?cat=24
release . Category = MapTrackerCatToNewznab ( cat ) ;
2016-10-27 07:35:31 +00:00
if ( qRow . Find ( "span.flTags" ) . Length > = 1 )
release . DownloadVolumeFactor = 0 ;
else
release . DownloadVolumeFactor = 1 ;
release . UploadVolumeFactor = 1 ;
2015-09-04 18:16:40 +00:00
releases . Add ( release ) ;
}
}
catch ( Exception ex )
{
OnParseError ( results . Content , ex ) ;
}
return releases ;
}
}
}