chore: 添加签到重试,仅每日签到获取token (#229)

* fix: 修复无法构建docker镜像的问题

* Update Dockerfile

* 🔧 自动更新requirements

* chore: 添加自动每日运行时间提示

* chore: 将时间类型从str改成int

* Add files via upload

* chore: 更新日志收集方法

* chore: 遵守代码规范

* chore: update issue templates

* chore: 删除测试代码

* chore: 更改日志输出样式

* chore: docker生成配置时随机生成自动运行时间

* chore: trailing-whitespace

* chore: 日志添加换行

* chore: 未配置验证码解决方案时直接跳过

* chore: 使用遍历方法找到键值,提升泛用性

* chore: 使用cron执行自动任务

* chore: snake_case

* chore: 修改运行时间

* Update config.py

* chore: 添加签到重试,仅每日签到获取token

* 🔧 自动更新requirements

* chore: 更新版本号

* Update config.py

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Night-stars-1 2023-12-04 22:21:41 +08:00 committed by GitHub
parent 6f5bc44082
commit f85232e5ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 94 additions and 74 deletions

View File

@ -1,7 +1,7 @@
'''
Date: 2023-11-13 20:29:19
LastEditors: Night-stars-1 nujj1042633805@gmail.com
LastEditTime: 2023-11-24 16:23:43
LastEditTime: 2023-12-03 01:53:48
'''
# new Env("MIUI-Auto-Task") # pylint: disable=missing-module-docstring
# cron 30 8 * * * miuitask.py
@ -9,7 +9,7 @@ LastEditTime: 2023-11-24 16:23:43
import asyncio
from utils.api.login import Login
from utils.api.sign import BaseSign
from utils.api.sign import BaseSign, CheckIn
from utils.config import ConfigManager
from utils.logger import InterceptHandler, log
from utils.request import notify_me
@ -25,7 +25,6 @@ async def main():
for account in _conf.accounts:
login_obj = Login(account)
if cookies := await login_obj.login():
token = await get_token(cookies["cUserId"])
sign_obj = BaseSign(cookies)
daily_tasks = await sign_obj.check_daily_tasks()
sign_task_obj = sign_obj.AVAILABLE_SIGNS # 签到任务对象合集
@ -34,6 +33,7 @@ async def main():
log.info(f"开始执行{task.name}任务")
if task_obj := sign_task_obj.get(task.name): # 签到任务对象
if getattr(account, task_obj.__name__):
token = await get_token(cookies["cUserId"]) if task_obj == CheckIn else None
await task_obj(cookies, token).sign()
else:
log.info(f"任务{task.name}被禁用")

View File

@ -100,8 +100,11 @@ dependencies = [
[[package]]
name = "onepush"
version = "1.3.0"
version = "1.2.0"
requires_python = ">=3.6"
git = "https://github.com/y1ndan/onepush.git"
ref = "main"
revision = "8b09e62330ad74ba3221bfc2b080d1732a1dcc55"
summary = "A Python library to send notifications to your iPhone, Discord, Telegram, WeChat, QQ and DingTalk."
dependencies = [
"pycryptodome",
@ -204,7 +207,7 @@ summary = "A small Python utility to set file creation time on Windows"
lock_version = "4.2"
cross_platform = true
groups = ["default"]
content_hash = "sha256:566a9a72c24c47971354bfa0ce10ce921cde51561fd737c3fd433c69621edd5e"
content_hash = "sha256:7c922391569ae98b5aba9438d7da9b0ab1b413b23a1e333df2e61bfab038c0ac"
[metadata.files]
"annotated-types 0.6.0" = [
@ -414,9 +417,6 @@ content_hash = "sha256:566a9a72c24c47971354bfa0ce10ce921cde51561fd737c3fd433c696
{url = "https://files.pythonhosted.org/packages/03/0a/4f6fed21aa246c6b49b561ca55facacc2a44b87d65b8b92362a8e99ba202/loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb"},
{url = "https://files.pythonhosted.org/packages/9e/30/d87a423766b24db416a46e9335b9602b054a72b96a88a241f2b09b560fa8/loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"},
]
"onepush 1.3.0" = [
{url = "https://files.pythonhosted.org/packages/e1/a2/1d65907128f1b7980d7da0e68b134298ced50d38df8ddf5133e32c8e9f99/onepush-1.3.0-py3-none-any.whl", hash = "sha256:196af2e147a54381b5ffa32565f5f3955a0647328cc283812ce2f87f4bc09f47"},
]
"orjson 3.9.10" = [
{url = "https://files.pythonhosted.org/packages/03/96/4fd0da4f4a5a450054e69439875b4e856654dcbbfea6907d7753b827c937/orjson-3.9.10-cp312-none-win_amd64.whl", hash = "sha256:3e892621434392199efb54e69edfff9f699f6cc36dd9553c5bf796058b14b20d"},
{url = "https://files.pythonhosted.org/packages/09/33/d090754faab1a63ecf80b1df220d6787605caefd570331c757a3553afbf2/orjson-3.9.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92af0d00091e744587221e79f68d617b432425a7e59328ca4c496f774a356071"},

View File

@ -4,7 +4,6 @@ version = ""
description = ""
authors = []
dependencies = [
"onepush",
"orjson>=3.9.10",
"loguru>=0.7.2",
"pydantic>=2.4.2",
@ -13,6 +12,7 @@ dependencies = [
"pyyaml>=6.0.1",
"tenacity>=8.2.3",
"tzdata>=2023.3",
"onepush @ git+https://github.com/y1ndan/onepush.git@main",
]
requires-python = ">=3.11"
license = {text = "MIT"}

View File

@ -1,5 +1,5 @@
cryptography==41.0.6
httpx==0.25.1
cryptography==41.0.7
httpx==0.25.2
loguru==0.7.2
onepush==1.3.0
orjson==3.9.10

View File

@ -3,10 +3,12 @@
import time
from typing import Dict, List, Optional, Type, Union, Any
from tenacity import RetryError, Retrying, stop_after_attempt
from ..data_model import ApiResultHandler, DailyTasksResult, SignResultHandler
from ..request import get, post
from ..logger import log
from ..utils import is_incorrect_return
class BaseSign:
@ -37,28 +39,32 @@ class BaseSign:
async def check_daily_tasks(self, nolog: bool = False) -> Union[List[DailyTasksResult], List[None]]:
"""获取每日任务状态"""
try:
response = await get('https://api.vip.miui.com/mtop/planet/vip/member/getCheckinPageCakeList',
cookies=self.cookie)
log.debug(response.text)
result = response.json()
api_data = ApiResultHandler(result)
if api_data.success:
task_status = []
tasks: List[Dict[str, List[Dict[str, Any]]]] = list(filter(
lambda x: x['head']['title'] in ["每日任务", "其他任务"], api_data.data))
for task in tasks:
for daily_task in task['data']:
task_name = daily_task['title']
task_desc = daily_task.get('desc', '')
show_type = True if daily_task['showType'] == 0 else False # pylint: disable=simplifiable-if-expression
task_status.append(DailyTasksResult(name=task_name, showType=show_type, desc=task_desc))
return task_status
for attempt in Retrying(stop=stop_after_attempt(3)):
with attempt:
response = await get('https://api.vip.miui.com/mtop/planet/vip/member/getCheckinPageCakeList',
cookies=self.cookie)
log.debug(response.text)
result = response.json()
api_data = ApiResultHandler(result)
if api_data.success:
task_status = []
tasks: List[Dict[str, List[Dict[str, Any]]]] = list(filter(
lambda x: x['head']['title'] in ["每日任务", "其他任务"], api_data.data))
for task in tasks:
for daily_task in task['data']:
task_name = daily_task['title']
task_desc = daily_task.get('desc', '')
show_type = True if daily_task['showType'] == 0 else False # pylint: disable=simplifiable-if-expression
task_status.append(DailyTasksResult(name=task_name, showType=show_type, desc=task_desc))
return task_status
else:
if not nolog:
log.error(f"获取每日任务状态失败:{api_data.message}")
return []
except RetryError as error:
if is_incorrect_return(error):
log.exception(f"每日任务 - 服务器没有正确返回 {response.text}")
else:
if not nolog:
log.error(f"获取每日任务状态失败:{api_data.message}")
return []
except Exception: # pylint: disable=broad-exception-caught
if not nolog:
log.exception("获取每日任务异常")
return []
@ -67,40 +73,44 @@ class BaseSign:
每日任务处理器
"""
try:
params = self.PARAMS.copy()
params['miui_vip_ph'] = self.cookie['miui_vip_ph'] if 'miui_vip_ph' in self.cookie else params
params['token'] = self.token if 'token' in params else params
data = self.DATA.copy()
data['miui_vip_ph'] = self.cookie['miui_vip_ph'] if 'miui_vip_ph' in self.cookie else data
if 'token' in data:
if self.token:
data['token'] = self.token
else:
log.info(f"未获取到token, 跳过{self.NAME}")
return False
response = await post(self.URL_SIGN,
params=params, data=data,
cookies=self.cookie, headers=self.headers)
log.debug(response.text)
result = response.json()
api_data = SignResultHandler(result)
if api_data:
if api_data.growth:
log.success(f"{self.NAME}结果: 成长值+{api_data.growth}")
else:
log.success(f"{self.NAME}结果: {api_data.message}")
return True
elif api_data.ck_invalid:
log.error(f"{self.NAME}失败: Cookie无效")
return False
for attempt in Retrying(stop=stop_after_attempt(3)):
with attempt:
params = self.PARAMS.copy()
params['miui_vip_ph'] = self.cookie['miui_vip_ph'] if 'miui_vip_ph' in self.cookie else params
params['token'] = self.token if 'token' in params else params
data = self.DATA.copy()
data['miui_vip_ph'] = self.cookie['miui_vip_ph'] if 'miui_vip_ph' in self.cookie else data
if 'token' in data:
if self.token:
data['token'] = self.token
else:
log.info(f"未获取到token, 跳过{self.NAME}")
return False
response = await post(self.URL_SIGN,
params=params, data=data,
cookies=self.cookie, headers=self.headers)
log.debug(response.text)
result = response.json()
api_data = SignResultHandler(result)
if api_data:
if api_data.growth:
log.success(f"{self.NAME}结果: 成长值+{api_data.growth}")
else:
log.success(f"{self.NAME}结果: {api_data.message}")
return True
elif api_data.ck_invalid:
log.error(f"{self.NAME}失败: Cookie无效")
return False
else:
log.error(f"{self.NAME}失败:{api_data.message}")
return False
except RetryError as error:
if is_incorrect_return(error):
log.exception(f"{self.NAME} - 服务器没有正确返回 {response.text}")
else:
log.error(f"{self.NAME}失败:{api_data.message}")
return False
except Exception: # pylint: disable=broad-exception-caught
log.exception(f"{self.NAME}出错")
log.exception("{self.NAME}出错")
return False
class CheckIn(BaseSign):
"""
每日签到

View File

@ -6,9 +6,9 @@ from json import JSONDecodeError
from pathlib import Path
from typing import Dict, List, Optional, Union
import yaml
from pydantic import BaseModel
from pydantic import ValidationError, field_validator
import orjson
import yaml # pylint: disable=wrong-import-order
from pydantic import BaseModel, ValidationError, field_validator
from .logger import log
@ -17,7 +17,10 @@ ROOT_PATH = Path(__name__).parent.absolute()
DATA_PATH = ROOT_PATH / "data"
"""数据保存目录"""
CONFIG_PATH = DATA_PATH / "config.yaml" if os.getenv("MIUITASK_CONFIG_PATH") is None else Path(os.getenv("MIUITASK_CONFIG_PATH"))
CONFIG_TYPE = "json" if os.path.isfile(DATA_PATH / "config.json") else "yaml"
"""数据文件类型"""
CONFIG_PATH = DATA_PATH / f"config.{CONFIG_TYPE}" if os.getenv("MIUITASK_CONFIG_PATH") is None else Path(os.getenv("MIUITASK_CONFIG_PATH"))
"""数据文件默认路径"""
os.makedirs(DATA_PATH, exist_ok=True)
@ -128,14 +131,18 @@ def write_plugin_data(data: Config = None):
if data is None:
data = ConfigManager.data_obj
try:
# str_data = orjson.dumps(data.dict(), option=orjson.OPT_PASSTHROUGH_DATETIME | orjson.OPT_SERIALIZE_NUMPY | orjson.OPT_INDENT_2)
str_data = yaml.dump(data.model_dump(), indent=4, allow_unicode=True, sort_keys=False)
if CONFIG_TYPE == "json":
str_data = orjson.dumps(data.model_dump(), option=orjson.OPT_PASSTHROUGH_DATETIME | orjson.OPT_SERIALIZE_NUMPY | orjson.OPT_INDENT_2)
with open(CONFIG_PATH, "wb") as file:
file.write(str_data)
else:
str_data = yaml.dump(data.model_dump(), indent=4, allow_unicode=True, sort_keys=False)
with open(CONFIG_PATH, "w", encoding="utf-8") as file:
file.write(str_data)
return True
except (AttributeError, TypeError, ValueError):
log.exception("数据对象序列化失败,可能是数据类型错误")
return False
with open(CONFIG_PATH, "w", encoding="utf-8") as file:
file.write(str_data)
return True
except OSError:
return False
@ -155,7 +162,10 @@ class ConfigManager:
if os.path.exists(DATA_PATH) and os.path.isfile(CONFIG_PATH):
try:
with open(CONFIG_PATH, 'r', encoding="utf-8") as file:
data = yaml.safe_load(file)
if CONFIG_TYPE == "json":
data = orjson.loads(file.read())
else:
data = yaml.safe_load(file)
new_model = Config.model_validate(data)
for attr in new_model.model_fields:
# ConfigManager.data_obj.__setattr__(attr, new_model.__getattribute__(attr))

View File

@ -10,7 +10,7 @@ from utils.logger import log
def print_info():
"""打印系统信息"""
log.info("MIUI-AUTO-TASK v1.7.2")
log.info("MIUI-AUTO-TASK v1.7.3")
log.info('---------- 系统信息 -------------')
system_info()
log.info('---------- 项目信息 -------------')