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 streamajoker.utils import SafeDialogProgress, get_quality_from_name, get_show_info_from_name, normalize_release_tags from streamajoker 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 streamajoker.utils import get_show_info_from_name show_info = get_quality_from_name(item["title"]) if not show_info: return