alroyso 1 year ago
commit
c552b4a150
5 changed files with 378 additions and 0 deletions
  1. 141 0
      Aria2Download.py
  2. 154 0
      alist.py
  3. 29 0
      main.py
  4. 43 0
      monitor_aria2.py
  5. 11 0
      requirements.txt

+ 141 - 0
Aria2Download.py

@@ -0,0 +1,141 @@
+import requests
+import json
+
+
+class Aria2Download:
+    def __init__(self, api_url, rpc_secret=None):
+        self.api_url = api_url
+        self.rpc_secret = rpc_secret
+        self.id = "QXJpYU5nXzE2NzUxMzUwMDFfMC42Mzc0MDA5MTc2NjAzNDM="
+
+    def addUri(self, url, path, file=None, proxy=None):
+        """
+        添加任务
+        :param url: 文件下载地址
+        :param path: 文件保存路径
+        :param file: 文件保存名称
+        :param proxy: 代{过}{滤}理地址
+        :return:
+        """
+        data = {
+            "id": self.id,
+            "jsonrpc": "2.0",
+            "method": "aria2.addUri",
+            "params": [[url], {"dir": path, "out": file, "all-proxy": proxy}]
+        }
+        req = requests.post(url=self.api_url, data=json.dumps(data))
+        return_json = req.json()
+        req.close()
+        # print("addUri", return_json)
+        return return_json
+
+    def getGlobalStat(self):
+        """
+        获取全部下载信息
+        :return:
+        """
+        data = {
+            "jsonrpc": "2.0",
+            "method": "aria2.getGlobalStat",
+            "id": self.id
+        }
+        req = requests.post(url=self.api_url, data=json.dumps(data))
+        return_json = req.json()
+        req.close()
+        # print("getGlobalStat", return_json)
+        return return_json
+
+    def tellActive(self):
+        """
+        正在下载
+        :return:
+        """
+        data = {
+            "jsonrpc": "2.0",
+            "method": "aria2.tellActive",
+            "id": self.id, "params": [
+                ["gid", "totalLength", "completedLength", "uploadSpeed", "downloadSpeed", "connections", "numSeeders",
+                 "seeder", "status", "errorCode", "verifiedLength", "verifyIntegrityPending", "files", "bittorrent",
+                 "infoHash"]]
+        }
+
+        req = requests.post(url=self.api_url, data=json.dumps(data))
+        return_json = req.json()
+        req.close()
+        # print("getGlobalStat", return_json)
+        return return_json
+
+    def tellWaiting(self):
+        """
+        正在等待
+        :return:
+        """
+        data = {"jsonrpc": "2.0", "method": "aria2.tellWaiting",
+                "id": self.id,
+                "params": [0, 1000, ["gid", "totalLength",
+                                     "completedLength",
+                                     "uploadSpeed",
+                                     "downloadSpeed",
+                                     "connections",
+                                     "numSeeders",
+                                     "seeder", "status",
+                                     "errorCode",
+                                     "verifiedLength",
+                                     "verifyIntegrityPending"]
+                           ]
+                }
+        req = requests.post(url=self.api_url, data=json.dumps(data))
+        return_json = req.json()
+        req.close()
+        print("tellWaiting", return_json)
+        return return_json
+
+    def tellStopped(self):
+        """
+        已完成/已停止
+        :return:
+        """
+        data = {"jsonrpc": "2.0",
+                "method": "aria2.tellStopped",
+                "id": self.id,
+                "params": [-1, 1000, ["gid", "totalLength",
+                                      "completedLength",
+                                      "uploadSpeed",
+                                      "downloadSpeed",
+                                      "connections",
+                                      "numSeeders", "seeder",
+                                      "status", "errorCode",
+                                      "verifiedLength",
+                                      "verifyIntegrityPending"]]
+                }
+        req = requests.post(url=self.api, data=json.dumps(data))
+        return_json = req.json()
+        req.close()
+        # print("tellStopped", return_json)
+        return return_json
+
+    def tellStatus(self, gid):
+        """
+        任务状态
+        :param gid: 任务ID
+        :return:
+        """
+        data = {"jsonrpc": "2.0", "method": "aria2.tellStatus", "id": self.id, "params": [gid]}
+        req = requests.post(url=self.api_url, data=json.dumps(data))
+        return_json = req.json()
+        req.close()
+        # print("tellWaiting", return_json)
+        return return_json
+
+    def removeDownloadResult(self, gid):
+        """
+        删除下载结束的任务
+        :param gid: 任务ID
+        :return:
+        """
+        data = {"jsonrpc": "2.0", "method": "aria2.removeDownloadResult", "id": self.id, "params": [gid]}
+        req = requests.post(url=self.api_url, data=json.dumps(data))
+        return_json = req.json()
+        req.close()
+        # print("removeDownloadResult", return_json)
+        return return_json

+ 154 - 0
alist.py

@@ -0,0 +1,154 @@
+import json
+import os
+import shutil
+import time
+
+import requests
+from aria2p import API, Client
+
+
+class AlistAPI:
+    def __init__(self, url, aria2_rpc_url=None, aria2_rpc_secret=None, username=None, password=None):
+        self.url = url
+        self.UserAgent = ('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
+                          'Chrome/87.0.4280.88 Safari/537.36')
+        self.headers = {
+            'UserAgent': self.UserAgent,
+            'Content-Type': 'application/json'
+        }
+        self.aria2_client = Client(aria2_rpc_url, secret=aria2_rpc_secret)
+        self.aria2_api = API(self.aria2_client)
+        if username and password:
+            self.login(username, password)
+
+    def login(self, username, password):
+        data = {
+            'username': username,
+            'password': password
+        }
+        response = requests.post(f'{self.url}/auth/login', data=json.dumps(data), headers=self.headers)
+        if response.status_code == 200:
+            token = response.json()
+            self.headers['Authorization'] = token['data']['token']
+        else:
+            raise Exception('Login failed')
+
+    def get_directory(self, path="", password="", page=1, per_page=0, refresh=False):
+        payload = {
+            "path": path,
+            "password": password,
+            "page": page,
+            "per_page": per_page,
+            "refresh": refresh
+        }
+        response = requests.post(f'{self.url}/fs/dirs', data=json.dumps(payload), headers=self.headers)
+        return response.json()
+
+    def copy_file(self, src_dir, dst_dir, names):
+        payload = {
+            "src_dir": src_dir,
+            "dst_dir": dst_dir,
+            "names": names
+        }
+        response = requests.post(f'{self.url}/fs/copy', data=json.dumps(payload), headers=self.headers)
+        return response.json()
+
+    def list_directory(self, path, password="", page=1, per_page=0, refresh=False):
+        payload = {
+            "path": path,
+            "password": password,
+            "page": page,
+            "per_page": per_page,
+            "refresh": refresh
+        }
+        response = requests.post(f'{self.url}/fs/list', data=json.dumps(payload), headers=self.headers)
+        return response.json()
+
+    def get_file_or_directory_info(self, path, password="", page=1, per_page=0, refresh=False):
+        payload = {
+            "path": path,
+            "password": password,
+            "page": page,
+            "per_page": per_page,
+            "refresh": refresh
+        }
+        response = requests.post(f"{self.url}/fs/get", data=json.dumps(payload), headers=self.headers)
+        return response.json()
+
+    def move_file(self, src_dir, dst_dir, names):
+        payload = json.dumps({
+            "src_dir": src_dir,
+            "dst_dir": dst_dir,
+            "names": names
+        })
+        response = requests.post(f"{self.url}/fs/move", data=payload, headers=self.headers)
+        return response.json()
+
+    def download_directory(self, path, download_path):
+        file_list = self.list_directory(path)
+        if not file_list:
+            return
+        for file_info in file_list['data']['content']:
+            if file_info['is_dir']:
+                self.download_directory(path + "/" + file_info['name'], download_path)
+            else:
+                file_download_url = self.url + "/d" + path + "/" + file_info['name']
+                sign = file_info.get('sign')
+                if sign:
+                    file_download_url += "?sign=" + sign
+                self.aria2_api.add_uris([file_download_url], options={"dir": download_path})
+
+    def debug_directory(self, path, download_path):
+        file_list = self.list_directory(path)
+        if not file_list:
+            return
+        for file_info in file_list['data']['content']:
+            if file_info['is_dir']:
+                print(f"Directory: {path}/{file_info['name']}")
+                self.debug_directory(path + "/" + file_info['name'], download_path)
+            else:
+                file_download_url = self.url + "/d" + path + "/" + file_info['name']
+                sign = file_info.get('sign')
+                if sign:
+                    file_download_url += "?sign=" + sign
+                print(f"File: {file_download_url}, Save to: {download_path}")
+
+    # alist 下载完成复制
+    def monitor_and_copy(self, download_path, destination_path, check_interval=10):
+        while True:
+            downloads = self.aria2_api.get_downloads()
+            for download in downloads:
+                if download.is_complete:
+                    for file in download.files:
+                        if file.selected:
+                            file_name = os.path.basename(file.path)
+                            names = [file_name]
+
+                            # 复制文件
+                            self.copy_file(download_path, destination_path, names)
+                            print(f"Copied: {file_name} from {download_path} to {destination_path}")
+
+                            # 从 Aria2 中移除已完成的下载记录
+                            download.remove()
+
+            time.sleep(check_interval)
+
+    # alist 下载完成移动
+    def monitor_and_move(self, download_path, destination_path, check_interval=10):
+        while True:
+            downloads = self.aria2_api.get_downloads()
+            for download in downloads:
+                if download.is_complete:
+                    for file in download.files:
+                        if file.selected:
+                            file_name = os.path.basename(file.path)
+                            names = [file_name]
+
+                            # 移动文件
+                            self.move_file(download_path, destination_path, names)
+                            print(f"Moved: {file_name} from {download_path} to {destination_path}")
+
+                            # 从 Aria2 中移除已完成的下载记录
+                            download.remove()
+
+            time.sleep(check_interval)

+ 29 - 0
main.py

@@ -0,0 +1,29 @@
+from alist import AlistAPI
+
+if __name__ == '__main__':
+    alist = AlistAPI('http://192.168.88.10:5244/api', 'http://192.168.88.10', '123456', 'admin', 'nokidc123@#')
+    directory_info = alist.get_directory()
+    print(directory_info)
+    # lis_file = alist.debug_directory('/box/media/moive', '/download/moive')
+    # print(lis_file)
+    #
+    # destination_folder = "/mnt/video/download/movie"
+    # alist.monitor_and_move(destination_folder)
+
+    download_path = "/data1/download/movie"
+    destination_path = "/video/sync/movie"
+    # 调用复制函数
+    alist.monitor_and_copy(download_path, destination_path)
+    # 调用移动函数
+    # alist.monitor_and_move(download_path, destination_path)
+
+    # file_or_dir = alist.list_directory('/data1/download/moive')
+    # print(file_or_dir['data']['content'])
+    # # 遍历content数组
+    # for item in file_or_dir['data']['content']:
+    #     if item['is_dir']:
+    #         # 是目录
+    #         print(f"{item['name']} is a directory")
+    #     else:
+    #         # 是文件
+    #         print(f"{item['name']} is a file")

+ 43 - 0
monitor_aria2.py

@@ -0,0 +1,43 @@
+import os
+import shutil
+import time
+from aria2p import API, Client
+
+
+class Aria2Monitor:
+    def __init__(self, aria2_rpc_url, aria2_rpc_secret=None):
+        self.aria2_client = Client(aria2_rpc_url, secret=aria2_rpc_secret)
+        self.aria2_api = API(self.aria2_client)
+
+    def monitor_and_move_shutil(self, destination_folder, check_interval=10):
+        """
+        Monitor active downloads and move completed downloads with multiple files to a destination folder.
+        """
+        while True:
+            downloads = self.aria2_api.get_downloads()
+            for download in downloads:
+                if download.is_complete:
+                    for file in download.files:
+                        if file.selected:
+                            file_path = file.path
+                            file_name = os.path.basename(file_path)
+
+                            # 构建目标路径
+                            target_path = os.path.join(destination_folder, file_name)
+
+                            # 移动文件
+                            if os.path.exists(file_path):
+                                shutil.move(file_path, target_path)
+                                print(f"Moved: {file_path} -> {target_path}")
+
+                    # 从 Aria2 中移除已完成的下载记录
+                    download.remove()
+
+            time.sleep(check_interval)
+
+
+if __name__ == '__main__':
+    # 使用示例
+    aria2_monitor = Aria2Monitor("http://192.168.88.10:6800/jsonrpc", "123456")
+    destination_folder = "/mnt/video/sync/movie"
+    aria2_monitor.monitor_and_move_shutil(destination_folder)

+ 11 - 0
requirements.txt

@@ -0,0 +1,11 @@
+appdirs==1.4.4
+aria2p==0.12.0
+certifi==2023.11.17
+charset-normalizer==3.3.2
+idna==3.6
+loguru==0.7.2
+requests==2.31.0
+tomli==2.0.1
+typing_extensions==4.9.0
+urllib3==2.1.0
+websocket-client==1.7.0