feat: 输出二维码登录链接,显示+1概率 (#268)

* feat: 输出二维码登录链接,显示+1概率

* modified:   utils/system_info.py

* modified:   miuitask.py

* modified:   requirements.txt
modified:   utils/api/login.py

* modified:   utils/api/login.py

* Update Dockerfile

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: 0-8-4 <ljd69154@liangjundi.cn>
This commit is contained in:
Night-stars-1 2024-04-06 14:58:18 +08:00 committed by GitHub
parent 597bd50a58
commit 08ddd7c66f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 286 additions and 168 deletions

View File

@ -1,6 +1,6 @@
FROM python:alpine
RUN apk add --no-cache gcc g++ musl-dev python3-dev libffi-dev
RUN apk add --no-cache gcc g++ musl-dev python3-dev libffi-dev rust cargo
RUN pip install --no-cache-dir pdm

View File

@ -1,14 +1,16 @@
'''
Date: 2023-11-13 20:29:19
"""
Author: Night-stars-1 nujj1042633805@gmail.com
Date: 2024-02-21 22:50:45
LastEditTime: 2024-04-05 22:43:45
LastEditors: Night-stars-1 nujj1042633805@gmail.com
LastEditTime: 2023-12-18 19:21:36
'''
"""
# new Env("MIUI-Auto-Task") # pylint: disable=missing-module-docstring
# cron 30 8 * * * miuitask.py
import asyncio
from tenacity import RetryError, Retrying, stop_after_attempt
from tenacity import Retrying, stop_after_attempt
from utils.api.login import Login
from utils.api.sign import BaseSign, CheckIn
@ -30,7 +32,8 @@ async def main():
with attempt:
login_obj = Login(account)
if cookies := await login_obj.login():
sign_obj = BaseSign(cookies, account.user_agent)
await login_obj.checkin_info()
sign_obj = BaseSign(account)
daily_tasks = await sign_obj.check_daily_tasks()
sign_task_obj = sign_obj.AVAILABLE_SIGNS # 签到任务对象合集
for task in daily_tasks:
@ -38,19 +41,25 @@ async def main():
if task.showType:
log.info(f"{task.name}任务已完成")
continue
if not (task_obj := sign_task_obj.get(task.name)): # 签到任务对象
if not (
task_obj := sign_task_obj.get(task.name)
): # 签到任务对象
log.error(f"未找到{task.name}任务")
continue
if not getattr(account, task_obj.__name__):
log.info(f"任务{task.name}被禁用")
continue
token = await get_token(cookies["cUserId"]) if task_obj == CheckIn else None
status, reason = await task_obj(cookies, account.user_agent, token).sign()
token = (
await get_token(cookies["cUserId"])
if task_obj == CheckIn
else None
)
status, reason = await task_obj(account, token).sign()
if not status and reason == "cookie":
raise ValueError("Cookie失效")
user_info = await sign_obj.user_info()
log.info(f"{user_info.title} 成长值: {user_info.point}")
except RetryError:
except ValueError:
...
notify_me(InterceptHandler.message)

View File

@ -180,6 +180,15 @@ dependencies = [
"urllib3<3,>=1.21.1",
]
[[package]]
name = "requests-toolbelt"
version = "1.0.0"
requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
summary = "A utility belt for advanced users of python-requests"
dependencies = [
"requests<3.0.0,>=2.0.1",
]
[[package]]
name = "sniffio"
version = "1.3.0"
@ -220,7 +229,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:fb7c34d8c74d9043647bf7d200afa5a64602e32c03b558cc9d2fb1e81ad1c1e5"
content_hash = "sha256:7af36f1ce91c55a4c7069ab2e19f0beb8309bb78ba480b5da81f975a2f9754a8"
[metadata.files]
"annotated-types 0.6.0" = [
@ -698,6 +707,10 @@ content_hash = "sha256:fb7c34d8c74d9043647bf7d200afa5a64602e32c03b558cc9d2fb1e81
{url = "https://files.pythonhosted.org/packages/70/8e/0e2d847013cb52cd35b38c009bb167a1a26b2ce6cd6965bf26b47bc0bf44/requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
{url = "https://files.pythonhosted.org/packages/9d/be/10918a2eac4ae9f02f6cfe6414b7a155ccd8f7f9d4380d62fd5b955065c3/requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
]
"requests-toolbelt 1.0.0" = [
{url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"},
{url = "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"},
]
"sniffio 1.3.0" = [
{url = "https://files.pythonhosted.org/packages/c3/a0/5dba8ed157b0136607c7f2151db695885606968d1fae123dc3391e0cfdbf/sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"},
{url = "https://files.pythonhosted.org/packages/cd/50/d49c388cae4ec10e8109b1b833fd265511840706808576df3ada99ecb0ac/sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"},

View File

@ -14,6 +14,7 @@ dependencies = [
"tzdata>=2023.3",
"onepush>=1.3.0",
"qrcode>=7.4.2",
"requests-toolbelt>=1.0.0",
]
requires-python = ">=3.11"
license = {text = "MIT"}

View File

@ -1,9 +1,10 @@
cryptography==41.0.7
cryptography==42.0.4
httpx==0.25.2
loguru==0.7.2
onepush==1.3.0
orjson==3.9.10
orjson==3.9.15
pydantic==2.5.2
PyYAML==6.0.1
qrcode==7.4.2
tenacity==8.2.3
qrcode>=7.4.2

View File

@ -1,8 +1,9 @@
"""
Date: 2023-11-12 14:05:06
LastEditors: Night-stars-1 nujj1042633805@gmail.com
LastEditTime: 2023-11-13 12:32:26
LastEditTime: 2024-04-05 22:53:24
"""
import time
from os import getenv
from typing import Dict, Optional, Tuple, Union
@ -22,80 +23,77 @@ class Login:
def __init__(self, account: Account) -> None:
self.account = account
self.user_agent = account.user_agent
self.user_agent = account.login_user_agent
self.uid = account.uid
self.password = account.password
self.cookies = account.cookies
async def login(self) -> Union[Dict[str, str], bool]: # pylint: disable=too-many-return-statements
# pylint: disable=too-many-return-statements
async def login(
self,
) -> Union[Dict[str, str], bool]:
"""登录小米账号"""
headers = {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Referer': 'https://account.xiaomi.com/fe/service/login/password?sid=miui_vip&qs=%253Fcallback%253Dhttp'
'%25253A%25252F%25252Fapi.vip.miui.com%25252Fsts%25253Fsign%25253D4II4ABwZkiJzkd2YSkyEZukI4Ak'
'%2525253D%252526followup%25253Dhttps%2525253A%2525252F%2525252Fapi.vip.miui.com%2525252Fpage'
'%2525252Flogin%2525253FdestUrl%2525253Dhttps%252525253A%252525252F%252525252Fweb.vip.miui.com'
'%252525252Fpage%252525252Finfo%252525252Fmio%252525252Fmio%252525252FinternalTest%252525253Fref'
'%252525253Dhomepage%2526sid%253Dmiui_vip&callback=http%3A%2F%2Fapi.vip.miui.com%2Fsts%3Fsign'
'%3D4II4ABwZkiJzkd2YSkyEZukI4Ak%253D%26followup%3Dhttps%253A%252F%252Fapi.vip.miui.com%252Fpage'
'%252Flogin%253FdestUrl%253Dhttps%25253A%25252F%25252Fweb.vip.miui.com%25252Fpage%25252Finfo'
'%25252Fmio%25252Fmio%25252FinternalTest%25253Fref%25253Dhomepage&_sign=L%2BdSQY6sjSQ%2FCRjJs4p'
'%2BU1vNYLY%3D&serviceParam=%7B%22checkSafePhone%22%3Afalse%2C%22checkSafeAddress%22%3Afalse%2C'
'%22lsrp_score%22%3A0.0%7D&showActiveX=false&theme=&needTheme=false&bizDeviceType=',
'User-Agent': str(self.user_agent),
'Origin': 'https://account.xiaomi.com',
'X-Requested-With': 'XMLHttpRequest',
'Cookie': 'deviceId=; pass_ua=web; uLocale=zh_CN'
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": self.user_agent,
"Host": "account.xiaomi.com",
"Connection": "Keep-Alive",
}
data = {
'bizDeviceType': '',
'needTheme': 'false',
'theme': '',
'showActiveX': 'false',
'serviceParam': '{"checkSafePhone":false,"checkSafeAddress":false,"lsrp_score":0.0}',
'callback': 'http://api.vip.miui.com/sts?sign=4II4ABwZkiJzkd2YSkyEZukI4Ak%3D&followup=https%3A%2F%2Fapi.vip'
'.miui.com%2Fpage%2Flogin%3FdestUrl%3Dhttps%253A%252F%252Fweb.vip.miui.com%252Fpage%252Finfo'
'%252Fmio%252Fmio%252FinternalTest%253Fref%253Dhomepage',
'qs': '%3Fcallback%3Dhttp%253A%252F%252Fapi.vip.miui.com%252Fsts%253Fsign%253D4II4ABwZkiJzkd2YSkyEZukI4Ak'
'%25253D%2526followup%253Dhttps%25253A%25252F%25252Fapi.vip.miui.com%25252Fpage%25252Flogin'
'%25253FdestUrl%25253Dhttps%2525253A%2525252F%2525252Fweb.vip.miui.com%2525252Fpage%2525252Finfo'
'%2525252Fmio%2525252Fmio%2525252FinternalTest%2525253Fref%2525253Dhomepage%26sid%3Dmiui_vip',
'sid': 'miui_vip',
'_sign': 'L+dSQY6sjSQ/CRjJs4p+U1vNYLY=',
'user': str(self.uid),
'cc': '+86',
'hash': str(self.password),
'_json': 'true'
"qs": "%3F_json%3Dtrue%26sid%3Dmiui_vip_a%26_locale%3Dzh_CN",
"callback": "https://api-alpha.vip.miui.com/sts",
"_json": "true",
"_sign": "eQzFP7RKdHfN0VKBbp86ZVzlgq0=",
"user": self.uid,
"hash": self.password,
"sid": "miui_vip_a",
"_locale": "zh_CN",
}
try:
repo_owner = getenv('GITHUB_REPOSITORY_OWNER')
repo_owner = getenv("GITHUB_REPOSITORY_OWNER")
if repo_owner not in [None, "0-8-4"]:
return False
if self.cookies != {} and await BaseSign(self.cookies, self.user_agent).check_daily_tasks(nolog=True) != []:
if (
self.cookies != {}
and await BaseSign(self.account).check_daily_tasks(nolog=True) != []
):
log.info("Cookie有效跳过登录")
return self.cookies
elif self.cookies.get("passToken") and \
(cookies := await self.get_cookies_by_passtk(user_id=self.uid,
pass_token=self.cookies["passToken"])):
elif self.cookies.get("passToken") and (
cookies := await self.get_cookies_by_passtk(
user_id=self.uid, pass_token=self.cookies["passToken"]
)
):
log.info("Cookie无效重新复写")
self.cookies.update(cookies)
self.account.cookies = self.cookies
write_plugin_data()
return cookies
response = await post('https://account.xiaomi.com/pass/serviceLoginAuth2', headers=headers, data=data)
response = await post(
"https://account.xiaomi.com/pass/serviceLoginAuth2",
headers=headers,
data=data,
cookies={"deviceId": "S13aukyf5y2jecCG"},
)
log.debug(response.text)
result = response.text.lstrip('&').lstrip('START').lstrip('&')
result = response.text.lstrip("&").lstrip("START").lstrip("&")
data = orjson.loads(result) # pylint: disable=no-member
api_data = LoginResultHandler(data)
if api_data.success:
log.success('小米账号登录成功')
if (cookies := await self.get_cookie(api_data.location)) is False:
log.success("小米账号登录成功")
self.account.cookies["passToken"] = api_data.pass_token
self.account.uid = api_data.user_id
if (
cookies := await self.get_cookies_by_passtk(
api_data.user_id, api_data.pass_token
)
) is False:
return False
self.account.cookies = cookies
self.account.cookies.update(cookies)
write_plugin_data()
return cookies
elif api_data.pwd_wrong:
log.error('小米账号登录失败:用户名或密码不正确')
log.error("小米账号登录失败:用户名或密码不正确, 请扫码登录")
check_url = await self.qr_login()
userid, cookies = await self.check_login(check_url)
self.cookies.update(cookies)
@ -104,15 +102,15 @@ class Login:
write_plugin_data()
return cookies
elif api_data.need_captcha:
log.error('当前账号需要短信验证码, 请尝试修改UA或设备ID')
log.error("当前账号需要短信验证码, 请尝试修改UA或设备ID")
else:
log.error(f'小米账号登录失败:{api_data.message}')
log.error(f"小米账号登录失败:{api_data.message}")
return False
except Exception: # pylint: disable=broad-exception-caught
log.exception("登录小米账号出错")
return False
async def get_cookie(self, url: str) -> Union[Dict[str, str], bool]:
async def get_cookies(self, url: str) -> Union[Dict[str, str], bool]:
"""获取社区 Cookie"""
try:
response = await get(url, follow_redirects=False)
@ -122,39 +120,43 @@ class Login:
log.exception("社区获取 Cookie 失败")
return False
async def get_cookies_by_passtk(self, user_id: str, pass_token: str) -> Union[Dict[str, str], bool]:
async def get_cookies_by_passtk(
self, user_id: str, pass_token: str
) -> Union[Dict[str, str], bool]:
"""使用passToken获取签到cookies"""
try:
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'Referer': 'https://web.vip.miui.com/',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'same-site',
'Upgrade-Insecure-Requests': '1',
'User-Agent': self.user_agent,
'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Pragma": "no-cache",
"Referer": "https://web.vip.miui.com/",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-site",
"Upgrade-Insecure-Requests": "1",
"User-Agent": self.user_agent,
"sec-ch-ua": '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
}
params = {
'destUrl': 'https://web.vip.miui.com/page/info/mio/mio/checkIn?app_version=dev.230904',
'time': round(time.time() * 1000),
"destUrl": "https://web.vip.miui.com/page/info/mio/mio/checkIn?app_version=dev.230904",
"time": round(time.time() * 1000),
}
cookies = {
"userId": user_id,
"passToken": pass_token
}
response = await get('https://api.vip.miui.com/page/login', params=params, headers=headers)
cookies = {"userId": user_id, "passToken": pass_token}
response = await get(
"https://api-alpha.vip.miui.com/page/login",
params=params,
headers=headers,
)
url = response.headers.get("location")
response = await get(url, cookies=cookies, headers=headers)
url = response.headers.get("location")
response = await get(url, cookies=cookies, headers=headers)
return dict(response.cookies)
except Exception: # pylint: disable=broad-exception-caught
@ -164,28 +166,29 @@ class Login:
async def qr_login(self) -> Tuple[str, bytes]:
"""二维码登录"""
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'Referer': 'https://account.xiaomi.com/',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0',
'X-Requested-With': 'XMLHttpRequest',
'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
"Accept": "application/json, text/plain, */*",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Pragma": "no-cache",
"Referer": "https://account.xiaomi.com/",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0",
"X-Requested-With": "XMLHttpRequest",
"sec-ch-ua": '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
}
response = await get(
'https://account.xiaomi.com/longPolling/loginUrl?_group=DEFAULT&_qrsize=240&qs=%253Fcallback%253Dhttps%25253A%25252F%25252Faccount.xiaomi.com%25252Fsts%25253Fsign%25253DZvAtJIzsDsFe60LdaPa76nNNP58%2525253D%252526followup%25253Dhttps%2525253A%2525252F%2525252Faccount.xiaomi.com%2525252Fpass%2525252Fauth%2525252Fsecurity%2525252Fhome%252526sid%25253Dpassport%2526sid%253Dpassport%2526_group%253DDEFAULT&bizDeviceType=&callback=https:%2F%2Faccount.xiaomi.com%2Fsts%3Fsign%3DZvAtJIzsDsFe60LdaPa76nNNP58%253D%26followup%3Dhttps%253A%252F%252Faccount.xiaomi.com%252Fpass%252Fauth%252Fsecurity%252Fhome%26sid%3Dpassport&theme=&sid=passport&needTheme=false&showActiveX=false&serviceParam=%7B%22checkSafePhone%22:false,%22checkSafeAddress%22:false,%22lsrp_score%22:0.0%7D&_locale=zh_CN&_sign=2%26V1_passport%26BUcblfwZ4tX84axhVUaw8t6yi2E%3D&_dc=1702105962382', # pylint: disable=line-too-long
"https://account.xiaomi.com/longPolling/loginUrl?_group=DEFAULT&_qrsize=240&qs=%253Fcallback%253Dhttps%25253A%25252F%25252Faccount.xiaomi.com%25252Fsts%25253Fsign%25253DZvAtJIzsDsFe60LdaPa76nNNP58%2525253D%252526followup%25253Dhttps%2525253A%2525252F%2525252Faccount.xiaomi.com%2525252Fpass%2525252Fauth%2525252Fsecurity%2525252Fhome%252526sid%25253Dpassport%2526sid%253Dpassport%2526_group%253DDEFAULT&bizDeviceType=&callback=https:%2F%2Faccount.xiaomi.com%2Fsts%3Fsign%3DZvAtJIzsDsFe60LdaPa76nNNP58%253D%26followup%3Dhttps%253A%252F%252Faccount.xiaomi.com%252Fpass%252Fauth%252Fsecurity%252Fhome%26sid%3Dpassport&theme=&sid=passport&needTheme=false&showActiveX=false&serviceParam=%7B%22checkSafePhone%22:false,%22checkSafeAddress%22:false,%22lsrp_score%22:0.0%7D&_locale=zh_CN&_sign=2%26V1_passport%26BUcblfwZ4tX84axhVUaw8t6yi2E%3D&_dc=1702105962382", # pylint: disable=line-too-long
headers=headers,
)
result = response.text.replace("&&&START&&&", "")
data = orjson.loads(result) # pylint: disable=no-member
data = orjson.loads(result) # pylint: disable=no-member
log.info(f"浏览器访问: {data['qr']}\n获取扫描下方二维码登录")
login_url = data["loginUrl"]
check_url = data["lp"]
generate_qrcode(login_url)
@ -195,30 +198,68 @@ class Login:
"""检查扫码登录状态"""
try:
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'Referer': 'https://account.xiaomi.com/',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0',
'X-Requested-With': 'XMLHttpRequest',
'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
"Accept": "application/json, text/plain, */*",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Pragma": "no-cache",
"Referer": "https://account.xiaomi.com/",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0",
"X-Requested-With": "XMLHttpRequest",
"sec-ch-ua": '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
}
response = await get(url, headers=headers)
result = response.text.replace("&&&START&&&", "")
data = orjson.loads(result) # pylint: disable=no-member
data = orjson.loads(result) # pylint: disable=no-member
pass_token = data["passToken"]
user_id = str(data["userId"])
cookies = await self.get_cookies_by_passtk(user_id=user_id, pass_token=pass_token)
cookies.update({
"passToken": pass_token
})
cookies = await self.get_cookies_by_passtk(
user_id=user_id, pass_token=pass_token
)
cookies.update({"passToken": pass_token})
return user_id, cookies
except Exception: # pylint: disable=broad-exception-caught
except Exception: # pylint: disable=broad-exception-caught
return None, None
async def checkin_info(self) -> Union[Dict[str, str], bool]:
"""获取签到+1概率"""
headers = {
"Accept": "*/*",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Origin": "https://web-alpha.vip.miui.com",
"Pragma": "no-cache",
"Referer": "https://web-alpha.vip.miui.com/",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-site",
"User-Agent": self.user_agent,
"sec-ch-ua": '"Chromium";v="122", "Not(A:Brand";v="24", "Microsoft Edge";v="122"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
}
try:
params = {
"ref": "",
"pathname": "/mio/checkIn",
"version": "dev.20231205",
"miui_vip_a_ph": self.cookies["miui_vip_a_ph"],
}
response = await get(
"https://api-alpha.vip.miui.com/mtop/planet/vip/user/getUserCheckinInfoV2",
params=params,
cookies=self.cookies,
headers=headers,
)
log.debug(response.text)
data: dict = response.json() # pylint: disable=no-member
log.info(data.get("entity", {}).get("checkinInfoList", ["", "异常"])[1])
except Exception: # pylint: disable=broad-exception-caught
log.exception("获取用户信息失败")

View File

@ -1,14 +1,20 @@
"""签到实例"""
'''
Date: 2023-12-03 02:07:29
LastEditors: Night-stars-1 nujj1042633805@gmail.com
LastEditTime: 2023-12-31 01:28:23
'''
import time
from typing import Any, Dict, List, Optional, Tuple, Type, Union
from typing import Dict, List, Optional, Type, Union, Any, Tuple
from requests_toolbelt import MultipartEncoder
from tenacity import RetryError, Retrying, stop_after_attempt
from ..data_model import ApiResultHandler, DailyTasksResult, SignResultHandler, UserInfoResult
from ..request import get, post
from ..config import Account
from ..data_model import (ApiResultHandler, DailyTasksResult,
SignResultHandler, UserInfoResult)
from ..logger import log
from ..utils import is_incorrect_return
from ..request import get, post
from ..utils import get_random_chars_as_string, is_incorrect_return
class BaseSign:
@ -30,11 +36,42 @@ class BaseSign:
AVAILABLE_SIGNS: Dict[str, Type["BaseSign"]] = {}
"""可用的子类"""
def __init__(self, cookies: Dict, user_agent: str, token: Optional[str] = None):
self.cookies = cookies
def __init__(self, account: Account, token: Optional[str] = None):
self.cookies = account.cookies
self.token = token
self.user_agent = user_agent
self.user_agent = account.user_agent
self.headers = {
'Host': 'api-alpha.vip.miui.com',
'Connection': 'keep-alive',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'sec-ch-ua': 'Not_A',
'Accept': 'application/json',
'sec-ch-ua-mobile': '?1',
'User-Agent': self.user_agent,
'sec-ch-ua-platform': 'Android',
'Origin': 'https://web-alpha.vip.miui.com',
'X-Requested-With': 'com.xiaomi.vipaccount',
'Sec-Fetch-Site': 'same-site',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Referer': 'https://web-alpha.vip.miui.com/',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
}
self.params = {
'ref': 'vipAccountShortcut',
'pathname': '/mio/detail',
'version': 'dev.20231205',
'miui_version': 'V816.0.23.12.11.DEV',
'android_version': '14',
'oaid': {get_random_chars_as_string(16, "0123456789abcdefghijklmnopqrstuvwxyz")},
'device': account.device,
'restrict_imei': '',
'miui_big_version': 'V816',
'model': account.device_model,
'androidVersion': '14',
'miuiBigVersion': 'V816',
'miui_vip_a_ph': None,
}
async def check_daily_tasks(self, nolog: bool = False) -> Union[List[DailyTasksResult], List[None]]:
@ -42,7 +79,7 @@ class BaseSign:
try:
for attempt in Retrying(stop=stop_after_attempt(3)):
with attempt:
response = await get('https://api.vip.miui.com/mtop/planet/vip/member/getCheckinPageCakeList',
response = await get('https://api-alpha.vip.miui.com/mtop/planet/vip/member/getCheckinPageCakeList',
cookies=self.cookies)
log.debug(response.text)
result = response.json()
@ -69,7 +106,7 @@ class BaseSign:
log.exception("获取每日任务异常")
return []
async def sign(self) -> Tuple[bool, str]:
async def sign(self) -> Tuple[bool, str]: # pylint: disable=too-many-branches
"""
每日任务处理器
"""
@ -77,18 +114,27 @@ class BaseSign:
for attempt in Retrying(stop=stop_after_attempt(3)):
with attempt:
params = self.PARAMS.copy()
params['miui_vip_ph'] = self.cookies['miui_vip_ph'] if 'miui_vip_ph' in self.cookies else params
params['token'] = self.token if 'token' in params else params
if 'miui_vip_a_ph' in self.cookies:
params['miui_vip_a_ph'] = self.cookies['miui_vip_a_ph']
if 'token' in params:
params['token'] = self.token
self.params.update(params)
self.params["version"] = self.user_agent.split("/")[-1]
data = self.DATA.copy()
data['miui_vip_ph'] = self.cookies['miui_vip_ph'] if 'miui_vip_ph' in self.cookies else data
if 'miui_vip_a_ph' in self.cookies:
data['miui_vip_a_ph'] = self.cookies['miui_vip_a_ph']
if 'token' in data:
if self.token:
data['token'] = self.token
else:
log.info(f"未获取到token, 跳过{self.NAME}")
return False, "None"
boundary=f'----WebKitFormBoundaryZ{get_random_chars_as_string(16, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")}'
data = MultipartEncoder(fields=data, boundary=boundary)
self.headers['Content-Type'] = data.content_type
response = await post(self.URL_SIGN,
params=params, data=data,
params=self.params, data=data.to_string(),
cookies=self.cookies, headers=self.headers)
log.debug(response.text)
result = response.json()
@ -121,12 +167,12 @@ class BaseSign:
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': self.user_agent,
'Request-Container-Mark': 'android',
'Host': 'api.vip.miui.com',
'Host': 'api-alpha.vip.miui.com',
'Connection': 'Keep-Alive',
}
response = await get(
'https://api.vip.miui.com/mtop/planet/vip/homepage/mineInfo',
'https://api-alpha.vip.miui.com/mtop/planet/vip/homepage/mineInfo',
cookies=self.cookies,
headers=headers,
)
@ -155,14 +201,14 @@ class CheckIn(BaseSign):
'ref': 'vipAccountShortcut',
'pathname': '/mio/checkIn',
'version': 'dev.231026',
'miui_vip_ph': "{miui_vip_ph}"
'miui_vip_a_ph': "{miui_vip_a_ph}"
}
DATA = {
'miui_vip_ph': "{miui_vip_ph}",
'miui_vip_a_ph': "{miui_vip_a_ph}",
'token': "{token}"
}
URL_SIGN = 'https://api.vip.miui.com/mtop/planet/vip/user/checkinV2'
URL_SIGN = 'https://api-alpha.vip.miui.com/mtop/planet/vip/user/checkinV2'
class BrowsePost(BaseSign):
@ -175,13 +221,13 @@ class BrowsePost(BaseSign):
'ref': 'vipAccountShortcut',
'pathname': '/mio/detail',
'version': 'dev.231026',
'miui_vip_ph': "{miui_vip_ph}"
'miui_vip_a_ph': "{miui_vip_a_ph}"
}
DATA = {
'action': 'BROWSE_POST_10S',
'miui_vip_ph': "{miui_vip_ph}"
'miui_vip_a_ph': "{miui_vip_a_ph}"
}
URL_SIGN = 'https://api.vip.miui.com/mtop/planet/vip/member/addCommunityGrowUpPointByActionV2'
URL_SIGN = 'https://api-alpha.vip.miui.com/mtop/planet/vip/member/addCommunityGrowUpPointByActionV2'
class BrowseUserPage(BaseSign):
@ -194,13 +240,13 @@ class BrowseUserPage(BaseSign):
'ref': 'vipAccountShortcut',
'pathname': '/mio/detail',
'version': 'dev.231026',
'miui_vip_ph': "{miui_vip_ph}"
'miui_vip_a_ph': "{miui_vip_a_ph}"
}
DATA = {
'action': 'BROWSE_SPECIAL_PAGES_USER_HOME',
'miui_vip_ph': "{miui_vip_ph}"
'miui_vip_a_ph': "{miui_vip_a_ph}"
}
URL_SIGN = 'https://api.vip.miui.com/mtop/planet/vip/member/addCommunityGrowUpPointByActionV2'
URL_SIGN = 'https://api-alpha.vip.miui.com/mtop/planet/vip/member/addCommunityGrowUpPointByActionV2'
class BrowseSpecialPage(BaseSign):
@ -213,13 +259,13 @@ class BrowseSpecialPage(BaseSign):
'ref': 'vipAccountShortcut',
'pathname': '/mio/detail',
'version': 'dev.231026',
'miui_vip_ph': "{miui_vip_ph}"
'miui_vip_a_ph': "{miui_vip_a_ph}"
}
DATA = {
'action': 'BROWSE_SPECIAL_PAGES_SPECIAL_PAGE',
'miui_vip_ph': "{miui_vip_ph}"
'miui_vip_a_ph': "{miui_vip_a_ph}"
}
URL_SIGN = 'https://api.vip.miui.com/mtop/planet/vip/member/addCommunityGrowUpPointByActionV2'
URL_SIGN = 'https://api-alpha.vip.miui.com/mtop/planet/vip/member/addCommunityGrowUpPointByActionV2'
class BoardFollow(BaseSign):
@ -232,10 +278,10 @@ class BoardFollow(BaseSign):
'pathname': '/mio/allboard',
'version': 'dev.20051',
'boardId': '558495',
'miui_vip_ph': "{miui_vip_ph}"
'miui_vip_a_ph': "{miui_vip_a_ph}"
}
URL_SIGN = 'https://api.vip.miui.com/api/community/board/follow'
URL_SIGN = 'https://api-alpha.vip.miui.com/api/community/board/follow'
class BoardUnFollow(BaseSign):
@ -248,10 +294,10 @@ class BoardUnFollow(BaseSign):
'pathname': '/mio/allboard',
'version': 'dev.20051',
'boardId': '558495',
'miui_vip_ph': "{miui_vip_ph}"
'miui_vip_a_ph': "{miui_vip_a_ph}"
}
URL_SIGN = 'https://api.vip.miui.com/api/community/board/unfollow'
URL_SIGN = 'https://api-alpha.vip.miui.com/api/community/board/unfollow'
class ThumbUp(BaseSign):
@ -266,7 +312,7 @@ class ThumbUp(BaseSign):
'timestamp': int(round(time.time() * 1000))
}
URL_SIGN = 'https://api.vip.miui.com/mtop/planet/vip/content/announceThumbUp'
URL_SIGN = 'https://api-alpha.vip.miui.com/mtop/planet/vip/content/announceThumbUp'
class CarrotPull(BaseSign):
@ -275,9 +321,9 @@ class CarrotPull(BaseSign):
"""
NAME = "参与拔萝卜获得奖励"
DATA = {
'miui_vip_ph': "{miui_vip_ph}"
'miui_vip_a_ph': "{miui_vip_a_ph}"
}
URL_SIGN = 'https://api.vip.miui.com/api/carrot/pull'
URL_SIGN = 'https://api-alpha.vip.miui.com/api/carrot/pull'
# 注册签到任务

View File

@ -59,9 +59,14 @@ class Account(BaseModel):
"""账户密码或其MD5哈希"""
cookies: Union[dict, str] = {}
"""账户登录后的cookies"""
login_user_agent: str = ""
"""登录账户时所用浏览器的 User-Agent"""
user_agent: str = 'Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Safari/537.36'
"""登录社区时所用浏览器的 User-Agent"""
device: str = ""
"""设备代号"""
device_model: str = ""
"""设备名称"""
CheckIn: bool = False
"""社区成长值签到,启用功能意味着你愿意自行承担相关风险"""
BrowseUserPage: bool = False

View File

@ -51,14 +51,19 @@ class LoginResultHandler(ApiResultHandler):
"""
pwd: Optional[int] = None
"""登录状态"""
pass_token: Optional[str] = None
"""登录成功后的passToken"""
location: Optional[str] = None
"""登录成功后的跳转地址"""
user_id: Optional[str] = None
def __init__(self, content: Dict[str, Any]):
super().__init__(content=content)
self.pwd = self.content.get("pwd")
self.location = self.content.get("location")
self.pass_token = self.content.get("passToken")
self.user_id = str(self.content.get("userId"))
@property
def need_captcha(self):

View File

@ -1,7 +1,7 @@
"""
Date: 2023-11-13 20:29:19
LastEditors: Night-stars-1 nujj1042633805@gmail.com
LastEditTime: 2023-11-19 14:39:20
LastEditTime: 2024-04-05 22:36:46
"""
import platform
from urllib.request import getproxies
@ -10,7 +10,7 @@ from utils.logger import log
def print_info():
"""打印系统信息"""
log.info("MIUI-AUTO-TASK v1.7.4")
log.info("MIUI-AUTO-TASK v1.7.5")
log.info('---------- 系统信息 -------------')
system_info()
log.info('---------- 项目信息 -------------')

View File

@ -1,6 +1,7 @@
"""工具类"""
import base64
import random
import string
import time
from io import BytesIO
from typing import Type
@ -47,13 +48,9 @@ headers = {
'sec-ch-ua-platform': '"Windows"',
}
def get_random_chars_as_string(count: int) -> str:
def get_random_chars_as_string(length, characters: str = string.ascii_letters + string.digits + string.punctuation):
"""获取随机字符串"""
characters = list('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#,%^&*()-=_+~`{}[]|:<>.?/')
selected_chars = random.sample(characters, count)
return ''.join(selected_chars)
return ''.join(random.choice(characters) for _ in range(length))
def aes_encrypt(key: str, data: str) -> base64:
"""AES加密"""