|
@@ -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 给我一个解决方案
|