From a3172d7503ab274bb612c0236e24b9b1651a96f5 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Wed, 20 Nov 2024 20:17:18 +0800 Subject: [PATCH] =?UTF-8?q?fix=20=E6=89=AB=E7=A0=81=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E4=B8=8E=E5=BA=95=E5=B1=82=E6=A8=A1=E5=9D=97=E8=A7=A3=E8=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/modules/filemanager/storages/__init__.py | 8 ++ app/modules/filemanager/storages/alipan.py | 22 ++-- app/modules/filemanager/storages/alist.py | 6 ++ app/modules/filemanager/storages/local.py | 6 ++ app/modules/filemanager/storages/rclone.py | 6 ++ app/modules/filemanager/storages/u115.py | 103 +++++++++++-------- 6 files changed, 102 insertions(+), 49 deletions(-) diff --git a/app/modules/filemanager/storages/__init__.py b/app/modules/filemanager/storages/__init__.py index ab037d2d..4528ff0e 100644 --- a/app/modules/filemanager/storages/__init__.py +++ b/app/modules/filemanager/storages/__init__.py @@ -16,6 +16,13 @@ class StorageBase(metaclass=ABCMeta): def __init__(self): self.storagehelper = StorageHelper() + @abstractmethod + def init_storage(self): + """ + 初始化 + """ + pass + def generate_qrcode(self, *args, **kwargs) -> Optional[Tuple[dict, str]]: pass @@ -40,6 +47,7 @@ class StorageBase(metaclass=ABCMeta): 设置配置 """ self.storagehelper.set_storage(self.schema.value, conf) + self.init_storage() def support_transtype(self) -> dict: """ diff --git a/app/modules/filemanager/storages/alipan.py b/app/modules/filemanager/storages/alipan.py index 9882285f..42f6f870 100644 --- a/app/modules/filemanager/storages/alipan.py +++ b/app/modules/filemanager/storages/alipan.py @@ -16,10 +16,11 @@ from app.schemas.types import StorageSchema from app.utils.http import RequestUtils from aligo import Aligo, BaseFile +from app.utils.singleton import Singleton from app.utils.string import StringUtils -class AliPan(StorageBase): +class AliPan(StorageBase, metaclass=Singleton): """ 阿里云相关操作 """ @@ -54,16 +55,21 @@ class AliPan(StorageBase): except FileNotFoundError: logger.debug('未发现 aria2c') self._has_aria2c = False + self.init_storage() - self.__init_aligo() - - def __init_aligo(self): + def init_storage(self): """ 初始化 aligo """ + def show_qrcode(qr_link: str): + """ + 显示二维码 + """ + logger.info(f"请用阿里云盘 App 扫码登录:{qr_link}") + refresh_token = self.__auth_params.get("refreshToken") if refresh_token: - self.aligo = Aligo(refresh_token=refresh_token, use_aria2=self._has_aria2c, + self.aligo = Aligo(refresh_token=refresh_token, show=show_qrcode, use_aria2=self._has_aria2c, name="MoviePilot V2", level=logging.ERROR) @property @@ -160,7 +166,7 @@ class AliPan(StorageBase): }) self.__update_params(data) self.__update_drives() - self.__init_aligo() + self.init_storage() except Exception as e: return {}, f"bizExt 解码失败:{str(e)}" return data, "" @@ -180,12 +186,16 @@ class AliPan(StorageBase): """ 获取用户信息(drive_id等) """ + if not self.aligo: + return {} return self.aligo.get_user() def __update_drives(self): """ 更新用户存储根目录 """ + if not self.aligo: + return drivers = self.aligo.list_my_drives() for driver in drivers: if driver.category == "resource": diff --git a/app/modules/filemanager/storages/alist.py b/app/modules/filemanager/storages/alist.py index 12563a73..8f355c1b 100644 --- a/app/modules/filemanager/storages/alist.py +++ b/app/modules/filemanager/storages/alist.py @@ -34,6 +34,12 @@ class Alist(StorageBase): def __init__(self): super().__init__() + def init_storage(self): + """ + 初始化 + """ + pass + @property def __get_base_url(self) -> str: """ diff --git a/app/modules/filemanager/storages/local.py b/app/modules/filemanager/storages/local.py index c7cb9da4..2fa5f678 100644 --- a/app/modules/filemanager/storages/local.py +++ b/app/modules/filemanager/storages/local.py @@ -25,6 +25,12 @@ class LocalStorage(StorageBase): "softlink": "软链接" } + def init_storage(self): + """ + 初始化 + """ + pass + def check(self) -> bool: """ 检查存储是否可用 diff --git a/app/modules/filemanager/storages/rclone.py b/app/modules/filemanager/storages/rclone.py index 509cdaa2..39fa664f 100644 --- a/app/modules/filemanager/storages/rclone.py +++ b/app/modules/filemanager/storages/rclone.py @@ -27,6 +27,12 @@ class Rclone(StorageBase): "copy": "复制" } + def init_storage(self): + """ + 初始化 + """ + pass + def set_config(self, conf: dict): """ 设置配置 diff --git a/app/modules/filemanager/storages/u115.py b/app/modules/filemanager/storages/u115.py index ac25f048..0b5e8668 100644 --- a/app/modules/filemanager/storages/u115.py +++ b/app/modules/filemanager/storages/u115.py @@ -1,13 +1,14 @@ from pathlib import Path from typing import Optional, Tuple, List -from p115 import P115Client, P115FileSystem, P115Path +from p115 import P115Client, P115Path from app import schemas from app.core.config import settings from app.log import logger from app.modules.filemanager.storages import StorageBase from app.schemas.types import StorageSchema +from app.utils.http import RequestUtils from app.utils.singleton import Singleton @@ -25,18 +26,29 @@ class U115Pan(StorageBase, metaclass=Singleton): "copy": "复制" } + # 115二维码登录地址 + qrcode_url = "https://qrcodeapi.115.com/api/1.0/web/1.0/token/" + # 115登录状态检查 + login_check_url = "https://qrcodeapi.115.com/get/status/" + # 115登录完成 alipaymini + login_done_api = f"https://passportapi.115.com/app/1.0/alipaymini/1.0/login/qrcode/" + client: P115Client = None - fs: P115FileSystem = None session_info: dict = None - def __init_cloud(self, force: bool = False) -> bool: + def __init__(self): + super().__init__() + self.init_storage() + + def init_storage(self) -> bool: """ 初始化Cloud """ + if not self.__credential: + return False try: - if not self.client or not self.client.cookies or force: - self.client = P115Client(self.__credential, app="alipaymini") - self.fs = P115FileSystem(self.client) + self.client = P115Client(self.__credential, app="alipaymini", + check_for_relogin=True, console_qrcode=False) except Exception as err: logger.error(f"115连接失败,请重新登录:{str(err)}") self.__clear_credential() @@ -71,10 +83,9 @@ class U115Pan(StorageBase, metaclass=Singleton): """ 生成二维码 """ - self.__init_cloud() - try: - resp = self.client.login_qrcode_token() - self.session_info = resp["data"] + res = RequestUtils(timeout=10).get_res(self.qrcode_url) + if res: + self.session_info = res.json().get("data") qrcode_content = self.session_info.pop("qrcode") if not qrcode_content: logger.warn("115生成二维码失败:未获取到二维码数据!") @@ -82,9 +93,9 @@ class U115Pan(StorageBase, metaclass=Singleton): return { "codeContent": qrcode_content }, "" - except Exception as e: - logger.warn(f"115生成二维码失败:{str(e)}") - return {}, f"115生成二维码失败:{str(e)}" + elif res is not None: + return {}, f"115生成二维码失败:{res.status_code} - {res.reason}" + return {}, f"115生成二维码失败:无法连接!" def check_login(self) -> Optional[Tuple[dict, str]]: """ @@ -93,8 +104,11 @@ class U115Pan(StorageBase, metaclass=Singleton): if not self.session_info: return {}, "请先生成二维码!" try: - resp = self.client.login_qrcode_scan_status(self.session_info) - match resp["data"].get("status"): + resp = RequestUtils(timeout=10).get_res(self.login_check_url, params=self.session_info) + if not resp: + return {}, "115登录确认失败:无法连接!" + result = resp.json() + match result["data"].get("status"): case 0: result = { "status": 0, @@ -107,15 +121,18 @@ class U115Pan(StorageBase, metaclass=Singleton): } case 2: # 确认完成,保存认证信息 - resp = self.client.login_qrcode_scan_result(uid=self.session_info.get("uid"), - app="alipaymini") + resp = RequestUtils(timeout=10).post_res(self.login_done_api, + data={"account": self.session_info.get("uid")}) + if not resp: + return {}, "115登录确认失败:无法连接!" if resp: # 保存认证信息 - cookie_dict = resp["data"]["cookie"] + result = resp.json() + cookie_dict = result["data"]["cookie"] cookie_str = "; ".join([f"{k}={v}" for k, v in cookie_dict.items()]) cookie_dict.update({"cookie": cookie_str}) self.__save_credential(cookie_dict) - self.__init_cloud(force=True) + self.init_storage() result = { "status": 2, "tip": "登录成功!" @@ -143,10 +160,10 @@ class U115Pan(StorageBase, metaclass=Singleton): """ 获取存储空间 """ - if not self.__init_cloud(): + if not self.client: return None try: - usage = self.fs.space_summury() + usage = self.client.fs.space_summury() if usage: return usage['rt_space_info']['all_total']['size'], usage['rt_space_info']['all_remain']['size'] except Exception as e: @@ -163,12 +180,12 @@ class U115Pan(StorageBase, metaclass=Singleton): """ 浏览文件 """ - if not self.__init_cloud(): + if not self.client: return [] try: if fileitem.type == "file": return [fileitem] - items: List[P115Path] = self.fs.list(fileitem.path) + items: List[P115Path] = self.client.fs.list(fileitem.path) return [schemas.FileItem( storage=self.schema.value, type="dir" if item.is_dir() else "file", @@ -187,10 +204,10 @@ class U115Pan(StorageBase, metaclass=Singleton): """ 创建目录 """ - if not self.__init_cloud(): + if not self.client: return None try: - result = self.fs.makedirs(Path(fileitem.path) / name, exist_ok=True) + result = self.client.fs.makedirs(Path(fileitem.path) / name, exist_ok=True) if result: return schemas.FileItem( storage=self.schema.value, @@ -208,10 +225,10 @@ class U115Pan(StorageBase, metaclass=Singleton): """ 根据文件路程获取目录,不存在则创建 """ - if not self.__init_cloud(): + if not self.client: return None try: - result = self.fs.makedirs(path, exist_ok=True) + result = self.client.fs.makedirs(path, exist_ok=True) if result: return schemas.FileItem( storage=self.schema.value, @@ -229,11 +246,11 @@ class U115Pan(StorageBase, metaclass=Singleton): """ 获取文件或目录,不存在返回None """ - if not self.__init_cloud(): + if not self.client: return None try: try: - item = self.fs.attr(path) + item = self.client.fs.attr(path) except FileNotFoundError: return None if item: @@ -255,11 +272,11 @@ class U115Pan(StorageBase, metaclass=Singleton): """ 获取文件详情 """ - if not self.__init_cloud(): + if not self.client: return None try: try: - item = self.fs.attr(fileitem.path) + item = self.client.fs.attr(fileitem.path) except FileNotFoundError: return None if item: @@ -281,10 +298,10 @@ class U115Pan(StorageBase, metaclass=Singleton): """ 删除文件 """ - if not self.__init_cloud(): + if not self.client: return False try: - self.fs.remove(fileitem.path) + self.client.fs.remove(fileitem.path) return True except Exception as e: logger.error(f"115删除文件失败:{str(e)}") @@ -294,10 +311,10 @@ class U115Pan(StorageBase, metaclass=Singleton): """ 重命名文件 """ - if not self.__init_cloud(): + if not self.client: return False try: - self.fs.rename(fileitem.path, Path(fileitem.path).with_name(name)) + self.client.fs.rename(fileitem.path, Path(fileitem.path).with_name(name)) return True except Exception as e: logger.error(f"115重命名文件失败:{str(e)}") @@ -307,11 +324,11 @@ class U115Pan(StorageBase, metaclass=Singleton): """ 获取下载链接 """ - if not self.__init_cloud(): + if not self.client: return None local_file = (path or settings.TEMP_PATH) / fileitem.name try: - task = self.fs.download(fileitem.path, file=local_file) + task = self.client.fs.download(fileitem.path, file=local_file) if task: return local_file except Exception as e: @@ -322,12 +339,12 @@ class U115Pan(StorageBase, metaclass=Singleton): """ 上传文件 """ - if not self.__init_cloud(): + if not self.client: return None try: new_path = Path(fileitem.path) / (new_name or path.name) with open(path, "rb") as f: - result = self.fs.upload(f, new_path) + result = self.client.fs.upload(f, new_path) if result: return schemas.FileItem( storage=self.schema.value, @@ -347,10 +364,10 @@ class U115Pan(StorageBase, metaclass=Singleton): """ 移动文件 """ - if not self.__init_cloud(): + if not self.client: return False try: - self.fs.move(fileitem.path, target.path) + self.client.fs.move(fileitem.path, target.path) return True except Exception as e: logger.error(f"115移动文件失败:{str(e)}") @@ -360,10 +377,10 @@ class U115Pan(StorageBase, metaclass=Singleton): """ 复制文件 """ - if not self.__init_cloud(): + if not self.client: return False try: - self.fs.copy(fileitem.path, target_file) + self.client.fs.copy(fileitem.path, target_file) return True except Exception as e: logger.error(f"115复制文件失败:{str(e)}")