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 ""
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
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 '', }
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' )
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])
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"
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")
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
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"
def get_name_as_unicode(self): return ensure_unicode(self.name, 'utf-8')
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"]
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')
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') }))