#!/usr/bin/env python3 # VERSION: 4.3 # AUTHORS: Khen Solomon Lethil import json, re, math try: from urllib.parse import urlencode, unquote, quote_plus # from html.parser import HTMLParser except ImportError: from urllib import urlencode, unquote, quote_plus # from HTMLParser import HTMLParser # local from novaprinter import prettyPrinter from helpers import retrieve_url class yts(object): url = 'https://yts.mx' name = 'YTS' supported_categories = {'all': 'All', 'movies': 'Movie'} def search(self, keyword, cat='all'): job = score() params = job.paramBuilder(unquote(keyword)) url = job.urlBuilder(self.url,['api', 'v2', 'list_movies.json'],params) data = retrieve_url(url) j = json.loads(data) # with open("assets/yts.v181109.json", "w") as f: # json.dump(j, f) if j['data']['movie_count'] and 'movies' in j['data']: page_of = '{}of{}'.format(j['data']['page_number'],int(math.ceil(int(j['data']['movie_count']) / int(j['data']['limit'])))) for movies in j['data']['movies']: for torrent in movies['torrents']: res = {'link':job.magnetBuilder(torrent['hash'],movies['title']), 'name': '{n} ({y}) [{q}]-[{p}]-[{i}]'.format(n=movies['title'], y=movies['year'], q=torrent['quality'], p=page_of, i=self.name), 'size': torrent['size'], 'seeds': torrent['seeds'], 'leech': torrent['peers'], 'engine_url': 'IMDB:{rating}, [{genres}]'.format(rating=movies['rating'], genres=', '.join(movies['genres'])), 'desc_link': movies['url']} job.done(res) elif job.supported_browse_params: url_params = job.supported_browse_params url_path = list(map(lambda i: i in params and params[i] or url_params[i], url_params)) url = job.urlBuilder(self.url,url_path,'page' in params and {'page':params['page']}) data = retrieve_url(url) data = re.sub("\s\s+", "", data).replace('\n', '').replace('\r', '') data_container = re.findall('
.*?
(.*?)
.*?
', data) if data_container and data_container[0]: page_of = re.findall('
  • (.*?)
  • ', data)[0] # 1 of 5 page_of = page_of and re.sub(' +','',page_of).strip() or '?' data_movie = re.findall('
    .*?
    ', data_container[0]) for hM in data_movie: movie_link = re.findall('.*?', hM)[0] response_detail = retrieve_url(movie_link) response_detail = re.sub("\s\s+", "", response_detail).replace('\n', '').replace('\r', '') movie_id = re.findall('data-movie-id="(\d+)"', response_detail)[0] if movie_id: url = job.urlBuilder(self.url,['api', 'v2', 'movie_details.json'],{'movie_id':movie_id}) data_detail = retrieve_url(url) j = json.loads(data_detail) movies = j['data']['movie'] for torrent in movies['torrents']: res = {'link':job.magnetBuilder(torrent['hash'],movies['title']), 'name': '{n} ({y}) [{q}]-[{p}]-[{i}]'.format(n=movies['title'], y=movies['year'], q=torrent['quality'], p=page_of,i=self.name[:-1]), 'size': torrent['size'], 'seeds': torrent['seeds'], 'leech': torrent['peers'], 'engine_url': 'IMDB:{rating}, [{genres}]'.format(rating=movies['rating'], genres=', '.join(movies['genres'])), 'desc_link': movies['url']} job.done(res) else: # TODO: ?? movie_title = re.findall('(.*?)', hM)[0] movie_year = re.findall('(.*?)', hM)[0] movie_rate = re.findall('(.*?)', hM)[0] movie_rate = movie_rate.split('/')[0] movie_genre = re.findall('
    .*?(

    .*

    ).*?
    ', hM)[0] movie_genre = re.findall('

    (.*?)

    ', movie_genre) # print(movie_title,movie_link,movie_year,movie_rate,movie_genre) job.done() else: # NOTE: No match found job.done() else: # NOTE: not supported browsing job.done() class score(object): supported_browse_params = {'browse':'browse-movies','query_term':'0', 'quality':'all','genre':'all','minimum_rating':'0','sort_by':'latest'} default_params = { 'genre':{'x':'(term=\w+[\s+|$]?)'}, 'quality':{'x':'(term=\w+[\s+|$]?)'}, 'minimum_rating':{'x':'(term=?[0-9]*[.]?[0-9]+[\s+|$]?)'}, 'sort_by':{'x':'(term=\w+[\s+|$]?)'}, 'order_by':{'x':'(term=\w+[\s+|$]?)'}, 'with_rt_ratings':{'x':'(term=\w+[\s+|$]?)'}, 'page':{'x':'(term=\w+[\s+|$]?)','value':'1'}, 'limit':{'x':'(term=.*[\s+|$]?)','value':'1'}, 'query_term':{'x':'(term=.*[\s+|$]?)','value':'%%'}} tracker = ['udp://open.demonii.com:1337/announce', 'udp://tracker.openbittorrent.com:80', 'udp://tracker.coppersurfer.tk:6969', 'udp://glotorrents.pw:6969/announce', 'udp://tracker.opentrackr.org:1337/announce', 'udp://torrent.gresille.org:80/announce', 'udp://p4p.arenabg.com:1337', 'udp://tracker.leechers-paradise.org:6969'] def magnetBuilder(self,hash, name): return "magnet:?xt=urn:btih:{}&{}&{}".format(hash,urlencode({'dn': name}),'&'.join(map(lambda x: 'tr='+quote_plus(x.strip()), self.tracker))) def urlBuilder(self, url, uri=[], param={}): for r in uri: url = '{}/{}'.format(url, r) if param: url = '{}?{}'.format(url, urlencode(param)) return url def paramBuilder(self, query_term): params = {} for name in self.default_params: o = self.default_params[name] regex = o['x'].replace('term',name) val = re.findall(regex, query_term) if len(val): query_term = re.sub(regex,"",query_term) val = re.findall("=(.*)", val[0])[0].strip() if 'value' in o and val != o['value']: """ limit > 1, page > 1, query_term != '%%' """ params[name] = val else: params[name] = val else: """ default value, if required """ query_term = re.sub(' +',' ',query_term).strip() if query_term: if query_term != self.default_params['query_term']['value']: params['query_term'] = query_term # quote_plus(query_term) return params def done(self,res={}): if res: # print(res['name']) prettyPrinter(res) else: """ None """ if __name__=="__main__": """ debug """