Esempio n. 1
0
    def get_name_as_unicode(self):
        """ Returns the info['name'] field as Unicode string.
        @return Unicode string. """
        if self.metainfo and b"name.utf-8" in self.metainfo[b"info"]:
            # There is an utf-8 encoded name.  We assume that it is
            # correctly encoded and use it normally
            try:
                return ensure_unicode(self.metainfo[b"info"][b"name.utf-8"],
                                      "UTF-8")
            except UnicodeError:
                pass

        if self.metainfo and b"name" in self.metainfo[b"info"]:
            # Try to use the 'encoding' field.  If it exists, it
            # should contain something like 'utf-8'
            if "encoding" in self.metainfo:
                try:
                    return ensure_unicode(self.metainfo[b"info"][b"name"],
                                          self.metainfo[b"encoding"])
                except UnicodeError:
                    pass
                except LookupError:
                    # Some encodings are not supported by python.  For
                    # instance, the MBCS codec which is used by
                    # Windows is not supported (Jan 2010)
                    pass

            # Try to convert the names in path to unicode, assuming
            # that it was encoded as utf-8
            try:
                return ensure_unicode(self.metainfo[b"info"][b"name"], "UTF-8")
            except UnicodeError:
                pass

            # Convert the names in path to unicode by replacing out
            # all characters that may -even remotely- cause problems
            # with the '?' character
            try:

                def filter_characters(name):
                    def filter_character(char):
                        if 0 < char < 128:
                            return chr(char)
                        self._logger.debug("Bad character 0x%X", char)
                        return "?"

                    return "".join([filter_character(char) for char in name])

                return filter_characters(self.metainfo[b"info"][b"name"])
            except UnicodeError:
                pass

        # We failed.  Returning an empty string
        return ""
Esempio n. 2
0
    def setup(self, config=None, hidden=False, checkpoint_disabled=False):
        """
        Create a Download object. Used internally by Session.
        @param config DownloadConfig or None (in which case a new DownloadConfig() is created
        :returns a Deferred to which a callback can be added which returns the result of network_create_engine_wrapper.
        """
        self.hidden = hidden
        self.checkpoint_disabled = checkpoint_disabled or self.dummy
        self.config = config or DownloadConfig(
            state_dir=self.session.config.get_state_dir())

        self._logger.debug("Setup: %s", hexlify(self.tdef.get_infohash()))

        self.checkpoint()

        atp = {
            "save_path":
            path_util.normpath(get_default_dest_dir() /
                               self.config.get_dest_dir()),
            "storage_mode":
            lt.storage_mode_t.storage_mode_sparse,
            "flags":
            lt.add_torrent_params_flags_t.flag_paused
            | lt.add_torrent_params_flags_t.flag_duplicate_is_error
            | lt.add_torrent_params_flags_t.flag_update_subscribe
        }

        if self.config.get_share_mode():
            atp["flags"] = atp[
                "flags"] | lt.add_torrent_params_flags_t.flag_share_mode
        if self.config.get_upload_mode():
            atp["flags"] = atp[
                "flags"] | lt.add_torrent_params_flags_t.flag_upload_mode

        resume_data = self.config.get_engineresumedata()
        if not isinstance(self.tdef, TorrentDefNoMetainfo):
            metainfo = self.tdef.get_metainfo()
            torrentinfo = lt.torrent_info(metainfo)

            atp["ti"] = torrentinfo
            if resume_data and isinstance(resume_data, dict):
                # Rewrite save_path as a global path, if it is given as a relative path
                if b"save_path" in resume_data and not path_util.isabs(
                        ensure_unicode(resume_data[b"save_path"], 'utf8')):
                    resume_data[
                        b"save_path"] = self.state_dir / ensure_unicode(
                            resume_data[b"save_path"], 'utf8')
                atp["resume_data"] = lt.bencode(resume_data)
        else:
            atp["url"] = self.tdef.get_url(
            ) or "magnet:?xt=urn:btih:" + hexlify(self.tdef.get_infohash())
            atp["name"] = self.tdef.get_name_as_unicode()

        return atp
Esempio n. 3
0
def tdef_to_metadata_dict(tdef):
    """
    Helper function to create a TorrentMetadata-compatible dict from TorrentDef
    """
    # We only want to determine the type of the data. XXX filtering is done by the receiving side
    try:
        tags = default_category_filter.calculateCategory(
            tdef.metainfo, tdef.get_name_as_unicode())
    except UnicodeDecodeError:
        tags = "Unknown"

    try:
        torrent_date = datetime.fromtimestamp(tdef.get_creation_date())
    except ValueError:
        torrent_date = EPOCH

    return {
        "infohash":
        tdef.get_infohash(),
        "title":
        tdef.get_name_as_unicode()[:300],
        "tags":
        tags[:200],
        "size":
        tdef.get_length(),
        "torrent_date":
        torrent_date if torrent_date >= EPOCH else EPOCH,
        "tracker_info":
        get_uniformed_tracker_url(
            ensure_unicode(tdef.get_tracker() or '', 'utf-8')) or '',
    }
Esempio n. 4
0
 def add_torrent_to_channel(self, torrent):
     data = {"torrent": torrent}
     if self.name:
         data.update({"title": ensure_unicode(self.name, 'utf8')})
     self.rest_request2 = TriblerNetworkRequest(
         "mychannel/torrents", self.on_torrent_to_channel_added, data=data, method='PUT'
     )
Esempio n. 5
0
def _safe_extended_peer_info(ext_peer_info):
    """
    Given a string describing peer info, return a json.dumps() safe representation.

    :param ext_peer_info: the string to convert to a dumpable format
    :return: the safe string
    """
    # First see if we can use this as-is
    if not ext_peer_info:
        return ''

    try:
        return ensure_unicode(ext_peer_info, "utf8")
    except UnicodeDecodeError:
        # We might have some special unicode characters in here
        return ''.join([chr(c) for c in ext_peer_info])
Esempio n. 6
0
    def parse_sys_args(self, args):
        for arg in args[1:]:
            if os.path.exists(arg):
                self.handle_uri(u'file:%s' % ensure_unicode(arg, 'utf8'))
            elif arg.startswith('magnet'):
                self.handle_uri(arg)

        if '--allow-code-injection' in sys.argv[1:]:
            variables = globals().copy()
            variables.update(locals())
            variables['window'] = self.activation_window()
            self.code_executor = CodeExecutor(5500, shell_variables=variables)
            self.activation_window().tribler_crashed.connect(
                self.code_executor.on_crash)

        if '--testnet' in sys.argv[1:]:
            os.environ['TESTNET'] = "YES"
Esempio n. 7
0
    def get_index_of_file_in_files(self, file):
        if not self.metainfo:
            raise ValueError("TorrentDef does not have metainfo")
        info = self.metainfo[b'info']

        if file is not None and b'files' in info:
            for i in range(len(info[b'files'])):
                file_dict = info[b'files'][i]

                if b'path.utf-8' in file_dict:
                    intorrentpath = maketorrent.pathlist2filename(file_dict[b'path.utf-8'])
                else:
                    intorrentpath = maketorrent.pathlist2filename(file_dict[b'path'])

                if intorrentpath == path_util.Path(ensure_unicode(file, 'utf8')):
                    return i
            raise ValueError("File not found in torrent")
        else:
            raise ValueError("File not found in single-file torrent")
Esempio n. 8
0
    def get_atp(self):
        save_path = self.config.get_dest_dir()
        atp = {
            "save_path":
            str(save_path),
            "storage_mode":
            lt.storage_mode_t.storage_mode_sparse,
            "flags":
            lt.add_torrent_params_flags_t.flag_paused
            | lt.add_torrent_params_flags_t.flag_duplicate_is_error
            | lt.add_torrent_params_flags_t.flag_update_subscribe
        }

        if self.config.get_share_mode():
            atp["flags"] = atp[
                "flags"] | lt.add_torrent_params_flags_t.flag_share_mode
        if self.config.get_upload_mode():
            atp["flags"] = atp[
                "flags"] | lt.add_torrent_params_flags_t.flag_upload_mode

        resume_data = self.config.get_engineresumedata()
        if not isinstance(self.tdef, TorrentDefNoMetainfo):
            metainfo = self.tdef.get_metainfo()
            torrentinfo = lt.torrent_info(metainfo)

            atp["ti"] = torrentinfo
            if resume_data and isinstance(resume_data, dict):
                # Rewrite save_path as a global path, if it is given as a relative path
                save_path = (ensure_unicode(resume_data[b"save_path"], 'utf8')
                             if b"save_path" in resume_data else None)
                if save_path and not Path(save_path).is_absolute():
                    resume_data[b"save_path"] = str(self.state_dir / save_path)
                atp["resume_data"] = lt.bencode(resume_data)
        else:
            atp["url"] = self.tdef.get_url(
            ) or "magnet:?xt=urn:btih:" + hexlify(self.tdef.get_infohash())
            atp["name"] = self.tdef.get_name_as_unicode()

        return atp
Esempio n. 9
0
    def parse_sys_args(self, args):
        for arg in args[1:]:
            if os.path.exists(arg):
                file_path = ensure_unicode(arg, 'utf8')
                uri = path_to_uri(file_path)
                self.handle_uri(uri)
            elif arg.startswith('magnet'):
                self.handle_uri(arg)

        if '--allow-code-injection' in sys.argv[1:]:
            variables = globals().copy()
            variables.update(locals())
            variables['window'] = self.activation_window()
            self.code_executor = CodeExecutor(5500, shell_variables=variables)
            connect(self.activation_window().tribler_crashed, self.code_executor.on_crash)

        if '--testnet' in sys.argv[1:]:
            os.environ['TESTNET'] = "YES"
        if '--trustchain-testnet' in sys.argv[1:]:
            os.environ['TRUSTCHAIN_TESTNET'] = "YES"
        if '--chant-testnet' in sys.argv[1:]:
            os.environ['CHANT_TESTNET'] = "YES"
        if '--tunnel-testnet' in sys.argv[1:]:
            os.environ['TUNNEL_TESTNET'] = "YES"
Esempio n. 10
0
 def get_name_as_unicode(self):
     return ensure_unicode(self.name, 'utf-8')
Esempio n. 11
0
    def _get_all_files_as_unicode_with_length(self):
        """ Get a generator for files in the torrent def. No filtering
        is possible and all tricks are allowed to obtain a unicode
        list of filenames.
        @return A unicode filename generator.
        """
        if self.metainfo and b"files" in self.metainfo[b"info"]:
            # Multi-file torrent
            files = self.metainfo[b"info"][b"files"]

            for file_dict in files:
                if b"path.utf-8" in file_dict:
                    # This file has an utf-8 encoded list of elements.
                    # We assume that it is correctly encoded and use
                    # it normally
                    try:
                        yield (Path(*[
                            ensure_unicode(element, "UTF-8")
                            for element in file_dict[b"path.utf-8"]
                        ]), file_dict[b"length"])
                        continue
                    except UnicodeError:
                        pass

                if b"path" in file_dict:
                    # Try to use the 'encoding' field.  If it exists,
                    # it should contain something like 'utf-8'
                    if b"encoding" in self.metainfo:
                        encoding = ensure_unicode(self.metainfo[b"encoding"],
                                                  "utf8")
                        try:
                            yield (Path(*[
                                ensure_unicode(element, encoding)
                                for element in file_dict[b"path"]
                            ]), file_dict[b"length"])
                            continue
                        except UnicodeError:
                            pass
                        except LookupError:
                            # Some encodings are not supported by
                            # python.  For instance, the MBCS codec
                            # which is used by Windows is not
                            # supported (Jan 2010)
                            pass

                    # Try to convert the names in path to unicode,
                    # assuming that it was encoded as utf-8
                    try:
                        yield (Path(*[
                            ensure_unicode(element, "UTF-8")
                            for element in file_dict[b"path"]
                        ]), file_dict[b"length"])
                        continue
                    except UnicodeError:
                        pass

                    # Convert the names in path to unicode by
                    # replacing out all characters that may -even
                    # remotely- cause problems with the '?' character
                    try:

                        def filter_characters(name):
                            def filter_character(char):
                                if 0 < char < 128:
                                    return chr(char)
                                self._logger.debug("Bad character 0x%X", char)
                                return "?"

                            return "".join(
                                [filter_character(char) for char in name])

                        yield (Path(*[
                            filter_characters(element)
                            for element in file_dict[b"path"]
                        ]), file_dict[b"length"])
                        continue
                    except UnicodeError:
                        pass

        elif self.metainfo:
            # Single-file torrent
            yield self.get_name_as_unicode(), self.metainfo[b"info"][b"length"]
Esempio n. 12
0
 def get_encoding(self):
     """
     Returns the used encoding of the TorrentDef.
     """
     return ensure_unicode(
         self.torrent_parameters.get(b'encoding', b'utf-8'), 'utf-8')
Esempio n. 13
0
    async def create_torrent(self, request):
        parameters = await request.json()
        params = {}

        if 'files' in parameters and parameters['files']:
            file_path_list = [
                ensure_unicode(f, 'utf-8') for f in parameters['files']
            ]
        else:
            return RESTResponse({"error": "files parameter missing"},
                                status=HTTP_BAD_REQUEST)

        if 'description' in parameters and parameters['description']:
            params['comment'] = parameters['description']

        if 'trackers' in parameters and parameters['trackers']:
            tracker_url_list = parameters['trackers']
            params['announce'] = tracker_url_list[0]
            params['announce-list'] = tracker_url_list

        name = 'unknown'
        if 'name' in parameters and parameters['name']:
            name = parameters['name']
            params['name'] = name

        export_dir = None
        if 'export_dir' in parameters and parameters['export_dir']:
            export_dir = Path(parameters['export_dir'])

        from tribler_core.version import version_id
        params['created by'] = '%s version: %s' % ('Tribler', version_id)

        params['nodes'] = False
        params['httpseeds'] = False
        params['encoding'] = False
        params['piece length'] = 0  # auto

        try:
            result = await self.session.dlmgr.create_torrent_file(
                file_path_list, recursive_bytes(params))
        except (IOError, UnicodeDecodeError, RuntimeError) as e:
            self._logger.exception(e)
            return return_handled_exception(request, e)

        metainfo_dict = bdecode_compat(result['metainfo'])

        if export_dir and export_dir.exists():
            save_path = export_dir / ("%s.torrent" % name)
            with open(save_path, "wb") as fd:
                fd.write(result['metainfo'])

        # Download this torrent if specified
        if 'download' in request.query and request.query[
                'download'] and request.query['download'] == "1":
            download_config = DownloadConfig()
            download_config.set_dest_dir(result['base_path'] if len(
                file_path_list) == 1 else result['base_dir'])
            try:
                self.session.dlmgr.start_download(
                    tdef=TorrentDef(metainfo_dict), config=download_config)
            except DuplicateDownloadException:
                self._logger.warning(
                    "The created torrent is already being downloaded.")

        return RESTResponse(
            json.dumps({
                "torrent":
                base64.b64encode(result['metainfo']).decode('utf-8')
            }))