@ -27,24 +27,29 @@ from lib.unidecode import unidecode
class TorrentLeechProvider ( generic . TorrentProvider ) :
def __init__ ( self ) :
generic . TorrentProvider . __init__ ( self , ' TorrentLeech ' , cache_update_freq = 15 )
generic . TorrentProvider . __init__ ( self , ' TorrentLeech ' )
self . url_base = ' https://v4.torrentleech.org/ '
self . urls = { ' config_provider_home_uri ' : self . url_base ,
' login_action ' : self . url_base ,
' browse ' : self . url_base + ' torrents/browse/index/categories/ %(cats)s ' ,
' search ' : self . url_base + ' torrents/browse/index/query/ %(query)s /categories/ %(cats)s ' }
' login ' : self . url_base ,
' browse ' : self . url_base + ' torrents/browse/index/categories/ %(cats)s / %(x)s ',
' search ' : self . url_base + ' torrents/browse/index/query/ %(query)s /categories/ %(cats)s / %(x)s '}
self . categories = { ' shows ' : [ 2 , 26 , 27 , 32 ] , ' anime ' : [ 7 , 34 , 35 ] }
self . url = self . urls [ ' config_provider_home_uri ' ]
self . username , self . password , self . minseed , self . minleech = 4 * [ None ]
self . digest , self . minseed , self . minleech , self . freeleech = 4 * [ None ]
def _authorised ( self , * * kwargs ) :
return super ( TorrentLeechProvider , self ) . _authorised ( logged_in = ( lambda y = None : self . has_all_cookies ( pre = ' tl ' ) ) ,
post_params = { ' remember_me ' : ' on ' , ' form_tmpl ' : True } )
return super ( TorrentLeechProvider , self ) . _authorised (
logged_in = ( lambda y = ' ' : all (
[ ' TorrentLeech ' in y , ' type= " password " ' not in y [ 0 : 4096 ] , self . has_all_cookies ( pre = ' tl ' ) ] ) ) ,
failed_msg = ( lambda y = None : u ' Invalid cookie details for %s . Check settings ' ) )
@staticmethod
def _has_signature ( data = None ) :
return generic . TorrentProvider . _has_signature ( data ) or ( data and re . search ( r ' (?i)<title[^<]+?leech ' , data ) )
def _search_provider ( self , search_params , * * kwargs ) :
@ -52,20 +57,41 @@ class TorrentLeechProvider(generic.TorrentProvider):
if not self . _authorised ( ) :
return results
items = { ' Cache ' : [ ] , ' Season ' : [ ] , ' Episode ' : [ ] , ' Propers ' : [ ] }
rc = dict ( ( k , re . compile ( ' (?i) ' + v ) ) for ( k , v ) in { ' get ' : ' download ' } . items ( ) )
last_recent_search = self . last_recent_search
last_recent_search = ' ' if not last_recent_search else last_recent_search . replace ( ' id- ' , ' ' )
for mode in search_params . keys ( ) :
urls = [ ]
for search_string in search_params [ mode ] :
search_url = self . urls [ ( ' search ' , ' browse ' ) [ ' Cache ' == mode ] ] % {
' cats ' : self . _categories_string ( mode , ' ' , ' , ' ) ,
' query ' : isinstance ( search_string , unicode ) and unidecode ( search_string ) or search_string }
urls + = [ [ ] ]
for page in range ( ( 3 , 5 ) [ ' Cache ' == mode ] ) [ 1 : ] :
urls [ - 1 ] + = [ self . urls [ ( ' search ' , ' browse ' ) [ ' Cache ' == mode ] ] % {
' cats ' : self . _categories_string ( mode , ' ' , ' , ' ) ,
' query ' : isinstance ( search_string , unicode ) and unidecode ( search_string ) or search_string ,
' x ' : ' %s page/ %s ' % ( ( ' facets/tags:FREELEECH/ ' , ' ' ) [ not self . freeleech ] , page )
} ]
results + = self . _search_urls ( mode , last_recent_search , urls )
last_recent_search = ' '
return results
def _search_urls ( self , mode , last_recent_search , urls ) :
results = [ ]
items = { ' Cache ' : [ ] , ' Season ' : [ ] , ' Episode ' : [ ] , ' Propers ' : [ ] }
rc = dict ( ( k , re . compile ( ' (?i) ' + v ) ) for ( k , v ) in dict ( get = ' download ' , id = r ' download.*?/([ \ d]+) ' ) . items ( ) )
lrs_found = False
lrs_new = True
for search_urls in urls : # this intentionally iterates once to preserve indentation
for search_url in search_urls :
html = self . get_url ( search_url )
if self . should_skip ( ) :
return results
cnt = len ( items [ mode ] )
cnt_search = 0
log_settings_hint = False
try :
if not html or self . _has_no_results ( html ) :
raise generic . HaltParseException
@ -77,22 +103,32 @@ class TorrentLeechProvider(generic.TorrentProvider):
if 2 > len ( tbl_rows ) :
raise generic . HaltParseException
if ' Cache ' == mode and 100 > len ( tbl_rows ) :
log_settings_hint = True
head = None
for tr in tbl_rows [ 1 : ] :
cells = tr . find_all ( ' td ' )
if 6 > len ( cells ) :
continue
cnt_search + = 1
try :
head = head if None is not head else self . _header_row ( tr )
seeders , leechers = [ tryInt ( n ) for n in [
tr . find ( ' td ' , class_ = x ) . get_text ( ) . strip ( ) for x in ' seeders ' , ' leechers ' ] ]
tr . find ( ' td ' , class_ = x ) . get_text ( ) . strip ( ) for x in ( ' seeders ' , ' leechers ' ) ] ]
if self . _reject_item ( seeders , leechers ) :
continue
dl = tr . find ( ' a ' , href = rc [ ' get ' ] ) [ ' href ' ]
dl_id = rc [ ' id ' ] . findall ( dl ) [ 0 ]
lrs_found = dl_id == last_recent_search
if lrs_found :
break
info = tr . find ( ' td ' , class_ = ' name ' ) . a
title = ( info . attrs . get ( ' title ' ) or info . get_text ( ) ) . strip ( )
size = cells [ head [ ' size ' ] ] . get_text ( ) . strip ( )
download_url = self . _link ( tr . find ( ' a ' , href = rc [ ' get ' ] ) [ ' href ' ] )
download_url = self . _link ( dl )
except ( AttributeError , TypeError , ValueError ) :
continue
@ -103,7 +139,11 @@ class TorrentLeechProvider(generic.TorrentProvider):
pass
except ( BaseException , Exception ) :
logger . log ( u ' Failed to parse. Traceback: %s ' % traceback . format_exc ( ) , logger . ERROR )
self . _log_search ( mode , len ( items [ mode ] ) - cnt , search_url )
self . _log_search ( mode , len ( items [ mode ] ) - cnt , search_url , log_settings_hint )
if self . is_search_finished ( mode , items , cnt_search , rc [ ' id ' ] , last_recent_search , lrs_new , lrs_found ) :
break
lrs_new = False
results = self . _sort_seeding ( mode , results + items [ mode ] )
@ -113,5 +153,8 @@ class TorrentLeechProvider(generic.TorrentProvider):
return super ( TorrentLeechProvider , self ) . _episode_strings ( ep_obj , sep_date = ' | ' , * * kwargs )
def ui_string ( self , key ) :
return ' torrentleech_digest ' == key and self . _valid_home ( ) and ' use... \' tluid=xx; tlpass=yy \' ' or ' '
provider = TorrentLeechProvider ( )