2015-04-16 01:16:16 +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-22 22:00:52 +00:00
using Jackett.Utils.Clients ;
2015-04-16 01:16:16 +00:00
using Newtonsoft.Json.Linq ;
2015-07-19 00:27:41 +00:00
using NLog ;
2015-04-16 01:16:16 +00:00
using System ;
using System.Collections.Generic ;
2015-07-29 19:30:28 +00:00
using System.Collections.Specialized ;
2015-05-05 04:25:28 +00:00
using System.Globalization ;
2015-04-16 01:16:16 +00:00
using System.Linq ;
using System.Net ;
using System.Net.Http ;
using System.Text ;
using System.Threading.Tasks ;
2015-04-18 22:08:36 +00:00
using System.Web ;
2015-08-03 21:38:45 +00:00
using Jackett.Models.IndexerConfig ;
2015-04-16 01:16:16 +00:00
namespace Jackett.Indexers
{
2015-07-19 17:18:54 +00:00
public class IPTorrents : BaseIndexer , IIndexer
2015-05-04 04:12:14 +00:00
{
2016-04-18 13:42:53 +00:00
private string UseLink { get { return ( ! String . IsNullOrEmpty ( this . configData . AlternateLink . Value ) ? this . configData . AlternateLink . Value : SiteLink ) ; } }
private string BrowseUrl { get { return UseLink + "t" ; } }
private List < String > KnownURLs = new List < String > { "https://nemo.iptorrents.com/" , "https://ipt.rocks/" } ;
2015-07-22 22:00:52 +00:00
2016-04-18 13:42:53 +00:00
new ConfigurationDataBasicLoginWithAlternateLink configData
2015-08-03 21:38:45 +00:00
{
2016-04-18 13:42:53 +00:00
get { return ( ConfigurationDataBasicLoginWithAlternateLink ) base . configData ; }
2015-08-03 21:38:45 +00:00
set { base . configData = value ; }
}
2015-08-07 19:09:13 +00:00
public IPTorrents ( IIndexerManagerService i , IWebClient wc , Logger l , IProtectionService ps )
2015-07-19 23:05:30 +00:00
: base ( name : "IPTorrents" ,
description : "Always a step ahead." ,
2015-07-27 00:03:51 +00:00
link : "https://iptorrents.com/" ,
2015-12-13 23:20:40 +00:00
caps : new TorznabCapabilities ( ) ,
2015-07-19 23:05:30 +00:00
manager : i ,
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-04-18 13:42:53 +00:00
configData : new ConfigurationDataBasicLoginWithAlternateLink ( ) )
2015-05-04 04:12:14 +00:00
{
2016-04-18 13:42:53 +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-07-29 19:30:28 +00:00
AddCategoryMapping ( 72 , TorznabCatType . Movies ) ;
AddCategoryMapping ( 77 , TorznabCatType . MoviesSD ) ;
AddCategoryMapping ( 89 , TorznabCatType . MoviesSD ) ;
AddCategoryMapping ( 90 , TorznabCatType . MoviesSD ) ;
AddCategoryMapping ( 96 , TorznabCatType . MoviesSD ) ;
AddCategoryMapping ( 6 , TorznabCatType . MoviesSD ) ;
AddCategoryMapping ( 48 , TorznabCatType . MoviesHD ) ;
AddCategoryMapping ( 54 , TorznabCatType . Movies ) ;
AddCategoryMapping ( 62 , TorznabCatType . MoviesSD ) ;
AddCategoryMapping ( 38 , TorznabCatType . MoviesForeign ) ;
AddCategoryMapping ( 68 , TorznabCatType . Movies ) ;
AddCategoryMapping ( 20 , TorznabCatType . MoviesHD ) ;
AddCategoryMapping ( 7 , TorznabCatType . MoviesSD ) ;
AddCategoryMapping ( 73 , TorznabCatType . TV ) ;
AddCategoryMapping ( 26 , TorznabCatType . TVSD ) ;
AddCategoryMapping ( 55 , TorznabCatType . TVSD ) ;
AddCategoryMapping ( 78 , TorznabCatType . TVSD ) ;
AddCategoryMapping ( 23 , TorznabCatType . TVHD ) ;
AddCategoryMapping ( 24 , TorznabCatType . TVSD ) ;
AddCategoryMapping ( 25 , TorznabCatType . TVSD ) ;
AddCategoryMapping ( 66 , TorznabCatType . TVSD ) ;
AddCategoryMapping ( 82 , TorznabCatType . TVSD ) ;
AddCategoryMapping ( 65 , TorznabCatType . TV ) ;
AddCategoryMapping ( 83 , TorznabCatType . TV ) ;
AddCategoryMapping ( 79 , TorznabCatType . TVSD ) ;
AddCategoryMapping ( 22 , TorznabCatType . TVHD ) ;
AddCategoryMapping ( 79 , TorznabCatType . TVSD ) ;
AddCategoryMapping ( 4 , TorznabCatType . TVSD ) ;
AddCategoryMapping ( 5 , TorznabCatType . TVHD ) ;
AddCategoryMapping ( 75 , TorznabCatType . Audio ) ;
AddCategoryMapping ( 73 , TorznabCatType . Audio ) ;
AddCategoryMapping ( 80 , TorznabCatType . AudioLossless ) ;
AddCategoryMapping ( 93 , TorznabCatType . Audio ) ;
2015-08-12 17:31:59 +00:00
AddCategoryMapping ( 60 , TorznabCatType . TVAnime ) ;
AddCategoryMapping ( 1 , TorznabCatType . PC ) ;
AddCategoryMapping ( 64 , TorznabCatType . AudioAudiobook ) ;
2015-07-29 19:30:28 +00:00
AddCategoryMapping ( 35 , TorznabCatType . Books ) ;
2015-08-12 17:31:59 +00:00
AddCategoryMapping ( 94 , TorznabCatType . BooksComics ) ;
2015-05-04 04:12:14 +00:00
}
2015-04-23 06:44:21 +00:00
2015-08-22 20:57:13 +00:00
public async Task < IndexerConfigurationStatus > ApplyConfiguration ( JToken configJson )
2015-05-04 04:12:14 +00:00
{
2015-08-03 21:38:45 +00:00
configData . 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 } ,
{ "password" , configData . Password . Value }
2015-07-27 00:03:51 +00:00
} ;
var request = new Utils . Clients . WebRequest ( )
2015-07-22 22:00:52 +00:00
{
2016-04-18 13:42:53 +00:00
Url = UseLink ,
2015-07-27 00:03:51 +00:00
Type = RequestType . POST ,
2016-04-18 13:42:53 +00:00
Referer = UseLink ,
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
2015-08-02 17:28:59 +00:00
await ConfigureIfOK ( firstCallCookies , response . Content . Contains ( "/my.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
}
2015-07-28 23:10:04 +00:00
public 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 ( ) ;
if ( ! string . IsNullOrWhiteSpace ( searchString ) )
{
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 ;
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 ( ) ;
var qTitleLink = qRow . Find ( "a.t_title" ) . First ( ) ;
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 ;
}
2015-07-18 20:35:02 +00:00
release . Description = release . Title ;
2016-04-18 13:42:53 +00:00
release . Guid = new Uri ( UseLink + 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" ) ;
2016-04-18 13:42:53 +00:00
release . Link = new Uri ( UseLink + HttpUtility . 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 ;
2015-07-29 19:30:28 +00:00
var cat = row . Cq ( ) . Find ( "td:eq(0) a" ) . First ( ) . Attr ( "href" ) . Substring ( 1 ) ;
release . Category = MapTrackerCatToNewznab ( cat ) ;
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
}