def _get_torrent_info(item): from xbmctorrent.search import scrapers as search from xbmctorrent.utils import get_quality_from_name scrapers = search.Scrapers() if not plugin.get_setting("rutor_usesearch", bool): meta = scrapers.default(item) else: meta = scrapers.scraper(scraper_name, item) meta["path"] = item["path"] meta["is_playable"] = item["is_playable"] meta.setdefault("stream_info", {}).update(get_quality_from_name(meta['label'])) return meta
def _get_torrent_info(item): from xbmctorrent.search import scrapers as search from xbmctorrent.utils import get_quality_from_name try: scrapers = search.Scrapers() if not plugin.get_setting("rutracker_usesearch", bool): meta = scrapers.default(item) else: meta = scrapers.scraper(scraper_name, item) meta["path"] = item["path"] meta["is_playable"] = item["is_playable"] meta.setdefault("stream_info", {}).update(get_quality_from_name(meta['label'])) return meta except: plugin.log.error("Unexpected error: %s" % format_exc().split('\n')[-2]) return scrapers.default(item)
def _get_torrent_info(item): from xbmctorrent.search import scrapers as search from xbmctorrent.utils import get_quality_from_name try: scrapers = search.Scrapers() if not plugin.get_setting("rutracker_usesearch", bool): meta = scrapers.default(item) else: meta = scrapers.scraper(scraper_name, item) meta["path"] = item["path"] meta["is_playable"] = item["is_playable"] meta.setdefault("stream_info", {}).update( get_quality_from_name(meta['label'])) return meta except: plugin.log.error("Unexpected error: %s" % format_exc().split('\n')[-2]) return scrapers.default(item)
def rutor_play(tid, pulsar): from copy import deepcopy from contextlib import closing from bencode import bencode, bdecode from urlparse import urljoin from xbmctorrent.magnet import generate_magnet from xbmctorrent.utils import first, SafeDialogProgress, get_quality_from_name, get_current_list_item from xbmctorrent.acestream import ace_supported with closing(SafeDialogProgress(delay_close=0)) as dialog: dialog.create(plugin.name) dialog.update(percent=0, line1="Получение информации о раздаче...") torrent_url = urljoin(DOWNLOAD_URL, "download/%s" % tid) try: metadata = bdecode(url_get(torrent_url, headers=HEADERS)) except: import xbmcgui plugin.log.error("Unexpected error: %s" % sys.exc_info()[0]) xbmcgui.Dialog().ok(plugin.name, "Не удалось получить данные от сервера") return dialog.update(percent=100, line1="Готово") # Get currently selected item current_item = get_current_list_item() current_item.setdefault("stream_info", {}).update(get_quality_from_name(current_item['label'])) if "files" in metadata["info"] and ace_supported(): items = {} for index, info in enumerate(metadata["info"]["files"]): name = "/".join(info["path"]) if not _rutor_valid_file(name): continue items[index] = deepcopy(current_item) items[index].update({ "label" : name, "path" : plugin.url_for("torrent_play", url=torrent_url, index=index, name=name), "is_playable" : True }) items[index].setdefault("info",{}).update({ "title" : name, }) # start playback if torrent contains only one file if len(items) == 1: index, item = items.popitem() if not plugin.get_setting("force_ace", bool): item["path"] = plugin.url_for("play", uri=generate_magnet(metadata, item["label"])) plugin.play_video(item) yield item else: plugin.add_sort_method('label') for i in items.values(): yield i else: name = metadata["info"].get("name") or " / ".join(first(metadata["info"]["files"])["path"]) or "rutor.org" if plugin.get_setting("force_ace", bool) and ace_supported(): current_item["path"] = plugin.url_for("torrent_play", url=torrent_url, index=0, name=name) else: current_item["path"] = plugin.url_for(["play","play_with_pulsar"][int(pulsar)], uri=generate_magnet(metadata, name)) current_item["is_playable"] = True plugin.play_video(current_item) yield current_item
def kickass_page(root, page): import re import xbmc import xbmcgui from bs4 import BeautifulSoup from contextlib import closing from concurrent import futures from urlparse import urljoin from xbmctorrent import tmdb from xbmctorrent.utils import first, terminating, url_get, get_quality_from_name content_type = first(plugin.request.args.get("content_type")) or None if content_type: plugin.set_content(content_type) page = int(page) page_data = url_get(urljoin(BASE_URL, "%s/%d" % (root, page))) soup = BeautifulSoup(page_data, "html5lib") torrent_nodes = [node.parent for node in soup.findAll("td", "torrentnameCell")] def _get_torrent_info_with_meta(url): torrent_info = get_torrent_info(url) if torrent_info["movie"] and torrent_info["imdb_id"]: torrent_info["tmdb"] = tmdb.get(torrent_info["imdb_id"]) return torrent_info with closing(xbmcgui.DialogProgress()) as dialog: dialog.create(plugin.name) dialog.update(percent=0, line1="Fetching torrent information...", line2="", line3="") state = {"done": 0} def on_torrent(future): data = future.result() state["done"] += 1 dialog.update( percent=int(state["done"] * 100.0 / len(torrent_nodes)), line2=data.get("title") or "", ) with futures.ThreadPoolExecutor(max_workers=3) as pool: movies = [] for node in torrent_nodes: info_nodes = node.findAll("td") a_node = first(info_nodes[0].select("div.torrentname a.plain")) movies.append(pool.submit(_get_torrent_info_with_meta, urljoin(BASE_URL, a_node["href"]))) [future.add_done_callback(on_torrent) for future in movies] while not all(job.done() for job in movies): if dialog.iscanceled(): return xbmc.sleep(100) movies = [movie.result() for movie in movies] for i, movie in enumerate(movies): if movie.get("tmdb"): item = tmdb.get_list_item(movie["tmdb"]) proper_kat_title = re.sub("\s+", " ", re.sub(r"[().-]", " ", movie["title"])) item["label"] = "%s (%s)" % (item["label"], re.sub(r"(?i)%s" % item["label"], "", proper_kat_title).strip()) else: item = { "label": movie["title"], "info": { "genre": ", ".join(movie["genres"]), } } lower_title = movie["title"].lower() if "x264" in lower_title: item.setdefault("stream_info", {})["codec"] = item.setdefault("info", {})["video_codec"] = "h264" if "xvid" in lower_title: item.setdefault("stream_info", {})["codec"] = item.setdefault("info", {})["video_codec"] = "xvid" if "720p" in lower_title: item.setdefault("stream_info", {}).update({ "width": 1280, "height": 720, }) if "1080p" in lower_title: item.setdefault("stream_info", {}).update({ "width": 1920, "height": 1080, }) item.update({ "path": plugin.url_for("play", magnet=movie["magnet_url"]), "is_playable": True, }) item.setdefault("info", {}).update({ "count": i, "genre": "%s (S:%s P:%s)" % (item.get("info", {}).get("genre") or "", movie["seeders"], movie["leechers"]), }) item.setdefault("stream_info", {}).update({ "video": get_quality_from_name(movie["title"]), }) yield item yield { "label": "Next page...", "path": plugin.url_for("kickass_page", root=root, page=page + 1, content_type=content_type), }
def parse(data, content_type=None): import xbmc import xml.etree.ElementTree as ET from itertools import izip_longest from concurrent import futures from contextlib import nested, closing from xbmctorrent.utils import SafeDialogProgress, get_quality_from_name, get_show_info_from_name, normalize_release_tags from xbmctorrent import tmdb root = ET.fromstring(data) def _text(node, path): n = node.find(path) if n is not None: return n.text def _attr(node, path, attrib): n = node.find(path) if n is not None: return n.attrib.get(attrib) items = [] for node in root.getiterator("item"): item = { "title": _text(node, "title"), "description": _text(node, "description"), "category": _text(node, "category"), "pub_date": _text(node, "pubDate"), "seeds": _text(node, ".//{%(torrent)s}seeds" % NSMAP) or _text(node, "numSeeders") or _text(node, "seeders"), "peers": _text(node, ".//{%(torrent)s}peers" % NSMAP) or _text(node, "numLeechers") or _text(node, "leechers"), "content_length": _text(node, ".//{%(torrent)s}contentLength" % NSMAP) or _attr(node, ".//enclosure", "length"), "href": _text(node, ".//{%(torrent)s}magnetURI" % NSMAP) or _attr(node, ".//enclosure", "url") or _text(node, "./link"), "filename": _text(node, ".//{%(torrent)s}fileName" % NSMAP), } find_image(item) check_imdb_id(item) items.append(item) tmdb_list = [] if content_type: with closing(SafeDialogProgress(delay_close=0)) as dialog: dialog.create(plugin.name) dialog.update(percent=0, line1="Fetching torrent information...", line2="", line3="") with futures.ThreadPoolExecutor(max_workers=POOL_WORKERS) as pool: futures = [] for item in items: if item.get("imdb_id"): futures.append(pool.submit(tmdb.get, item["imdb_id"])) else: futures.append(None) state = {"done": 0} def on_item(future): state["done"] += 1 dialog.update( percent=int(state["done"] * 100.0 / len(filter(None, futures))), ) [future.add_done_callback(on_item) for future in futures if future] while not all(future.done() for future in futures if future): if dialog.iscanceled(): return xbmc.sleep(100) tmdb_list = [future and future.result() or None for future in futures] for item, tmdb_data in izip_longest(items, tmdb_list): if tmdb_data: list_item = tmdb.get_list_item(tmdb_data) release_tags = normalize_release_tags(item["title"], list_item["label"]) if release_tags: list_item["label"] = "%s (%s)" % (list_item["label"], release_tags) else: list_item = { "label": item["title"], "icon": item.get("img") or "", "thumbnail": item.get("img") or "", "info": { "genre": item["category"], } } list_item.update({ "path": plugin.url_for("play", uri=item["href"]), "is_playable": True, }) list_item.setdefault("info", {}).update({ "genre": "%s (S:%s P:%s)" % (list_item.get("info", {}).get("genre") or "", item["seeds"], item["peers"]), }) list_item.setdefault("stream_info", {}).update(get_quality_from_name(item["title"])) yield list_item
def check_episode_data(item): from xbmctorrent.utils import get_show_info_from_name show_info = get_quality_from_name(item["title"]) if not show_info: return
def parse(data, content_type=None): import xbmc import xml.etree.ElementTree as ET from itertools import izip_longest from concurrent import futures from contextlib import nested, closing from xbmctorrent.utils import SafeDialogProgress, get_quality_from_name, get_show_info_from_name, normalize_release_tags from xbmctorrent import tmdb root = ET.fromstring(data) def _text(node, path): n = node.find(path) if n is not None: return n.text def _attr(node, path, attrib): n = node.find(path) if n is not None: return n.attrib.get(attrib) items = [] for node in root.getiterator("item"): item = { "title": _text(node, "title"), "description": _text(node, "description"), "category": _text(node, "category"), "pub_date": _text(node, "pubDate"), "seeds": _text(node, ".//{%(torrent)s}seeds" % NSMAP) or _text(node, "numSeeders") or _text(node, "seeders"), "peers": _text(node, ".//{%(torrent)s}peers" % NSMAP) or _text(node, "numLeechers") or _text(node, "leechers"), "content_length": _text(node, ".//{%(torrent)s}contentLength" % NSMAP) or _attr(node, ".//enclosure", "length"), "href": _text(node, ".//{%(torrent)s}magnetURI" % NSMAP) or _attr(node, ".//enclosure", "url") or _text(node, "./link"), "filename": _text(node, ".//{%(torrent)s}fileName" % NSMAP), } find_image(item) check_imdb_id(item) items.append(item) tmdb_list = [] if content_type: with closing(SafeDialogProgress(delay_close=0)) as dialog: dialog.create(plugin.name) dialog.update(percent=0, line1="Fetching torrent information...", line2="", line3="") with futures.ThreadPoolExecutor(max_workers=POOL_WORKERS) as pool: futures = [] for item in items: if item.get("imdb_id"): futures.append(pool.submit(tmdb.get, item["imdb_id"])) else: futures.append(None) state = {"done": 0} def on_item(future): state["done"] += 1 dialog.update(percent=int(state["done"] * 100.0 / len(filter(None, futures))), ) [ future.add_done_callback(on_item) for future in futures if future ] while not all(future.done() for future in futures if future): if dialog.iscanceled(): return xbmc.sleep(100) tmdb_list = [future and future.result() or None for future in futures] for item, tmdb_data in izip_longest(items, tmdb_list): if tmdb_data: list_item = tmdb.get_list_item(tmdb_data) release_tags = normalize_release_tags(item["title"], list_item["label"]) if release_tags: list_item["label"] = "%s (%s)" % (list_item["label"], release_tags) else: list_item = { "label": item["title"], "icon": item.get("img") or "", "thumbnail": item.get("img") or "", "info": { "genre": item["category"], } } list_item.update({ "path": plugin.url_for("play", uri=item["href"]), "is_playable": True, }) list_item.setdefault("info", {}).update({ "genre": "%s (S:%s P:%s)" % (list_item.get("info", {}).get("genre") or "", item["seeds"], item["peers"]), }) list_item.setdefault("stream_info", {}).update(get_quality_from_name(item["title"])) yield list_item
def rutor_play(tid, pulsar): from copy import deepcopy from contextlib import closing from bencode import bencode, bdecode from urlparse import urljoin from xbmctorrent.magnet import generate_magnet from xbmctorrent.utils import first, SafeDialogProgress, get_quality_from_name, get_current_list_item from xbmctorrent.acestream import ace_supported with closing(SafeDialogProgress(delay_close=0)) as dialog: dialog.create(plugin.name) dialog.update(percent=0, line1="Получение информации о раздаче...") torrent_url = urljoin(DOWNLOAD_URL, "download/%s" % tid) try: metadata = bdecode(url_get(torrent_url, headers=HEADERS)) except: import xbmcgui plugin.log.error("Unexpected error: %s" % sys.exc_info()[0]) xbmcgui.Dialog().ok(plugin.name, "Не удалось получить данные от сервера") return dialog.update(percent=100, line1="Готово") # Get currently selected item current_item = get_current_list_item() current_item.setdefault("stream_info", {}).update( get_quality_from_name(current_item['label'])) if "files" in metadata["info"] and ace_supported(): items = {} for index, info in enumerate(metadata["info"]["files"]): name = "/".join(info["path"]) if not _rutor_valid_file(name): continue items[index] = deepcopy(current_item) items[index].update({ "label": name, "path": plugin.url_for("torrent_play", url=torrent_url, index=index, name=name), "is_playable": True }) items[index].setdefault("info", {}).update({ "title": name, }) # start playback if torrent contains only one file if len(items) == 1: index, item = items.popitem() if not plugin.get_setting("force_ace", bool): item["path"] = plugin.url_for("play", uri=generate_magnet( metadata, item["label"])) plugin.play_video(item) yield item else: plugin.add_sort_method('label') for i in items.values(): yield i else: name = metadata["info"].get("name") or " / ".join( first(metadata["info"]["files"])["path"]) or "rutor.org" if plugin.get_setting("force_ace", bool) and ace_supported(): current_item["path"] = plugin.url_for("torrent_play", url=torrent_url, index=0, name=name) else: current_item["path"] = plugin.url_for( ["play", "play_with_pulsar"][int(pulsar)], uri=generate_magnet(metadata, name)) current_item["is_playable"] = True plugin.play_video(current_item) yield current_item
def rutor_details(catind, tid): import urllib from bs4 import BeautifulSoup, SoupStrainer from urlparse import urljoin from xbmctorrent.utils import get_quality_from_name from xbmctorrent.search import scrapers as search scraper_name = "" category = ([cat for cat in CATEGORIES if cat[0] == catind] or [("0", u"", "", "")])[0] scraper_name = category[3] plugin.set_content(category[2]) tid = int(tid) try: html_data = url_get(urljoin(BASE_URL, "torrent/%d/" % tid), headers=HEADERS) except: import xbmcgui xbmcgui.Dialog().ok(plugin.name, "Не удалось получить данные от сервера") return soup = BeautifulSoup(html_data, "html5lib") div_download = soup.select("div#download")[0] div_index = soup.select("div#index") if len(div_index) == 0: plugin.redirect(plugin.url_for("rutor_play", tid=tid)) return scrapers = search.Scrapers() details = soup.select("table#details")[0].findAll("tr") seeds = details[4].contents[1].text peers = details[5].contents[1].text size = details[8].contents[1].text size = size[:size.find(" ")] title = _rutor_cleantitle(soup.h1.text) label = "%s | %s (S:%s P:%s)" % (title, size, seeds, peers) item = {"label": label, "info": {"title": title}} if plugin.get_setting("rutor_usesearch", bool): meta = scrapers.scraper(scraper_name, item) else: meta = scrapers.default(item) meta["path"] = plugin.url_for("rutor_play", tid=tid) meta["is_playable"] = False meta.setdefault("stream_info", {}).update(get_quality_from_name(meta['label'])) meta["context_menu"] = [ ("Play with Pulsar", actions.update_view(plugin.url_for("rutor_play_pulsar", tid=tid))) ] del meta["search"] del meta["subdir"] yield meta if len(div_index) > 0: nodes = div_index[0].findAll("tr", class_=["gai", "tum"]) nodes = [node for node in _rutor_filter_nodes(nodes)] for node in nodes: cells = node.findAll("td") seeds, peers = map(lambda x: x.text.strip(), cells[len(cells) - 1].findAll("span")) donwload_node, magnet_node, title_node = cells[1].findAll("a") size = cells[len(cells) - 2].text title = _rutor_cleantitle(title_node.text) tid = int(title_node["href"][9:title_node["href"].find(u"/", 9)]) label = "%s | %s (S:%s P:%s)" % (title, size, seeds, peers) item = scrapers.default({"label": label, "info": {"title": title}}) item.update({ "path": plugin.url_for("rutor_play", tid=tid), "is_playable": False, "thumbnail": meta["thumbnail"], "icon": meta["icon"] }) item["info"].update(meta["info"]) item["properties"].update(meta["properties"]) item.setdefault("stream_info", {}).update(get_quality_from_name(item['label'])) item["context_menu"] = [("Play with Pulsar", actions.update_view( plugin.url_for("rutor_play_pulsar", tid=tid)))] del item["search"] del item["subdir"] yield item
def lostfilm_play(showid, season, episode): import re, xbmcgui from urlparse import urljoin from contextlib import closing from bs4 import BeautifulSoup from xbmctorrent.acestream import ace_supported from xbmctorrent.magnet import generate_magnet from xbmctorrent.utils import SafeDialogProgress, get_quality_from_name with closing(SafeDialogProgress(delay_close=0)) as dialog: dialog.create(plugin.name) dialog.update(percent=0, line1="Получение информации о релизе...", line2="", line3="") params = { "c" : showid, "s" : season, "e" : episode } try: html = url_get(urljoin(BASE_URL, "nrdr.php"), params=params) # catch 'log in first' then login if html.find("log in first") >= 0: dialog.update(percent=10, line2="Требуется авторизация. Авторизация...") if not plugin.get_setting("lostfilm_login") and not plugin.get_setting("lostfilm_passwd"): plugin.notify("Проверьте настройки авторизации.", delay=15000) return _lostfilm_login() dialog.update(percent=30, line2="Загрузка.", line3="") html = url_get(urljoin(BASE_URL, "nrdr.php"), params=params) if html.find("log in first") >= 0: xbmcgui.Dialog().ok(plugin.name, "Авторизация неудалась. Проверьте настройки.") return except: plugin.log.error("Unexpected error: %s" % sys.exc_info()[0]) xbmcgui.Dialog().ok(plugin.name, "Не удалось получить данные от сервера") return dialog.update(percent=50, line2="Обработка данных.") soup = BeautifulSoup(html, "html5lib", from_encoding="windows-1251") releases = soup.findAll("a", href=re.compile("tracktor.in"), style=re.compile("bold")) select_items = [] for release in releases: span = release.find_next("span") select_items.append(span.contents[0]) select = xbmcgui.Dialog().select("Выберите желаемое качество", select_items) if select >= 0: selected = releases[select] torrent_url = selected["href"] if ((not "-" in episode and int(episode) == 99) or ("." in season and "-" in episode)) and ace_supported(): if "." in season: season = season[:season.find(u".")] show_info = _lostfilm_get_db_info(showid) plugin.add_sort_method("label") try: from bencode import bencode, bdecode torrent_data = url_get(torrent_url, headers=HEADERS) metadata = bdecode(torrent_data) except: plugin.log.error("Cannot get data from remote server") xbmcgui.Dialog().ok(plugin.name, "Не удалось получить данные от сервера") return e = re.compile("(e[\d]+)?e([\d]+)\.", re.I|re.S|re.U) for index, item in enumerate(metadata["info"]["files"]): file_name = " / ".join(item["path"]) print file_name r = e.search(file_name) if r: if r.group(1): episode = r.group(1)[1:] else: episode = r.group(2) else: episode = u"" yield _lostfilm_updateitem_from_info({ "label" : file_name, "path" : plugin.url_for("torrent_play", url=torrent_url, index=index, name=file_name), "is_playable" : True, "info" : { "title" : file_name, "season" : season, "episode" : episode }, "stream_info" : get_quality_from_name(file_name) }, show_info) _lostfilm_close_dbase() else: plugin.redirect(plugin.url_for("play", uri=torrent_url))
def kickass_page(root, page): import re import xbmc import xbmcgui from bs4 import BeautifulSoup from contextlib import closing from concurrent import futures from urlparse import urljoin from xbmctorrent import tmdb from xbmctorrent.utils import first, terminating, url_get, get_quality_from_name content_type = first(plugin.request.args.get("content_type")) or None if content_type: plugin.set_content(content_type) page = int(page) page_data = url_get(urljoin(BASE_URL, "%s/%d" % (root, page))) soup = BeautifulSoup(page_data, "html5lib") torrent_nodes = [ node.parent for node in soup.findAll("td", "torrentnameCell") ] def _get_torrent_info_with_meta(url): torrent_info = get_torrent_info(url) if torrent_info["movie"] and torrent_info["imdb_id"]: torrent_info["tmdb"] = tmdb.get(torrent_info["imdb_id"]) return torrent_info with closing(xbmcgui.DialogProgress()) as dialog: dialog.create(plugin.name) dialog.update(percent=0, line1="Fetching torrent information...", line2="", line3="") state = {"done": 0} def on_torrent(future): data = future.result() state["done"] += 1 dialog.update( percent=int(state["done"] * 100.0 / len(torrent_nodes)), line2=data.get("title") or "", ) with futures.ThreadPoolExecutor(max_workers=3) as pool: movies = [] for node in torrent_nodes: info_nodes = node.findAll("td") a_node = first(info_nodes[0].select("div.torrentname a.plain")) movies.append( pool.submit(_get_torrent_info_with_meta, urljoin(BASE_URL, a_node["href"]))) [future.add_done_callback(on_torrent) for future in movies] while not all(job.done() for job in movies): if dialog.iscanceled(): return xbmc.sleep(100) movies = [movie.result() for movie in movies] for i, movie in enumerate(movies): if movie.get("tmdb"): item = tmdb.get_list_item(movie["tmdb"]) proper_kat_title = re.sub("\s+", " ", re.sub(r"[().-]", " ", movie["title"])) item["label"] = "%s (%s)" % (item["label"], re.sub(r"(?i)%s" % item["label"], "", proper_kat_title).strip()) else: item = { "label": movie["title"], "info": { "genre": ", ".join(movie["genres"]), } } lower_title = movie["title"].lower() if "x264" in lower_title: item.setdefault("stream_info", {})["codec"] = item.setdefault( "info", {})["video_codec"] = "h264" if "xvid" in lower_title: item.setdefault("stream_info", {})["codec"] = item.setdefault( "info", {})["video_codec"] = "xvid" if "720p" in lower_title: item.setdefault("stream_info", {}).update({ "width": 1280, "height": 720, }) if "1080p" in lower_title: item.setdefault("stream_info", {}).update({ "width": 1920, "height": 1080, }) item.update({ "path": plugin.url_for("play", magnet=movie["magnet_url"]), "is_playable": True, }) item.setdefault("info", {}).update({ "count": i, "genre": "%s (S:%s P:%s)" % (item.get("info", {}).get("genre") or "", movie["seeders"], movie["leechers"]), }) item.setdefault("stream_info", {}).update({ "video": get_quality_from_name(movie["title"]), }) yield item yield { "label": "Next page...", "path": plugin.url_for("kickass_page", root=root, page=page + 1, content_type=content_type), }
def rutracker_play(tid, pulsar): from copy import deepcopy from contextlib import closing from bencode import bencode, bdecode from urlparse import urljoin from xbmctorrent.magnet import generate_magnet from xbmctorrent.utils import first, SafeDialogProgress, get_quality_from_name, get_current_list_item from xbmctorrent.acestream import ace_supported with closing(SafeDialogProgress(delay_close=0)) as dialog: dialog.create(plugin.name) dialog.update(percent=0, line1="Получение информации о раздаче...") torrent_url = urljoin("http://dl.rutracker.org/forum/", "dl.php?t=%s" % tid) try: plugin.log.debug("loading data from uri: " + torrent_url) params = {"t": tid} import os, xbmc, cookielib cookie = cookielib.Cookie(version=0, name='bb_dl', value=tid, port=None, port_specified=False, domain='.rutracker.org', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False) data = url_get(torrent_url, headers=HEADERS, post=params, cookie=cookie) metadata = bdecode(data) plugin.log.debug("Metadata received " + str(metadata)) except: import xbmcgui plugin.log.error("Unexpected error: %s " % format_exc().split('\n')[-2]) xbmcgui.Dialog().ok(plugin.name, "Не удалось получить данные от сервера") return dialog.update(percent=100, line1="Готово") # Get currently selected item current_item = get_current_list_item() current_item.setdefault("stream_info", {}).update(get_quality_from_name(current_item['label'])) if "files" in metadata["info"] and ace_supported(): items = {} for index, info in enumerate(metadata["info"]["files"]): name = "/".join(info["path"]) if not _rutracker_valid_file(name): continue items[index] = deepcopy(current_item) items[index].update({ "label": name, "path": plugin.url_for("play_torrent_raw", raw=data, index=index, name=name), "is_playable": True }) items[index].setdefault("info", {}).update({ "title": name, }) # start playback if torrent contains only one file if len(items) == 1: index, item = items.popitem() if not plugin.get_setting("force_ace", bool): item["path"] = plugin.url_for("play", uri=generate_magnet(metadata, item["label"])) plugin.play_video(item) yield item else: plugin.add_sort_method('label') for i in items.values(): yield i else: name = metadata["info"].get("name") or " / ".join(first(metadata["info"]["files"])["path"]) or "rutor.org" if plugin.get_setting("force_ace", bool) and ace_supported(): current_item["path"] = plugin.url_for("play_torrent_raw", raw=data, index=0, name=name) else: current_item["path"] = plugin.url_for(["play","play_with_pulsar"][int(pulsar)], uri=generate_magnet(metadata, name)) current_item["is_playable"] = True plugin.play_video(current_item) yield current_item
def rutracker_play(tid, pulsar): from copy import deepcopy from contextlib import closing from bencode import bencode, bdecode from urlparse import urljoin from xbmctorrent.magnet import generate_magnet from xbmctorrent.utils import first, SafeDialogProgress, get_quality_from_name, get_current_list_item from xbmctorrent.acestream import ace_supported with closing(SafeDialogProgress(delay_close=0)) as dialog: dialog.create(plugin.name) dialog.update(percent=0, line1="Получение информации о раздаче...") torrent_url = urljoin("http://dl.rutracker.org/forum/", "dl.php?t=%s" % tid) try: plugin.log.debug("loading data from uri: " + torrent_url) params = {"t": tid} import os, xbmc, cookielib cookie = cookielib.Cookie(version=0, name='bb_dl', value=tid, port=None, port_specified=False, domain='.rutracker.org', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={'HttpOnly': None}, rfc2109=False) data = url_get(torrent_url, headers=HEADERS, post=params, cookie=cookie) metadata = bdecode(data) plugin.log.debug("Metadata received " + str(metadata)) except: import xbmcgui plugin.log.error("Unexpected error: %s " % format_exc().split('\n')[-2]) xbmcgui.Dialog().ok(plugin.name, "Не удалось получить данные от сервера") return dialog.update(percent=100, line1="Готово") # Get currently selected item current_item = get_current_list_item() current_item.setdefault("stream_info", {}).update( get_quality_from_name(current_item['label'])) if "files" in metadata["info"] and ace_supported(): items = {} for index, info in enumerate(metadata["info"]["files"]): name = "/".join(info["path"]) if not _rutracker_valid_file(name): continue items[index] = deepcopy(current_item) items[index].update({ "label": name, "path": plugin.url_for("play_torrent_raw", raw=data, index=index, name=name), "is_playable": True }) items[index].setdefault("info", {}).update({ "title": name, }) # start playback if torrent contains only one file if len(items) == 1: index, item = items.popitem() if not plugin.get_setting("force_ace", bool): item["path"] = plugin.url_for("play", uri=generate_magnet( metadata, item["label"])) plugin.play_video(item) yield item else: plugin.add_sort_method('label') for i in items.values(): yield i else: name = metadata["info"].get("name") or " / ".join( first(metadata["info"]["files"])["path"]) or "rutor.org" if plugin.get_setting("force_ace", bool) and ace_supported(): current_item["path"] = plugin.url_for("play_torrent_raw", raw=data, index=0, name=name) else: current_item["path"] = plugin.url_for( ["play", "play_with_pulsar"][int(pulsar)], uri=generate_magnet(metadata, name)) current_item["is_playable"] = True plugin.play_video(current_item) yield current_item
def lostfilm_play(showid, season, episode): import re from contextlib import closing from bs4 import BeautifulSoup from xbmctorrent.acestream import ace_supported from xbmctorrent.utils import SafeDialogProgress, get_quality_from_name with closing(SafeDialogProgress(delay_close=0)) as dialog: dialog.create(plugin.name) dialog.update(percent=0, line1="Получение информации о релизе...", line2="", line3="") params = {"c": showid, "s": season, "e": episode} try: search_url = BASE_URL + "v_search.php" html = url_get(search_url, params=params) # catch 'log in first' then login if html.find("log in first") >= 0: dialog.update(percent=10, line2="Требуется авторизация. Авторизация...") if not plugin.get_setting("lostfilm_login") and not plugin.get_setting("lostfilm_passwd"): plugin.notify("Проверьте настройки авторизации.", delay=15000) return if not _lostfilm_login(): xbmcgui.Dialog().ok(plugin.name, "Авторизация неудалась1. Проверьте настройки.") return dialog.update(percent=30, line2="Загрузка.", line3="") html = url_get(search_url, params=params) if html.find("log in first") >= 0: xbmcgui.Dialog().ok(plugin.name, "Авторизация неудалась2. Проверьте настройки.") return except Exception: plugin.log.error("Unexpected error: %s" % sys.exc_info()[0]) xbmcgui.Dialog().ok(plugin.name, "Не удалось получить данные от сервера") return # catch redirect if html.find("location.replace") >= 0: replace_url = html[html.find("(\"") + 2:html.find("\");")] html = url_get(replace_url) dialog.update(percent=50, line2="Обработка данных.") soup = BeautifulSoup(html, "html5lib") divs = soup.find_all("div", class_=re.compile("main")) releases = [d.find("a") for d in divs] quality = plugin.get_setting("lostfilm_qlt", int) or 0 if quality <= 0 or quality > len(releases): select_items = [] for release in releases: lines = release.text.split("\n") select_items.append(lines[-1]) select = xbmcgui.Dialog().select("Выберите желаемое качество", select_items) else: select = quality - 1 if select >= 0: selected = releases[select] torrent_url = selected["href"] if (("-" not in episode and int(episode) == 999) or ("." in season and "-" in episode)): if "." in season: season = season[:season.find(u".")] plugin.add_sort_method("label") show_info = _lostfilm_get_db_info_by_id(showid) _lostfilm_close_dbase() try: from bencode import bdecode torrent_data = url_get(torrent_url) metadata = bdecode(torrent_data) except Exception: plugin.log.error("Cannot get data from remote server") xbmcgui.Dialog().ok(plugin.name, "Не удалось получить данные от сервера") return e = re.compile("(e[\d]+)?e([\d]+)\.", re.I | re.S | re.U) for index, item in enumerate(metadata["info"]["files"]): file_name = " / ".join(item["path"]) r = e.search(file_name) if r: if r.group(1): episode = r.group(1)[1:] else: episode = r.group(2) else: episode = u"" if plugin.get_setting("torrent_engine", int) == 1 and ace_supported(): path = plugin.url_for("torrent_play", url=torrent_url, index=index, name=file_name) else: path = plugin.url_for("play_file", uri=torrent_url, index=index) yield _lostfilm_updateitem_from_info({ "label": file_name, "path": path, "is_playable": True, "info": { "title": file_name, "season": season, "episode": episode }, "stream_info": get_quality_from_name(file_name) }, show_info) else: if plugin.get_setting("torrent_engine", int) == 1 and ace_supported(): path = plugin.url_for("torrent_play", url=torrent_url, index=0, name="LostFilm.Tv") else: path = plugin.url_for("play", uri=torrent_url) plugin.redirect(path)
def rutor_details(catind, tid): import xbmcgui from bs4 import BeautifulSoup from urlparse import urljoin from xbmctorrent.utils import get_quality_from_name from xbmctorrent.search import scrapers as search scraper_name = "" category = ([cat for cat in CATEGORIES if cat[0] == catind] or [("0", u"", "", "")])[0] scraper_name = category[3] plugin.set_content(category[2]) tid = int(tid) try: html_data = url_get(urljoin(BASE_URL, "torrent/%d/" % tid), headers=HEADERS) except Exception: xbmcgui.Dialog().ok(plugin.name, "Не удалось получить данные от сервера") return soup = BeautifulSoup(html_data, "html5lib") if len(soup.select("div#download")) == 0: # it may occur if site redirects a request to his mirror xbmcgui.Dialog().ok(plugin.name, "Раздачи не существует. Обновите список") return div_index = soup.select("div#index") scrapers = search.Scrapers() details = soup.select("table#details")[0].findAll("tr") shift = 1 if len(details[1].select("a")) > 0 else 0 seeds = details[3 + shift].contents[1].text peers = details[4 + shift].contents[1].text size = details[7 + shift].contents[1].text size = size[:size.find(" ")] title = _rutor_cleantitle(soup.h1.text) label = "%s | %s (S:%s P:%s)" % (title, size, seeds, peers) item = { "label": label, "info": {"title": title} } if plugin.get_setting("rutor_usesearch", bool): meta = scrapers.scraper(scraper_name, item) else: meta = scrapers.default(item) meta["path"] = plugin.url_for("rutor_play", tid=tid) meta["is_playable"] = True meta.setdefault("stream_info", {}).update(get_quality_from_name(meta['label'])) meta["context_menu"] = [("Play with Pulsar", actions.update_view(plugin.url_for("rutor_play_pulsar", tid=tid)))] del meta["search"] del meta["subdir"] yield meta if len(div_index) > 0: nodes = div_index[0].findAll("tr", class_=["gai", "tum"]) nodes = [node for node in _rutor_filter_nodes(nodes)] for node in nodes: cells = node.findAll("td") seeds, peers = map(lambda x: x.text.strip(), cells[len(cells) - 1].findAll("span")) donwload_node, magnet_node, title_node = cells[1].findAll("a") size = cells[len(cells) - 2].text title = _rutor_cleantitle(title_node.text) tid = int(title_node["href"][9:title_node["href"].find(u"/", 9)]) label = "%s | %s (S:%s P:%s)" % (title, size, seeds, peers) item = scrapers.default({ "label": label, "info": {"title": title} }) item.update({ "path": plugin.url_for("rutor_play", tid=tid), "is_playable": True, "thumbnail": meta["thumbnail"], "icon": meta["icon"] }) item["info"].update(meta["info"]) item["properties"].update(meta["properties"]) item.setdefault("stream_info", {}).update(get_quality_from_name(item['label'])) item["context_menu"] = [("Play with Pulsar", actions.update_view(plugin.url_for("rutor_play_pulsar", tid=tid)))] del item["search"] del item["subdir"] yield item