2017-10-29 06:21:18 +00:00
using System ;
2015-04-16 01:16:16 +00:00
using System.Collections.Generic ;
2015-07-29 19:30:28 +00:00
using System.Collections.Specialized ;
2015-04-16 01:16:16 +00:00
using System.Linq ;
2017-11-05 09:42:03 +00:00
using System.Net ;
2015-04-16 01:16:16 +00:00
using System.Text ;
using System.Threading.Tasks ;
2017-10-29 06:21:18 +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:21:18 +00:00
using Newtonsoft.Json.Linq ;
using NLog ;
2015-04-16 01:16:16 +00:00
2018-03-10 08:05:56 +00:00
namespace Jackett.Common.Indexers
2015-04-16 01:16:16 +00:00
{
2017-07-10 20:58:44 +00:00
public class IPTorrents : BaseWebIndexer
2015-05-04 04:12:14 +00:00
{
2017-10-29 06:21:18 +00:00
private string LoginUrl { get { return SiteLink + "login.php" ; } }
private string TakeLoginUrl { get { return SiteLink + "take_login.php" ; } }
2017-01-02 20:39:28 +00:00
private string BrowseUrl { get { return SiteLink + "t" ; } }
2017-10-29 06:21:18 +00:00
2017-08-31 09:13:09 +00:00
public override string [ ] AlternativeSiteLinks { get ; protected set ; } = new string [ ] {
"https://iptorrents.com/" ,
2019-02-03 05:53:09 +00:00
"https://www.iptorrents.com/" ,
2017-08-31 09:13:09 +00:00
"https://ipt-update.com/" ,
"https://iptorrents.eu/" ,
"https://nemo.iptorrents.com/" ,
"https://ipt.rocks/" ,
2017-08-31 10:14:31 +00:00
"http://ipt.read-books.org/" ,
"http://alien.eating-organic.net/" ,
"http://kong.net-freaks.com/" ,
"http://ghost.cable-modem.org/" ,
"http://logan.unusualperson.com/" ,
"http://baywatch.workisboring.com/" ,
2018-10-21 17:17:22 +00:00
"https://ipt.getcrazy.me" ,
"https://ipt.findnemo.net" ,
"https://ipt.beelyrics.net" ,
"https://ipt.venom.global" ,
"https://ipt.workisboring.net" ,
"https://ipt.lol" ,
2019-01-16 11:46:01 +00:00
"https://ipt.cool" ,
"https://ipt.world" ,
2017-08-31 09:13:09 +00:00
} ;
2015-07-22 22:00:52 +00:00
2017-10-29 06:21:18 +00:00
private new ConfigurationDataRecaptchaLogin configData
2015-08-03 21:38:45 +00:00
{
2017-01-02 20:39:28 +00:00
get { return ( ConfigurationDataRecaptchaLogin ) base . configData ; }
2015-08-03 21:38:45 +00:00
set { base . configData = value ; }
}
2017-11-05 09:42:03 +00:00
public IPTorrents ( IIndexerConfigurationService configService , Utils . Clients . WebClient wc , Logger l , IProtectionService ps )
2015-07-19 23:05:30 +00:00
: base ( name : "IPTorrents" ,
description : "Always a step ahead." ,
2016-12-19 19:25:18 +00:00
link : "https://iptorrents.com/" ,
2015-12-13 23:20:40 +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 ,
2017-01-02 20:39:28 +00:00
configData : new ConfigurationDataRecaptchaLogin ( ) )
2015-05-04 04:12:14 +00:00
{
2017-11-05 09:42:03 +00:00
Encoding = Encoding . UTF8 ;
2016-12-09 17:20:58 +00:00
Language = "en-us" ;
2017-01-27 15:57:32 +00:00
Type = "private" ;
2016-12-06 13:56:47 +00:00
2019-05-11 03:27:25 +00:00
TorznabCaps . SupportsImdbMovieSearch = true ;
2017-04-15 08:45:10 +00:00
AddCategoryMapping ( 72 , TorznabCatType . Movies , "Movies" ) ;
AddCategoryMapping ( 87 , TorznabCatType . Movies3D , "Movie/3D" ) ;
AddCategoryMapping ( 77 , TorznabCatType . MoviesSD , "Movie/480p" ) ;
2017-12-31 17:39:56 +00:00
AddCategoryMapping ( 101 , TorznabCatType . MoviesHD , "Movie/4K" ) ;
2017-04-20 08:21:14 +00:00
AddCategoryMapping ( 89 , TorznabCatType . MoviesHD , "Movie/BD-R" ) ;
2017-04-15 08:45:10 +00:00
AddCategoryMapping ( 90 , TorznabCatType . MoviesSD , "Movie/BD-Rip" ) ;
AddCategoryMapping ( 96 , TorznabCatType . MoviesSD , "Movie/Cam" ) ;
AddCategoryMapping ( 6 , TorznabCatType . MoviesDVD , "Movie/DVD-R" ) ;
AddCategoryMapping ( 48 , TorznabCatType . MoviesBluRay , "Movie/HD/Bluray" ) ;
AddCategoryMapping ( 54 , TorznabCatType . Movies , "Movie/Kids" ) ;
AddCategoryMapping ( 62 , TorznabCatType . MoviesSD , "Movie/MP4" ) ;
AddCategoryMapping ( 38 , TorznabCatType . MoviesForeign , "Movie/Non-English" ) ;
AddCategoryMapping ( 68 , TorznabCatType . Movies , "Movie/Packs" ) ;
AddCategoryMapping ( 20 , TorznabCatType . MoviesHD , "Movie/Web-DL" ) ;
AddCategoryMapping ( 7 , TorznabCatType . MoviesSD , "Movie/Xvid" ) ;
AddCategoryMapping ( 100 , TorznabCatType . Movies , "Movie/x265" ) ;
AddCategoryMapping ( 73 , TorznabCatType . TV , "TV" ) ;
AddCategoryMapping ( 26 , TorznabCatType . TVDocumentary , "Documentaries" ) ;
AddCategoryMapping ( 55 , TorznabCatType . TVSport , "Sports" ) ;
AddCategoryMapping ( 78 , TorznabCatType . TVSD , "TV/480p" ) ;
AddCategoryMapping ( 23 , TorznabCatType . TVHD , "TV/BD" ) ;
AddCategoryMapping ( 24 , TorznabCatType . TVSD , "TV/DVD-R" ) ;
AddCategoryMapping ( 25 , TorznabCatType . TVSD , "TV/DVD-Rip" ) ;
AddCategoryMapping ( 66 , TorznabCatType . TVSD , "TV/Mobile" ) ;
AddCategoryMapping ( 82 , TorznabCatType . TVFOREIGN , "TV/Non-English" ) ;
AddCategoryMapping ( 65 , TorznabCatType . TV , "TV/Packs" ) ;
AddCategoryMapping ( 83 , TorznabCatType . TVFOREIGN , "TV/Packs/Non-English" ) ;
AddCategoryMapping ( 79 , TorznabCatType . TVSD , "TV/SD/x264" ) ;
AddCategoryMapping ( 22 , TorznabCatType . TVWEBDL , "TV/Web-DL" ) ;
AddCategoryMapping ( 5 , TorznabCatType . TVHD , "TV/x264" ) ;
AddCategoryMapping ( 99 , TorznabCatType . TVHD , "TV/x265" ) ;
AddCategoryMapping ( 4 , TorznabCatType . TVSD , "TV/Xvid" ) ;
AddCategoryMapping ( 74 , TorznabCatType . Console , "Games" ) ;
AddCategoryMapping ( 2 , TorznabCatType . ConsoleOther , "Games/Mixed" ) ;
AddCategoryMapping ( 47 , TorznabCatType . ConsoleNDS , "Games/Nintendo DS" ) ;
AddCategoryMapping ( 43 , TorznabCatType . PCISO , "Games/PC-ISO" ) ;
AddCategoryMapping ( 45 , TorznabCatType . PCGames , "Games/PC-Rip" ) ;
AddCategoryMapping ( 39 , TorznabCatType . ConsolePS3 , "Games/PS2" ) ;
AddCategoryMapping ( 71 , TorznabCatType . ConsolePS3 , "Games/PS3" ) ;
AddCategoryMapping ( 40 , TorznabCatType . ConsolePSP , "Games/PSP" ) ;
AddCategoryMapping ( 50 , TorznabCatType . ConsoleWii , "Games/Wii" ) ;
AddCategoryMapping ( 44 , TorznabCatType . ConsoleXbox360 , "Games/Xbox-360" ) ;
AddCategoryMapping ( 75 , TorznabCatType . Audio , "Music" ) ;
AddCategoryMapping ( 3 , TorznabCatType . AudioMP3 , "Music/Audio" ) ;
AddCategoryMapping ( 80 , TorznabCatType . AudioLossless , "Music/Flac" ) ;
AddCategoryMapping ( 93 , TorznabCatType . Audio , "Music/Packs" ) ;
AddCategoryMapping ( 37 , TorznabCatType . AudioVideo , "Music/Video" ) ;
AddCategoryMapping ( 21 , TorznabCatType . AudioVideo , "Podcast" ) ;
AddCategoryMapping ( 76 , TorznabCatType . Other , "Miscellaneous" ) ;
AddCategoryMapping ( 60 , TorznabCatType . TVAnime , "Anime" ) ;
AddCategoryMapping ( 1 , TorznabCatType . PC0day , "Appz" ) ;
AddCategoryMapping ( 86 , TorznabCatType . PC0day , "Appz/Non-English" ) ;
AddCategoryMapping ( 64 , TorznabCatType . AudioAudiobook , "AudioBook" ) ;
AddCategoryMapping ( 35 , TorznabCatType . Books , "Books" ) ;
AddCategoryMapping ( 94 , TorznabCatType . BooksComics , "Comics" ) ;
AddCategoryMapping ( 95 , TorznabCatType . BooksOther , "Educational" ) ;
AddCategoryMapping ( 98 , TorznabCatType . Other , "Fonts" ) ;
AddCategoryMapping ( 69 , TorznabCatType . PCMac , "Mac" ) ;
AddCategoryMapping ( 92 , TorznabCatType . BooksMagazines , "Magazines / Newspapers" ) ;
AddCategoryMapping ( 58 , TorznabCatType . PCPhoneOther , "Mobile" ) ;
AddCategoryMapping ( 36 , TorznabCatType . Other , "Pics/Wallpapers" ) ;
AddCategoryMapping ( 88 , TorznabCatType . XXX , "XXX" ) ;
AddCategoryMapping ( 85 , TorznabCatType . XXXOther , "XXX/Magazines" ) ;
AddCategoryMapping ( 8 , TorznabCatType . XXX , "XXX/Movie" ) ;
AddCategoryMapping ( 81 , TorznabCatType . XXX , "XXX/Movie/0Day" ) ;
AddCategoryMapping ( 91 , TorznabCatType . XXXPacks , "XXX/Packs" ) ;
2017-01-17 07:28:36 +00:00
AddCategoryMapping ( 84 , TorznabCatType . XXXImageset , "XXX/Pics/Wallpapers" ) ;
2015-05-04 04:12:14 +00:00
}
2015-04-23 06:44:21 +00:00
2017-04-15 08:45:10 +00:00
public override async Task < ConfigurationData > GetConfigurationForSetup ( )
{
var loginPage = await RequestStringWithCookies ( LoginUrl , string . Empty ) ;
CQ cq = loginPage . Content ;
var captcha = cq . Find ( ".g-recaptcha" ) ;
2017-10-29 06:21:18 +00:00
if ( captcha . Any ( ) )
2017-04-15 08:45:10 +00:00
{
var result = this . configData ;
result . CookieHeader . Value = loginPage . Cookies ;
result . Captcha . SiteKey = captcha . Attr ( "data-sitekey" ) ;
result . Captcha . Version = "2" ;
return result ;
}
2016-11-05 18:25:38 +00:00
else
{
2017-01-02 20:39:28 +00:00
var result = new ConfigurationDataBasicLogin ( ) ;
result . SiteLink . Value = configData . SiteLink . Value ;
2016-11-05 18:25:38 +00:00
result . Instructions . Value = configData . Instructions . Value ;
result . Username . Value = configData . Username . Value ;
result . Password . Value = configData . Password . Value ;
result . CookieHeader . Value = loginPage . Cookies ;
return result ;
2017-04-15 08:45:10 +00:00
}
2016-11-05 18:25:38 +00:00
}
2017-06-28 05:31:38 +00:00
public override async Task < IndexerConfigurationStatus > ApplyConfiguration ( JToken configJson )
2015-05-04 04:12:14 +00:00
{
2017-01-02 20:39:28 +00:00
LoadValuesFromJson ( configJson ) ;
2015-05-04 04:12:14 +00:00
var pairs = new Dictionary < string , string > {
2015-08-03 21:38:45 +00:00
{ "username" , configData . Username . Value } ,
2016-11-05 18:25:38 +00:00
{ "password" , configData . Password . Value } ,
{ "g-recaptcha-response" , configData . Captcha . Value }
2015-07-27 00:03:51 +00:00
} ;
2016-11-05 18:25:38 +00:00
if ( ! string . IsNullOrWhiteSpace ( configData . Captcha . Cookie ) )
{
CookieHeader = configData . Captcha . Cookie ;
try
{
var results = await PerformQuery ( new TorznabQuery ( ) ) ;
if ( results . Count ( ) = = 0 )
{
throw new Exception ( "Your cookie did not work" ) ;
}
IsConfigured = true ;
2017-05-06 17:39:02 +00:00
SaveConfig ( ) ;
2016-11-05 18:25:38 +00:00
return IndexerConfigurationStatus . Completed ;
}
catch ( Exception e )
{
IsConfigured = false ;
throw new Exception ( "Your cookie did not work: " + e . Message ) ;
}
}
2015-07-27 00:03:51 +00:00
var request = new Utils . Clients . WebRequest ( )
2015-07-22 22:00:52 +00:00
{
2016-10-28 05:51:50 +00:00
Url = TakeLoginUrl ,
2015-07-27 00:03:51 +00:00
Type = RequestType . POST ,
2017-01-02 20:39:28 +00:00
Referer = SiteLink ,
2016-12-21 16:32:24 +00:00
Encoding = Encoding ,
2015-07-27 00:03:51 +00:00
PostData = pairs
} ;
var response = await webclient . GetString ( request ) ;
var firstCallCookies = response . Cookies ;
2015-07-28 19:22:23 +00:00
// Redirect to ? then to /t
await FollowIfRedirect ( response , request . Url , null , firstCallCookies ) ;
2015-07-27 00:03:51 +00:00
2018-10-30 10:04:41 +00:00
await ConfigureIfOK ( firstCallCookies , response . Content . Contains ( "/lout.php" ) , ( ) = >
2015-07-22 22:00:52 +00:00
{
2015-07-27 00:03:51 +00:00
CQ dom = response . Content ;
2015-05-04 04:12:14 +00:00
var messageEl = dom [ "body > div" ] . First ( ) ;
var errorMessage = messageEl . Text ( ) . Trim ( ) ;
2015-08-03 21:38:45 +00:00
throw new ExceptionWithConfigData ( errorMessage , configData ) ;
2015-07-27 00:03:51 +00:00
} ) ;
2015-08-22 20:57:13 +00:00
return IndexerConfigurationStatus . RequiresTesting ;
2015-05-04 04:12:14 +00:00
}
2017-07-03 05:15:47 +00:00
protected override async Task < IEnumerable < ReleaseInfo > > PerformQuery ( TorznabQuery query )
2015-05-04 04:12:14 +00:00
{
2015-07-19 17:18:54 +00:00
var releases = new List < ReleaseInfo > ( ) ;
2015-08-14 21:20:51 +00:00
var searchString = query . GetQueryString ( ) ;
2015-07-29 19:30:28 +00:00
var searchUrl = BrowseUrl ;
var queryCollection = new NameValueCollection ( ) ;
2017-01-16 17:14:28 +00:00
if ( ! string . IsNullOrWhiteSpace ( query . ImdbID ) )
{
queryCollection . Add ( "q" , query . ImdbID ) ;
}
else if ( ! string . IsNullOrWhiteSpace ( searchString ) )
2015-07-29 19:30:28 +00:00
{
queryCollection . Add ( "q" , searchString ) ;
}
foreach ( var cat in MapTorznabCapsToTrackers ( query ) )
{
queryCollection . Add ( cat , string . Empty ) ;
}
if ( queryCollection . Count > 0 )
{
2015-07-30 20:09:38 +00:00
searchUrl + = "?" + queryCollection . GetQueryString ( ) ;
2015-07-29 19:30:28 +00:00
}
2015-08-03 21:38:45 +00:00
2015-07-29 19:30:28 +00:00
var response = await RequestStringWithCookiesAndRetry ( searchUrl , null , BrowseUrl ) ;
2015-05-04 04:12:14 +00:00
2015-07-22 22:00:52 +00:00
var results = response . Content ;
2018-12-02 09:33:18 +00:00
2018-12-15 09:23:41 +00:00
if ( string . IsNullOrWhiteSpace ( query . ImdbID ) & & string . IsNullOrWhiteSpace ( query . SearchTerm ) & & results . Contains ( "No Torrents Found!" ) )
2018-12-02 09:33:18 +00:00
throw new Exception ( "Got No Torrents Found! Make sure your IPTorrents profile config contain proper default category settings." ) ;
2015-07-18 20:35:02 +00:00
try
{
CQ dom = results ;
2015-05-04 04:12:14 +00:00
2016-08-18 06:05:32 +00:00
var rows = dom [ "table[id='torrents'] > tbody > tr" ] ;
2015-07-18 20:35:02 +00:00
foreach ( var row in rows . Skip ( 1 ) )
2015-05-04 04:12:14 +00:00
{
2015-07-18 20:35:02 +00:00
var release = new ReleaseInfo ( ) ;
var qRow = row . Cq ( ) ;
2017-01-17 07:19:25 +00:00
var qTitleLink = qRow . Find ( "a[href^=\"/details.php?id=\"]" ) . First ( ) ;
2015-07-18 20:35:02 +00:00
release . Title = qTitleLink . Text ( ) . Trim ( ) ;
2015-07-26 10:27:50 +00:00
2015-07-26 10:27:55 +00:00
// If we search an get no results, we still get a table just with no info.
2015-07-26 10:27:50 +00:00
if ( string . IsNullOrWhiteSpace ( release . Title ) )
{
break ;
}
2017-01-02 20:39:28 +00:00
release . Guid = new Uri ( SiteLink + qTitleLink . Attr ( "href" ) . Substring ( 1 ) ) ;
2015-07-18 20:35:02 +00:00
release . Comments = release . Guid ;
var descString = qRow . Find ( ".t_ctime" ) . Text ( ) ;
var dateString = descString . Split ( '|' ) . Last ( ) . Trim ( ) ;
dateString = dateString . Split ( new string [ ] { " by " } , StringSplitOptions . None ) [ 0 ] ;
2015-07-23 05:16:13 +00:00
release . PublishDate = DateTimeUtil . FromTimeAgo ( dateString ) ;
2015-07-18 20:35:02 +00:00
var qLink = row . ChildElements . ElementAt ( 3 ) . Cq ( ) . Children ( "a" ) ;
2017-11-05 09:42:03 +00:00
release . Link = new Uri ( SiteLink + WebUtility . UrlEncode ( qLink . Attr ( "href" ) . TrimStart ( '/' ) ) ) ;
2015-07-18 20:35:02 +00:00
2015-07-26 03:53:53 +00:00
var sizeStr = row . ChildElements . ElementAt ( 5 ) . Cq ( ) . Text ( ) ;
release . Size = ReleaseInfo . GetBytes ( sizeStr ) ;
2015-07-18 20:35:02 +00:00
release . Seeders = ParseUtil . CoerceInt ( qRow . Find ( ".t_seeders" ) . Text ( ) . Trim ( ) ) ;
release . Peers = ParseUtil . CoerceInt ( qRow . Find ( ".t_leechers" ) . Text ( ) . Trim ( ) ) + release . Seeders ;
2017-02-20 13:35:44 +00:00
var catIcon = row . Cq ( ) . Find ( "td:eq(0) a" ) ;
if ( catIcon . Length > = 1 ) // Torrents - Category column == Icons
release . Category = MapTrackerCatToNewznab ( catIcon . First ( ) . Attr ( "href" ) . Substring ( 1 ) ) ;
2018-03-12 17:24:50 +00:00
else // Torrents - Category column == Text or Code
throw new Exception ( "Please go to " + SiteLink + "settings.php and change the \"Torrents - Category column\" option to \"Icons\". Wait a minute (cache) and then try again." ) ;
//release.Category = MapTrackerCatDescToNewznab(row.Cq().Find("td:eq(0)").Text()); // Works for "Text" but only contains the parent category
2017-03-15 18:36:54 +00:00
2017-02-16 10:38:41 +00:00
var filesElement = row . Cq ( ) . Find ( "a[href*=\"/files\"]" ) ; // optional
if ( filesElement . Length = = 1 )
release . Files = ParseUtil . CoerceLong ( filesElement . Text ( ) ) ;
2015-07-29 19:30:28 +00:00
2017-02-16 10:38:41 +00:00
var grabs = row . Cq ( ) . Find ( "td:nth-last-child(3)" ) . Text ( ) ;
2016-10-27 07:35:31 +00:00
release . Grabs = ParseUtil . CoerceInt ( grabs ) ;
2017-10-29 06:21:18 +00:00
if ( row . Cq ( ) . Find ( "span.t_tag_free_leech" ) . Any ( ) )
2017-04-15 08:45:10 +00:00
release . DownloadVolumeFactor = 0 ;
2016-10-27 07:35:31 +00:00
else
release . DownloadVolumeFactor = 1 ;
release . UploadVolumeFactor = 1 ;
2015-07-18 20:35:02 +00:00
releases . Add ( release ) ;
2015-05-04 04:12:14 +00:00
}
2015-07-18 20:35:02 +00:00
}
catch ( Exception ex )
{
2015-07-19 17:18:54 +00:00
OnParseError ( results , ex ) ;
2015-05-04 04:12:14 +00:00
}
2015-07-28 23:10:04 +00:00
return releases ;
2015-05-04 04:12:14 +00:00
}
}
2015-04-16 01:16:16 +00:00
}