diff --git a/addon.py b/addon.py index d9bc58d..d7a0e11 100644 --- a/addon.py +++ b/addon.py @@ -4,7 +4,7 @@ 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 +from resources.lib.searchers import rutor, kinozal from resources.lib.utils import localize, store_torrent_file, get_engine from resources.lib.overrrides.session import torrent_file_fetch from resources.lib.player import VideoLoop @@ -12,7 +12,8 @@ from resources.lib.player import VideoLoop video_extensions = ('.mp4', '.avi', '.3gp', '.ogv', '.mkv', '.ts', '.mpg', '.mpeg', '.webm', '.flv', '.vob') search_engines = [ - rutor.SearchEngine + rutor.SearchEngine, + kinozal.SearchEngine ] ROOT = os.path.abspath(os.path.dirname(__file__)) @@ -66,7 +67,8 @@ def search(plugin, search_query, thumb=None): progress = xbmcgui.DialogProgress() found_items = [] progress.create(localize(33054)) - for p, se in zip(range(0, 100, 100 / len(search_engines)), search_engines): + 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) found_items.extend(se().search(search_query)) res_items = [] diff --git a/resources/language/resource.language.en_gb/strings.po b/resources/language/resource.language.en_gb/strings.po index 683a107..1eaed8e 100644 --- a/resources/language/resource.language.en_gb/strings.po +++ b/resources/language/resource.language.en_gb/strings.po @@ -23,6 +23,14 @@ msgctxt "#33001" msgid "General" msgstr "General" +msgctxt "#33002" +msgid "RuTor" +msgstr "RuTor" + +msgctxt "#33003" +msgid "Kinozal" +msgstr "Kinozal" + msgctxt "#33011" msgid "Storage folder" msgstr "Storage folder" @@ -59,3 +67,22 @@ msgctxt "#33055" msgid "Waiting for download" msgstr "Waiting for download" +msgctxt "#33056" +msgid "Invalid login or password" +msgstr "Invalid login or password" + +msgctxt "#33057" +msgid "Enable searcher" +msgstr "Enable searcher" + +msgctxt "#33058" +msgid "Searcher URL" +msgstr "Searcher URL" + +msgctxt "#33059" +msgid "Login" +msgstr "Login" + +msgctxt "#33060" +msgid "Password" +msgstr "Password" diff --git a/resources/language/resource.language.ru_ru/strings.po b/resources/language/resource.language.ru_ru/strings.po index d8d019f..73c702f 100644 --- a/resources/language/resource.language.ru_ru/strings.po +++ b/resources/language/resource.language.ru_ru/strings.po @@ -23,6 +23,14 @@ msgctxt "#33001" msgid "General" msgstr "Основные" +msgctxt "#33002" +msgid "RuTor" +msgstr "RuTor" + +msgctxt "#33003" +msgid "Kinozal" +msgstr "Kinozal" + msgctxt "#33011" msgid "Storage folder" msgstr "Папка хранения" @@ -58,3 +66,15 @@ msgstr "Поиск на трекерах" msgctxt "#33055" msgid "Waiting for download" msgstr "Ожидаем начало загрузки" + +msgctxt "#33056" +msgid "Invalid login or password" +msgstr "Неверный логин или пароль" + +msgctxt "#33057" +msgid "Enable searcher" +msgstr "Включить поисковик" + +msgctxt "#33058" +msgid "Searcher URL" +msgstr "URL поисковика" diff --git a/resources/lib/overrrides/session.py b/resources/lib/overrrides/session.py index 6b8f574..a44a451 100644 --- a/resources/lib/overrrides/session.py +++ b/resources/lib/overrrides/session.py @@ -66,7 +66,7 @@ class Session(urlquick.Session): # 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 diff --git a/resources/lib/searchers/__init__.py b/resources/lib/searchers/__init__.py index a5a2919..816a4b5 100644 --- a/resources/lib/searchers/__init__.py +++ b/resources/lib/searchers/__init__.py @@ -23,21 +23,26 @@ class Searcher(object): name = 'BaseClass' def __init__(self): self.session = session.Session() + 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', + 'Referer': self.base_url + } def prepare(self): '''Login or something else if needed''' + return True def search(self, query): - self.prepare() - url_constructor = urljoin_partial(self.base_url) - s_url = url_constructor(self.search_path.format(urlquick.quote(query))) - self.set_headers() - resp = self.session.get(s_url, cookies=self.cookies, headers=self.headers) - self.cookies = resp.cookies - body = resp.parse('body') - return self.process(body) + 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)))) + resp = self.session.get(s_url, cookies=self.cookies, headers=self.headers) + body = resp.parse('body') + return self.process(body) + except: + return [] + else: + return [] def process(self, body): '''Process element tree''' - def set_headers(self): - 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', - 'Referer': self.base_url - } + def normalize_url(self, url): + return url diff --git a/resources/lib/searchers/kinozal.py b/resources/lib/searchers/kinozal.py new file mode 100644 index 0000000..61d8299 --- /dev/null +++ b/resources/lib/searchers/kinozal.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +from . import Searcher, urljoin_partial, ResultItem +from ..settings import option +from ..utils import notify, localize +from codequick.listing import local_image # @UnresolvedImport + +class SearchEngine(Searcher): + base_url = option['kinozal_url'] + search_path = '/browse.php?s={}&g=0&c=0&v=0&d=0&w=0&t=1&f=0' + name = 'Kinozal.tv' + icon = 'searcher_kinozal.png' + enabled = option.get_boolean('kinozal_enable') # @UndefinedVariable + def prepare(self): + if self.cookies: + c_uid = self.cookies.get('uid', None) + c_pass = self.cookies.get('pass', None) + 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]'))) + for r in rows: + link = r.find('.//td[@class="nam"]/a') + url_part = link.get('href').strip().split('=')[1] + url = url_constructor(u'/download.php?id={}'.format(url_part)) + title = link.text + seeders = int(r.find('.//td[@class="sl_s"]').text.strip()) + leachers = int(r.find('.//td[@class="sl_p"]').text.strip()) + size = list( + list(filter(lambda x: x.text.strip().endswith((u'ГБ', u'МБ')), + r.findall('.//td[@class="s"]')) + )[0].text.strip() + )[0].strip() + 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': ''}, + cookies={}, headers=self.headers, allow_redirects=False) + if not resp.ok: + raise Exception + cookies = resp.cookies + c_uid = cookies.get('uid', None) + c_pass = cookies.get('pass', None) + if not c_uid or not c_pass: + raise Exception + self.cookies = cookies + return True + except: + notify('Kinozal.tv', localize(33056), local_image.format('searcher_kinozal.png')) + return False + def normalize_url(self, url): + return url.encode('cp1251') diff --git a/resources/lib/searchers/rutor.py b/resources/lib/searchers/rutor.py index 740ff89..9593104 100644 --- a/resources/lib/searchers/rutor.py +++ b/resources/lib/searchers/rutor.py @@ -1,11 +1,12 @@ from . import Searcher, urljoin_partial, ResultItem +from ..settings import option class SearchEngine(Searcher): - #base_url = 'http://new-tor.top' - base_url = 'http://rutor.info' + base_url = option['rutor_url'] search_path = '/search/0/0/100/2/{}' name = 'RuTor.org' icon = 'searcher_rutor.png' + enabled = option.get_boolean('rutor_enable') # @UndefinedVariable def process(self, body): url_constructor = urljoin_partial(self.base_url) rows = list(filter(lambda x: len(x.findall('.//a')) == 3, body.findall('.//tr'))) diff --git a/resources/lib/utils/__init__.py b/resources/lib/utils/__init__.py index e44adb4..3c71479 100644 --- a/resources/lib/utils/__init__.py +++ b/resources/lib/utils/__init__.py @@ -13,6 +13,10 @@ if py3: else: from urllib 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): diff --git a/resources/settings.xml b/resources/settings.xml index 25b9f2e..00220f5 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -6,4 +6,14 @@ + + + + + + + + + +