mirror of
https://github.com/0-8-4/miui-auto-tasks.git
synced 2024-11-16 04:35:51 +00:00
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:
parent
6f5bc44082
commit
f85232e5ee
@ -1,7 +1,7 @@
|
|||||||
'''
|
'''
|
||||||
Date: 2023-11-13 20:29:19
|
Date: 2023-11-13 20:29:19
|
||||||
LastEditors: Night-stars-1 nujj1042633805@gmail.com
|
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
|
# new Env("MIUI-Auto-Task") # pylint: disable=missing-module-docstring
|
||||||
# cron 30 8 * * * miuitask.py
|
# cron 30 8 * * * miuitask.py
|
||||||
@ -9,7 +9,7 @@ LastEditTime: 2023-11-24 16:23:43
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
from utils.api.login import Login
|
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.config import ConfigManager
|
||||||
from utils.logger import InterceptHandler, log
|
from utils.logger import InterceptHandler, log
|
||||||
from utils.request import notify_me
|
from utils.request import notify_me
|
||||||
@ -25,7 +25,6 @@ async def main():
|
|||||||
for account in _conf.accounts:
|
for account in _conf.accounts:
|
||||||
login_obj = Login(account)
|
login_obj = Login(account)
|
||||||
if cookies := await login_obj.login():
|
if cookies := await login_obj.login():
|
||||||
token = await get_token(cookies["cUserId"])
|
|
||||||
sign_obj = BaseSign(cookies)
|
sign_obj = BaseSign(cookies)
|
||||||
daily_tasks = await sign_obj.check_daily_tasks()
|
daily_tasks = await sign_obj.check_daily_tasks()
|
||||||
sign_task_obj = sign_obj.AVAILABLE_SIGNS # 签到任务对象合集
|
sign_task_obj = sign_obj.AVAILABLE_SIGNS # 签到任务对象合集
|
||||||
@ -34,6 +33,7 @@ async def main():
|
|||||||
log.info(f"开始执行{task.name}任务")
|
log.info(f"开始执行{task.name}任务")
|
||||||
if task_obj := sign_task_obj.get(task.name): # 签到任务对象
|
if task_obj := sign_task_obj.get(task.name): # 签到任务对象
|
||||||
if getattr(account, task_obj.__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()
|
await task_obj(cookies, token).sign()
|
||||||
else:
|
else:
|
||||||
log.info(f"任务{task.name}被禁用")
|
log.info(f"任务{task.name}被禁用")
|
||||||
|
10
pdm.lock
10
pdm.lock
@ -100,8 +100,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "onepush"
|
name = "onepush"
|
||||||
version = "1.3.0"
|
version = "1.2.0"
|
||||||
requires_python = ">=3.6"
|
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."
|
summary = "A Python library to send notifications to your iPhone, Discord, Telegram, WeChat, QQ and DingTalk."
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pycryptodome",
|
"pycryptodome",
|
||||||
@ -204,7 +207,7 @@ summary = "A small Python utility to set file creation time on Windows"
|
|||||||
lock_version = "4.2"
|
lock_version = "4.2"
|
||||||
cross_platform = true
|
cross_platform = true
|
||||||
groups = ["default"]
|
groups = ["default"]
|
||||||
content_hash = "sha256:566a9a72c24c47971354bfa0ce10ce921cde51561fd737c3fd433c69621edd5e"
|
content_hash = "sha256:7c922391569ae98b5aba9438d7da9b0ab1b413b23a1e333df2e61bfab038c0ac"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
"annotated-types 0.6.0" = [
|
"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/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"},
|
{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" = [
|
"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/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"},
|
{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"},
|
||||||
|
@ -4,7 +4,6 @@ version = ""
|
|||||||
description = ""
|
description = ""
|
||||||
authors = []
|
authors = []
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"onepush",
|
|
||||||
"orjson>=3.9.10",
|
"orjson>=3.9.10",
|
||||||
"loguru>=0.7.2",
|
"loguru>=0.7.2",
|
||||||
"pydantic>=2.4.2",
|
"pydantic>=2.4.2",
|
||||||
@ -13,6 +12,7 @@ dependencies = [
|
|||||||
"pyyaml>=6.0.1",
|
"pyyaml>=6.0.1",
|
||||||
"tenacity>=8.2.3",
|
"tenacity>=8.2.3",
|
||||||
"tzdata>=2023.3",
|
"tzdata>=2023.3",
|
||||||
|
"onepush @ git+https://github.com/y1ndan/onepush.git@main",
|
||||||
]
|
]
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
license = {text = "MIT"}
|
license = {text = "MIT"}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
cryptography==41.0.6
|
cryptography==41.0.7
|
||||||
httpx==0.25.1
|
httpx==0.25.2
|
||||||
loguru==0.7.2
|
loguru==0.7.2
|
||||||
onepush==1.3.0
|
onepush==1.3.0
|
||||||
orjson==3.9.10
|
orjson==3.9.10
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
from typing import Dict, List, Optional, Type, Union, Any
|
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 ..data_model import ApiResultHandler, DailyTasksResult, SignResultHandler
|
||||||
from ..request import get, post
|
from ..request import get, post
|
||||||
from ..logger import log
|
from ..logger import log
|
||||||
|
from ..utils import is_incorrect_return
|
||||||
|
|
||||||
|
|
||||||
class BaseSign:
|
class BaseSign:
|
||||||
@ -37,28 +39,32 @@ class BaseSign:
|
|||||||
async def check_daily_tasks(self, nolog: bool = False) -> Union[List[DailyTasksResult], List[None]]:
|
async def check_daily_tasks(self, nolog: bool = False) -> Union[List[DailyTasksResult], List[None]]:
|
||||||
"""获取每日任务状态"""
|
"""获取每日任务状态"""
|
||||||
try:
|
try:
|
||||||
response = await get('https://api.vip.miui.com/mtop/planet/vip/member/getCheckinPageCakeList',
|
for attempt in Retrying(stop=stop_after_attempt(3)):
|
||||||
cookies=self.cookie)
|
with attempt:
|
||||||
log.debug(response.text)
|
response = await get('https://api.vip.miui.com/mtop/planet/vip/member/getCheckinPageCakeList',
|
||||||
result = response.json()
|
cookies=self.cookie)
|
||||||
api_data = ApiResultHandler(result)
|
log.debug(response.text)
|
||||||
if api_data.success:
|
result = response.json()
|
||||||
task_status = []
|
api_data = ApiResultHandler(result)
|
||||||
tasks: List[Dict[str, List[Dict[str, Any]]]] = list(filter(
|
if api_data.success:
|
||||||
lambda x: x['head']['title'] in ["每日任务", "其他任务"], api_data.data))
|
task_status = []
|
||||||
for task in tasks:
|
tasks: List[Dict[str, List[Dict[str, Any]]]] = list(filter(
|
||||||
for daily_task in task['data']:
|
lambda x: x['head']['title'] in ["每日任务", "其他任务"], api_data.data))
|
||||||
task_name = daily_task['title']
|
for task in tasks:
|
||||||
task_desc = daily_task.get('desc', '')
|
for daily_task in task['data']:
|
||||||
show_type = True if daily_task['showType'] == 0 else False # pylint: disable=simplifiable-if-expression
|
task_name = daily_task['title']
|
||||||
task_status.append(DailyTasksResult(name=task_name, showType=show_type, desc=task_desc))
|
task_desc = daily_task.get('desc', '')
|
||||||
return task_status
|
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:
|
else:
|
||||||
if not nolog:
|
|
||||||
log.error(f"获取每日任务状态失败:{api_data.message}")
|
|
||||||
return []
|
|
||||||
except Exception: # pylint: disable=broad-exception-caught
|
|
||||||
if not nolog:
|
|
||||||
log.exception("获取每日任务异常")
|
log.exception("获取每日任务异常")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@ -67,40 +73,44 @@ class BaseSign:
|
|||||||
每日任务处理器
|
每日任务处理器
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
params = self.PARAMS.copy()
|
for attempt in Retrying(stop=stop_after_attempt(3)):
|
||||||
params['miui_vip_ph'] = self.cookie['miui_vip_ph'] if 'miui_vip_ph' in self.cookie else params
|
with attempt:
|
||||||
params['token'] = self.token if 'token' in params else params
|
params = self.PARAMS.copy()
|
||||||
data = self.DATA.copy()
|
params['miui_vip_ph'] = self.cookie['miui_vip_ph'] if 'miui_vip_ph' in self.cookie else params
|
||||||
data['miui_vip_ph'] = self.cookie['miui_vip_ph'] if 'miui_vip_ph' in self.cookie else data
|
params['token'] = self.token if 'token' in params else params
|
||||||
if 'token' in data:
|
data = self.DATA.copy()
|
||||||
if self.token:
|
data['miui_vip_ph'] = self.cookie['miui_vip_ph'] if 'miui_vip_ph' in self.cookie else data
|
||||||
data['token'] = self.token
|
if 'token' in data:
|
||||||
else:
|
if self.token:
|
||||||
log.info(f"未获取到token, 跳过{self.NAME}")
|
data['token'] = self.token
|
||||||
return False
|
else:
|
||||||
response = await post(self.URL_SIGN,
|
log.info(f"未获取到token, 跳过{self.NAME}")
|
||||||
params=params, data=data,
|
return False
|
||||||
cookies=self.cookie, headers=self.headers)
|
response = await post(self.URL_SIGN,
|
||||||
log.debug(response.text)
|
params=params, data=data,
|
||||||
result = response.json()
|
cookies=self.cookie, headers=self.headers)
|
||||||
api_data = SignResultHandler(result)
|
log.debug(response.text)
|
||||||
if api_data:
|
result = response.json()
|
||||||
if api_data.growth:
|
api_data = SignResultHandler(result)
|
||||||
log.success(f"{self.NAME}结果: 成长值+{api_data.growth}")
|
if api_data:
|
||||||
else:
|
if api_data.growth:
|
||||||
log.success(f"{self.NAME}结果: {api_data.message}")
|
log.success(f"{self.NAME}结果: 成长值+{api_data.growth}")
|
||||||
return True
|
else:
|
||||||
elif api_data.ck_invalid:
|
log.success(f"{self.NAME}结果: {api_data.message}")
|
||||||
log.error(f"{self.NAME}失败: Cookie无效")
|
return True
|
||||||
return False
|
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:
|
else:
|
||||||
log.error(f"{self.NAME}失败:{api_data.message}")
|
log.exception("{self.NAME}出错")
|
||||||
return False
|
|
||||||
except Exception: # pylint: disable=broad-exception-caught
|
|
||||||
log.exception(f"{self.NAME}出错")
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class CheckIn(BaseSign):
|
class CheckIn(BaseSign):
|
||||||
"""
|
"""
|
||||||
每日签到
|
每日签到
|
||||||
|
@ -6,9 +6,9 @@ from json import JSONDecodeError
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List, Optional, Union
|
from typing import Dict, List, Optional, Union
|
||||||
|
|
||||||
import yaml
|
import orjson
|
||||||
from pydantic import BaseModel
|
import yaml # pylint: disable=wrong-import-order
|
||||||
from pydantic import ValidationError, field_validator
|
from pydantic import BaseModel, ValidationError, field_validator
|
||||||
|
|
||||||
from .logger import log
|
from .logger import log
|
||||||
|
|
||||||
@ -17,7 +17,10 @@ ROOT_PATH = Path(__name__).parent.absolute()
|
|||||||
DATA_PATH = ROOT_PATH / "data"
|
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)
|
os.makedirs(DATA_PATH, exist_ok=True)
|
||||||
@ -128,14 +131,18 @@ def write_plugin_data(data: Config = None):
|
|||||||
if data is None:
|
if data is None:
|
||||||
data = ConfigManager.data_obj
|
data = ConfigManager.data_obj
|
||||||
try:
|
try:
|
||||||
# str_data = orjson.dumps(data.dict(), option=orjson.OPT_PASSTHROUGH_DATETIME | orjson.OPT_SERIALIZE_NUMPY | orjson.OPT_INDENT_2)
|
if CONFIG_TYPE == "json":
|
||||||
str_data = yaml.dump(data.model_dump(), indent=4, allow_unicode=True, sort_keys=False)
|
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):
|
except (AttributeError, TypeError, ValueError):
|
||||||
log.exception("数据对象序列化失败,可能是数据类型错误")
|
log.exception("数据对象序列化失败,可能是数据类型错误")
|
||||||
return False
|
return False
|
||||||
with open(CONFIG_PATH, "w", encoding="utf-8") as file:
|
|
||||||
file.write(str_data)
|
|
||||||
return True
|
|
||||||
except OSError:
|
except OSError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -155,7 +162,10 @@ class ConfigManager:
|
|||||||
if os.path.exists(DATA_PATH) and os.path.isfile(CONFIG_PATH):
|
if os.path.exists(DATA_PATH) and os.path.isfile(CONFIG_PATH):
|
||||||
try:
|
try:
|
||||||
with open(CONFIG_PATH, 'r', encoding="utf-8") as file:
|
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)
|
new_model = Config.model_validate(data)
|
||||||
for attr in new_model.model_fields:
|
for attr in new_model.model_fields:
|
||||||
# ConfigManager.data_obj.__setattr__(attr, new_model.__getattribute__(attr))
|
# ConfigManager.data_obj.__setattr__(attr, new_model.__getattribute__(attr))
|
||||||
|
@ -10,7 +10,7 @@ from utils.logger import log
|
|||||||
|
|
||||||
def print_info():
|
def print_info():
|
||||||
"""打印系统信息"""
|
"""打印系统信息"""
|
||||||
log.info("MIUI-AUTO-TASK v1.7.2")
|
log.info("MIUI-AUTO-TASK v1.7.3")
|
||||||
log.info('---------- 系统信息 -------------')
|
log.info('---------- 系统信息 -------------')
|
||||||
system_info()
|
system_info()
|
||||||
log.info('---------- 项目信息 -------------')
|
log.info('---------- 项目信息 -------------')
|
||||||
|
Loading…
Reference in New Issue
Block a user