fix 扫码逻辑与底层模块解耦

This commit is contained in:
jxxghp
2024-11-20 20:17:18 +08:00
parent 8d5e0b26d5
commit a3172d7503
6 changed files with 102 additions and 49 deletions
@@ -16,6 +16,13 @@ class StorageBase(metaclass=ABCMeta):
def __init__(self): def __init__(self):
self.storagehelper = StorageHelper() self.storagehelper = StorageHelper()
@abstractmethod
def init_storage(self):
"""
初始化
"""
pass
def generate_qrcode(self, *args, **kwargs) -> Optional[Tuple[dict, str]]: def generate_qrcode(self, *args, **kwargs) -> Optional[Tuple[dict, str]]:
pass pass
@@ -40,6 +47,7 @@ class StorageBase(metaclass=ABCMeta):
设置配置 设置配置
""" """
self.storagehelper.set_storage(self.schema.value, conf) self.storagehelper.set_storage(self.schema.value, conf)
self.init_storage()
def support_transtype(self) -> dict: def support_transtype(self) -> dict:
""" """
+16 -6
View File
@@ -16,10 +16,11 @@ from app.schemas.types import StorageSchema
from app.utils.http import RequestUtils from app.utils.http import RequestUtils
from aligo import Aligo, BaseFile from aligo import Aligo, BaseFile
from app.utils.singleton import Singleton
from app.utils.string import StringUtils from app.utils.string import StringUtils
class AliPan(StorageBase): class AliPan(StorageBase, metaclass=Singleton):
""" """
阿里云相关操作 阿里云相关操作
""" """
@@ -54,16 +55,21 @@ class AliPan(StorageBase):
except FileNotFoundError: except FileNotFoundError:
logger.debug('未发现 aria2c') logger.debug('未发现 aria2c')
self._has_aria2c = False self._has_aria2c = False
self.init_storage()
self.__init_aligo() def init_storage(self):
def __init_aligo(self):
""" """
初始化 aligo 初始化 aligo
""" """
def show_qrcode(qr_link: str):
"""
显示二维码
"""
logger.info(f"请用阿里云盘 App 扫码登录:{qr_link}")
refresh_token = self.__auth_params.get("refreshToken") refresh_token = self.__auth_params.get("refreshToken")
if refresh_token: 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) name="MoviePilot V2", level=logging.ERROR)
@property @property
@@ -160,7 +166,7 @@ class AliPan(StorageBase):
}) })
self.__update_params(data) self.__update_params(data)
self.__update_drives() self.__update_drives()
self.__init_aligo() self.init_storage()
except Exception as e: except Exception as e:
return {}, f"bizExt 解码失败:{str(e)}" return {}, f"bizExt 解码失败:{str(e)}"
return data, "" return data, ""
@@ -180,12 +186,16 @@ class AliPan(StorageBase):
""" """
获取用户信息(drive_id等) 获取用户信息(drive_id等)
""" """
if not self.aligo:
return {}
return self.aligo.get_user() return self.aligo.get_user()
def __update_drives(self): def __update_drives(self):
""" """
更新用户存储根目录 更新用户存储根目录
""" """
if not self.aligo:
return
drivers = self.aligo.list_my_drives() drivers = self.aligo.list_my_drives()
for driver in drivers: for driver in drivers:
if driver.category == "resource": if driver.category == "resource":
@@ -34,6 +34,12 @@ class Alist(StorageBase):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
def init_storage(self):
"""
初始化
"""
pass
@property @property
def __get_base_url(self) -> str: def __get_base_url(self) -> str:
""" """
@@ -25,6 +25,12 @@ class LocalStorage(StorageBase):
"softlink": "软链接" "softlink": "软链接"
} }
def init_storage(self):
"""
初始化
"""
pass
def check(self) -> bool: def check(self) -> bool:
""" """
检查存储是否可用 检查存储是否可用
@@ -27,6 +27,12 @@ class Rclone(StorageBase):
"copy": "复制" "copy": "复制"
} }
def init_storage(self):
"""
初始化
"""
pass
def set_config(self, conf: dict): def set_config(self, conf: dict):
""" """
设置配置 设置配置
+60 -43
View File
@@ -1,13 +1,14 @@
from pathlib import Path from pathlib import Path
from typing import Optional, Tuple, List from typing import Optional, Tuple, List
from p115 import P115Client, P115FileSystem, P115Path from p115 import P115Client, P115Path
from app import schemas from app import schemas
from app.core.config import settings from app.core.config import settings
from app.log import logger from app.log import logger
from app.modules.filemanager.storages import StorageBase from app.modules.filemanager.storages import StorageBase
from app.schemas.types import StorageSchema from app.schemas.types import StorageSchema
from app.utils.http import RequestUtils
from app.utils.singleton import Singleton from app.utils.singleton import Singleton
@@ -25,18 +26,29 @@ class U115Pan(StorageBase, metaclass=Singleton):
"copy": "复制" "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 client: P115Client = None
fs: P115FileSystem = None
session_info: dict = 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 初始化Cloud
""" """
if not self.__credential:
return False
try: try:
if not self.client or not self.client.cookies or force: self.client = P115Client(self.__credential, app="alipaymini",
self.client = P115Client(self.__credential, app="alipaymini") check_for_relogin=True, console_qrcode=False)
self.fs = P115FileSystem(self.client)
except Exception as err: except Exception as err:
logger.error(f"115连接失败,请重新登录:{str(err)}") logger.error(f"115连接失败,请重新登录:{str(err)}")
self.__clear_credential() self.__clear_credential()
@@ -71,10 +83,9 @@ class U115Pan(StorageBase, metaclass=Singleton):
""" """
生成二维码 生成二维码
""" """
self.__init_cloud() res = RequestUtils(timeout=10).get_res(self.qrcode_url)
try: if res:
resp = self.client.login_qrcode_token() self.session_info = res.json().get("data")
self.session_info = resp["data"]
qrcode_content = self.session_info.pop("qrcode") qrcode_content = self.session_info.pop("qrcode")
if not qrcode_content: if not qrcode_content:
logger.warn("115生成二维码失败:未获取到二维码数据!") logger.warn("115生成二维码失败:未获取到二维码数据!")
@@ -82,9 +93,9 @@ class U115Pan(StorageBase, metaclass=Singleton):
return { return {
"codeContent": qrcode_content "codeContent": qrcode_content
}, "" }, ""
except Exception as e: elif res is not None:
logger.warn(f"115生成二维码失败:{str(e)}") return {}, f"115生成二维码失败:{res.status_code} - {res.reason}"
return {}, f"115生成二维码失败:{str(e)}" return {}, f"115生成二维码失败:无法连接!"
def check_login(self) -> Optional[Tuple[dict, str]]: def check_login(self) -> Optional[Tuple[dict, str]]:
""" """
@@ -93,8 +104,11 @@ class U115Pan(StorageBase, metaclass=Singleton):
if not self.session_info: if not self.session_info:
return {}, "请先生成二维码!" return {}, "请先生成二维码!"
try: try:
resp = self.client.login_qrcode_scan_status(self.session_info) resp = RequestUtils(timeout=10).get_res(self.login_check_url, params=self.session_info)
match resp["data"].get("status"): if not resp:
return {}, "115登录确认失败:无法连接!"
result = resp.json()
match result["data"].get("status"):
case 0: case 0:
result = { result = {
"status": 0, "status": 0,
@@ -107,15 +121,18 @@ class U115Pan(StorageBase, metaclass=Singleton):
} }
case 2: case 2:
# 确认完成,保存认证信息 # 确认完成,保存认证信息
resp = self.client.login_qrcode_scan_result(uid=self.session_info.get("uid"), resp = RequestUtils(timeout=10).post_res(self.login_done_api,
app="alipaymini") data={"account": self.session_info.get("uid")})
if not resp:
return {}, "115登录确认失败:无法连接!"
if resp: 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_str = "; ".join([f"{k}={v}" for k, v in cookie_dict.items()])
cookie_dict.update({"cookie": cookie_str}) cookie_dict.update({"cookie": cookie_str})
self.__save_credential(cookie_dict) self.__save_credential(cookie_dict)
self.__init_cloud(force=True) self.init_storage()
result = { result = {
"status": 2, "status": 2,
"tip": "登录成功!" "tip": "登录成功!"
@@ -143,10 +160,10 @@ class U115Pan(StorageBase, metaclass=Singleton):
""" """
获取存储空间 获取存储空间
""" """
if not self.__init_cloud(): if not self.client:
return None return None
try: try:
usage = self.fs.space_summury() usage = self.client.fs.space_summury()
if usage: if usage:
return usage['rt_space_info']['all_total']['size'], usage['rt_space_info']['all_remain']['size'] return usage['rt_space_info']['all_total']['size'], usage['rt_space_info']['all_remain']['size']
except Exception as e: except Exception as e:
@@ -163,12 +180,12 @@ class U115Pan(StorageBase, metaclass=Singleton):
""" """
浏览文件 浏览文件
""" """
if not self.__init_cloud(): if not self.client:
return [] return []
try: try:
if fileitem.type == "file": if fileitem.type == "file":
return [fileitem] return [fileitem]
items: List[P115Path] = self.fs.list(fileitem.path) items: List[P115Path] = self.client.fs.list(fileitem.path)
return [schemas.FileItem( return [schemas.FileItem(
storage=self.schema.value, storage=self.schema.value,
type="dir" if item.is_dir() else "file", 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 return None
try: 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: if result:
return schemas.FileItem( return schemas.FileItem(
storage=self.schema.value, storage=self.schema.value,
@@ -208,10 +225,10 @@ class U115Pan(StorageBase, metaclass=Singleton):
""" """
根据文件路程获取目录,不存在则创建 根据文件路程获取目录,不存在则创建
""" """
if not self.__init_cloud(): if not self.client:
return None return None
try: try:
result = self.fs.makedirs(path, exist_ok=True) result = self.client.fs.makedirs(path, exist_ok=True)
if result: if result:
return schemas.FileItem( return schemas.FileItem(
storage=self.schema.value, storage=self.schema.value,
@@ -229,11 +246,11 @@ class U115Pan(StorageBase, metaclass=Singleton):
""" """
获取文件或目录,不存在返回None 获取文件或目录,不存在返回None
""" """
if not self.__init_cloud(): if not self.client:
return None return None
try: try:
try: try:
item = self.fs.attr(path) item = self.client.fs.attr(path)
except FileNotFoundError: except FileNotFoundError:
return None return None
if item: if item:
@@ -255,11 +272,11 @@ class U115Pan(StorageBase, metaclass=Singleton):
""" """
获取文件详情 获取文件详情
""" """
if not self.__init_cloud(): if not self.client:
return None return None
try: try:
try: try:
item = self.fs.attr(fileitem.path) item = self.client.fs.attr(fileitem.path)
except FileNotFoundError: except FileNotFoundError:
return None return None
if item: if item:
@@ -281,10 +298,10 @@ class U115Pan(StorageBase, metaclass=Singleton):
""" """
删除文件 删除文件
""" """
if not self.__init_cloud(): if not self.client:
return False return False
try: try:
self.fs.remove(fileitem.path) self.client.fs.remove(fileitem.path)
return True return True
except Exception as e: except Exception as e:
logger.error(f"115删除文件失败:{str(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 return False
try: 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 return True
except Exception as e: except Exception as e:
logger.error(f"115重命名文件失败:{str(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 return None
local_file = (path or settings.TEMP_PATH) / fileitem.name local_file = (path or settings.TEMP_PATH) / fileitem.name
try: try:
task = self.fs.download(fileitem.path, file=local_file) task = self.client.fs.download(fileitem.path, file=local_file)
if task: if task:
return local_file return local_file
except Exception as e: except Exception as e:
@@ -322,12 +339,12 @@ class U115Pan(StorageBase, metaclass=Singleton):
""" """
上传文件 上传文件
""" """
if not self.__init_cloud(): if not self.client:
return None return None
try: try:
new_path = Path(fileitem.path) / (new_name or path.name) new_path = Path(fileitem.path) / (new_name or path.name)
with open(path, "rb") as f: with open(path, "rb") as f:
result = self.fs.upload(f, new_path) result = self.client.fs.upload(f, new_path)
if result: if result:
return schemas.FileItem( return schemas.FileItem(
storage=self.schema.value, storage=self.schema.value,
@@ -347,10 +364,10 @@ class U115Pan(StorageBase, metaclass=Singleton):
""" """
移动文件 移动文件
""" """
if not self.__init_cloud(): if not self.client:
return False return False
try: try:
self.fs.move(fileitem.path, target.path) self.client.fs.move(fileitem.path, target.path)
return True return True
except Exception as e: except Exception as e:
logger.error(f"115移动文件失败:{str(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 return False
try: try:
self.fs.copy(fileitem.path, target_file) self.client.fs.copy(fileitem.path, target_file)
return True return True
except Exception as e: except Exception as e:
logger.error(f"115复制文件失败:{str(e)}") logger.error(f"115复制文件失败:{str(e)}")