✨ 新增在线查漏补缺功能
This commit is contained in:
+135
-16
@@ -2,11 +2,20 @@ import json
|
||||
import os
|
||||
|
||||
import httpx
|
||||
from rich.progress import (
|
||||
BarColumn,
|
||||
DownloadColumn,
|
||||
Progress,
|
||||
TextColumn,
|
||||
TimeRemainingColumn,
|
||||
TransferSpeedColumn,
|
||||
)
|
||||
|
||||
from zhenxun.configs.config import Config
|
||||
from zhenxun.services.log import logger
|
||||
|
||||
from .config import g_sSignInPath
|
||||
from .config import g_sPlantPath, g_sSignInPath
|
||||
from .dbService import g_pDBService
|
||||
from .tool import g_pToolManager
|
||||
|
||||
|
||||
@@ -22,7 +31,7 @@ class CRequestManager:
|
||||
params: dict | None = None,
|
||||
jsonData: dict | None = None,
|
||||
) -> bool:
|
||||
"""下载文件到指定路径并覆盖已存在的文件
|
||||
"""下载文件到指定路径并覆盖已存在的文件,并显示下载进度条
|
||||
|
||||
Args:
|
||||
url (str): 文件的下载链接
|
||||
@@ -30,33 +39,53 @@ class CRequestManager:
|
||||
fileName (str): 保存后的文件名
|
||||
params (dict | None): 可选的 URL 查询参数
|
||||
jsonData (dict | None): 可选的 JSON 请求体
|
||||
|
||||
Returns:
|
||||
bool: 是否下载成功
|
||||
"""
|
||||
headers = {"token": cls.m_sTokens}
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=10.0) as client:
|
||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
||||
requestArgs: dict = {"headers": headers}
|
||||
if params:
|
||||
requestArgs["params"] = params
|
||||
if jsonData:
|
||||
requestArgs["json"] = jsonData
|
||||
|
||||
response = await client.request("GET", url, **requestArgs)
|
||||
response = await client.request(
|
||||
"GET", url, **requestArgs, follow_redirects=True
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
fullPath = os.path.join(savePath, fileName)
|
||||
os.makedirs(os.path.dirname(fullPath), exist_ok=True)
|
||||
with open(fullPath, "wb") as f:
|
||||
f.write(response.content)
|
||||
return True
|
||||
else:
|
||||
if response.status_code != 200:
|
||||
logger.warning(
|
||||
f"文件下载失败: HTTP {response.status_code} {response.text}"
|
||||
)
|
||||
return False
|
||||
|
||||
totalLength = int(response.headers.get("Content-Length", 0))
|
||||
fullPath = os.path.join(savePath, fileName)
|
||||
os.makedirs(os.path.dirname(fullPath), exist_ok=True)
|
||||
|
||||
with Progress(
|
||||
TextColumn("[progress.description]{task.description}"),
|
||||
BarColumn(),
|
||||
DownloadColumn(),
|
||||
TransferSpeedColumn(),
|
||||
TimeRemainingColumn(),
|
||||
transient=True,
|
||||
) as progress:
|
||||
task = progress.add_task(
|
||||
f"[green]【真寻农场】正在下载 {fileName}", total=totalLength
|
||||
)
|
||||
|
||||
with open(fullPath, "wb") as f:
|
||||
async for chunk in response.aiter_bytes(chunk_size=1024):
|
||||
f.write(chunk)
|
||||
progress.advance(task, len(chunk))
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"下载文件异常: {e}")
|
||||
return False
|
||||
@@ -77,7 +106,7 @@ class CRequestManager:
|
||||
dict: 返回请求结果的JSON数据
|
||||
"""
|
||||
baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
|
||||
url = f"{baseUrl.rstrip('/')}/{endpoint.lstrip('/')}"
|
||||
url = f"{baseUrl.rstrip('/')}:8998/{endpoint.lstrip('/')}"
|
||||
headers = {"token": cls.m_sTokens}
|
||||
|
||||
try:
|
||||
@@ -110,7 +139,7 @@ class CRequestManager:
|
||||
dict: 返回请求结果的JSON数据
|
||||
"""
|
||||
baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
|
||||
url = f"{baseUrl.rstrip('/')}/{endpoint.lstrip('/')}"
|
||||
url = f"{baseUrl.rstrip('/')}:8998/{endpoint.lstrip('/')}"
|
||||
headers = {"token": cls.m_sTokens}
|
||||
|
||||
try:
|
||||
@@ -156,20 +185,110 @@ class CRequestManager:
|
||||
|
||||
@classmethod
|
||||
async def downloadSignInFile(cls) -> bool:
|
||||
"""下载签到文件,并重命名为 sign_in.json
|
||||
|
||||
Returns:
|
||||
bool: 是否下载成功
|
||||
"""
|
||||
try:
|
||||
baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
|
||||
|
||||
url = f"{baseUrl.rstrip('/')}:8998/sign_in"
|
||||
path = str(g_sSignInPath.parent.resolve(strict=False))
|
||||
yearMonth = g_pToolManager.dateTime().now().strftime("%Y%m")
|
||||
|
||||
await cls.download(url, path, "signTemp.json", jsonData={"date": yearMonth})
|
||||
g_pToolManager.renameFile(f"{path}/signTemp.json", "sign_in.json")
|
||||
# 下载为 signTemp.json
|
||||
success = await cls.download(
|
||||
url=url,
|
||||
savePath=path,
|
||||
fileName="signTemp.json",
|
||||
jsonData={"date": yearMonth},
|
||||
)
|
||||
|
||||
if not success:
|
||||
return False
|
||||
|
||||
# 重命名为 sign_in.json
|
||||
g_pToolManager.renameFile(f"{path}/signTemp.json", "sign_in.json")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error("下载签到文件失败", e=e)
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
async def initPlantDBFile(cls) -> bool:
|
||||
"""检查本地 plant.db 版本,如远程版本更新则重新下载
|
||||
|
||||
Returns:
|
||||
bool: 是否为最新版或成功更新
|
||||
"""
|
||||
versionPath = os.path.join(os.path.dirname(g_sPlantPath), "version.json")
|
||||
|
||||
try:
|
||||
with open(versionPath, encoding="utf-8") as f:
|
||||
localVersion = json.load(f).get("version", 0)
|
||||
except Exception as e:
|
||||
logger.warning(f"读取本地版本失败,默认版本为0: {e}")
|
||||
localVersion = 0
|
||||
|
||||
remoteInfo = await cls.get("plant_version", name="版本检查")
|
||||
remoteVersion = remoteInfo.get("version")
|
||||
|
||||
if remoteVersion is None:
|
||||
logger.warning("获取远程版本失败")
|
||||
return False
|
||||
|
||||
if float(remoteVersion) <= float(localVersion):
|
||||
logger.debug("plant.db 已为最新版本")
|
||||
return True
|
||||
|
||||
logger.warning(
|
||||
f"发现新版本 plant.db(远程: {remoteVersion} / 本地: {localVersion}),开始更新..."
|
||||
)
|
||||
|
||||
# 先断开数据库连接
|
||||
await g_pDBService.cleanup()
|
||||
|
||||
return await cls.downloadPlantDBFile(remoteVersion)
|
||||
|
||||
@classmethod
|
||||
async def downloadPlantDBFile(cls, remoteVersion: float) -> bool:
|
||||
"""下载最新版 plant.db 并更新本地 version.json
|
||||
|
||||
Args:
|
||||
remoteVersion (float): 远程版本号
|
||||
|
||||
Returns:
|
||||
bool: 是否下载并更新成功
|
||||
"""
|
||||
baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
|
||||
|
||||
savePath = os.path.dirname(g_sPlantPath)
|
||||
success = await cls.download(
|
||||
url=f"{baseUrl.rstrip('/')}:8998/file/plant.db",
|
||||
savePath=savePath,
|
||||
fileName="plantTemp.db",
|
||||
)
|
||||
|
||||
if not success:
|
||||
return False
|
||||
|
||||
# 重命名为 sign_in.json
|
||||
g_pToolManager.renameFile(f"{savePath}/plantTemp.db", "plant.db")
|
||||
|
||||
versionPath = os.path.join(savePath, "version.json")
|
||||
try:
|
||||
with open(versionPath, "w", encoding="utf-8") as f:
|
||||
json.dump({"version": remoteVersion}, f)
|
||||
logger.debug("版本文件已更新")
|
||||
except Exception as e:
|
||||
logger.warning(f"写入版本文件失败: {e}")
|
||||
return False
|
||||
|
||||
await g_pDBService.plant.init()
|
||||
await g_pDBService.plant.downloadPlant()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
g_pRequestManager = CRequestManager()
|
||||
|
||||
Reference in New Issue
Block a user