From baf6d0c369f6844f8636f232479630bfd0963136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D1=80=D0=BE=D0=B4=D0=B8=D0=BD=20=D0=A0=D0=BE?= =?UTF-8?q?=D0=BC=D0=B0=D0=BD?= Date: Mon, 14 Mar 2022 09:16:22 +0300 Subject: [PATCH] =?UTF-8?q?=D0=92=D0=B5=D1=80=D1=81=D0=B8=D1=8F=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20Kodi=2019?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addon.py | 96 ++++++++++++++------- addon.xml | 13 +-- resources/lib/overrrides/session.py | 91 ++++---------------- resources/lib/player.py | 121 ++++++++++++++------------- resources/lib/searchers/__init__.py | 40 ++++++--- resources/lib/searchers/kinozal.py | 27 ++++-- resources/lib/searchers/rutracker.py | 7 ++ resources/lib/utils/__init__.py | 43 +++++----- 8 files changed, 235 insertions(+), 203 deletions(-) diff --git a/addon.py b/addon.py index cf74c92..5b923cb 100644 --- a/addon.py +++ b/addon.py @@ -1,13 +1,17 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from codequick import Route, Script, Listitem, utils, run # @UnresolvedImport -from codequick.storage import PersistentList # @UnresolvedImport + import os.path -import xbmcgui, xbmc -from resources.lib.searchers import rutor, kinozal, rutracker -from resources.lib.utils import localize, store_torrent_file, get_engine + +import xbmc +import xbmcgui +from codequick import Route, Script, Listitem, utils, run # @UnresolvedImport +from codequick.storage import PersistentList # @UnresolvedImport + from resources.lib.overrrides.session import torrent_file_fetch from resources.lib.player import VideoLoop +from resources.lib.searchers import rutor, kinozal, rutracker +from resources.lib.utils import localize, store_torrent_file, get_engine video_extensions = ('.mp4', '.avi', '.3gp', '.ogv', '.mkv', '.ts', '.mpg', '.mpeg', '.webm', '.flv', '.vob') @@ -15,31 +19,37 @@ search_engines = [ rutor.SearchEngine, kinozal.SearchEngine, rutracker.SearchEngine - ] +] ROOT = os.path.abspath(os.path.dirname(__file__)) ICON_DIR = os.path.join(ROOT, 'resources', 'icons') + @Route.register def root(plugin, content_type='video'): @Route.register_delayed def set_view(): xbmc.executebuiltin('Container.SetViewMode("500")') + def build_item(a): cb, name, image = a i = Listitem.from_dict(cb, name) i.art.local_thumb(image) return i - return map(build_item, ( - (search_history, localize(33052), 'history2.png'), - (new_search, localize(33053), 'search.png') - )) + + for li in ( + (search_history, localize(33052), 'history2.png'), + (new_search, localize(33053), 'search.png')): + yield build_item(li) + + @Route.register def search_history(plugin): try: @Route.register_delayed def set_view(): xbmc.executebuiltin('Container.SetViewMode("51")') + h_list = PersistentList('search_history') for i in h_list: item = Listitem.from_dict(search, i, params={'search_query': i}) @@ -49,18 +59,23 @@ def search_history(plugin): yield None except: yield False + + @Route.register def new_search(plugin): q = utils.keyboard('Поиск') if not q: return False return search(plugin, q) + + @Route.register def search(plugin, search_query, thumb=None): try: @Route.register_delayed def set_view(): xbmc.executebuiltin('Container.SetViewMode("51")') + with PersistentList('search_history') as h_list: if search_query in h_list: del h_list[h_list.index(search_query)] @@ -69,21 +84,25 @@ def search(plugin, search_query, thumb=None): found_items = [] progress.create(localize(33054)) search_in = list(filter(lambda x: x.enabled, search_engines)) - for p, se in zip(range(0, 100, 100 / len(search_in)), search_in): - progress.update(p, line1=se.name) + for p, se in zip(range(0, 100, 100 // len(search_in)), search_in): + progress.update(p, se.name) found_items.extend(se().search(search_query)) - #open('/tmp/t.t', 'w').write(repr(list(map(lambda x: x.url, found_items)))) + # open('/tmp/t.t', 'w').write(repr(list(map(lambda x: x.url, found_items)))) res_items = [] for i in sorted(found_items, key=lambda x: x.seeders, reverse=True): - if '2160p' in i.title: hd = '[2160p/{}] '.format(i.size) - elif '1080p' in i.title: hd = '[1080p/{}] '.format(i.size) - elif '720p' in i.title: hd = '[720p/{}] '.format(i.size) - else: hd = '' + if '2160p' in i.title: + hd = '[2160p/{}] '.format(i.size) + elif '1080p' in i.title: + hd = '[1080p/{}] '.format(i.size) + elif '720p' in i.title: + hd = '[720p/{}] '.format(i.size) + else: + hd = '' item = Listitem.from_dict( open_torrent, '{}{} {} ({}/{})'.format(hd, i.title, i.size, i.seeders, i.leachers), params={'url': i.url, 'cookies': i.cookies, 'referer': i.referer} - ) + ) if thumb: item.art['thumb'] = thumb else: @@ -93,6 +112,8 @@ def search(plugin, search_query, thumb=None): return res_items except: return False + + @Route.register def open_torrent(plugin, url='--back--', cookies={}, referer='', path=''): try: @@ -103,37 +124,44 @@ def open_torrent(plugin, url='--back--', cookies={}, referer='', path=''): @Route.register_delayed def set_view(): xbmc.executebuiltin('Container.SetViewMode("51")') + tf = torrent_file_fetch(url, referer, cookies) - if not tf: yield False + if not tf: + yield False t_full_path = store_torrent_file(tf) e = get_engine(t_full_path) files = sorted(list(filter( - lambda x: x.name.decode('utf-8').startswith(path) and x.name.decode('utf-8').lower().endswith(video_extensions), e.list_from_info(media_types=['video']))), - key=lambda x: x.name) - dirs = list(set(list(map( lambda x: x.name.decode('utf-8')[len(path):].lstrip('/').split('/')[0], filter( lambda x: len(x.name.decode('utf-8')[len(path):].lstrip('/').split('/')) > 1, files ) )))) + lambda x: x.name.startswith(path) and x.name.lower().endswith( + video_extensions), e.list_from_info(media_types=['video']))), + key=lambda x: x.name) + dirs = list(set(list(map(lambda x: x.name[len(path):].lstrip('/').split('/')[0], filter( + lambda x: len(x.name[len(path):].lstrip('/').split('/')) > 1, files))))) for d in sorted(dirs): item = Listitem.from_dict(open_torrent, - d, - params={'url': url, 'cookies': cookies, 'referer': referer, 'path': '{}/{}'.format( - path, d + d, + params={'url': url, 'cookies': cookies, 'referer': referer, + 'path': '{}/{}'.format( + path, d ) if path != '' else d} - ) + ) item.art.local_thumb('folder.png') yield item for i in range(len(files)): f = files[i] - p = f.name.decode('utf-8')[len(path):].lstrip('/').split('/') + p = f.name[len(path):].lstrip('/').split('/') if len(p) == 1: item = Listitem.from_dict(play_file, - '{} ({:.3f} GB)'.format(p[0], f.size / 1024.0 / 1024.0 /1024.0), - params={'t_full_path': t_full_path, 'f_index': f.index} - ) + '{} ({:.3f} GB)'.format(p[0], f.size / 1024.0 / 1024.0 / 1024.0), + params={'t_full_path': t_full_path, 'f_index': f.index} + ) item.art.local_thumb('video.png') yield item else: yield None except: yield False + + @Script.register def play_file(plugin, t_full_path, f_index): try: @@ -141,6 +169,14 @@ def play_file(plugin, t_full_path, f_index): vl.start(f_index) return False except: + + # todo + import traceback + xbmc.log(f'PLAY exception: {traceback.format_exc()}') + # + return False + + if __name__ == '__main__': run() diff --git a/addon.xml b/addon.xml index d211457..0d63fc7 100644 --- a/addon.xml +++ b/addon.xml @@ -1,11 +1,11 @@ - + - - - - - + + + + + video @@ -22,6 +22,7 @@ roman@ukamnya.ru all en_GB ru_RU + - 3.3.0: Support for Kodi 19 - 3.2.1: Fix wrong torrent size for rutracker - 3.2.0: Add searcher rutracker.org. Add socks-proxy for trackers - 3.1.0: Add searcher kinozal.tv diff --git a/resources/lib/overrrides/session.py b/resources/lib/overrrides/session.py index a44a451..0cd6e47 100644 --- a/resources/lib/overrrides/session.py +++ b/resources/lib/overrrides/session.py @@ -1,85 +1,28 @@ -import urlquick # @UnresolvedImport +from typing import Optional + from ..settings import option -import socks +import requests -class SocksiPyConnection(urlquick.HTTPConnection): - def __init__(self, proxytype, proxyaddr, proxyport=None, host='127.0.0.1', port=9050, rdns=True, username=None, password=None, **kwargs): - self.proxyargs = (proxytype, proxyaddr, proxyport, rdns, username, password) - urlquick.HTTPConnection.__init__(self, host, port=port, **kwargs) - def connect(self): - self.sock = socks.socksocket() - self.sock.setproxy(*self.proxyargs) - if type(self.timeout) in (int, float): - self.sock.settimeout(self.timeout) - self.sock.connect((self.host, self.port)) - -class SocksiPyConnectionS(urlquick.HTTPSConnection): - def __init__(self, proxytype, proxyaddr, proxyport=None, host='127.0.0.1', port=9050, rdns=True, username=None, password=None, **kwargs): - self.proxyargs = (proxytype, proxyaddr, proxyport, rdns, username, password) - urlquick.HTTPSConnection.__init__(self, host, port=port, **kwargs) - - def connect(self): - sock = socks.socksocket() - sock.setproxy(*self.proxyargs) - if type(self.timeout) in (int, float): - sock.settimeout(self.timeout) - sock.connect((self.host, self.port)) - self.sock = urlquick.ssl.wrap_socket(sock, self.key_file, self.cert_file) - -class Session(urlquick.Session): - def connect(self, req, timeout, verify): - # Fetch connection from pool and attempt to reuse if available - pool = self.request_handler[req.type] - if req.host in pool: - try: - # noinspection PyTypeChecker - return self.send_request(pool[req.host], req) - except Exception as e: - # Remove the connection from the pool as it's unusable - pool[req.host].close() - del pool[req.host] - - # Raise the exception if it's not a subclass of UrlError - if not isinstance(e, urlquick.UrlError): - raise - - - host_port = req.host.split(':') - host = host_port[0] - port = int(host_port[2]) if len(host_port) > 1 else 443 if req.type == 'https' else 80 - # Create a new connection - if not option.get_boolean('use_socks'): # @UndefinedVariable - if req.type == "https": - context = urlquick.ssl._create_unverified_context() if verify is False else None - conn = urlquick.HTTPSConnection(host, port, timeout=timeout, context=context) - else: - conn = urlquick.HTTPConnection(host, port, timeout=timeout) - else: - if req.type == "https": - context = urlquick.ssl._create_unverified_context() if verify is False else None - conn = SocksiPyConnectionS(socks.PROXY_TYPE_SOCKS5, option['socks_ip'], proxyport=int(option['socks_port']), - host=host, port=port, timeout=timeout, context=context) - else: - conn = SocksiPyConnection(socks.PROXY_TYPE_SOCKS5, option['socks_ip'], proxyport=int(option['socks_port']), - host=host, port=port, timeout=timeout) - - # Make first connection to server - response = self.send_request(conn, req) - - # Add connection to the pool if the response is not set to close - if not response.will_close: - pool[req.host] = conn - return response def torrent_file_fetch(url, referer, cookies): - sess = Session() headers = { - 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 YaBrowser/14.10.2062.12061 Safari/537.36', + 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' + 'Chrome/37.0.2062.124 YaBrowser/14.10.2062.12061 Safari/537.36', 'Referer': referer - } - resp = sess.get(url, cookies=cookies, headers=headers) + } + + resp = requests.get(url, cookies=cookies, headers=headers, proxies=proxies()) if resp.ok: return resp.content else: return None + +def proxies(): + if option.get_boolean('use_socks'): + return { + 'http': f'socks5://{option["socks_ip"]}:{option["socks_port"]}', + 'https': f'socks5://{option["socks_ip"]}:{option["socks_port"]}' + } + else: + return None diff --git a/resources/lib/player.py b/resources/lib/player.py index 55f2a9f..1b11700 100644 --- a/resources/lib/player.py +++ b/resources/lib/player.py @@ -1,61 +1,69 @@ import xbmc, xbmcgui from .utils import get_engine, localize -class TorrentPlayer(xbmc.Player) : - pyrrent_engine = None - loop = None - paused = False - def onPlayBackEnded(self): - self.pyrrent_engine.close() - self.loop.stopped = True - xbmc.Player().stop() - def onPlayBackPaused(self): - self.pyrrent_engine.pause() - self.paused = True - def onPlayBackResumed(self): - self.paused = False - self.pyrrent_engine.resume() - def onPlayBackStopped(self): - self.pyrrent_engine.close() - self.loop.stopped = True - xbmc.Player().stop() - def play(self, engine, f_index): - self.pyrrent_engine = engine - self.pyrrent_engine.start() - self.pyrrent_engine.activate_file(f_index) - monitor = xbmc.Monitor() - pw = xbmcgui.DialogProgress() - pw.create(localize(33055), line1='0 Kbit/s') - f_size = self.pyrrent_engine.file_status(f_index).size - EXPECTED_KBYTES = f_size / 3 / 1024 / 1024 - if EXPECTED_KBYTES > 768: - EXPECTED_KBYTES = 768 - while True: - xbmc.sleep(500) - if monitor.abortRequested() or pw.iscanceled(): - pw.close() - self.pyrrent_engine.close() - xbmc.Player().stop() - self.loop.stopped = True - return False - status = self.pyrrent_engine.status() - d_rate = status.download_rate - # xbmc.log('*** DRATE: {}'.format(d_rate), level=xbmc.LOGNOTICE) - perc = d_rate / EXPECTED_KBYTES * 100 - if perc > 100: perc = 100 - pw.update(perc, line1=' {} / {} KB/s'.format(int(d_rate), int(EXPECTED_KBYTES))) - if perc == 100: - pw.close() - break - fstat = self.pyrrent_engine.file_status(f_index) - listitem = xbmcgui.ListItem('.'.join(fstat.name.split('/')[-1].split('.')[:-1])[:-1], path=fstat.url) - xbmc.Player.play(self, fstat.url, listitem) +class TorrentPlayer(xbmc.Player): + pyrrent_engine = None + loop = None + paused = False + + def onPlayBackEnded(self): + self.pyrrent_engine.close() + self.loop.stopped = True + xbmc.Player().stop() + + def onPlayBackPaused(self): + self.pyrrent_engine.pause() + self.paused = True + + def onPlayBackResumed(self): + self.paused = False + self.pyrrent_engine.resume() + + def onPlayBackStopped(self): + self.pyrrent_engine.close() + self.loop.stopped = True + xbmc.Player().stop() + + def play(self, engine, f_index): + self.pyrrent_engine = engine + self.pyrrent_engine.start() + self.pyrrent_engine.activate_file(f_index) + monitor = xbmc.Monitor() + pw = xbmcgui.DialogProgress() + pw.create(localize(33055), '0 Kbit/s') + f_size = self.pyrrent_engine.file_status(f_index).size + EXPECTED_KBYTES = f_size // 3 // 1024 // 1024 + if EXPECTED_KBYTES > 768: + EXPECTED_KBYTES = 768 + while True: + xbmc.sleep(500) + if monitor.abortRequested() or pw.iscanceled(): + pw.close() + self.pyrrent_engine.close() + xbmc.Player().stop() + self.loop.stopped = True + return False + status = self.pyrrent_engine.status() + d_rate = status.download_rate + # xbmc.log('*** DRATE: {}'.format(d_rate), level=xbmc.LOGNOTICE) + perc = d_rate // EXPECTED_KBYTES * 100 + if perc > 100: perc = 100 + pw.update(perc, ' {} / {} KB/s'.format(int(d_rate), int(EXPECTED_KBYTES))) + if perc == 100: + pw.close() + break + fstat = self.pyrrent_engine.file_status(f_index) + listitem = xbmcgui.ListItem('.'.join(fstat.name.split('/')[-1].split('.')[:-1])[:-1], path=fstat.url) + xbmc.Player.play(self, fstat.url, listitem) + class VideoLoop(object): stopped = False + def __init__(self, torr_fp): self.e = get_engine(torr_fp) + def start(self, f_index): self.statinfo = xbmcgui.Dialog() self.mediaPlayer = TorrentPlayer() @@ -68,11 +76,12 @@ class VideoLoop(object): status = self.e.status() f_status = self.e.file_status(f_index) if self.mediaPlayer.paused: - self.statinfo.notification('[{}]{}.'.format(('|' * (int(f_status.progress * 100) / 2)).ljust(50, '.'), ' ' * 100), - 'S: {} DL: {} KB/s UL: {} KB/s'.format(status.num_seeds, - status.download_rate, - status.upload_rate), - time=2, sound=False - ) + self.statinfo.notification( + # '[{}]{}.'.format(('|' * (int(f_status.progress * 100) // 2)).ljust(50, '.'), ' ' * 100), + '[{}]'.format(('|' * (int(f_status.progress * 100) // 2)).ljust(50, '.')), + 'S: {} DL: {} KB/s UL: {} KB/s'.format(status.num_seeds, + status.download_rate, + status.upload_rate), + time=2, sound=False + ) xbmc.sleep(1000) - diff --git a/resources/lib/searchers/__init__.py b/resources/lib/searchers/__init__.py index 816a4b5..fbac717 100644 --- a/resources/lib/searchers/__init__.py +++ b/resources/lib/searchers/__init__.py @@ -1,8 +1,10 @@ -from codequick.utils import urljoin_partial # @UnresolvedImport -import urlquick # @UnresolvedImport -from ..settings import option -from ..overrrides import session -#import xbmc +import xbmc +from codequick.utils import urljoin_partial +from ..overrrides.session import proxies +from requests.sessions import Session +from htmlement import HTMLement +from urllib.parse import quote + class ResultItem(object): def __init__(self, url, title, size, seeders, leachers, icon='video.png', cookies={}, referer=''): @@ -15,34 +17,46 @@ class ResultItem(object): self.cookies = cookies self.referer = referer + class Searcher(object): base_url = None search_path = None cookies = {} headers = {} name = 'BaseClass' + def __init__(self): - self.session = session.Session() + self.session = Session() + self.session.proxies.update(proxies()) self.headers = { - 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 YaBrowser/14.10.2062.12061 Safari/537.36', + 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' + 'Chrome/37.0.2062.124 YaBrowser/14.10.2062.12061 Safari/537.36', 'Referer': self.base_url - } + } + def prepare(self): - '''Login or something else if needed''' + """Login or something else if needed""" return True + def search(self, query): if self.prepare(): try: url_constructor = urljoin_partial(self.base_url) - s_url = self.normalize_url(url_constructor(self.search_path.format(urlquick.quote(query)))) + s_url = self.normalize_url(url_constructor(self.search_path.format(quote(query)))) resp = self.session.get(s_url, cookies=self.cookies, headers=self.headers) - body = resp.parse('body') - return self.process(body) + parser = HTMLement('body') + parser.feed(resp.text) + # todo отладка + xbmc.log(f'SEARCH BODY:\n{resp.text}') + # + return self.process(parser.close()) except: return [] else: return [] + def process(self, body): - '''Process element tree''' + """Process element tree""" + def normalize_url(self, url): return url diff --git a/resources/lib/searchers/kinozal.py b/resources/lib/searchers/kinozal.py index aa3eb17..7ed9284 100644 --- a/resources/lib/searchers/kinozal.py +++ b/resources/lib/searchers/kinozal.py @@ -1,15 +1,19 @@ # -*- coding: utf-8 -*- +import xbmc + from . import Searcher, urljoin_partial, ResultItem from ..settings import option from ..utils import notify, localize -from codequick.listing import local_image # @UnresolvedImport +from codequick.listing import local_image + class SearchEngine(Searcher): base_url = option['kinozal_url'] search_path = '/browse.php?s={}&t=1' name = 'Kinozal.tv' icon = 'searcher_kinozal.png' - enabled = option.get_boolean('kinozal_enable') # @UndefinedVariable + enabled = option.get_boolean('kinozal_enable') + def prepare(self): if self.cookies: c_uid = self.cookies.get('uid', None) @@ -17,6 +21,7 @@ class SearchEngine(Searcher): if c_uid and c_pass: return True return self.login() + def process(self, body): url_constructor = urljoin_partial(self.base_url) rows = list(filter(lambda x: x.get('class') in ['first bg', 'bg'], body.findall('.//tr[@class]'))) @@ -28,20 +33,31 @@ class SearchEngine(Searcher): seeders = int(r.find('.//td[@class="sl_s"]').text.strip()) leachers = int(r.find('.//td[@class="sl_p"]').text.strip()) size_l = list(filter(lambda x: x.text.strip().endswith((u'ГБ', u'МБ')), - r.findall('.//td[@class="s"]')) - ) + r.findall('.//td[@class="s"]')) + ) size = size_l[0].text.strip() if len(size_l) else '0' yield ResultItem(url, title, size, seeders, leachers, self.icon, self.cookies, self.base_url) + def login(self): user = option['kinozal_login'] password = option['kinozal_password'] try: if not user or not password: raise Exception - resp = self.session.post('{}/takelogin.php'.format(self.base_url), data={'username': user, 'password': password, 'returnto': ''}, + resp = self.session.post('{}/takelogin.php'.format(self.base_url), + data={'username': user, 'password': password, 'returnto': ''}, cookies={}, headers=self.headers, allow_redirects=False) + # todo отладка + xbmc.log(f'Kinozal LOGIN BODY:\n{resp.text}') + # + if not resp.ok: raise Exception + + # todo отладка + xbmc.log(f'LOGIN COOKIE:\n{resp.cookies}') + # + cookies = resp.cookies c_uid = cookies.get('uid', None) c_pass = cookies.get('pass', None) @@ -52,5 +68,6 @@ class SearchEngine(Searcher): except: notify(self.name, localize(33056), local_image.format(self.icon)) return False + def normalize_url(self, url): return url.encode('cp1251') diff --git a/resources/lib/searchers/rutracker.py b/resources/lib/searchers/rutracker.py index 6c1dbd0..a45b46f 100644 --- a/resources/lib/searchers/rutracker.py +++ b/resources/lib/searchers/rutracker.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +import xbmc + from . import Searcher, urljoin_partial, ResultItem from ..settings import option from ..utils import notify, localize @@ -43,6 +45,11 @@ class SearchEngine(Searcher): cookies={}, headers=self.headers, allow_redirects=False) if not resp.ok: raise Exception + + # todo отладка + xbmc.log(f'RuTracker LOGIN BODY:\n{resp.text}') + # + cookies = resp.cookies bb_session = cookies.get('bb_session', None) if not bb_session: diff --git a/resources/lib/utils/__init__.py b/resources/lib/utils/__init__.py index 348ce0b..7ce9284 100644 --- a/resources/lib/utils/__init__.py +++ b/resources/lib/utils/__init__.py @@ -1,28 +1,26 @@ -from codequick.support import addon_data # @UnresolvedImport -from codequick.listing import local_image # @UnresolvedImport -from urlquick import urljoin # @UnresolvedImport +from codequick.support import addon_data # @UnresolvedImport +from codequick.utils import urljoin_partial # @UnresolvedImport from ..settings import option import xbmcgui import os from hashlib import sha1 from pyrrent2http import Engine # @UnresolvedImport -import sys -py3 = sys.version_info >= (3, 0) -if py3: - from urllib.request import pathname2url # @UnresolvedImport -else: - from urllib import pathname2url +from urllib.request import pathname2url + def notify(heading, message, icon=xbmcgui.NOTIFICATION_INFO): n = xbmcgui.Dialog() n.notification(heading, message, icon, time=5, sound=True) + def localize(sid): return addon_data.getLocalizedString(sid) + + def store_torrent_file(file_bytes): h = sha1(file_bytes).hexdigest() t_fname = '{}.torrent'.format(h) - full_path = os.path.join(storage_toorents_dir, t_fname) + full_path = os.path.join(storage_torrents_dir, t_fname) if os.path.exists(full_path): with open(full_path, 'rb') as f: if sha1(f.read()).hexdigest() == h: @@ -30,32 +28,39 @@ def store_torrent_file(file_bytes): with open(full_path, 'wb') as f: f.write(file_bytes) return full_path + + def torrent_full_path(t_fname): - return os.path.join(storage_toorents_dir, t_fname) + return os.path.join(storage_torrents_dir, t_fname) + def file_url(path): if not path.startswith('file:'): - path = urljoin('file:', pathname2url(path)) + path = urljoin_partial('file:')(pathname2url(path)) return path + def get_engine(torrent_uri): - if option.get_boolean('use_socks_for_trackers'): # @UndefinedVariable + if option.get_boolean('use_socks_for_trackers'): # @UndefinedVariable proxy = { 'host': option['socks_ip'], 'port': int(option['socks_port']) - } + } else: proxy = None return Engine(uri=file_url(torrent_uri), download_path=storage_download_dir, - encryption=1, keep_complete=False, keep_incomplete=False, - dht_routers=["router.bittorrent.com:6881", "router.utorrent.com:6881"], use_random_port=False, listen_port=6881, - user_agent='', enable_dht=True, proxy=proxy) + encryption=1, keep_complete=False, keep_incomplete=False, + dht_routers=["router.bittorrent.com:6881", "router.utorrent.com:6881"], use_random_port=False, + listen_port=6881, + user_agent='', enable_dht=True, proxy=proxy) + + while not option['storage_dir']: dialog = xbmcgui.Dialog() dialog.ok(localize(33000), localize(33051)) addon_data.openSettings() storage_root = os.path.abspath(os.path.join(option['storage_dir'], 'Torrenter3')) -storage_toorents_dir = os.path.join(storage_root, 'torrents') +storage_torrents_dir = os.path.join(storage_root, 'torrents') storage_download_dir = os.path.join(storage_root, 'download') -if not os.path.exists(storage_toorents_dir): os.makedirs(storage_toorents_dir) +if not os.path.exists(storage_torrents_dir): os.makedirs(storage_torrents_dir) if not os.path.exists(storage_download_dir): os.makedirs(storage_download_dir)