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

View File

@@ -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:
"""

View File

@@ -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":

View File

@@ -34,6 +34,12 @@ class Alist(StorageBase):
def __init__(self):
super().__init__()
def init_storage(self):
"""
初始化
"""
pass
@property
def __get_base_url(self) -> str:
"""

View File

@@ -25,6 +25,12 @@ class LocalStorage(StorageBase):
"softlink": "软链接"
}
def init_storage(self):
"""
初始化
"""
pass
def check(self) -> bool:
"""
检查存储是否可用

View File

@@ -27,6 +27,12 @@ class Rclone(StorageBase):
"copy": "复制"
}
def init_storage(self):
"""
初始化
"""
pass
def set_config(self, conf: dict):
"""
设置配置

View File

@@ -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)}")