diff --git a/python_rpc/http_downloader.py b/python_rpc/http_downloader.py index 4358373e..4a71607c 100644 --- a/python_rpc/http_downloader.py +++ b/python_rpc/http_downloader.py @@ -1,61 +1,89 @@ -import aria2p +import os +import subprocess +import json class HttpDownloader: - def __init__(self): - self.download = None - self.aria2 = aria2p.API( - aria2p.Client( - host="http://localhost", - port=6800, - secret="" - ) - ) + def __init__(self): + self.binaries_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "binaries") + self.hydra_exe = os.path.join(self.binaries_path, "hydra-httpdl.exe") + self.process = None + self.last_status = None - def start_download(self, url: str, save_path: str, header: str, out: str = None, allow_multiple_connections: bool = False): - if self.download: - self.aria2.resume([self.download]) - else: - options = { - "header": header, - "dir": save_path, - "out": out - } + def start_download(self, url: str, save_path: str, header: str = None, out: str = None, allow_multiple_connections: bool = False): + cmd = [self.hydra_exe] + + cmd.append(url) + + cmd.extend([ + "--chunk-size", "10", + "--buffer-size", "16", + "--json-output", + "--silent" + ]) + + if allow_multiple_connections: + cmd.extend(["--connections", "24"]) + + print(f"running hydra-httpdl: {' '.join(cmd)}") + + try: + self.process = subprocess.Popen( + cmd, + cwd=save_path, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True + ) + except Exception as e: + print(f"error running hydra-httpdl: {e}") - if allow_multiple_connections: - options.update({ - "split": "16", - "max-connection-per-server": "16", - "min-split-size": "1M" - }) - - downloads = self.aria2.add(url, options=options) + + + def get_download_status(self): + + if not self.process: + return None + + try: + line = self.process.stdout.readline() + if line: + status = json.loads(line.strip()) + self.last_status = status + elif self.last_status: + status = self.last_status + else: + return None + + response = { + "status": "active", + "progress": status["progress"] / 100, + "downloadSpeed": status["download_speed"], + "numPeers": 0, + "numSeeds": 0, + "bytesDownloaded": status["bytes_downloaded"], + "fileSize": status["file_size"], + "folderName": status["file_name"] + } + + if status["progress"] == 100.0: + response["status"] = "complete" + + return response + + except Exception as e: + print(f"error getting download status: {e}") + return None - self.download = downloads[0] - - def pause_download(self): - if self.download: - self.aria2.pause([self.download]) - - def cancel_download(self): - if self.download: - self.aria2.remove([self.download]) - self.download = None - - def get_download_status(self): - if self.download == None: - return None - - download = self.aria2.get_download(self.download.gid) - - response = { - 'folderName': download.name, - 'fileSize': download.total_length, - 'progress': download.completed_length / download.total_length if download.total_length else 0, - 'downloadSpeed': download.download_speed, - 'numPeers': 0, - 'numSeeds': 0, - 'status': download.status, - 'bytesDownloaded': download.completed_length, - } - - return response + + + def stop_download(self): + if self.process: + self.process.terminate() + self.process = None + self.last_status = None + + def pause_download(self): + self.stop_download() + + def cancel_download(self): + self.stop_download()