2017-10-29 06:50:47 +00:00
using System ;
2015-07-19 02:19:09 +00:00
using System.Collections.Generic ;
2017-10-29 06:50:47 +00:00
using System.Collections.Specialized ;
2015-07-19 02:19:09 +00:00
using System.Globalization ;
2016-01-19 13:08:00 +00:00
using System.Linq ;
2016-12-09 17:20:58 +00:00
using System.Text ;
2015-07-19 02:19:09 +00:00
using System.Threading.Tasks ;
2017-10-29 06:50:47 +00:00
using CsQuery ;
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 ;
2015-07-19 02:19:09 +00:00
2018-03-10 08:05:56 +00:00
namespace Jackett.Common.Indexers
2015-07-19 02:19:09 +00:00
{
2017-07-10 20:58:44 +00:00
public class SpeedCD : BaseWebIndexer
2015-07-19 02:19:09 +00:00
{
2018-08-25 16:49:04 +00:00
private string LoginUrl { get { return SiteLink + "takelogin.php" ; } }
2016-01-19 13:08:00 +00:00
private string SearchUrl { get { return SiteLink + "browse.php" ; } }
2015-08-03 21:38:45 +00:00
2017-10-29 06:50:47 +00:00
private new ConfigurationDataBasicLogin configData
2015-08-03 21:38:45 +00:00
{
get { return ( ConfigurationDataBasicLogin ) base . configData ; }
set { base . configData = value ; }
}
2017-11-05 09:42:03 +00:00
public SpeedCD ( IIndexerConfigurationService configService , WebClient wc , Logger l , IProtectionService ps )
2015-07-19 23:05:30 +00:00
: base ( name : "Speed.cd" ,
description : "Your home now!" ,
2016-01-19 13:08:00 +00:00
link : "https://speed.cd/" ,
2015-12-09 08:45:44 +00:00
caps : new TorznabCapabilities ( ) ,
2017-07-10 20:58:44 +00:00
configService : configService ,
2015-07-27 00:03:51 +00:00
client : wc ,
2015-08-03 21:38:45 +00:00
logger : l ,
2015-08-07 19:09:13 +00:00
p : ps ,
2016-07-27 04:14:57 +00:00
configData : new ConfigurationDataBasicLogin ( @ "Speed.Cd have increased their security. If you are having problems please check the security tab in your Speed.Cd profile.
eg . Geo Locking , your seedbox may be in a different country to the one where you login via your web browser "))
2015-07-19 02:19:09 +00:00
{
2016-12-09 17:20:58 +00:00
Encoding = Encoding . UTF8 ;
Language = "en-us" ;
2017-01-27 15:57:32 +00:00
Type = "private" ;
2016-12-09 17:20:58 +00:00
2017-02-24 18:13:55 +00:00
TorznabCaps . SupportsImdbSearch = true ;
2015-12-09 08:45:44 +00:00
AddCategoryMapping ( "1" , TorznabCatType . MoviesOther ) ;
AddCategoryMapping ( "42" , TorznabCatType . Movies ) ;
AddCategoryMapping ( "32" , TorznabCatType . Movies ) ;
AddCategoryMapping ( "43" , TorznabCatType . MoviesHD ) ;
AddCategoryMapping ( "47" , TorznabCatType . Movies ) ;
AddCategoryMapping ( "28" , TorznabCatType . MoviesBluRay ) ;
AddCategoryMapping ( "48" , TorznabCatType . Movies3D ) ;
AddCategoryMapping ( "40" , TorznabCatType . MoviesDVD ) ;
AddCategoryMapping ( "49" , TorznabCatType . TVHD ) ;
AddCategoryMapping ( "50" , TorznabCatType . TVSport ) ;
AddCategoryMapping ( "52" , TorznabCatType . TVHD ) ;
AddCategoryMapping ( "53" , TorznabCatType . TVSD ) ;
AddCategoryMapping ( "41" , TorznabCatType . TV ) ;
AddCategoryMapping ( "55" , TorznabCatType . TV ) ;
2018-08-16 09:50:30 +00:00
AddCategoryMapping ( "2" , TorznabCatType . TVSD ) ;
2015-12-09 08:45:44 +00:00
AddCategoryMapping ( "30" , TorznabCatType . TVAnime ) ;
AddCategoryMapping ( "25" , TorznabCatType . PCISO ) ;
AddCategoryMapping ( "39" , TorznabCatType . ConsoleWii ) ;
AddCategoryMapping ( "45" , TorznabCatType . ConsolePS3 ) ;
AddCategoryMapping ( "35" , TorznabCatType . Console ) ;
AddCategoryMapping ( "33" , TorznabCatType . ConsoleXbox360 ) ;
AddCategoryMapping ( "46" , TorznabCatType . PCPhoneOther ) ;
AddCategoryMapping ( "24" , TorznabCatType . PC0day ) ;
AddCategoryMapping ( "51" , TorznabCatType . PCMac ) ;
AddCategoryMapping ( "27" , TorznabCatType . Books ) ;
AddCategoryMapping ( "26" , TorznabCatType . Audio ) ;
AddCategoryMapping ( "44" , TorznabCatType . Audio ) ;
AddCategoryMapping ( "29" , TorznabCatType . AudioVideo ) ;
2015-07-19 02:19:09 +00:00
}
2017-06-28 05:31:38 +00:00
public override async Task < IndexerConfigurationStatus > ApplyConfiguration ( JToken configJson )
2015-07-19 02:19:09 +00:00
{
2017-01-02 20:39:28 +00:00
LoadValuesFromJson ( configJson ) ;
2016-05-28 09:40:39 +00:00
await DoLogin ( ) ;
return IndexerConfigurationStatus . RequiresTesting ;
}
private async Task DoLogin ( )
{
2015-07-19 02:19:09 +00:00
var pairs = new Dictionary < string , string > {
2015-08-03 21:38:45 +00:00
{ "username" , configData . Username . Value } ,
{ "password" , configData . Password . Value } ,
} ;
2015-07-19 02:19:09 +00:00
2015-08-02 18:14:21 +00:00
var result = await RequestLoginAndFollowRedirect ( LoginUrl , pairs , null , true , null , SiteLink ) ;
2016-05-28 09:40:39 +00:00
2016-07-27 04:14:57 +00:00
await ConfigureIfOK ( result . Cookies , result . Content ! = null & & result . Content . Contains ( "/browse.php" ) , ( ) = >
2015-07-19 02:19:09 +00:00
{
2015-07-27 00:03:51 +00:00
CQ dom = result . Content ;
2016-07-27 04:14:57 +00:00
var errorMessage = dom . Text ( ) ;
2015-08-03 21:38:45 +00:00
throw new ExceptionWithConfigData ( errorMessage , configData ) ;
2015-07-27 00:03:51 +00:00
} ) ;
2015-07-19 02:19:09 +00:00
}
2017-07-03 05:15:47 +00:00
protected override async Task < IEnumerable < ReleaseInfo > > PerformQuery ( TorznabQuery query )
2015-07-19 02:19:09 +00:00
{
2015-07-27 00:03:51 +00:00
var releases = new List < ReleaseInfo > ( ) ;
2015-12-09 08:45:44 +00:00
2016-01-19 13:08:00 +00:00
NameValueCollection qParams = new NameValueCollection ( ) ;
2015-12-09 08:45:44 +00:00
2017-02-24 18:13:55 +00:00
if ( ! string . IsNullOrWhiteSpace ( query . ImdbID ) )
{
qParams . Add ( "search" , query . ImdbID ) ;
qParams . Add ( "d" , "on" ) ;
}
else if ( ! string . IsNullOrEmpty ( query . GetQueryString ( ) ) )
2015-12-09 08:45:44 +00:00
{
2016-01-20 08:45:39 +00:00
qParams . Add ( "search" , query . GetQueryString ( ) ) ;
2015-12-09 08:45:44 +00:00
}
List < string > catList = MapTorznabCapsToTrackers ( query ) ;
foreach ( string cat in catList )
{
qParams . Add ( "c" + cat , "1" ) ;
}
2016-01-19 13:08:00 +00:00
string urlSearch = SearchUrl ;
if ( qParams . Count > 0 )
2015-07-19 02:19:09 +00:00
{
2016-01-19 13:08:00 +00:00
urlSearch + = $"?{qParams.GetQueryString()}" ;
}
2015-07-19 02:19:09 +00:00
2016-01-19 13:08:00 +00:00
var response = await RequestStringWithCookiesAndRetry ( urlSearch ) ;
2017-02-24 18:13:55 +00:00
if ( ! response . Content . Contains ( "/logout.php" ) )
{
//Cookie appears to expire after a period of time or logging in to the site via browser
await DoLogin ( ) ;
response = await RequestStringWithCookiesAndRetry ( urlSearch ) ;
}
2015-07-19 02:19:09 +00:00
2016-01-19 13:08:00 +00:00
try
{
CQ dom = response . Content ;
2017-09-11 08:50:23 +00:00
var rows = dom [ "div[id='torrentTable'] > div[class^='box torrentBox'] > div[class='boxContent'] > table > tbody > tr" ] ;
2015-07-19 02:19:09 +00:00
2016-01-19 13:08:00 +00:00
foreach ( IDomObject row in rows )
{
CQ torrentData = row . OuterHTML ;
CQ cells = row . Cq ( ) . Find ( "td" ) ;
2018-08-29 10:26:48 +00:00
string title = torrentData . Find ( "td[class='lft'] > div > a" ) . First ( ) . Text ( ) . Trim ( ) ;
Uri link = new Uri ( SiteLink + torrentData . Find ( "img[title='Download']" ) . First ( ) . Parent ( ) . Attr ( "href" ) . Trim ( ) ) ;
Uri guid = link ;
2016-01-20 08:45:39 +00:00
long size = ReleaseInfo . GetBytes ( cells . Elements . ElementAt ( 4 ) . Cq ( ) . Text ( ) ) ;
2018-08-29 10:26:48 +00:00
int grabs = ParseUtil . CoerceInt ( cells . Elements . ElementAt ( 5 ) . Cq ( ) . Text ( ) ) ;
int seeders = ParseUtil . CoerceInt ( cells . Elements . ElementAt ( 6 ) . Cq ( ) . Text ( ) ) ;
int leechers = ParseUtil . CoerceInt ( cells . Elements . ElementAt ( 7 ) . Cq ( ) . Text ( ) ) ;
2016-01-19 13:08:00 +00:00
string pubDateStr = torrentData . Find ( "span[class^='elapsedDate']" ) . First ( ) . Attr ( "title" ) . Trim ( ) . Replace ( " at" , "" ) ;
DateTime publishDate = DateTime . ParseExact ( pubDateStr , "dddd, MMMM d, yyyy h:mmtt" , CultureInfo . InvariantCulture , DateTimeStyles . AssumeUniversal ) . ToLocalTime ( ) ;
long category = 0 ;
2018-08-29 10:26:48 +00:00
string cat = torrentData . Find ( "img[class^='Tcat']" ) . First ( ) . Parent ( ) . Attr ( "href" ) . Trim ( ) . Remove ( 0 , 5 ) ;
2016-01-19 13:08:00 +00:00
long . TryParse ( cat , out category ) ;
2015-12-09 08:45:44 +00:00
2016-01-19 13:08:00 +00:00
var release = new ReleaseInfo ( ) ;
release . Title = title ;
release . Guid = guid ;
release . Link = link ;
release . PublishDate = publishDate ;
release . Size = size ;
2018-08-29 10:26:48 +00:00
release . Grabs = grabs ;
2016-01-19 13:08:00 +00:00
release . Seeders = seeders ;
release . Peers = seeders + leechers ;
release . MinimumRatio = 1 ;
release . MinimumSeedTime = 172800 ;
release . Category = MapTrackerCatToNewznab ( category . ToString ( ) ) ;
release . Comments = guid ;
2015-07-19 02:19:09 +00:00
2017-02-24 18:16:57 +00:00
if ( torrentData . Find ( "span:contains(\"[Freeleech]\")" ) . Any ( ) )
release . DownloadVolumeFactor = 0 ;
else
2017-04-15 08:45:10 +00:00
release . DownloadVolumeFactor = 1 ;
2017-02-24 18:16:57 +00:00
release . UploadVolumeFactor = 1 ;
2015-07-19 02:19:09 +00:00
releases . Add ( release ) ;
}
}
catch ( Exception ex )
{
2015-07-27 00:03:51 +00:00
OnParseError ( response . Content , ex ) ;
2015-07-19 02:19:09 +00:00
}
2015-07-28 23:10:04 +00:00
return releases ;
2015-07-19 02:19:09 +00:00
}
}
2016-01-20 08:45:39 +00:00
}