def _download_existing_torrent(self, handle, infohash, on_complete, on_start_download, on_update=None, abort_ev=None, on_timeout=None): log.debug("downloading previously added torrent") status = handle.status() if status.is_seeding: log.debug("Torrent already seeding. Returning handle...") # get full path data = TorrentInfo.from_dict(self.get_torrent_info(str(infohash))) on_complete(data["full_path"]) elif status.state == lt.torrent_status.downloading_metadata: log.debug("Torrent is awaiting download") self.await_download_start(handle, on_start_download, abort_ev, on_timeout) self.await_download_completion(handle, on_complete, on_update, abort_ev, on_timeout) return else: log.debug("Torrent is already downloading. Awaiting...") self.await_download_completion(handle, on_complete, on_update, abort_ev, on_timeout) return
def resume_torrent(self, infohash): log.debug("Pausing torrent %s" % infohash) info = self.get_torrent_info(infohash) lt_info = lt.parse_magnet_uri(info["magnet"]) handle = self.session.find_torrent(lt_info.info_hash) if handle.is_valid(): handle.resume() ti = TorrentInfo.from_dict(self.get_torrent_info(infohash)) ti["status"] = "active" self._write_torrent_info_data( self._get_torrent_info_path(infohash), ti.dump()) else: log.exception("Error pausing torrent: handle is invalid! %s " % get_stack())
def save_torrent_info(self, at_params, magnet, status="active", save_path=None): """ Saves torrent info in JSON file. If file already exists - it will be overwritten :param at_params: libtorrent add_torrent_params object :param magnet: str Magnet link :param status: status to assign to torrent :param save_path: Save path :return: """ log.debug("Saving torrent info %s" % magnet) ti = lt.parse_magnet_uri(magnet) #infohash = str(at_params.ti.info_hash) infohash = str(ti.info_hash) torrent_dir = None torrent_path = None if save_path: torrent_path = save_path torrent_dir = os.path.dirname(save_path) else: torrent_dir = os.path.join(self.torrents_path, infohash) torrent_path = os.path.join(torrent_dir, at_params.name) filepath = os.path.join(self.torrent_metadata_path, ("%s.json" % infohash)) log.debug("Initializing TorrentInfo object %s " % magnet) info = TorrentInfo.from_dict({ "infohash": infohash, "magnet": magnet, "torrent_directory": torrent_dir, "name": at_params.name, "full_path": torrent_path, "status": status }) log.debug("Done. Writing to file...") self._write_torrent_info_data(filepath, info.dump()) log.debug("Torrent info saved")
def await_download_completion(self, handle, on_complete, on_update=None, abort_ev=None, on_timeout=None, poll_timeout=1): log.debug("Awaiting download completion.. abort_ev: %s" % str(abort_ev)) if abort_ev and abort_ev.is_set(): log.debug("Abort event is set returning...") return log.debug("Awaiting torrent for torrent download to finish") status = handle.status() start = time.time() progress = status.progress epsilon = 30 * 1024 # minimal acceptable bitrate (bytes/sec) while not status.is_seeding: if abort_ev and abort_ev.is_set(): log.debug( "await_download_completion: Install aborted. exiting.. ") return status = handle.status() if on_update: on_update({ "progress": status.progress, "num_seeds": status.num_seeds, "num_peers": status.num_peers, "state": status.state, "info_hash": status.info_hash, "total": status.total_wanted, "total_done": status.total_done, }) log.debug( '\r%.2f%% complete (down: %.1f kB/s up: %.1f kB/s peers: %d) %s' % (status.progress * 100, status.download_rate / 1000, status.upload_rate / 1000, status.num_peers, status.state)) alerts = self.session.pop_alerts() for a in alerts: if a.category() & lt.alert.category_t.error_notification: log.warning(a) time.sleep(poll_timeout) dt_time = time.time() - start if dt_time > 40: average_bitrate_per_second = ( status.progress - progress) * status.total_wanted / dt_time if average_bitrate_per_second < epsilon and on_timeout: log.debug("Torrent download timeout") on_timeout() else: progress = status.progress start = time.time() log.debug("Download completed. \nName: %s\nPath: %s" % (status.name, status.save_path)) infohash = str(status.info_hash) data = TorrentInfo.from_dict(self.get_torrent_info(infohash)) on_complete(data["full_path"])