示例#1
0
        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
示例#2
0
        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)
示例#4
0
        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)
示例#5
0
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
示例#6
0
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),
    }
示例#7
0
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
示例#8
0
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
示例#9
0
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
示例#10
0
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
示例#11
0
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
示例#12
0
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))
示例#13
0
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),
    }
示例#14
0
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
示例#15
0
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
示例#16
0
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)
示例#17
0
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
示例#18
0
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