def clear(update: Update, context: CallbackContext) -> None: """ Limpia los torrents finalizados de la cola de descarga """ FINISHED_STATES = [ 'uploading', 'pausedUP', 'stalledUP', 'queuedUP', ] if int(update.effective_chat.id) not in config.ALLOWED_IDS: not_allowed(update) else: logger.info(' Un usuario CON permiso ha ejecutado /clear') qb = Client(config.TORRENT['server']) qb.login(config.TORRENT['user'], config.TORRENT['pass']) torrents = qb.torrents() del_torrents = len(torrents) for torrent in torrents: if torrent['state'] in FINISHED_STATES: qb.delete(torrent['hash']) torrents = qb.torrents() del_torrents = del_torrents - len(torrents) qb.logout() logger.info('{} torrents han sido eliminados de la cola'.format(del_torrents)) if del_torrents != 0: update.message.reply_text('Borrados todos los torrents finalizados') else: update.message.reply_text('No se ha eliminado ningún torrent de la cola')
pathMapping=path_mapping) elif settings.qBittorrent['bypass'].startswith(label): log.info("Bypassing any further processing as per category.") # Run a qbittorrent action after conversion. if settings.qBittorrent['actionafter']: # currently only support resuming or deleting torrent if settings.qBittorrent['actionafter'] == 'resume': log.debug("Sending action %s to qBittorrent" % settings.qBittorrent['actionafter']) qb.resume(torrent_hash) elif settings.qBittorrent['actionafter'] == 'delete': # this will delete the torrent from qBittorrent but it WILL NOT delete the data log.debug("Sending action %s to qBittorrent" % settings.qBittorrent['actionafter']) qb.delete(torrent_hash) elif settings.qBittorrent['actionafter'] == 'deletedata': # this will delete the torrent from qBittorrent and delete data log.debug("Sending action %s to qBittorrent" % settings.qBittorrent['actionafter']) qb.delete_permanently(torrent_hash) if delete_dir: if os.path.exists(delete_dir): try: os.rmdir(delete_dir) log.debug("Successfully removed tempoary directory %s." % delete_dir) except: log.exception("Unable to delete temporary directory") except:
class QBittorrentDownloader: """ Class that uses the qBittorrent Server API to download torrents """ def __init__(self, url: str, username: str, password: str, download_dir: str): """ :param url: :param username: :param password: :param download_dir: """ self.client = Client(url) self.client.login(username, password) self.download_dir = download_dir @classmethod def from_config(cls) -> "QBittorrentDownloader": """ :return: A QBittorrentDownloader object based on the stored configuration files """ config = Config.load() return cls(config.qbittorrent_address, config.qbittorrent_username, config.qbittorrent_password, config.qbittorrent_download_dir) def download(self, torrents: List[TorrentDownload]): """ Downloads a list of torrent files :param torrents: The torrents to download :return: None """ for torrent in torrents: torrent_info = torrent.torrent_info print(f"Downloading Torrent: {torrent_info.filename}") if torrent_info.magnet_link is not None: self.client.download_from_link(torrent_info.magnet_link) else: assert torrent_info.torrent_file is not None torrent_file = torrent_info.torrent_file if not os.path.isfile(torrent_file): torrent_file = "/tmp/torrentdltemp.torrent" content = requests.get(torrent_info.torrent_file).content with open(torrent_file, "wb") as f: f.write(content) with open(torrent_file, "rb") as f: self.client.download_from_file(f) time.sleep(1) while len(self.client.torrents()) > 0: for active in self.client.torrents(): if active["state"] not in [ "downloading", "metaDL", "stalledDL" ]: print("Done. ") torrent_path = os.path.join(self.download_dir, active["name"]) if os.path.isdir(torrent_path): children = [ os.path.join(torrent_path, x) for x in os.listdir(torrent_path) ] children.sort(key=lambda x: os.path.getsize(x), reverse=True) torrent_path = children[0] ext = torrent_path.rsplit(".", 1)[1] torrent.add_extension(ext) self.client.delete(active["hash"]) if os.path.isdir(torrent.destination): shutil.move( torrent_path, os.path.join(torrent.destination, os.path.basename(torrent_path))) else: shutil.move(torrent_path, torrent.destination) else: print(f"{(100 * active['progress']):.2f}%", end="\r") time.sleep(1)
class QBittorrentClient(BTClientBase): def __init__(self, rpc_address, rpc_port, username, password, config={'use_https': False}): self.rpc_address = rpc_address self.rpc_port = rpc_port self.username = username self.password = password if 'use_https' in config: self.use_https = config['use_https'] else: self.use_https = False self.rpc_addr = str(rpc_address) + ':' + str(rpc_port) + '/' if self.use_https: self.rpc_addr = 'https://' + self.rpc_addr else: self.rpc_addr = 'http://' + self.rpc_addr self.client = Client(self.rpc_addr) self.connected = False def connect(self): login_ret = self.client.login(username=self.username, password=self.password) if login_ret is None: self.connected = True ret = ClientRet(ret_type=2) else: ret = ClientRet(ret_type=-2) return ret def add_torrent(self, torrent_path, download_path=None): if not self.connected: return ClientRet(ret_type=-2) abs_torrent_path = str(Path(torrent_path).resolve()) buf = open(abs_torrent_path, 'rb') if download_path is None: try: api_ret = self.client.download_from_file(buf) if 'Ok.' in api_ret: buf.close() info_hash = torf.Torrent.read(abs_torrent_path).infohash ret = ClientRet(ret_type=3, ret_value=info_hash) else: ret = ClientRet(ret_type=-3) except: ret = ClientRet(ret_type=-3) finally: return ret else: try: abs_download_path = str(Path(download_path).resolve()) api_ret = self.client.download_from_file( buf, save_path=abs_download_path) if 'Ok.' in api_ret: buf.close() info_hash = torf.Torrent.read(abs_torrent_path).infohash ret = ClientRet(ret_type=3, ret_value=info_hash) else: ret = ClientRet(ret_type=-3) except: ret = ClientRet(ret_type=-3) finally: return ret def list_torrents(self): if not self.connected: return ClientRet(ret_type=-2) torrent_list = self.client.torrents() session_status = {} for torrent in torrent_list: is_finished = math.isclose(torrent['progress'], 1) torrent_status = TorrentStatus(torrent_id=torrent['hash'], is_finished=is_finished, name=torrent['name']) session_status[torrent['hash']] = torrent_status ret = ClientRet(ret_type=4, ret_value=session_status) return ret def get_torrent_status(self, idx): if not self.connected: return ClientRet(ret_type=-2) tlist = self.client.torrents() for torrent in tlist: if idx == torrent[ 'hash']: # No progress info in get_torrent() method, really... is_finished = math.isclose(torrent['progress'], 1) torrent_status = TorrentStatus(torrent_id=torrent['hash'], is_finished=is_finished, name=torrent['name']) ret = ClientRet(ret_type=6, ret_value=torrent_status) return ret return ClientRet(ret_type=-6) def del_torrent(self, idx, remove_data=True): if not self.connected: return ClientRet(ret_type=-2) try: if remove_data: self.client.delete_permanently(idx) else: self.client.delete(idx) ret = ClientRet(ret_type=5) except: ret = ClientRet(ret_type=-5) finally: return ret def disconnect(self): if self.connected: self.client.logout() self.connected = False ret = ClientRet(ret_type=0) return ret
time.sleep(10) #darn, the pause function isn't working too well. put this here for a cheap fix. todo: make this more stable. qb.pause(tor[0]['hash']) while (int(temp_cTime[0]) > 6): t = time.localtime() current_time = time.strftime("%H:%M:%S", t) temp_cTime = current_time.split(':') time.sleep(600) #this is all very inefficient :( print('waking up...') qb.resume(tor[0]['hash']) if (tor[0]['progress']) == 1: print('Finished downloading ' + tor[0]['name']) qb.delete(tor[0]['hash']) magnetLinks.pop(0) searchAr.pop(0) searchDoc.truncate(0) magnetFile.truncate(0) for it in searchAr: searchDoc.write(it + '\n') for it in magnetLinks: magnetFile.write(it + '\n') #now i Need to make it so that the folder that gets downloaded, the mp4 downloading = False else: time.sleep(60) searchDoc.close() magnetFile.close() print('finished')
class AutoTorrent: def __init__(self): self.init_google_sheets() self.init_qb() self.downloading = {} def init_google_sheets(self): creds = None # The file token.pickle stores the user's access and refresh tokens, and is # created automatically when the authorization flow completes for the first # time. if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds = pickle.load(token) # If there are no (valid) credentials available, let the user log in. if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) # Save the credentials for the next run with open('token.pickle', 'wb') as token: pickle.dump(creds, token) self.google_sheets = build('sheets', 'v4', credentials=creds) def init_qb(self): self.qb = TorrentClient("http://127.0.0.1:8080/") self.qb.login("admin", "adminadmin") def get_movies(self): sheet = self.google_sheets.spreadsheets() result = sheet.values().get(spreadsheetId=SPREADSHEET_ID, range=RANGE_NAME).execute() values = result.get('values', []) if not values: print('No data found.') filtered = filter( lambda m: m[0] in ["No Descargada", "Auto Descargando"] and (len(m) < 5 or m[4] not in ["No", "Pocos Seeds"]), values) movies = map(lambda m: Movie(m[1], m[2]), filtered) return movies def download_movie(self, movie): torrent = movie.get_torrent() if not torrent: print(" Torrent not found for {}. Skipping".format(movie)) self.update_movie_yts(movie, "No") return magnet = torrent.magnet path = movie.local_path if not os.path.isdir(path): os.mkdir(path) self.qb.download_from_link(magnet, savepath=path) self.update_movie(movie, "Auto Descargando") for t in self.qb.torrents(): if os.path.normpath(t["save_path"]) == os.path.normpath(path): torrent_hash = t["hash"] break self.downloading[torrent_hash] = movie print(" Started downloading {}".format(movie)) def update_movie(self, movie, status): sheet = self.google_sheets.spreadsheets() result = sheet.values().get(spreadsheetId=SPREADSHEET_ID, range=RANGE_NAME).execute() values = list(result.get('values', [])) for value in values: if value[1] == movie.name and int(value[2]) == movie.year: value[0] = status body = {'values': values} sheet.values().update(spreadsheetId=SPREADSHEET_ID, range=RANGE_NAME, valueInputOption=VALUE_INPUT_OPTION, body=body).execute() def update_movie_yts(self, movie, yts): sheet = self.google_sheets.spreadsheets() result = sheet.values().get(spreadsheetId=SPREADSHEET_ID, range=RANGE_NAME).execute() values = list(result.get('values', [])) for value in values: if value[1] == movie.name and int(value[2]) == movie.year: if len(value) == 4: value.append(yts) else: value[4] = yts body = {'values': values} sheet.values().update(spreadsheetId=SPREADSHEET_ID, range=RANGE_NAME, valueInputOption=VALUE_INPUT_OPTION, body=body).execute() def should_download(self): current_torrents = len(self.qb.torrents(filter="downloading")) less_than_max = current_torrents < MAX_CONCURRENT_DOWNLOADS just_started = len(self.downloading) < MAX_CONCURRENT_DOWNLOADS return less_than_max or just_started def start(self): movies = self.get_movies() while True: sleep(1) self.clean_torrents() if not self.should_download(): continue movie = next(movies) print(movie) self.download_movie(movie) def clean_torrents(self): timed_out = [] done = [] for torrent in self.qb.torrents(): if torrent["progress"] == 1: done.append(torrent["hash"]) elif is_timed_out(torrent): timed_out.append(torrent["hash"]) for h in timed_out: if h not in self.downloading: continue movie = self.downloading[h] print("{} timed out. Removing".format(movie)) self.update_movie(movie, "No Descargada") self.update_movie_yts(movie, "Pocos Seeds") self.qb.delete(h) movie.delete_folder() for h in done: if h not in self.downloading: continue movie = self.downloading[h] self.update_movie(movie, "Descargada") self.qb.delete(h) movie.clean_folder() movie.move_to_drive() print("{} finished downloading. Moving to Google Drive".format( movie))
savePath = torrent['save_path'] nameFile = torrent['name'] magnet_uri = torrent['magnet_uri'] SLog.LogInfo( "magnet_uri : [{}]".format(magnet_uri)) SLog.LogInfo("torrent name : [{}]".format(nameFile)) SLog.LogInfo("save path : [{}]".format(savePath)) if not Options['dry-run']: # delete torrent file du serveur qbitorrent SLog.LogInfo("-" * 10) SLog.LogInfo( "del qbitorrent : [{}]".format(nameFile)) SLog.LogInfo("-" * 10) qb.delete(hashFile) else: SLog.LogCritical("Bad hash : [{}]".format(hashFile)) SLog.LogCritical( "-_|_- -_|_-") SLog.LogCritical( " -_|_- -_|_-") SLog.LogCritical(" -_|_- /!\\ /!\\ -_|_-") SLog.LogCritical(" ! exit !") SLog.LogCritical(" -_|_- \\|/ \\|/ -_|_-") SLog.LogCritical( " -_|_- -_|_-") SLog.LogCritical( "-_|_- -_|_-") sys.exit(1)