2017-10-29 06:21:18 +00:00
using System ;
2016-09-07 15:29:56 +00:00
using System.Collections.Generic ;
2017-10-29 06:21:18 +00:00
using System.Collections.Specialized ;
2016-09-07 15:29:56 +00:00
using System.Globalization ;
2017-10-29 06:21:18 +00:00
using System.Text ;
using System.Threading.Tasks ;
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 ;
2017-04-15 08:45:10 +00:00
2018-03-10 08:05:56 +00:00
namespace Jackett.Common.Indexers
2016-09-07 15:29:56 +00:00
{
2017-07-10 20:58:44 +00:00
public class BitCityReloaded : BaseWebIndexer
2016-09-07 15:29:56 +00:00
{
2018-06-15 08:30:43 +00:00
private string LoginUrl { get { return SiteLink + "login/index.php" ; } }
2017-10-29 06:21:18 +00:00
private string BrowseUrl { get { return SiteLink + "uebersicht.php" ; } }
private TimeZoneInfo germanyTz = TimeZoneInfo . CreateCustomTimeZone ( "W. Europe Standard Time" , new TimeSpan ( 1 , 0 , 0 ) , "W. Europe Standard Time" , "W. Europe Standard Time" ) ;
2016-09-07 15:29:56 +00:00
2017-10-29 06:21:18 +00:00
private new ConfigurationDataBasicLoginWithRSSAndDisplay configData
2016-09-07 15:29:56 +00:00
{
get { return ( ConfigurationDataBasicLoginWithRSSAndDisplay ) base . configData ; }
set { base . configData = value ; }
}
2017-11-05 09:42:03 +00:00
public BitCityReloaded ( IIndexerConfigurationService configService , WebClient wc , Logger l , IProtectionService ps )
2016-09-07 15:29:56 +00:00
: base ( name : "Bit-City Reloaded" ,
description : "A German general tracker." ,
link : "https://bc-reloaded.net/" ,
caps : TorznabUtil . CreateDefaultTorznabTVCaps ( ) ,
2017-07-10 20:58:44 +00:00
configService : configService ,
2016-09-07 15:29:56 +00:00
client : wc ,
logger : l ,
p : ps ,
configData : new ConfigurationDataBasicLoginWithRSSAndDisplay ( ) )
{
2016-12-06 13:56:47 +00:00
Encoding = Encoding . GetEncoding ( "iso-8859-1" ) ;
2016-12-09 17:20:58 +00:00
Language = "de-de" ;
2017-01-27 15:57:32 +00:00
Type = "private" ;
2016-12-06 13:56:47 +00:00
2017-04-15 08:45:10 +00:00
this . configData . DisplayText . Value = "Only the results from the first search result page are shown, adjust your profile settings to show a reasonable amount (it looks like there's no maximum)." ;
2016-09-07 15:29:56 +00:00
this . configData . DisplayText . Name = "Notice" ;
2017-04-15 08:45:10 +00:00
AddCategoryMapping ( 1 , TorznabCatType . Other ) ; // Anderes
AddCategoryMapping ( 2 , TorznabCatType . TVAnime ) ; // Anime
AddCategoryMapping ( 34 , TorznabCatType . PC ) ; // Appz/Linux
AddCategoryMapping ( 35 , TorznabCatType . PCMac ) ; // Appz/Mac
AddCategoryMapping ( 36 , TorznabCatType . PC ) ; // Appz/Other
AddCategoryMapping ( 20 , TorznabCatType . PC ) ; // Appz/Win
AddCategoryMapping ( 3 , TorznabCatType . TVDocumentary ) ; // Doku/Alle Formate
AddCategoryMapping ( 4 , TorznabCatType . Books ) ; // EBooks
AddCategoryMapping ( 12 , TorznabCatType . ConsolePS4 ) ; // Games PS / PSX
AddCategoryMapping ( 11 , TorznabCatType . ConsoleNDS ) ; // Games/Nintendo DS
AddCategoryMapping ( 10 , TorznabCatType . PCGames ) ; // Games/PC
AddCategoryMapping ( 13 , TorznabCatType . ConsoleWii ) ; // Games/Wii
AddCategoryMapping ( 14 , TorznabCatType . ConsoleXbox ) ; // Games/Xbox & 360
AddCategoryMapping ( 15 , TorznabCatType . PCPhoneOther ) ; // Handy & PDA
AddCategoryMapping ( 16 , TorznabCatType . AudioAudiobook ) ; // Hörspiel/Hörbuch
AddCategoryMapping ( 30 , TorznabCatType . Other ) ; // International
AddCategoryMapping ( 17 , TorznabCatType . Other ) ; // MegaPack
AddCategoryMapping ( 43 , TorznabCatType . Movies3D ) ; // Movie/3D
AddCategoryMapping ( 5 , TorznabCatType . MoviesDVD ) ; // Movie/DVD/R
AddCategoryMapping ( 6 , TorznabCatType . MoviesHD ) ; // Movie/HD 1080p
AddCategoryMapping ( 7 , TorznabCatType . MoviesHD ) ; // Movie/HD 720p
AddCategoryMapping ( 32 , TorznabCatType . MoviesOther ) ; // Movie/TVRip
AddCategoryMapping ( 9 , TorznabCatType . MoviesOther ) ; // Movie/XviD,DivX,h264
AddCategoryMapping ( 26 , TorznabCatType . XXX ) ; // Movie/XXX
AddCategoryMapping ( 41 , TorznabCatType . XXXOther ) ; // Movie/XXX/Other
AddCategoryMapping ( 42 , TorznabCatType . XXXPacks ) ; // Movie/XXX/Pack
AddCategoryMapping ( 45 , TorznabCatType . MoviesHD ) ; // Movies/4K
AddCategoryMapping ( 33 , TorznabCatType . MoviesBluRay ) ; // Movies/BluRay
AddCategoryMapping ( 18 , TorznabCatType . Audio ) ; // Musik
AddCategoryMapping ( 19 , TorznabCatType . AudioVideo ) ; // Musik Videos
AddCategoryMapping ( 44 , TorznabCatType . TVOTHER ) ; // Serie/DVD/R
AddCategoryMapping ( 22 , TorznabCatType . TVHD ) ; // Serie/HDTV
AddCategoryMapping ( 38 , TorznabCatType . TV ) ; // Serie/Pack
AddCategoryMapping ( 23 , TorznabCatType . TVOTHER ) ; // Serie/XviD,DivX,h264
2016-09-07 15:29:56 +00:00
AddCategoryMapping ( 25 , TorznabCatType . TVSport ) ; // Sport
}
2017-06-28 05:31:38 +00:00
public override async Task < IndexerConfigurationStatus > ApplyConfiguration ( JToken configJson )
2016-09-07 15:29:56 +00:00
{
2017-01-02 20:39:28 +00:00
LoadValuesFromJson ( configJson ) ;
2016-09-07 15:29:56 +00:00
var pairs = new Dictionary < string , string >
{
{ "username" , configData . Username . Value } ,
{ "password" , configData . Password . Value }
} ;
var result = await RequestLoginAndFollowRedirect ( LoginUrl , pairs , null , true , null , LoginUrl ) ;
await ConfigureIfOK ( result . Cookies , result . Content ! = null & & result . Content . Contains ( "logout.php" ) , ( ) = >
{
CQ dom = result . Content ;
var errorMessage = dom [ "#login_error" ] . Text ( ) . Trim ( ) ;
throw new ExceptionWithConfigData ( errorMessage , configData ) ;
} ) ;
return IndexerConfigurationStatus . RequiresTesting ;
}
2017-07-03 05:15:47 +00:00
protected override async Task < IEnumerable < ReleaseInfo > > PerformQuery ( TorznabQuery query )
2016-09-07 15:29:56 +00:00
{
var releases = new List < ReleaseInfo > ( ) ;
2017-04-15 08:45:10 +00:00
var searchString = query . GetQueryString ( ) ;
var searchUrl = BrowseUrl ;
var queryCollection = new NameValueCollection ( ) ;
queryCollection . Add ( "showsearch" , "0" ) ;
queryCollection . Add ( "incldead" , "1" ) ;
queryCollection . Add ( "blah" , "0" ) ;
queryCollection . Add ( "team" , "0" ) ;
queryCollection . Add ( "orderby" , "added" ) ;
queryCollection . Add ( "sort" , "desc" ) ;
if ( ! string . IsNullOrWhiteSpace ( searchString ) )
{
queryCollection . Add ( "search" , searchString ) ;
}
foreach ( var cat in MapTorznabCapsToTrackers ( query ) )
{
queryCollection . Add ( "c" + cat , "1" ) ;
}
2016-09-07 15:29:56 +00:00
searchUrl + = "?" + queryCollection . GetQueryString ( ) ;
var response = await RequestStringWithCookiesAndRetry ( searchUrl , null , BrowseUrl ) ;
var results = response . Content ;
try
{
CQ dom = results ;
var rows = dom [ "table.tableinborder[cellpadding=0] > tbody > tr" ] ;
foreach ( var row in rows )
{
var release = new ReleaseInfo ( ) ;
2017-04-15 08:45:10 +00:00
release . MinimumRatio = 0.7 ;
2016-09-07 15:29:56 +00:00
release . MinimumSeedTime = 48 * 60 * 60 ;
2016-12-29 11:47:58 +00:00
release . DownloadVolumeFactor = 1 ;
release . UploadVolumeFactor = 1 ;
2016-09-07 15:29:56 +00:00
var qRow = row . Cq ( ) ;
var flagImgs = qRow . Find ( "table tbody tr: eq(0) td > img" ) ;
List < string > flags = new List < string > ( ) ;
2017-04-15 08:45:10 +00:00
flagImgs . Each ( flagImg = > {
var flag = flagImg . GetAttribute ( "src" ) . Replace ( "pic/torrent_" , "" ) . Replace ( ".gif" , "" ) . ToUpper ( ) ;
if ( flag = = "OU" )
release . DownloadVolumeFactor = 0 ;
else
flags . Add ( flag ) ;
} ) ;
2016-09-07 15:29:56 +00:00
var titleLink = qRow . Find ( "table tbody tr:eq(0) td a:has(b)" ) . First ( ) ;
2017-04-15 08:45:10 +00:00
var DLLink = qRow . Find ( "td.tableb > a:has(img[title=\"Torrent herunterladen\"])" ) . First ( ) ;
release . Comments = new Uri ( SiteLink + titleLink . Attr ( "href" ) . Replace ( "&hit=1" , "" ) ) ;
2016-09-07 15:29:56 +00:00
release . Link = new Uri ( SiteLink + DLLink . Attr ( "href" ) ) ;
release . Title = titleLink . Text ( ) . Trim ( ) ;
2016-10-25 06:46:06 +00:00
2017-04-15 08:45:10 +00:00
if ( ! query . MatchQueryStringAND ( release . Title ) )
2016-10-25 06:46:06 +00:00
continue ;
2016-09-07 15:29:56 +00:00
release . Description = String . Join ( ", " , flags ) ;
release . Guid = release . Link ;
var dateStr = qRow . Find ( "table tbody tr:eq(1) td:eq(4)" ) . Html ( ) . Replace ( " " , " " ) . Trim ( ) ;
var dateGerman = DateTime . SpecifyKind ( DateTime . ParseExact ( dateStr , "dd.MM.yyyy HH:mm:ss" , CultureInfo . InvariantCulture ) , DateTimeKind . Unspecified ) ;
2017-04-15 08:45:10 +00:00
DateTime pubDateUtc = TimeZoneInfo . ConvertTimeToUtc ( dateGerman , germanyTz ) ;
2016-09-07 15:29:56 +00:00
release . PublishDate = pubDateUtc . ToLocalTime ( ) ;
var sizeStr = qRow . Find ( "table tbody tr:eq(1) td b" ) . First ( ) . Text ( ) . Trim ( ) ;
release . Size = ReleaseInfo . GetBytes ( sizeStr . Replace ( "," , "." ) ) ;
release . Seeders = ParseUtil . CoerceInt ( qRow . Find ( "table tbody tr:eq(1) td:eq(1) b:eq(0) font" ) . Text ( ) . Trim ( ) ) ;
release . Peers = ParseUtil . CoerceInt ( qRow . Find ( "table tbody tr:eq(1) td:eq(1) b:eq(1) font" ) . Text ( ) . Trim ( ) ) + release . Seeders ;
var catId = qRow . Find ( "td:eq(0) a" ) . First ( ) . Attr ( "href" ) . Split ( '=' ) [ 1 ] ;
release . Category = MapTrackerCatToNewznab ( catId ) ;
2016-10-27 07:35:31 +00:00
var files = qRow . Find ( "td:has(a[href*=\"&filelist=1\"])> b:nth-child(2)" ) . Text ( ) ;
release . Files = ParseUtil . CoerceInt ( files ) ;
var grabs = qRow . Find ( "td:has(a[href*=\"&tosnatchers=1\"])> b:nth-child(1)" ) . Text ( ) ;
release . Grabs = ParseUtil . CoerceInt ( grabs ) ;
2016-09-07 15:29:56 +00:00
releases . Add ( release ) ;
}
}
catch ( Exception ex )
{
OnParseError ( results , ex ) ;
}
return releases ;
}
}
}