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 get_dest_dir(self): """ Gets the directory where to save this Download. """ dest_dir = self.config['download_defaults']['saveas'] if not dest_dir: dest_dir = get_default_dest_dir() self.set_dest_dir(dest_dir) # This is required to support relative paths if not path_util.isabs(dest_dir): dest_dir = self.state_dir / dest_dir return Path(dest_dir)
async def add_torrent_to_channel(self, request): channel_pk, channel_id = self.get_channel_from_request(request) with db_session: channel = self.session.mds.CollectionNode.get( public_key=database_blob(channel_pk), id_=channel_id) if not channel: return RESTResponse({"error": "Unknown channel"}, status=HTTP_NOT_FOUND) parameters = await request.json() extra_info = {} if parameters.get('description', None): extra_info = {'description': parameters['description']} # First, check whether we did upload a magnet link or URL if parameters.get('uri', None): uri = parameters['uri'] if uri.startswith("http:") or uri.startswith("https:"): async with ClientSession() as session: response = await session.get(uri) data = await response.read() tdef = TorrentDef.load_from_memory(data) elif uri.startswith("magnet:"): _, xt, _ = parse_magnetlink(uri) if (xt and is_infohash(codecs.encode(xt, 'hex')) and (self.session.mds.torrent_exists_in_personal_channel(xt) or channel.copy_torrent_from_infohash(xt))): return RESTResponse({"added": 1}) meta_info = await self.session.dlmgr.get_metainfo(xt, timeout=30, url=uri) if not meta_info: raise RuntimeError("Metainfo timeout") tdef = TorrentDef.load_from_dict(meta_info) else: return RESTResponse({"error": "unknown uri type"}, status=HTTP_BAD_REQUEST) added = 0 if tdef: channel.add_torrent_to_channel(tdef, extra_info) added = 1 return RESTResponse({"added": added}) torrents_dir = None if parameters.get('torrents_dir', None): torrents_dir = parameters['torrents_dir'] if not path_util.isabs(torrents_dir): return RESTResponse( {"error": "the torrents_dir should point to a directory"}, status=HTTP_BAD_REQUEST) recursive = False if parameters.get('recursive'): recursive = parameters['recursive'] if not torrents_dir: return RESTResponse( { "error": "the torrents_dir parameter should be provided when the recursive parameter is set" }, status=HTTP_BAD_REQUEST, ) if torrents_dir: torrents_list, errors_list = channel.add_torrents_from_dir( torrents_dir, recursive) return RESTResponse({ "added": len(torrents_list), "errors": errors_list }) if not parameters.get('torrent', None): return RESTResponse({"error": "torrent parameter missing"}, status=HTTP_BAD_REQUEST) # Try to parse the torrent data # Any errors will be handled by the error_middleware torrent = base64.b64decode(parameters['torrent']) torrent_def = TorrentDef.load_from_memory(torrent) channel.add_torrent_to_channel(torrent_def, extra_info) return RESTResponse({"added": 1})