2025-05-26 15:10:12 +08:00
|
|
|
|
import json
|
2025-04-27 17:00:58 +08:00
|
|
|
|
import os
|
2025-04-08 19:00:17 +08:00
|
|
|
|
|
2025-04-27 10:52:28 +08:00
|
|
|
|
import httpx
|
|
|
|
|
|
|
|
|
|
|
|
from zhenxun.configs.config import Config
|
|
|
|
|
|
from zhenxun.services.log import logger
|
2025-04-08 19:00:17 +08:00
|
|
|
|
|
2025-05-26 15:10:12 +08:00
|
|
|
|
from .config import g_sSignInPath
|
|
|
|
|
|
from .tool import g_pToolManager
|
|
|
|
|
|
|
2025-04-08 19:00:17 +08:00
|
|
|
|
|
|
|
|
|
|
class CRequestManager:
|
2025-05-26 15:10:12 +08:00
|
|
|
|
m_sTokens = "xZ%?z5LtWV7H:0-Xnwp+bNRNQ-jbfrxG"
|
2025-04-08 19:00:17 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2025-06-06 10:56:22 +08:00
|
|
|
|
async def download(
|
|
|
|
|
|
cls,
|
|
|
|
|
|
url: str,
|
|
|
|
|
|
savePath: str,
|
|
|
|
|
|
fileName: str,
|
|
|
|
|
|
params: dict | None = None,
|
|
|
|
|
|
jsonData: dict | None = None,
|
|
|
|
|
|
) -> bool:
|
2025-04-27 17:00:58 +08:00
|
|
|
|
"""下载文件到指定路径并覆盖已存在的文件
|
2025-04-27 10:52:28 +08:00
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
url (str): 文件的下载链接
|
2025-04-27 17:00:58 +08:00
|
|
|
|
savePath (str): 保存文件夹路径
|
2025-04-27 10:52:28 +08:00
|
|
|
|
fileName (str): 保存后的文件名
|
2025-05-26 15:10:12 +08:00
|
|
|
|
params (dict | None): 可选的 URL 查询参数
|
|
|
|
|
|
jsonData (dict | None): 可选的 JSON 请求体
|
2025-04-27 10:52:28 +08:00
|
|
|
|
Returns:
|
|
|
|
|
|
bool: 是否下载成功
|
|
|
|
|
|
"""
|
2025-05-26 15:10:12 +08:00
|
|
|
|
headers = {"token": cls.m_sTokens}
|
|
|
|
|
|
|
2025-04-08 19:00:17 +08:00
|
|
|
|
try:
|
2025-04-27 10:52:28 +08:00
|
|
|
|
async with httpx.AsyncClient(timeout=10.0) as client:
|
2025-05-26 15:10:12 +08:00
|
|
|
|
requestArgs: dict = {"headers": headers}
|
|
|
|
|
|
if params:
|
|
|
|
|
|
requestArgs["params"] = params
|
|
|
|
|
|
if jsonData:
|
|
|
|
|
|
requestArgs["json"] = jsonData
|
|
|
|
|
|
|
|
|
|
|
|
response = await client.request("GET", url, **requestArgs)
|
|
|
|
|
|
|
2025-04-27 10:52:28 +08:00
|
|
|
|
if response.status_code == 200:
|
2025-04-27 17:00:58 +08:00
|
|
|
|
fullPath = os.path.join(savePath, fileName)
|
|
|
|
|
|
os.makedirs(os.path.dirname(fullPath), exist_ok=True)
|
2025-04-27 10:52:28 +08:00
|
|
|
|
with open(fullPath, "wb") as f:
|
|
|
|
|
|
f.write(response.content)
|
|
|
|
|
|
return True
|
|
|
|
|
|
else:
|
2025-06-06 10:56:22 +08:00
|
|
|
|
logger.warning(
|
|
|
|
|
|
f"文件下载失败: HTTP {response.status_code} {response.text}"
|
|
|
|
|
|
)
|
2025-04-27 10:52:28 +08:00
|
|
|
|
return False
|
2025-05-26 15:10:12 +08:00
|
|
|
|
|
2025-04-27 10:52:28 +08:00
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.warning(f"下载文件异常: {e}")
|
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2025-05-27 18:15:11 +08:00
|
|
|
|
async def post(cls, endpoint: str, name: str = "", jsonData: dict = {}) -> dict:
|
2025-04-29 18:11:09 +08:00
|
|
|
|
"""发送POST请求到指定接口,统一调用,仅支持JSON格式数据
|
2025-04-27 10:52:28 +08:00
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
endpoint (str): 请求的接口路径
|
|
|
|
|
|
name (str, optional): 操作名称用于日志记录
|
2025-04-29 18:11:09 +08:00
|
|
|
|
jsonData (dict): 以JSON格式发送的数据
|
2025-04-27 10:52:28 +08:00
|
|
|
|
|
|
|
|
|
|
Raises:
|
2025-04-29 18:11:09 +08:00
|
|
|
|
ValueError: 当jsonData未提供时抛出
|
2025-04-27 10:52:28 +08:00
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
dict: 返回请求结果的JSON数据
|
|
|
|
|
|
"""
|
|
|
|
|
|
baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
|
|
|
|
|
|
url = f"{baseUrl.rstrip('/')}/{endpoint.lstrip('/')}"
|
2025-05-26 15:10:12 +08:00
|
|
|
|
headers = {"token": cls.m_sTokens}
|
2025-04-27 10:52:28 +08:00
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
async with httpx.AsyncClient(timeout=5.0) as client:
|
2025-04-29 18:11:09 +08:00
|
|
|
|
response = await client.post(url, json=jsonData, headers=headers)
|
2025-04-27 10:52:28 +08:00
|
|
|
|
|
|
|
|
|
|
if response.status_code == 200:
|
|
|
|
|
|
return response.json()
|
|
|
|
|
|
else:
|
2025-06-06 10:56:22 +08:00
|
|
|
|
logger.warning(
|
|
|
|
|
|
f"{name}请求失败: HTTP {response.status_code} {response.text}"
|
|
|
|
|
|
)
|
2025-04-27 10:52:28 +08:00
|
|
|
|
return {}
|
|
|
|
|
|
except httpx.RequestError as e:
|
2025-04-29 18:11:09 +08:00
|
|
|
|
logger.warning(f"{name}请求异常", e=e)
|
2025-04-27 10:52:28 +08:00
|
|
|
|
return {}
|
|
|
|
|
|
except Exception as e:
|
2025-04-29 18:11:09 +08:00
|
|
|
|
logger.warning(f"{name}处理异常", e=e)
|
2025-04-08 19:00:17 +08:00
|
|
|
|
return {}
|
|
|
|
|
|
|
2025-04-29 18:11:09 +08:00
|
|
|
|
@classmethod
|
|
|
|
|
|
async def get(cls, endpoint: str, name: str = "") -> dict:
|
|
|
|
|
|
"""发送GET请求到指定接口,统一调用,仅支持无体的查询
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
endpoint (str): 请求的接口路径
|
|
|
|
|
|
name (str, optional): 操作名称用于日志记录
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
dict: 返回请求结果的JSON数据
|
|
|
|
|
|
"""
|
|
|
|
|
|
baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
|
|
|
|
|
|
url = f"{baseUrl.rstrip('/')}/{endpoint.lstrip('/')}"
|
2025-05-26 15:10:12 +08:00
|
|
|
|
headers = {"token": cls.m_sTokens}
|
2025-04-29 18:11:09 +08:00
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
async with httpx.AsyncClient(timeout=5.0) as client:
|
|
|
|
|
|
response = await client.get(url, headers=headers)
|
|
|
|
|
|
|
|
|
|
|
|
if response.status_code == 200:
|
|
|
|
|
|
return response.json()
|
|
|
|
|
|
else:
|
2025-06-06 10:56:22 +08:00
|
|
|
|
logger.warning(
|
|
|
|
|
|
f"{name}请求失败: HTTP {response.status_code} {response.text}"
|
|
|
|
|
|
)
|
2025-04-29 18:11:09 +08:00
|
|
|
|
return {}
|
|
|
|
|
|
except httpx.RequestError as e:
|
|
|
|
|
|
logger.warning(f"{name}请求异常", e=e)
|
|
|
|
|
|
return {}
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.warning(f"{name}处理异常", e=e)
|
|
|
|
|
|
return {}
|
2025-04-27 10:52:28 +08:00
|
|
|
|
|
2025-04-08 19:00:17 +08:00
|
|
|
|
@classmethod
|
2025-05-27 18:15:11 +08:00
|
|
|
|
async def initSignInFile(cls) -> bool:
|
2025-05-26 15:10:12 +08:00
|
|
|
|
if os.path.exists(g_sSignInPath):
|
|
|
|
|
|
try:
|
2025-06-06 10:56:22 +08:00
|
|
|
|
with open(g_sSignInPath, encoding="utf-8") as f:
|
2025-05-26 15:10:12 +08:00
|
|
|
|
content = f.read()
|
|
|
|
|
|
sign = json.loads(content)
|
2025-04-08 19:00:17 +08:00
|
|
|
|
|
2025-05-26 15:10:12 +08:00
|
|
|
|
date = sign.get("date", "")
|
2025-05-27 18:15:11 +08:00
|
|
|
|
yearMonth = g_pToolManager.dateTime().now().strftime("%Y%m")
|
2025-04-09 17:14:37 +08:00
|
|
|
|
|
2025-05-26 15:10:12 +08:00
|
|
|
|
if date == yearMonth:
|
|
|
|
|
|
logger.debug("真寻农场签到文件检查完毕")
|
2025-05-27 18:15:11 +08:00
|
|
|
|
return True
|
2025-05-26 15:10:12 +08:00
|
|
|
|
else:
|
|
|
|
|
|
logger.warning("真寻农场签到文件检查失败, 即将下载")
|
2025-05-27 18:15:11 +08:00
|
|
|
|
return await cls.downloadSignInFile()
|
2025-06-06 10:56:22 +08:00
|
|
|
|
except json.JSONDecodeError:
|
|
|
|
|
|
logger.warning("真寻农场签到文件格式错误, 即将下载")
|
2025-05-27 18:15:11 +08:00
|
|
|
|
return await cls.downloadSignInFile()
|
2025-04-09 17:14:37 +08:00
|
|
|
|
else:
|
2025-05-27 18:15:11 +08:00
|
|
|
|
return await cls.downloadSignInFile()
|
2025-05-26 15:10:12 +08:00
|
|
|
|
|
|
|
|
|
|
@classmethod
|
2025-05-27 18:15:11 +08:00
|
|
|
|
async def downloadSignInFile(cls) -> bool:
|
|
|
|
|
|
try:
|
|
|
|
|
|
baseUrl = Config.get_config("zhenxun_plugin_farm", "服务地址")
|
2025-05-26 15:10:12 +08:00
|
|
|
|
|
2025-05-27 18:15:11 +08:00
|
|
|
|
url = f"{baseUrl.rstrip('/')}:8998/sign_in"
|
|
|
|
|
|
path = str(g_sSignInPath.parent.resolve(strict=False))
|
|
|
|
|
|
yearMonth = g_pToolManager.dateTime().now().strftime("%Y%m")
|
2025-05-26 15:10:12 +08:00
|
|
|
|
|
2025-06-06 10:56:22 +08:00
|
|
|
|
await cls.download(url, path, "signTemp.json", jsonData={"date": yearMonth})
|
2025-05-27 18:15:11 +08:00
|
|
|
|
g_pToolManager.renameFile(f"{path}/signTemp.json", "sign_in.json")
|
2025-04-08 19:00:17 +08:00
|
|
|
|
|
2025-05-27 18:15:11 +08:00
|
|
|
|
return True
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
logger.error("下载签到文件失败", e=e)
|
|
|
|
|
|
return False
|
2025-04-08 19:00:17 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
g_pRequestManager = CRequestManager()
|