class RealDebridCloudScraper(CloudScraper):
    def __init__(self, terminate_flag):
        super(RealDebridCloudScraper, self).__init__(terminate_flag)
        self.api_adapter = RealDebrid()
        self.debrid_provider = 'real_debrid'
        self._source_normalization = (('path', 'release_title',
                                       lambda k: k.lower().split('/')[-1]),
                                      ('bytes', 'size', lambda k:
                                       (k / 1024) / 1024), ('size', 'size',
                                                            None),
                                      ('filename', 'release_title',
                                       None), ('id', 'id',
                                               None), ('links', 'links', None),
                                      ('selected', 'selected', None))

    def _fetch_cloud_items(self):
        return self.api_adapter.list_torrents()

    def _source_to_file(self, source):
        if "links" not in source:
            return None
        source_files = self._normalize_item(
            self.api_adapter.torrent_info(source['id'])['files'])
        source_files = [i for i in source_files if i["selected"]]
        [file.update({'idx': idx}) for idx, file in enumerate(source_files)]
        source_files = self._identify_items(source_files)
        [
            file.update({'url': source['links'][file['idx']]})
            for file in source_files
        ]
        return source_files[0] if source_files else None
class _RealDebridDownloader(_DebridDownloadBase):
    def __init__(self, source):
        super(_RealDebridDownloader, self).__init__(source)
        self.debrid_module = RealDebrid()
        self.available_files = []

    def _fetch_available_files(self):
        availability = self.debrid_module.check_hash(self.source["hash"])
        availability = [
            i for i in availability[self.source["hash"]]["rd"]
            if self.debrid_module.is_streamable_storage_type(i)
        ]
        try:
            availability = sorted(availability,
                                  key=lambda k: len(k.values()))[0]
        except IndexError:
            raise SourceNotAvailable

        self.available_files = [{
            "path": value["filename"],
            "index": key
        } for key, value in availability.items()]
        return self.available_files

    def _resolve_file_url(self, file):
        return self.debrid_module.resolve_hoster(file[0]["url"])

    def _resolver_setup(self, selected_files):
        if self.source.get("type") in ["hoster", "cloud"]:
            return [(self.source.get("url",
                                     ""), self.source.get("release_tile"))]

        torrent_id = self.debrid_module.add_magnet(self.source["magnet"])["id"]
        self.debrid_module.torrent_select(
            torrent_id, ",".join([i["index"] for i in self.available_files]))
        info = self.debrid_module.torrent_info(torrent_id)
        remote_files = {
            str(i["id"]): idx
            for idx, i in enumerate(info["files"])
        }
        selected_files = [(remote_files[i[0]["index"]], i[1])
                          for i in selected_files]
        selected_files = [(info["links"][i[0]], i[1]) for i in selected_files]
        return selected_files

    def _get_single_item_info(self, source):
        return source
Esempio n. 3
0
class RealDebridResolver(TorrentResolverBase):
    """
    Resolver for Real Debrid
    """
    def __init__(self):
        super(RealDebridResolver, self).__init__()
        self.debrid_module = RealDebrid()
        self._source_normalization = (
            ("path", "path", None),
            ("bytes", "size", lambda k: (k / 1024) / 1024),
            ("size", "size", None),
            ("filename", "release_title", None),
            ("id", "id", None),
            ("link", "link", None),
            ("selected", "selected", None),
        )
        self.torrent_id = None

    def _get_files_from_check_hash(self, torrent, item_information):
        hash_check = self.debrid_module.check_hash(
            torrent["hash"])[torrent["hash"]]["rd"]
        try:
            hash_check = [
                storage_variant for storage_variant in hash_check if
                self.debrid_module.is_streamable_storage_type(storage_variant)
            ]
        except IndexError:
            raise FileIdentification(hash_check)
        if self.media_type == "episode":
            hash_check = [
                i for i in hash_check if get_best_episode_match(
                    "filename", i.values(), item_information)
            ][0]
        else:
            hash_check = hash_check[0]
        [value.update({"idx": key}) for key, value in hash_check.items()]
        return hash_check.values()

    def _get_selected_files(self, torrent_id):
        info = self.debrid_module.torrent_info(torrent_id)
        files = [i for i in info["files"] if i["selected"]]
        [i.update({"link": info["links"][idx]}) for idx, i in enumerate(files)]
        return files

    def _fetch_source_files(self, torrent, item_information):
        hash_check = self._get_files_from_check_hash(torrent, item_information)
        cached_torrent = self.debrid_module.add_magnet(torrent["magnet"])
        self.debrid_module.torrent_select(
            cached_torrent["id"], ",".join([i["idx"] for i in hash_check]))
        self.torrent_id = cached_torrent["id"]
        return self._get_selected_files(self.torrent_id)

    def resolve_stream_url(self, file_info):
        """
        Convert provided source file into a link playable through debrid service
        :param file_info: Normalised information on source file
        :return: streamable link
        """
        return self.debrid_module.resolve_hoster(file_info["link"])

    def _do_post_processing(self, item_information, torrent):
        if g.get_bool_setting("rd.autodelete"):
            self.debrid_module.delete_torrent(self.torrent_id)