alroyso 1 year ago
parent
commit
67b5726a19

+ 2 - 2
main.py

@@ -16,7 +16,7 @@ if __name__ == '__main__':
     current_directory = os.path.dirname(os.path.abspath(__file__))
 
     # 获取当前脚本所在目录的上级目录
-     # parent_directory = os.path.dirname(current_directory)
+    # parent_directory = os.path.dirname(current_directory)
 
     # 构建 config.ini 文件的路径
     config_path = os.path.join(current_directory, 'config', 'config.ini')
@@ -29,7 +29,7 @@ if __name__ == '__main__':
     app_service = Application(config, current_directory)
 
     # task
-    app_service.test_nas_tools_service()
+    app_service.run()
 
     # 执行主循环
     app_service.main_loop()

+ 3 - 26
src/api/NasToolsClient.py

@@ -72,31 +72,11 @@ class NasToolsClient:
         logging.info(response.json())
         return response.json()
 
-    def start_sync(self):
-        """
-        /library/sync/start
-        :return:
-        """
-        url = f'{self.base_url}/api/v1/library/sync/start'
-        # {"Bearer Auth": {"type": "apiKey", "name": "Authorization", "in": "header"}}
-        headers = {
-            'accept': 'application/json',
-            'security': self.api_key,
-            "Authorization": f"{self.token}",
-        }
-        logging.info(f"headers: {headers}")
-        params = {
-            'apikey': self.api_key,
-        }
-        response = requests.post(url, params=params, headers=headers)
-        logging.info(response.text)
-        return response.text
-
-    def sync(self):
+    def sync(self, sid):
         """
         同步目录 {cmd: "run_directory_sync", data: {sid: []}}
         """
-        url = f'{self.base_url}/api/v1/sync/run'
+        url = f'{self.base_url}/api/v1/sync/directory/run'
         # {"Bearer Auth": {"type": "apiKey", "name": "Authorization", "in": "header"}}
         headers = {
             'accept': 'application/json',
@@ -106,10 +86,7 @@ class NasToolsClient:
         logging.info(f"headers: {headers}")
         params = {
             'apikey': self.api_key,
-            'cmd': 'run_directory_sync',
-            'data': {
-                'sid': []
-            }
+            'sid': sid
 
         }
         response = requests.get(url, params=params, headers=headers)

+ 5 - 0
src/api/alist.py

@@ -166,6 +166,11 @@ class AlistAPI:
                                    current_sub_path=''):
         contents = []
         file_list = self.list_directory(remote_download_path)
+        file_info_json = json.dumps(file_list, indent=4)
+        logging.info(f'file_info_json: {file_info_json}')
+        if file_list['data']['total'] == 0:
+            return []
+
         for file_info in file_list['data']['content']:
             # 拼接完整的远程路径
             full_path = os.path.join(remote_download_path, file_info['name']).replace('\\', '/')

+ 28 - 1
src/api/radarr.py

@@ -14,7 +14,7 @@ class RadarClient:
         return self.client.get_movie()
 
     def delete_movie(self, movie_id):
-        return self.client.del_movie(movie_id)
+        return self.client.del_movie(movie_id, delete_files=True)
 
     def save_movies_to_json(self, file_name='data/movies.json'):
         movies = self.get_all_movies()
@@ -45,3 +45,30 @@ class RadarClient:
                     custom_action(movie)
                     already_processed.add(movie['id'])
             time.sleep(check_interval)
+
+    def find_movie_id_by_filename(self, filename):
+        """根据文件名搜索并返回已完成下载的电影的 ID"""
+        try:
+
+            movies = self.get_all_movies()
+            for movie in movies:
+                # 检查电影是否已下载
+                if 'movieFile' in movie and movie['movieFile']:
+                    movie_file_name = movie['movieFile']['relativePath']
+                    # 检查文件名是否匹配
+                    if filename in movie_file_name:
+                        return movie['id']
+            return None
+        except Exception as e:
+            return None
+
+    def get_all_movie_names(self):
+        """获取所有电影名称的集合"""
+        movie_names = set()
+        movies = self.get_all_movies()
+        for movie in movies:
+            if 'movieFile' in movie and movie['movieFile']:
+                movie_file_name = movie['movieFile']['relativePath']
+                movie_names.add(movie_file_name)
+        return movie_names
+

+ 14 - 8
src/app/application.py

@@ -20,10 +20,10 @@ class Application:
     def __init__(self, config, parent_directory, remote_download_service=True):
         self.config = config
         self.parent_dir = parent_directory
-        base_url = config['NSTOOLS']['URL']
-        api_key = config['NSTOOLS']['API_KEY']
-
-        self.nas_tools_api = NasToolsClient(base_url, api_key)
+        # base_url = config['NSTOOLS']['URL']
+        # api_key = config['NSTOOLS']['API_KEY']
+        #
+        # self.nas_tools_api = NasToolsClient(base_url, api_key)
 
         self.aria2_service = Aria2Service(config)
 
@@ -36,9 +36,7 @@ class Application:
         signal.signal(signal.SIGINT, self.handle_signal)
 
     def test_nas_tools_service(self):
-        self.nas_tools_api.login('admin', 'password')
-        # self.nas_tools_api.run_service('sync')
-        self.nas_tools_api.start_sync()
+        pass
 
     def handle_signal(self, signum, frame):
         """处理中断信号,优雅地退出循环"""
@@ -46,7 +44,10 @@ class Application:
         print("Exiting...")
 
     def start_remote_download(self):
-        self.remote_download_service.process_downloads()
+        self.remote_download_service.start_monitoring()
+
+    def stop_remote_download(self):
+        self.remote_download_service.stop_monitoring()
 
     def start_aria2_monitoring(self):
         self.aria2_service.start_monitoring()
@@ -54,10 +55,15 @@ class Application:
     def stop_aria2_monitoring(self):
         self.aria2_service.stop_monitoring()
 
+    def run(self):
+        self.start_remote_download()
+        self.start_aria2_monitoring()
+
     def main_loop(self):
         # 主循环
         while self.is_running:
             # print("Running...")
             time.sleep(1)  # 模拟任务执行
         print("Stopped.")
+        self.stop_remote_download()
         self.stop_aria2_monitoring()

+ 9 - 1
src/services/Aria2Service.py

@@ -1,15 +1,23 @@
 from src.api.Aria2API import Aria2API
+from src.api.NasToolsClient import NasToolsClient
 from src.task.Aria2FileCopyTask import Aria2FileCopyTask
 
 
 class Aria2Service:
     def __init__(self, config):
         self.config = config
+        self.check_interval = config['COMMON']['CHECK_INTERVAL']
+        base_url = config['NSTOOLS']['URL']
+        api_key = config['NSTOOLS']['API_KEY']
+        self.nas_tools_api = NasToolsClient(base_url, api_key)
+        self.aria2_api = Aria2API(config['ARIA2']['RPC_URL'], config['ARIA2']['RPC_SECRET'])
         self.aria2_api = Aria2API(config['ARIA2']['RPC_URL'], config['ARIA2']['RPC_SECRET'])
         self.file_copy_service = Aria2FileCopyTask(
             aria2_api=self.aria2_api,
+            nas_tools_api=self.nas_tools_api,
             download_path=config['ARIA2']['DESTINATION_PATH'],
-            destination_path=config['ARIA2']['DES_COPY_PATH']
+            destination_path=config['ARIA2']['DES_COPY_PATH'],
+            check_interval=self.check_interval
         )
 
     def start_monitoring(self):

+ 8 - 80
src/services/RemoteDownloadSerivce.py

@@ -5,90 +5,18 @@ import os
 from src.api.Aria2API import Aria2API
 from src.api.alist import AlistAPI
 from src.api.radarr import RadarClient
+from src.task.RemoteDownloadTask import RemoteDownloadTask
 
 
 class RemoteDownloadService:
     def __init__(self, config, parent_dir):
-        self.config = config
-        self.remote_alist_api = AlistAPI(self.config['REMOTE_ALIST']['API_URL'],
-                                         self.config['REMOTE_ALIST']['USERNAME'],
-                                         self.config['REMOTE_ALIST']['PASSWORD'])
-        self.radar_client = RadarClient(self.config['RADAR']['URL'],
-                                        self.config['RADAR']['API_KEY'])
+        self.remote_download_task = RemoteDownloadTask(config, parent_dir)
 
-        self.home_alist_api = AlistAPI(self.config['HOME_ALIST']['API_URL'],
-                                       self.config['HOME_ALIST']['USERNAME'],
-                                       self.config['HOME_ALIST']['PASSWORD'])
+    def download(self):
+        self.remote_download_task.process_downloads()
 
-        self.aria2_api = Aria2API(config['ARIA2']['RPC_URL'], config['ARIA2']['RPC_SECRET'])
+    def start_monitoring(self):
+        self.remote_download_task.start_monitoring()
 
-        # 读取路径等配置
-        self.remote_alist_download_path = self.config['REMOTE_ALIST']['DOWNLOAD_PATH']
-        self.home_alist_download_path = self.config['HOME_ALIST']['DOWNLOAD_PATH']
-        self.home_scy_alist_copy_path = self.config['HOME_ALIST']['SCY_COPY_PATH']
-        self.home_des_alist_copy_path = self.config['HOME_ALIST']['DES_COPY_PATH']
-        self.remote_data = self.config['COMMON']['REMOTE_DATA']
-        self.home_data = self.config['COMMON']['HOME_DATA']
-        self.aria2_download_path = self.config['ARIA2']['DESTINATION_PATH']
-        self.aria2_docker_download_path = self.config['ARIA2']['DOCKER_DOWNLOAD_PATH']
-        self.parent_dir = parent_dir
-        self.home_json_path = os.path.join(parent_dir, 'data', self.home_data)
-
-    def save_directory_contents(self,
-                                remote_download_path,
-                                local_download_path,
-                                scy_copy_path,
-                                des_copy_path,
-                                parent_dir):
-        """获取远程和本地对应的目录结构,并保存为 JSON 文件"""
-        # 获取远程目录结构
-        remote_data = self.remote_alist_api.recursive_collect_contents(
-            remote_download_path,
-            local_download_path
-        )
-        remote_json_path = os.path.join(parent_dir, 'data', 'remote_data.json')
-        with open(remote_json_path, 'w', encoding='utf-8') as f:
-            json.dump(remote_data, f, indent=4)
-
-        # # 获取本地目录结构
-        # home_data = self.home_alist_api.recursive_collect_contents(
-        #     scy_copy_path, des_copy_path, scy_copy_path, des_copy_path
-        # )
-        # home_json_path = os.path.join(parent_dir, 'data', self.home_data)
-        # with open(home_json_path, 'w', encoding='utf-8') as f:
-        #     json.dump(home_data, f, indent=4)
-
-        return remote_data
-
-    def process_downloads(self):
-
-        # 获取远程目录结构
-        remote_json_path = self.save_directory_contents(
-            self.remote_alist_download_path,
-            self.home_alist_download_path,
-            self.home_scy_alist_copy_path,
-            self.home_des_alist_copy_path,
-            self.parent_dir,
-        )
-        # 获取远程目录结构
-
-        # 从 Radarr 获取已完成电影的数量
-        already_movies = self.radar_client.get_already_movies()
-        for movie in already_movies:
-            logging.info(movie)
-            # 从 Alist 获取所有远程电影的路径并获取文件真实下载路径,然后添加到aira2开始下载
-            for home in remote_json_path:
-                if not home['is_dir']:
-                    cent_data = self.remote_alist_api.get_file_or_directory_info(home['path'])
-                    if cent_data is not None:
-                        # json_data = json.dumps(cent_data, indent=4)
-                        # logging.info(f"is file info: {json_data}")
-                        self.send_to_aria2(cent_data['data']['raw_url'])
-                        logging.info(f"start to download {cent_data['data']['raw_url']}")
-                    else:
-                        logging.info(f"file no ")
-
-    def send_to_aria2(self, file_path):
-        # 将文件添加到 Aria2 下载队列
-        self.aria2_api.add_url(file_path, options={"dir": self.aria2_docker_download_path + "/movie"})
-        logging.info(f"Added to Aria2: {file_path}")
+    def stop_monitoring(self):
+        self.remote_download_task.stop_monitoring()

+ 29 - 24
src/task/Aria2FileCopyTask.py

@@ -6,12 +6,14 @@ import time
 
 
 class Aria2FileCopyTask:
-    def __init__(self, aria2_api, download_path, destination_path):
+    def __init__(self, aria2_api, nas_tools_api, download_path, destination_path, check_interval):
+        self.nas_tools_api = nas_tools_api
         self.aria2_api = aria2_api
         self.download_path = download_path
         self.destination_path = destination_path
         self.is_running = False
         self.thread = None
+        self.check_interval = check_interval
 
     def start_monitoring(self):
         if not self.is_running:
@@ -25,21 +27,36 @@ class Aria2FileCopyTask:
             self.thread.join()
 
     def monitor_aria2_and_move(self):
+        logging.info("Starting monitoring aria2 is complete and move to " + self.destination_path)
         while self.is_running:
             # 获取 Aria2 当前的下载列表
             downloads = self.aria2_api.get_downloads()
             for download in downloads:
                 if download.is_complete:
-                    # 从 Aria2 中移除已完成的下载记录
-                    # 无论 Aria2 是否有记录,都执行移动操作
-                    self.move_new_files(self.download_path, self.destination_path)
-                    # 添加移动完成的提示
-                    logging.info("Completed checking for new files to move.")
-                    download.remove()
-                    logging.info("delete ara2 ")
+                    # 检查下载路径是否存在并且里面是否有文件
+                    if os.path.exists(self.download_path) and os.listdir(self.download_path):
+                        # 无论 Aria2 是否有记录,都执行移动操作
+                        self.move_new_files(self.download_path, self.destination_path)
+
+                    else:
+                        logging.info("No new files to move.")
 
             time.sleep(10)
 
+    def nas_sync(self):
+        logging.info("Notify nas tools synchronization")
+        self.nas_tools_api.login('admin', 'password')
+        # self.nas_tools_api.run_service('sync')
+
+        directory_ids = [29, 30]
+
+        # for directory_id in sync_directories:
+        #     directory_info = sync_directories[directory_id]
+        #     directory_ids.append(directory_info["id"])
+
+        for directory_id in directory_ids:
+            self.nas_tools_api.sync(directory_id)
+
     def move_new_files(self, src_dir, dest_dir):
         """移动新文件和目录,如果它们在目标目录中不存在"""
         if not os.path.exists(dest_dir):
@@ -63,25 +80,13 @@ class Aria2FileCopyTask:
                 if not os.path.exists(dest_item):
                     shutil.move(src_item, dest_item)
                     logging.info(f"Moved file from {src_item} to {dest_item}")
+                    # 添加移动完成的提示
+                    logging.info(f"move complete {dest_item} ")
+                    self.nas_sync()
+                    logging.info("Completed checking for new files to move.")
                 else:
                     logging.info(f"File already exists, skipping: {dest_item}")
 
-    def monitor_aria2_and_copy(self):
-        while self.is_running:
-            # 获取 Aria2 当前的下载列表
-            downloads = self.aria2_api.get_downloads()
-            for download in downloads:
-                if download.is_complete:
-                    # 从 Aria2 中移除已完成的下载记录
-                    download.remove()
-
-            # 无论 Aria2 是否有记录,都执行复制操作
-            self.copy_new_files(self.download_path, self.destination_path)
-            # 添加复制完成的提示
-            logging.info("Completed checking for new files to copy.")
-
-            time.sleep(10)
-
     def copy_new_files(self, src_dir, dest_dir):
         """复制新文件,如果它们在目标目录中不存在"""
         if not os.path.exists(dest_dir):

+ 166 - 0
src/task/RemoteDownloadTask.py

@@ -0,0 +1,166 @@
+import json
+import logging
+import os
+import threading
+import time
+
+from src.api.Aria2API import Aria2API
+from src.api.alist import AlistAPI
+from src.api.radarr import RadarClient
+
+
+class RemoteDownloadTask:
+    def __init__(self, config, parent_dir):
+
+        self.current_downloads = None
+        self.completed_downloads = None
+        self.config = config
+        self.is_running = False
+
+        self.monitor_thread = None
+        self.download_thread = None
+        self.check_interval = int(config['COMMON']['CHECK_INTERVAL'])
+        self.remote_alist_api = AlistAPI(self.config['REMOTE_ALIST']['API_URL'],
+                                         self.config['REMOTE_ALIST']['USERNAME'],
+                                         self.config['REMOTE_ALIST']['PASSWORD'])
+
+        self.radar_client = RadarClient(self.config['RADAR']['URL'],
+                                        self.config['RADAR']['API_KEY'])
+
+        self.home_alist_api = AlistAPI(self.config['HOME_ALIST']['API_URL'],
+                                       self.config['HOME_ALIST']['USERNAME'],
+                                       self.config['HOME_ALIST']['PASSWORD'])
+
+        self.aria2_api = Aria2API(config['ARIA2']['RPC_URL'], config['ARIA2']['RPC_SECRET'])
+
+        # 读取路径等配置
+        self.remote_alist_download_path = self.config['REMOTE_ALIST']['DOWNLOAD_PATH']
+        self.home_alist_download_path = self.config['HOME_ALIST']['DOWNLOAD_PATH']
+        self.home_scy_alist_copy_path = self.config['HOME_ALIST']['SCY_COPY_PATH']
+        self.home_des_alist_copy_path = self.config['HOME_ALIST']['DES_COPY_PATH']
+        self.remote_data = self.config['COMMON']['REMOTE_DATA']
+        self.home_data = self.config['COMMON']['HOME_DATA']
+        self.aria2_download_path = self.config['ARIA2']['DESTINATION_PATH']
+        self.aria2_docker_download_path = self.config['ARIA2']['DOCKER_DOWNLOAD_PATH']
+        self.parent_dir = parent_dir
+        self.home_json_path = os.path.join(parent_dir, 'data', self.home_data)
+
+    def start_monitoring(self):
+        if not self.is_running:
+            self.is_running = True
+            self.monitor_thread = threading.Thread(target=self.monitor_aria2_and_delete)
+            self.download_thread = threading.Thread(target=self.process_downloads)
+
+            self.monitor_thread.start()
+            self.download_thread.start()
+
+    def stop_monitoring(self):
+        self.is_running = False
+        if self.monitor_thread:
+            self.monitor_thread.join()
+        if self.download_thread:
+            self.download_thread.join()
+
+    def _save_directory_contents(self,
+                                 remote_download_path,
+                                 local_download_path,
+                                 scy_copy_path,
+                                 des_copy_path,
+                                 parent_dir):
+        """获取远程和本地对应的目录结构,并保存为 JSON 文件"""
+        # 获取远程目录结构
+        remote_data = self.remote_alist_api.recursive_collect_contents(
+            remote_download_path,
+            local_download_path
+        )
+        remote_json_path = os.path.join(parent_dir, 'data', 'remote_data.json')
+        with open(remote_json_path, 'w', encoding='utf-8') as f:
+            json.dump(remote_data, f, indent=4)
+
+        # # 获取本地目录结构
+        # home_data = self.home_alist_api.recursive_collect_contents(
+        #     scy_copy_path, des_copy_path, scy_copy_path, des_copy_path
+        # )
+        # home_json_path = os.path.join(parent_dir, 'data', self.home_data)
+        # with open(home_json_path, 'w', encoding='utf-8') as f:
+        #     json.dump(home_data, f, indent=4)
+
+        return remote_data
+
+    def init_download_states(self):
+        # 获取已完成下载的电影文件名
+        self.completed_downloads = self.radar_client.get_all_movie_names()
+
+        # 获取当前 Aria2 下载队列中的文件名
+        self.current_downloads = {os.path.basename(file.path) for download in self.aria2_api.get_downloads() for file in
+                                  download.files if file.selected}
+
+    def process_downloads(self):
+        logging.info('Start remote download monitoring')
+        self.init_download_states()
+
+        while self.is_running:
+            # 更新当前下载队列集合
+            self.current_downloads = {os.path.basename(file.path) for download in self.aria2_api.get_downloads() for
+                                      file in download.files if file.selected}
+
+            # 获取已完成电影的文件名集合
+            already_movie_names = self.radar_client.get_all_movie_names()
+
+            for home in already_movie_names:
+                if home not in self.current_downloads and home not in self.current_downloads:
+                    # 获取远程目录结构
+                    remote_json_path = self._save_directory_contents(self.remote_alist_download_path,
+                                                                     self.home_alist_download_path,
+                                                                     self.home_scy_alist_copy_path,
+                                                                     self.home_des_alist_copy_path, self.parent_dir)
+
+                    for home_item in remote_json_path:
+                        if not home_item['is_dir'] and home_item['name'] == home:
+                            cent_data = self.remote_alist_api.get_file_or_directory_info(home_item['path'])
+                            if cent_data:
+                                self.send_to_aria2(cent_data['data']['raw_url'])
+                                logging.info(f"Started to download {cent_data['data']['raw_url']}")
+                                self.current_downloads.add(home_item['name'])
+                            else:
+                                logging.info("File not found")
+
+            time.sleep(self.check_interval)
+
+    def send_to_aria2(self, file_path):
+        # 将文件添加到 Aria2 下载队列
+        self.aria2_api.add_url(file_path, options={"dir": self.aria2_docker_download_path + "/movie"})
+        logging.info(f"Added to Aria2: {file_path}")
+
+    def monitor_aria2_and_delete(self):
+        logging.info('Start remote Aria2 download is_complete monitoring')
+        while self.is_running:
+            # 获取 Aria2 当前的下载列表
+            downloads = self.aria2_api.get_downloads()
+            for download in downloads:
+                if download.is_complete:
+                    # 获取下载完成的文件名
+                    # completed_files = [os.path.basename(file.path) for file in download.files if file.selected]
+
+                    movie_name = self.radar_client.get_all_movie_names()
+                    for file_name in movie_name:
+                        # logging.info(f"Download completed: {file_name}")
+                        # 处理每个下载完成的文件
+                        # 调用方法并获取返回的电影 ID
+                        movie_id = self.radar_client.find_movie_id_by_filename(file_name)
+
+                        # 打印结果
+                        if movie_id is not None:
+                            print(f"Found movie ID for '{file_name}': {movie_id}")
+                        else:
+                            print(f"No movie found for '{file_name}'")
+
+                        # try:
+                        #     delete_info = self.radar_client.delete_movie(movie_id)
+                        #     if delete_info is not None:
+                        #         delete_info = json.dumps(delete_info, indent=4)
+                        #         print(f"delete_info: {delete_info}")
+                        # except Exception as e:
+                        #     print(f'Exception: {e}')
+
+            time.sleep(self.check_interval)

+ 34 - 109
tests/test.py

@@ -1,125 +1,50 @@
-# def monitor_copy_and_delete(self, local_json_path, destination_path, check_interval=10, is_debug=False,
-#                             is_running=True):
-#     """监控 Aria2 下载完成后,执行拷贝操作并删除原始文件及历史记录"""
-#     try:
-#         while is_running:
-#             # 读取本地 JSON 文件
-#             with open(local_json_path, 'r', encoding='utf-8') as f:
-#                 directory_contents = json.load(f)
-#
-#             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)
-#
-#                             for item in directory_contents:
-#                                 if item['name'] == file_name and not item['is_dir']:
-#                                     original_path = item['downloads_path']  # 获取原始文件路径
-#
-#                                     if is_debug:
-#                                         logging.info(f"Debug mode: Copy {file_name}")
-#                                     else:
-#                                         # 复制文件
-#                                         self.copy_file(original_path, destination_path, [file_name])
-#                                         logging.info(
-#                                             f"Copied: {file_name} from {original_path} to {destination_path}")
-#
-#                                         # 删除原始文件和 Aria2 历史记录
-#                                         self.remove_files_or_folders([file_name], original_path)
-#                                         download.remove()
-#                                         logging.info(f"Removed: {file_name} from Aria2 and original path")
-#
-#             time.sleep(check_interval)
-#     except Exception as e:
-#         logging.error(f"Error occurred: {e}")
-#     finally:
-#         logging.info("Monitoring, copying, and deleting completed")
+import configparser
 import json
 import logging
 import os
 
+from src.api.Aria2API import Aria2API
+from src.api.radarr import RadarClient
 
-def download_directory(self, is_debug=False, json_file_path='directory_contents.json'):
-    # 读取 JSON 文件中的目录内容
-    with open(json_file_path, 'r', encoding='utf-8') as f:
-        directory_contents = json.load(f)
 
-    # 获取 Aria2 的所有下载记录
-    downloads = self.aria2_api.get_downloads()
+# 运行测试
 
-    # 获取已完成下载的文件名列表
-    completed_files = []
-    for download in downloads:
-        if download.is_complete:
-            for file in download.files:
-                if file.selected:
-                    file_name = os.path.basename(file.path)
-                    completed_files.append(file_name)
-
-    for item in directory_contents:
-        if not item['is_dir']:
-            # 构建完整的本地路径
-            # full_local_path = os.path.join(os.path.relpath(item['path'], start="/")).replace('\\', '/')
-            # local_file_path = os.path.join(local_base_path, item['name']).replace('\\', '/')
-            full_local_path = item['downloads_path']
-            local_file = item['name']
-            if local_file not in completed_files:
-                file_detail = self.get_file_or_directory_info(item['path'])
-                if file_detail and file_detail['code'] == 200:
-                    raw_url = file_detail['data']['raw_url']
-                    if not is_debug:
-                        # 添加到 Aria2 下载队列
-                        self.aria2_api.add_uris([raw_url], options={"dir": full_local_path})
-                else:
-                    logging.error(f"Failed to get detailed information for {local_file}")
-            else:
-                logging.info(f"File already downloaded, skipping: {local_file}")
+def test_find_movie_id_by_filename():
+    # 初始化日志和配置
+    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
+    # 获取当前脚本的绝对路径
+    current_directory = os.path.dirname(os.path.abspath(__file__))
 
+    # 获取当前脚本所在目录的上级目录
+    parent_directory = os.path.dirname(current_directory)
 
-# 创建一个全局变量,用来表示是否继续监控
-is_running = True
+    # 构建 config.ini 文件的路径
+    config_path = os.path.join(parent_directory, 'config', 'config.ini')
 
-# 定义信号处理函数
-# def handle_signal(signum, frame):
-#     global is_running
-#     is_running = False
-#     logging.info(f"is run {is_running}")
+    # 读取配置文件
+    config = configparser.ConfigParser()
+    config.read(config_path)
 
+    # 创建 RadarClient 实例
+    radar_client = RadarClient(config['RADAR']['URL'],
+                               config['RADAR']['API_KEY'])
 
-# def my_custom_action(movie,
-#                      remote_alist_api,
-#                      home_alist_api,
-#                      remote_download_path,
-#                      Local_download_path,
-#                      home_download_path,
-#                      copy_or_move_download_path,
-#                      copy_or_move_destination_path,
-#                      ):
-#     global is_running
-#
-#     print(f"Performing custom action on movie: {movie['title']}")
-#     # 这里的 movie_path 可能需要根据实际情况调整
-#     movie_path = remote_download_path + "/" + movie['title']
-#     print(f"movie path -> {movie_path}")
-#     # 这里是 home 路径
-#     remote_alist_api.save_directory_contents_to_json(remote_download_path, Local_download_path,
-#                                                      json_file_path='data/remote.json')
-#     logging.info(f" remote save_directory path {remote_download_path} to data/remote.json")
-#     # 这里是 home 路径
-#     home_alist_api.save_directory_contents_to_json(home_download_path,
-#                                                    original_path=copy_or_move_download_path,
-#                                                    copy_or_move_destination_path=copy_or_move_destination_path,
-#                                                    json_file_path='data/home.json')
-#     logging.info(f" remote save_directory path {home_download_path} to data/home.json")
-#
-#     logging.info("Task completion")
+    movies = radar_client.get_all_movie_names()
 
+    print(f"movies_jons: {movies}")
 
-# def start_task(self):
+    aria2_api = Aria2API(config['ARIA2']['RPC_URL'], config['ARIA2']['RPC_SECRET'])
+    downloads = aria2_api.get_downloads()
+    for download in downloads:
+        if download.is_complete:
+            completed_files = [os.path.basename(file.path) for file in download.files if file.selected]
+            print(f"completed_files: {completed_files}")
+            # 查找电影ID
+            for completed_file in completed_files:
+                ids = radar_client.find_movie_id_by_filename(completed_file)
+                if ids is not None:
+                    print(f"ids: {ids}")
 
-#
 
-#
-#     self.run()
+# 运行测试
+test_find_movie_id_by_filename()

+ 0 - 360
tests/test2.py

@@ -1,360 +0,0 @@
-"""RemoteDownloadSerivce 类"""
-"""主要实现功能"""
-"""通过读取radarr服务器上的api 获取已经完成的电影"""
-"""并通过alist api 获取到对应到文件到下载地址 """
-"""并送到本地 airai2 下载"""
-
-"""相关配置"""
-# [COMMON]
-# LOG_LEVEL = INFO
-# TIMEOUT = 3600
-# CHECK_INTERVAL = 10
-# REMOTE_DATA=remote.json
-# HOME_DATA=home.json
-#
-# [ARIA2]
-# RPC_URL = http://192.168.88.29
-# RPC_SECRET = 123456
-# DESTINATION_PATH = /home/downloads
-# DES_COPY_PATH = /home/video/sync
-#
-# [HOME_ALIST]
-# API_URL = http://192.168.88.29:5244/api
-# WEB_URL = http://192.168.88.29
-# CLIENT_ID = 4e34854d5d7390ef7801
-# USERNAME = admin
-# PASSWORD = nokidc123@#
-# DOWNLOAD_PATH = /downloads/movie
-# SCY_COPY_PATH = /downloads/movie
-# DES_COPY_PATH = /media/sync/movie
-#
-# [REMOTE_ALIST]
-# API_URL = http://box.szfa.xyz:5244/api
-# WEB_URL = http://box.szfa.xyz:5244
-# CLIENT_ID = 4e34854d5d7390ef7801
-# USERNAME = admin
-# PASSWORD = nokidc123@#
-# DOWNLOAD_PATH = /data/media/moive
-#
-# [RADAR]
-# URL = http://box.szfa.xyz:7878
-# API_KEY = bd45569f422a4c159600964b7b85a0bd
-
-
-"""这里需要修改一下"""
-
-
-# def process_downloads(self):
-#     completed_movies = self.radar_client.get_already_movies()
-#     for movie in completed_movies:
-#         file_path = self.get_remote_file_path(movie)
-#         if file_path:
-#             self.send_to_aria2(file_path)
-"""这里radar_client 只能获取到数量,用来循环"""
-"""电影到下载地址,应该是 远程 apist 提供到,所以需要遍历了 远程路径"""
-# self.remote_download_path = config['REMOTE_ALIST']['DOWNLOAD_PATH']
-"""alist api 的实现"""
-# import json
-# import logging
-# import os
-# import requests
-# from src.models.task_type import TaskType, ActionType
-#
-
-# def construct_path(base_path, sub_path, file_name):
-#     # 确保路径部分不包含反斜杠
-#     base_path = base_path.replace('\\', '/')
-#     sub_path = sub_path.replace('\\', '/')
-#     file_name = file_name.replace('\\', '/')
-#
-#     # 使用 os.path.join 构建整个路径
-#     return os.path.join(base_path, sub_path, file_name)
-#
-#
-# class AlistAPI:
-#     def __init__(self, url, username, password):
-#         self.url = url
-#         self.headers = {
-#             'UserAgent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
-#                          'Chrome/87.0.4280.88 Safari/537.36',
-#             'Content-Type': 'application/json'
-#         }
-#         # self.aria2_client = Client(rpc_url, secret=rpc_secret)
-#         # self.aria2_api = API(self.aria2_client)
-#         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 get_completed_tasks(self, task_type):
-#         """获取指定任务类型的已完成任务列表"""
-#         if task_type == TaskType.UPLOAD:
-#             api_endpoint = '/admin/task/upload/done'
-#         elif task_type == TaskType.COPY:
-#             api_endpoint = '/admin/task/copy/done'
-#         elif task_type == TaskType.ARIA2_DOWNLOAD:
-#             api_endpoint = '/admin/task/aria2_down/done'
-#         elif task_type == TaskType.ARIA2_TRANSFER:
-#             api_endpoint = '/admin/task/aria2_transfer/done'
-#         elif task_type == TaskType.QBITTORRENT_DOWNLOAD:
-#             api_endpoint = '/admin/task/qbit_down/done'
-#         elif task_type == TaskType.QBITTORRENT_TRANSFER:
-#             api_endpoint = '/admin/task/qbit_transfer/done'
-#         else:
-#             raise ValueError("Invalid task type")
-#
-#         response = requests.get(
-#             f'{self.url}{api_endpoint}',
-#             headers=self.headers
-#         )
-#         return response.json()
-#
-#     def copy_directory(self, src_path, dst_path):
-#         file_list = self.list_directory(src_path)
-#         if not file_list:
-#             return
-#         for file_info in file_list['data']['content']:
-#             if file_info['is_dir']:
-#                 new_src_path = src_path + "/" + file_info['name']
-#                 new_dst_path = dst_path + "/" + file_info['name']
-#                 # new_src_path = os.path.join(src_path, file_info['name'])
-#                 # new_dst_path = os.path.join(dst_path, file_info['name'])
-#                 print(f"Copying directory: {new_src_path} to {new_dst_path}")
-#                 self.copy_directory(new_src_path, new_dst_path)
-#             else:
-#                 file_name = file_info['name']
-#                 print(f"Copying file: {src_path}/{file_name} to {dst_path}/{file_name}")
-#                 # 这里原本是调用 self.copy_file,现在改为仅打印信息
-#                 self.copy_file(src_path, dst_path, [file_name])
-#
-#     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)
-#         if response.status_code == 200:
-#             return response.json()
-#         return None
-#
-#     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 remove_files_or_folders(self, dir_path, names):
-#         """删除指定目录下的文件或文件夹"""
-#         payload = {
-#             "dir": dir_path,
-#             "names": names
-#         }
-#         response = requests.post(
-#             f'{self.url}/fs/remove',
-#             headers=self.headers,
-#             json=payload
-#         )
-#         return response.json()
-#
-#     def remove_empty_directory(self, src_dir):
-#         """删除空文件夹"""
-#         payload = {
-#             "src_dir": src_dir
-#         }
-#         response = requests.post(
-#             f'{self.url}/fs/remove_empty_director',
-#             headers=self.headers,
-#             json=payload
-#         )
-#         return response.json()
-#
-#     def recursive_collect_contents(self,
-#                                    remote_download_path,
-#                                    home_download_path,
-#                                    src_dir,
-#                                    dest_path,
-#                                    current_sub_path=''):
-#         contents = []
-#         file_list = self.list_directory(remote_download_path)
-#         for file_info in file_list['data']['content']:
-#             # 拼接完整的远程路径
-#             full_path = os.path.join(remote_download_path, file_info['name']).replace('\\', '/')
-#
-#             # 初始化本地下载路径和复制/移动目的地路径
-#             local_download_path = ''
-#             new_dest_path = ''
-#             new_src_dir = ''
-#             # 根据条件构建本地下载路径和复制/移动目的地路径
-#             if home_download_path is not None:
-#                 local_download_path = os.path.join(home_download_path, current_sub_path, file_info['name']).replace(
-#                     '\\',
-#                     '/')
-#             if dest_path is not None:
-#                 new_dest_path = os.path.join(dest_path, current_sub_path).replace('\\', '/')
-#
-#             if src_dir is not None:
-#                 new_src_dir = os.path.join(src_dir, current_sub_path).replace('\\', '/')
-#
-#             item = {
-#                 'name': file_info['name'],
-#                 'is_dir': file_info['is_dir'],
-#                 'path': full_path,  # 存储完整的远程路径
-#                 'downloads_path': local_download_path,
-#                 'src_dir': new_src_dir,
-#                 'dst_dir': new_dest_path
-#             }
-#             contents.append(item)
-#
-#             if file_info['is_dir']:
-#                 # 更新子路径为当前文件夹的路径
-#                 new_sub_path = os.path.join(current_sub_path, file_info['name'])
-#                 sub_contents = self.recursive_collect_contents(full_path,
-#                                                                home_download_path,
-#                                                                src_dir,
-#                                                                dest_path,
-#                                                                new_sub_path)
-#                 contents.extend(sub_contents)
-#
-#         return contents
-#
-#     def copy_files(self, local_json_path, is_debug=False):
-#         """执行拷贝文件"""
-#         # 读取本地 JSON 文件
-#         with open(local_json_path, 'r', encoding='utf-8') as f:
-#             directory_contents = json.load(f)
-#
-#         for item in directory_contents:
-#
-#             if not item['is_dir']:
-#                 file_name = item['name']
-#                 original_path = item['src_dir']  # 获取原始文件路径
-#                 des_path = item['dst_dir']  # 获取原始文件路径
-#
-#                 if is_debug:
-#                     logging.info(f"Debug mode: Copy {file_name}")
-#                 else:
-#                     # 复制文件
-#                     self.copy_file(original_path, des_path, [file_name])
-#                     logging.info(
-#                         f"Copied: {file_name} from {original_path} to {des_path}")
-
-"""这个函数已经是实现了,遍历"""
-# recursive_collect_contents
-"""结果是"""
-# [
-#     {
-#         "name": "Alien Covenant (2017)",
-#         "is_dir": true,
-#         "path": "/data/media/moive/Alien Covenant (2017)",
-#         "downloads_path": "/mnt/data1/downloads/movie/Alien Covenant (2017)",
-#         "scy_path": "",
-#         "copy_des_path": ""
-#     },
-#     {
-#         "name": "Alien Covenant (2017) Bluray-1080p Proper.mp4",
-#         "is_dir": false,
-#         "path": "/data/media/moive/Alien Covenant (2017)/Alien Covenant (2017) Bluray-1080p Proper.mp4",
-#         "downloads_path": "/mnt/data1/downloads/movie/Alien Covenant (2017)/Alien Covenant (2017) Bluray-1080p Proper.mp4",
-#         "scy_path": "",
-#         "copy_des_path": ""
-#     },
-# ]
-
-
-"""你说的我了解,我增加一个"""
-import time
-
-from pyarr import RadarrAPI
-import json
-
-
-class RadarClient:
-    def __init__(self, url, key):
-        self.url = url
-        self.api_key = key
-        self.client = RadarrAPI(self.url, self.api_key)
-
-    def get_all_movies(self):
-        return self.client.get_movie()
-
-    def delete_movie(self, movie_id):
-        return self.client.del_movie(movie_id)
-
-    def save_movies_to_json(self, file_name='data/movies.json'):
-        movies = self.get_all_movies()
-        with open(file_name, 'w') as f:
-            json.dump(movies, f, indent=4)
-        print(f"Movies saved to {file_name}")
-
-    def get_already_movies(self):
-        """获取全部已经跟踪已经处理完成的电影"""
-        already_processed = set()  # 用于跟踪已处理的电影
-        movies = self.get_all_movies()
-        for movie in movies:
-            if 'movieFile' in movie and movie['movieFile'] and movie['id'] not in already_processed:
-                already_processed.add(movie['id'])
-        return already_processed
-
-    def continuous_monitoring(self, check_interval=60, custom_action=None):
-        """
-        Continuously monitor movies and perform a custom action if movieFile exists.
-        check_interval: Time in seconds between checks
-        custom_action: Function to be called for each downloaded movie
-        """
-        already_processed = set()  # 用于跟踪已处理的电影
-        while True:
-            movies = self.get_all_movies()
-            for movie in movies:
-                if 'movieFile' in movie and movie['movieFile'] and movie['id'] not in already_processed:
-                    custom_action(movie)
-                    already_processed.add(movie['id'])
-            time.sleep(check_interval)
-#### 是为了更好的检测远程服务器是不是下载完成了,不然没有下载完成的,开始下载这不符合我的预期
-
-# 你应该没有明白的需要,我需要获取处理完的电影,然后通过调用远程alist api获取到所有到电影的地址,然后下载,那么我RemoteDownloadService 给我一个解决方案