|
@@ -1,12 +1,7 @@
|
|
|
import json
|
|
|
import logging
|
|
|
import os
|
|
|
-import shutil
|
|
|
-import time
|
|
|
-
|
|
|
import requests
|
|
|
-from aria2p import API, Client
|
|
|
-
|
|
|
from src.models.task_type import TaskType, ActionType
|
|
|
|
|
|
|
|
@@ -21,15 +16,15 @@ def construct_path(base_path, sub_path, file_name):
|
|
|
|
|
|
|
|
|
class AlistAPI:
|
|
|
- def __init__(self, url, username, password, rpc_url, rpc_secret):
|
|
|
+ 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.aria2_client = Client(rpc_url, secret=rpc_secret)
|
|
|
+ # self.aria2_api = API(self.aria2_client)
|
|
|
self.login(username, password)
|
|
|
|
|
|
def login(self, username, password):
|
|
@@ -125,7 +120,9 @@ class AlistAPI:
|
|
|
"refresh": refresh
|
|
|
}
|
|
|
response = requests.post(f"{self.url}/fs/get", data=json.dumps(payload), headers=self.headers)
|
|
|
- return response.json()
|
|
|
+ if response.status_code == 200:
|
|
|
+ return response.json()
|
|
|
+ return None
|
|
|
|
|
|
def move_file(self, src_dir, dst_dir, names):
|
|
|
payload = json.dumps({
|
|
@@ -161,167 +158,72 @@ class AlistAPI:
|
|
|
)
|
|
|
return response.json()
|
|
|
|
|
|
- def save_directory_contents_to_json(self, remote_path, local_base_path=None, original_path=None,
|
|
|
- copy_or_move_destination_path=None,
|
|
|
- json_file_path=''):
|
|
|
- file_list = self.list_directory(remote_path)
|
|
|
- if not file_list:
|
|
|
- return
|
|
|
-
|
|
|
- directory_contents = self._recursive_collect_contents(remote_path, local_base_path,
|
|
|
- original_path,
|
|
|
- copy_or_move_destination_path)
|
|
|
-
|
|
|
- with open(json_file_path, 'w', encoding='utf-8') as f:
|
|
|
- json.dump(directory_contents, f, indent=4, ensure_ascii=False)
|
|
|
-
|
|
|
- def _recursive_collect_contents(self, path, local_base_path, original_path, copy_or_move_destination_path,
|
|
|
- current_sub_path=''):
|
|
|
+ def recursive_collect_contents(self,
|
|
|
+ remote_download_path,
|
|
|
+ home_download_path,
|
|
|
+ src_dir,
|
|
|
+ dest_path,
|
|
|
+ current_sub_path=''):
|
|
|
contents = []
|
|
|
- file_list = self.list_directory(path)
|
|
|
+ file_list = self.list_directory(remote_download_path)
|
|
|
for file_info in file_list['data']['content']:
|
|
|
# 拼接完整的远程路径
|
|
|
- full_path = os.path.join(path, file_info['name']).replace('\\', '/')
|
|
|
+ full_path = os.path.join(remote_download_path, file_info['name']).replace('\\', '/')
|
|
|
|
|
|
# 初始化本地下载路径和复制/移动目的地路径
|
|
|
local_download_path = ''
|
|
|
- copy_move_dest_path = ''
|
|
|
- scy_path = ''
|
|
|
+ new_dest_path = ''
|
|
|
+ new_src_dir = ''
|
|
|
# 根据条件构建本地下载路径和复制/移动目的地路径
|
|
|
- if local_base_path is not None:
|
|
|
- local_download_path = os.path.join(local_base_path, current_sub_path, file_info['name']).replace('\\',
|
|
|
- '/')
|
|
|
- if copy_or_move_destination_path is not None:
|
|
|
- copy_move_dest_path = os.path.join(copy_or_move_destination_path, current_sub_path).replace('\\', '/')
|
|
|
+ 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 copy_or_move_destination_path is not None:
|
|
|
- scy_path = os.path.join(original_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,
|
|
|
- 'scy_path': scy_path,
|
|
|
- 'copy_des_path': copy_move_dest_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, local_base_path,
|
|
|
- original_path,
|
|
|
- copy_or_move_destination_path, new_sub_path)
|
|
|
+ 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 download_directory(self, is_debug=False, json_file_path='directory_contents.json'):
|
|
|
- # 读取 JSON 文件中的目录内容
|
|
|
- with open(json_file_path, 'r', encoding='utf-8') as f:
|
|
|
+ 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)
|
|
|
|
|
|
- # 获取 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 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")
|
|
|
-
|
|
|
- def monitor_and_copy(self, local_json_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['scy_path'] # 获取原始文件路径
|
|
|
- des_path = item['copy_des_path'] # 获取原始文件路径
|
|
|
-
|
|
|
- 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}")
|
|
|
+ if not item['is_dir']:
|
|
|
+ file_name = item['name']
|
|
|
+ original_path = item['src_dir'] # 获取原始文件路径
|
|
|
+ des_path = item['dst_dir'] # 获取原始文件路径
|
|
|
|
|
|
- time.sleep(check_interval)
|
|
|
- except Exception as e:
|
|
|
- logging.error(f"Error occurred: {e}")
|
|
|
- finally:
|
|
|
- logging.info("Monitoring and copying completed")
|
|
|
+ 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}")
|