2020-02-09 02:35:16 +00:00
using System ;
2017-04-15 08:45:10 +00:00
using System.Collections.Generic ;
using System.Globalization ;
using System.Linq ;
using System.Text ;
2017-10-29 06:21:18 +00:00
using System.Text.RegularExpressions ;
2017-04-15 08:45:10 +00:00
using System.Threading.Tasks ;
2020-02-29 19:03:51 +00:00
using AngleSharp.Html.Parser ;
2018-03-10 08:05:56 +00:00
using Jackett.Common.Models ;
using Jackett.Common.Models.IndexerConfig.Bespoke ;
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
2017-04-15 08:45:10 +00:00
{
2017-07-10 20:58:44 +00:00
public class NCore : BaseWebIndexer
2017-04-15 08:45:10 +00:00
{
2020-02-25 16:08:03 +00:00
private string LoginUrl = > SiteLink + "login.php" ;
private string SearchUrl = > SiteLink + "torrents.php" ;
2020-02-10 22:16:19 +00:00
private readonly string [ ] LanguageCats = new string [ ] { "xvidser" , "dvdser" , "hdser" , "xvid" , "dvd" , "dvd9" , "hd" , "mp3" , "lossless" , "ebook" } ;
2017-04-15 08:45:10 +00:00
2017-10-29 06:21:18 +00:00
private new ConfigurationDataNCore configData
2017-04-15 08:45:10 +00:00
{
2020-02-25 16:08:03 +00:00
get = > ( ConfigurationDataNCore ) base . configData ;
set = > base . configData = value ;
2017-04-15 08:45:10 +00:00
}
2017-11-05 09:42:03 +00:00
public NCore ( IIndexerConfigurationService configService , WebClient wc , Logger l , IProtectionService ps )
2017-04-15 08:45:10 +00:00
: base ( name : "nCore" ,
description : "A Hungarian private torrent site." ,
link : "https://ncore.cc/" ,
caps : new TorznabCapabilities ( ) ,
2017-07-10 20:58:44 +00:00
configService : configService ,
2017-04-15 08:45:10 +00:00
client : wc ,
logger : l ,
p : ps ,
configData : new ConfigurationDataNCore ( ) )
{
Encoding = Encoding . UTF8 ;
Language = "hu-hu" ;
Type = "private" ;
AddCategoryMapping ( "xvid_hun" , TorznabCatType . MoviesSD , "Film SD/HU" ) ;
2017-10-29 06:21:18 +00:00
AddCategoryMapping ( "xvid" , TorznabCatType . MoviesSD , "Film SD/EN" ) ;
2017-04-15 08:45:10 +00:00
AddCategoryMapping ( "dvd_hun" , TorznabCatType . MoviesDVD , "Film DVDR/HU" ) ;
AddCategoryMapping ( "dvd" , TorznabCatType . MoviesDVD , "Film DVDR/EN" ) ;
AddCategoryMapping ( "dvd9_hun" , TorznabCatType . MoviesDVD , "Film DVD9/HU" ) ;
AddCategoryMapping ( "dvd9" , TorznabCatType . MoviesDVD , "Film DVD9/EN" ) ;
AddCategoryMapping ( "hd_hun" , TorznabCatType . MoviesHD , "Film HD/HU" ) ;
AddCategoryMapping ( "hd" , TorznabCatType . MoviesHD , "Film HD/EN" ) ;
2017-10-29 06:21:18 +00:00
AddCategoryMapping ( "xvidser_hun" , TorznabCatType . TVSD , "Sorozat SD/HU" ) ;
AddCategoryMapping ( "xvidser" , TorznabCatType . TVSD , "Sorozat SD/EN" ) ;
AddCategoryMapping ( "dvdser_hun" , TorznabCatType . TVSD , "Sorozat DVDR/HU" ) ;
2017-04-15 08:45:10 +00:00
AddCategoryMapping ( "dvdser" , TorznabCatType . TVSD , "Sorozat DVDR/EN" ) ;
AddCategoryMapping ( "hdser_hun" , TorznabCatType . TVHD , "Sorozat HD/HU" ) ;
2017-10-29 06:21:18 +00:00
AddCategoryMapping ( "hdser" , TorznabCatType . TVHD , "Sorozat HD/EN" ) ;
2017-04-15 08:45:10 +00:00
2017-10-29 06:21:18 +00:00
AddCategoryMapping ( "mp3_hun" , TorznabCatType . AudioMP3 , "Zene MP3/HU" ) ;
2017-04-15 08:45:10 +00:00
AddCategoryMapping ( "mp3" , TorznabCatType . AudioMP3 , "Zene MP3/EN" ) ;
AddCategoryMapping ( "lossless_hun" , TorznabCatType . AudioLossless , "Zene Lossless/HU" ) ;
AddCategoryMapping ( "lossless" , TorznabCatType . AudioLossless , "Zene Lossless/EN" ) ;
2017-10-29 06:21:18 +00:00
AddCategoryMapping ( "clip" , TorznabCatType . AudioVideo , "Zene Klip" ) ;
2017-04-15 08:45:10 +00:00
2017-10-29 06:21:18 +00:00
AddCategoryMapping ( "xxx_xvid" , TorznabCatType . XXXXviD , "XXX SD" ) ;
2017-04-15 08:45:10 +00:00
AddCategoryMapping ( "xxx_dvd" , TorznabCatType . XXXDVD , "XXX DVDR" ) ;
2017-10-29 06:21:18 +00:00
AddCategoryMapping ( "xxx_imageset" , TorznabCatType . XXXImageset , "XXX Imageset" ) ;
AddCategoryMapping ( "xxx_hd" , TorznabCatType . XXX , "XXX HD" ) ;
2017-04-15 08:45:10 +00:00
2017-10-29 06:21:18 +00:00
AddCategoryMapping ( "game_iso" , TorznabCatType . PCGames , "Játék PC/ISO" ) ;
AddCategoryMapping ( "game_rip" , TorznabCatType . PCGames , "Játék PC/RIP" ) ;
AddCategoryMapping ( "console" , TorznabCatType . Console , "Játék Konzol" ) ;
2017-04-15 08:45:10 +00:00
2017-10-29 06:21:18 +00:00
AddCategoryMapping ( "iso" , TorznabCatType . PCISO , "Program Prog/ISO" ) ;
AddCategoryMapping ( "misc" , TorznabCatType . PC0day , "Program Prog/RIP" ) ;
AddCategoryMapping ( "mobil" , TorznabCatType . PCPhoneOther , "Program Prog/Mobil" ) ;
2017-04-15 08:45:10 +00:00
2017-10-29 06:21:18 +00:00
AddCategoryMapping ( "ebook_hun" , TorznabCatType . Books , "Könyv eBook/HU" ) ;
AddCategoryMapping ( "ebook" , TorznabCatType . Books , "Könyv eBook/EN" ) ;
2017-04-15 08:45:10 +00:00
}
2017-06-28 05:31:38 +00:00
public override async Task < IndexerConfigurationStatus > ApplyConfiguration ( JToken configJson )
2017-04-15 08:45:10 +00:00
{
LoadValuesFromJson ( configJson ) ;
if ( configData . Hungarian . Value = = false & & configData . English . Value = = false )
throw new ExceptionWithConfigData ( "Please select atleast one language." , configData ) ;
var loginPage = await RequestStringWithCookies ( LoginUrl , string . Empty ) ;
var pairs = new Dictionary < string , string > {
{ "nev" , configData . Username . Value } ,
{ "pass" , configData . Password . Value } ,
{ "ne_leptessen_ki" , "1" } ,
{ "set_lang" , "en" } ,
{ "submitted" , "1" } ,
{ "submit" , "Access!" }
} ;
2017-06-13 12:00:41 +00:00
if ( ! string . IsNullOrEmpty ( configData . TwoFactor . Value ) )
{
pairs . Add ( "2factor" , configData . TwoFactor . Value ) ;
}
2017-04-15 08:45:10 +00:00
var result = await RequestLoginAndFollowRedirect ( LoginUrl , pairs , loginPage . Cookies , true , referer : SiteLink ) ;
await ConfigureIfOK ( result . Cookies , result . Content ! = null & & result . Content . Contains ( "profile.php" ) , ( ) = >
{
2020-02-29 19:03:51 +00:00
var parser = new HtmlParser ( ) ;
var dom = parser . ParseDocument ( result . Content ) ;
var messageEl = dom . QuerySelector ( "#hibauzenet table tbody tr" ) ;
var msgContainer = messageEl . Children [ 1 ] ;
var errorMessage = msgContainer ! = null ? msgContainer . TextContent : "Error while trying to login." ;
2017-04-15 08:45:10 +00:00
throw new ExceptionWithConfigData ( errorMessage , configData ) ;
} ) ;
return IndexerConfigurationStatus . RequiresTesting ;
}
2020-02-10 22:16:19 +00:00
private List < ReleaseInfo > parseTorrents ( WebClientStringResult results , string seasonep , TorznabQuery query , int already_founded , int limit , int previously_parsed_on_page )
2017-04-15 08:45:10 +00:00
{
var releases = new List < ReleaseInfo > ( ) ;
try
{
2020-02-29 19:03:51 +00:00
var parser = new HtmlParser ( ) ;
var dom = parser . ParseDocument ( results . Content ) ;
2017-04-15 08:45:10 +00:00
ReleaseInfo release ;
2020-02-29 19:03:51 +00:00
var rows = dom . QuerySelector ( ".box_torrent_all" ) . QuerySelectorAll ( ".box_torrent" ) ;
2017-04-15 08:45:10 +00:00
2018-10-09 17:30:00 +00:00
// Check torrents only till we reach the query Limit
2020-02-10 22:16:19 +00:00
for ( var i = previously_parsed_on_page ; ( i < rows . Length & & ( ( already_founded + releases . Count ) < limit ) ) ; i + + )
2020-02-09 02:35:16 +00:00
{
2018-10-17 06:09:33 +00:00
try
2017-04-15 08:45:10 +00:00
{
2020-02-29 19:03:51 +00:00
var row = rows [ i ] ;
var key = dom . QuerySelector ( "link[rel=alternate]" ) . GetAttribute ( "href" ) . Split ( '=' ) . Last ( ) ;
2018-10-17 06:09:33 +00:00
release = new ReleaseInfo ( ) ;
2020-02-29 19:03:51 +00:00
var torrentTxt = row . QuerySelector ( ".torrent_txt, .torrent_txt2" ) . QuerySelector ( "a" ) ;
2018-10-17 06:09:33 +00:00
//if (torrentTxt == null) continue;
release . Title = torrentTxt . GetAttribute ( "title" ) ;
2020-02-29 19:03:51 +00:00
release . Description = row . QuerySelector ( "span" ) . GetAttribute ( "title" ) + " " + row . QuerySelector ( "a.infolink" ) . TextContent ;
2018-10-17 06:09:33 +00:00
release . MinimumRatio = 1 ;
2020-01-11 18:07:19 +00:00
release . MinimumSeedTime = 172800 ; // 48 hours
2018-10-17 06:09:33 +00:00
release . DownloadVolumeFactor = 0 ;
release . UploadVolumeFactor = 1 ;
2020-02-10 22:16:19 +00:00
var downloadLink = SiteLink + torrentTxt . GetAttribute ( "href" ) ;
var downloadId = downloadLink . Substring ( downloadLink . IndexOf ( "&id=" ) + 4 ) ;
2018-10-17 06:09:33 +00:00
release . Link = new Uri ( SiteLink . ToString ( ) + "torrents.php?action=download&id=" + downloadId + "&key=" + key ) ;
release . Comments = new Uri ( SiteLink . ToString ( ) + "torrents.php?action=details&id=" + downloadId ) ;
2020-02-09 02:35:16 +00:00
release . Guid = new Uri ( release . Comments . ToString ( ) + "#comments" ) ;
;
2020-02-29 19:03:51 +00:00
release . Seeders = ParseUtil . CoerceInt ( row . QuerySelector ( ".box_s2" ) . QuerySelector ( "a" ) . TextContent ) ;
release . Peers = ParseUtil . CoerceInt ( row . QuerySelector ( ".box_l2" ) . QuerySelector ( "a" ) . TextContent ) + release . Seeders ;
var imdblink = row . QuerySelector ( "a[href*=\".imdb.com/title\"]" ) . GetAttribute ( "href" ) ;
2018-10-17 06:09:33 +00:00
release . Imdb = ParseUtil . GetLongFromString ( imdblink ) ;
2020-02-29 19:03:51 +00:00
var banner = row . QuerySelector ( "img.infobar_ico" ) . GetAttribute ( "onmouseover" ) ;
2018-10-17 06:09:33 +00:00
if ( banner ! = null )
{
2020-02-10 22:16:19 +00:00
var BannerRegEx = new Regex ( @"mutat\('(.*?)', '" , RegexOptions . Compiled ) ;
2018-10-17 06:09:33 +00:00
var BannerMatch = BannerRegEx . Match ( banner ) ;
var bannerurl = BannerMatch . Groups [ 1 ] . Value ;
release . BannerUrl = new Uri ( bannerurl ) ;
}
2020-02-29 19:03:51 +00:00
release . PublishDate = DateTime . Parse ( row . QuerySelector ( ".box_feltoltve2" ) . InnerHtml . Replace ( "<br />" , " " ) , CultureInfo . InvariantCulture ) ;
var sizeSplit = row . QuerySelector ( ".box_meret2" ) . TextContent . Split ( ' ' ) ;
2018-10-17 06:09:33 +00:00
release . Size = ReleaseInfo . GetBytes ( sizeSplit [ 1 ] . ToLower ( ) , ParseUtil . CoerceFloat ( sizeSplit [ 0 ] ) ) ;
2020-02-29 19:03:51 +00:00
var catlink = row . QuerySelector ( "a:has(img[class='categ_link'])" ) . GetAttribute ( "href" ) ;
2020-02-10 22:16:19 +00:00
var cat = ParseUtil . GetArgumentFromQueryString ( catlink , "tipus" ) ;
2018-10-17 06:09:33 +00:00
release . Category = MapTrackerCatToNewznab ( cat ) ;
/* if the release name not contains the language we add it because it is know from category */
2019-02-28 18:23:00 +00:00
if ( cat . Contains ( "hun" ) & & ! release . Title . ToLower ( ) . Contains ( "hun" ) )
2018-10-17 06:09:33 +00:00
release . Title + = ".hun" ;
if ( seasonep = = null )
releases . Add ( release ) ;
else
2018-06-11 15:15:21 +00:00
{
2018-10-17 06:09:33 +00:00
if ( query . MatchQueryStringAND ( release . Title , null , seasonep ) )
2018-06-14 15:44:22 +00:00
{
2018-10-17 06:09:33 +00:00
/* For sonnar if the search querry was english the title must be english also so we need to change the Description and Title */
var temp = release . Title ;
// releasedata everithing after Name.S0Xe0X
2020-02-10 22:16:19 +00:00
var releasedata = release . Title . Split ( new [ ] { seasonep } , StringSplitOptions . None ) [ 1 ] . Trim ( ) ;
2018-10-17 06:09:33 +00:00
/* if the release name not contains the language we add it because it is know from category */
if ( cat . Contains ( "hun" ) & & ! releasedata . Contains ( "hun" ) )
releasedata + = ".hun" ;
// release description contains [imdb: ****] but we only need the data before it for title
2020-02-10 22:16:19 +00:00
string [ ] description = { release . Description , "" } ;
2018-10-17 06:09:33 +00:00
if ( release . Description . Contains ( "[imdb:" ) )
{
description = release . Description . Split ( '[' ) ;
description [ 1 ] = "[" + description [ 1 ] ;
}
release . Title = ( description [ 0 ] . Trim ( ) + "." + seasonep . Trim ( ) + "." + releasedata . Trim ( '.' ) ) . Replace ( ' ' , '.' ) ;
// if search is done for S0X than we dont want to put . between S0X and E0X
2020-02-10 22:16:19 +00:00
var match = Regex . Match ( releasedata , @"^E\d\d?" ) ;
2018-10-17 06:09:33 +00:00
if ( seasonep . Length = = 3 & & match . Success )
release . Title = ( description [ 0 ] . Trim ( ) + "." + seasonep . Trim ( ) + releasedata . Trim ( '.' ) ) . Replace ( ' ' , '.' ) ;
// add back imdb points to the description [imdb: 8.7]
release . Description = temp + " " + description [ 1 ] ;
release . Description = release . Description . Trim ( ) ;
releases . Add ( release ) ;
2018-06-14 15:44:22 +00:00
}
2018-06-11 15:15:21 +00:00
}
}
2018-10-17 06:09:33 +00:00
catch ( FormatException ex )
2020-02-09 02:35:16 +00:00
{
2020-02-29 19:03:51 +00:00
logger . Error ( "Problem of parsing Torrent:" + rows [ i ] . InnerHtml ) ;
2018-10-17 06:09:33 +00:00
logger . Error ( "Exception was the following:" + ex ) ;
}
2017-04-15 08:45:10 +00:00
}
}
catch ( Exception ex )
{
OnParseError ( results . Content , ex ) ;
}
return releases ;
}
2018-06-11 15:15:21 +00:00
2020-02-10 22:16:19 +00:00
protected async Task < IEnumerable < ReleaseInfo > > PerformQuery ( TorznabQuery query , string seasonep )
2018-10-09 17:30:00 +00:00
{
var releases = new List < ReleaseInfo > ( ) ;
var searchString = query . GetQueryString ( ) ;
var pairs = new List < KeyValuePair < string , string > > ( ) ;
if ( seasonep ! = null )
{
searchString = query . SanitizedSearchTerm ;
}
pairs . Add ( new KeyValuePair < string , string > ( "nyit_sorozat_resz" , "true" ) ) ;
pairs . Add ( new KeyValuePair < string , string > ( "miben" , "name" ) ) ;
pairs . Add ( new KeyValuePair < string , string > ( "tipus" , "kivalasztottak_kozott" ) ) ;
pairs . Add ( new KeyValuePair < string , string > ( "submit.x" , "1" ) ) ;
pairs . Add ( new KeyValuePair < string , string > ( "submit.y" , "1" ) ) ;
pairs . Add ( new KeyValuePair < string , string > ( "submit" , "Ok" ) ) ;
pairs . Add ( new KeyValuePair < string , string > ( "mire" , searchString ) ) ;
var cats = MapTorznabCapsToTrackers ( query ) ;
if ( cats . Count = = 0 )
cats = GetAllTrackerCategories ( ) ;
foreach ( var lcat in LanguageCats )
{
if ( ! configData . Hungarian . Value )
cats . Remove ( lcat + "_hun" ) ;
if ( ! configData . English . Value )
cats . Remove ( lcat ) ;
}
foreach ( var cat in cats )
{
pairs . Add ( new KeyValuePair < string , string > ( "kivalasztott_tipus[]" , cat ) ) ;
}
var results = await PostDataWithCookiesAndRetry ( SearchUrl , pairs ) ;
2020-02-09 02:35:16 +00:00
2018-10-09 17:30:00 +00:00
2020-02-29 19:03:51 +00:00
var parser = new HtmlParser ( ) ;
var dom = parser . ParseDocument ( results . Content ) ;
2020-02-10 22:16:19 +00:00
var numVal = 0 ;
2018-10-09 17:30:00 +00:00
2019-02-28 18:23:00 +00:00
// find number of torrents / page
2020-02-29 19:03:51 +00:00
var torrent_per_page = dom . QuerySelector ( ".box_torrent_all" ) . QuerySelectorAll ( ".box_torrent" ) . Length ;
2020-02-09 02:35:16 +00:00
if ( torrent_per_page = = 0 )
2019-02-28 18:23:00 +00:00
return releases ;
2020-02-10 22:16:19 +00:00
var start_page = ( query . Offset / torrent_per_page ) + 1 ;
var previously_parsed_on_page = query . Offset - ( start_page * torrent_per_page ) + 1 ; //+1 because indexing start from 0
2019-02-28 18:23:00 +00:00
if ( previously_parsed_on_page < 0 )
previously_parsed_on_page = query . Offset ;
2018-10-09 17:30:00 +00:00
// find pagelinks in the bottom
2020-02-29 19:03:51 +00:00
var pagelinks = dom . QuerySelector ( "div[id=pager_bottom]" ) . QuerySelectorAll ( "a" ) ;
2018-10-09 17:30:00 +00:00
if ( pagelinks . Length > 0 )
{
// If there are several pages find the link for the latest one
2020-02-10 22:16:19 +00:00
for ( var i = pagelinks . Length - 1 ; i > 0 ; i - - )
2018-11-22 23:01:39 +00:00
{
2020-02-29 19:03:51 +00:00
var last_page_link = ( pagelinks [ i ] . GetAttribute ( "href" ) ) . Trim ( ) ;
2018-11-22 23:01:39 +00:00
if ( last_page_link . Contains ( "oldal" ) )
{
2020-02-10 22:16:19 +00:00
var match = Regex . Match ( last_page_link , @"(?<=[\?,&]oldal=)(\d+)(?=&)" ) ;
numVal = int . Parse ( match . Value ) ;
2018-11-22 23:01:39 +00:00
break ;
}
}
2020-02-09 02:35:16 +00:00
}
2018-10-15 15:17:42 +00:00
var limit = query . Limit ;
if ( limit = = 0 )
limit = 100 ;
2018-10-09 17:30:00 +00:00
2019-02-28 18:23:00 +00:00
if ( start_page = = 1 )
{
releases = parseTorrents ( results , seasonep , query , releases . Count , limit , previously_parsed_on_page ) ;
previously_parsed_on_page = 0 ;
start_page + + ;
}
2020-02-09 02:35:16 +00:00
2018-10-09 17:30:00 +00:00
// Check all the pages for the torrents.
// The starting index is 2. (the first one is the original where we parse out the pages.)
2020-02-10 22:16:19 +00:00
for ( var i = start_page ; ( i < = numVal & & releases . Count < limit ) ; i + + )
2018-10-09 17:30:00 +00:00
{
pairs . Add ( new KeyValuePair < string , string > ( "oldal" , i . ToString ( ) ) ) ;
results = await PostDataWithCookiesAndRetry ( SearchUrl , pairs ) ;
2019-02-28 18:23:00 +00:00
releases . AddRange ( parseTorrents ( results , seasonep , query , releases . Count , limit , previously_parsed_on_page ) ) ;
previously_parsed_on_page = 0 ;
2018-10-09 17:30:00 +00:00
pairs . Remove ( new KeyValuePair < string , string > ( "oldal" , i . ToString ( ) ) ) ;
}
return releases ;
}
2018-06-11 15:15:21 +00:00
protected override async Task < IEnumerable < ReleaseInfo > > PerformQuery ( TorznabQuery query )
{
var results = await PerformQuery ( query , null ) ;
2020-02-09 02:35:16 +00:00
if ( results . Count ( ) = = 0 & & query . IsTVSearch ) // if we search for a localized title ncore can't handle any extra S/E information, search without it and AND filter the results. See #1450
2018-06-11 15:15:21 +00:00
{
2020-02-09 02:35:16 +00:00
results = await PerformQuery ( query , query . GetEpisodeSearchString ( ) ) ;
2018-06-11 15:15:21 +00:00
}
return results ;
}
2017-04-15 08:45:10 +00:00
}
}