chore: 添加cookies登录方式 (#141)

* chore: 从pdm生成requirements.txt
chore: 添加cookies登录方式

* modified:   .github/workflows/docker-image.yml

* chore: 登录成功后写入cookie到配置文件
This commit is contained in:
Night-stars-1 2023-11-13 22:31:39 +08:00 committed by GitHub
parent 56c27977da
commit c5ee4496bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 17 deletions

View File

@ -25,9 +25,24 @@ jobs:
with: with:
python-version: '3.11' python-version: '3.11'
- name: Install PDM
run: |
pip install pdm
- name: Export requirements.txt
run: |
pdm export -f requirements --without-hashes -o requirements.txt
- name: Upload requirements.txt
uses: actions/upload-artifact@v3.1.3
with:
name: requirements.txt
path: requirements.txt
- -
name: run the program once to create the `/data` name: run the program once to create the `/data`
run: python3 miuitask.py run: |
python3 miuitask.py
- -
name: Set up QEMU name: Set up QEMU

View File

@ -1,8 +1,28 @@
onepush # This file is @generated by PDM.
orjson>=3.9.10 # Please do not edit it manually.
loguru>=0.7.2
pydantic>=2.4.2 annotated-types==0.6.0
httpx>=0.25.1 anyio==4.0.0
cryptography>=41.0.5 certifi==2023.7.22
pyyaml>=6.0.1 cffi==1.16.0
tenacity>=8.2.3 charset-normalizer==3.3.2
colorama==0.4.6
cryptography==41.0.5
h11==0.14.0
httpcore==1.0.2
httpx==0.25.1
idna==3.4
loguru==0.7.2
onepush==1.3.0
orjson==3.9.10
pycparser==2.21
pycryptodome==3.19.0
pydantic==2.4.2
pydantic-core==2.10.1
pyyaml==6.0.1
requests==2.31.0
sniffio==1.3.0
tenacity==8.2.3
typing-extensions==4.8.0
urllib3==2.0.7
win32-setctime==1.1.0

View File

@ -7,17 +7,20 @@ import orjson
from typing import Dict, List, Optional, Union from typing import Dict, List, Optional, Union
from ..config import Account from ..config import Account, write_plugin_data
from ..request import get, post from ..request import get, post
from ..logger import log from ..logger import log
from ..data_model import LoginResultHandler from ..data_model import LoginResultHandler
from .sign import BaseSign
class Login: class Login:
def __init__(self, account: Account) -> None: def __init__(self, account: Account) -> None:
self.account = account
self.user_agent = account.user_agent self.user_agent = account.user_agent
self.uid = account.uid self.uid = account.uid
self.password = account.password self.password = account.password
self.cookies = account.cookies
async def login(self) -> Union[Dict[str, str], bool]: async def login(self) -> Union[Dict[str, str], bool]:
headers = { headers = {
@ -59,6 +62,9 @@ class Login:
'_json': 'true' '_json': 'true'
} }
try: try:
if self.cookies != {} and await BaseSign(self.cookies).check_daily_tasks(nolog=True) != []:
log.info("Cookie有效跳过登录")
return self.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)
log.debug(response.text) log.debug(response.text)
result = response.text.lstrip('&').lstrip('START').lstrip('&') result = response.text.lstrip('&').lstrip('START').lstrip('&')
@ -67,6 +73,8 @@ class Login:
if api_data.success: if api_data.success:
log.success('小米账号登录成功') log.success('小米账号登录成功')
cookies = await self.get_cookie(api_data.location) cookies = await self.get_cookie(api_data.location)
self.account.cookies = cookies
write_plugin_data()
return cookies return cookies
elif not api_data.pwd_wrong: elif not api_data.pwd_wrong:
log.error('小米账号登录失败:' + api_data.message) log.error('小米账号登录失败:' + api_data.message)

View File

@ -32,7 +32,7 @@ class BaseSign:
self.headers = { self.headers = {
} }
async def check_daily_tasks(self) -> 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', response = await get('https://api.vip.miui.com/mtop/planet/vip/member/getCheckinPageCakeList',
cookies=self.cookie) cookies=self.cookie)
@ -49,10 +49,10 @@ class BaseSign:
task_status.append(DailyTasksResult(name=task_name, showType=showType, desc=task_desc)) task_status.append(DailyTasksResult(name=task_name, showType=showType, desc=task_desc))
return task_status return task_status
else: else:
log.error("获取每日任务状态失败:" + api_data.message) log.error("获取每日任务状态失败:" + api_data.message) if not nolog else None
return [] return []
except Exception as e: except Exception:
log.exception("获取每日任务异常") log.exception("获取每日任务异常") if not nolog else None
return [] return []
async def sign(self) -> bool: async def sign(self) -> bool:

View File

@ -1,7 +1,7 @@
import os import os
import orjson import orjson
from pathlib import Path from pathlib import Path
from typing import Dict, List, Optional from typing import Dict, List, Optional, Union
from hashlib import md5 from hashlib import md5
import yaml import yaml
@ -21,12 +21,20 @@ CONFIG_PATH = DATA_PATH / "config.yaml"
def md5_crypto(passwd: str) -> str: def md5_crypto(passwd: str) -> str:
return md5(passwd.encode('utf8')).hexdigest().upper() return md5(passwd.encode('utf8')).hexdigest().upper()
def cookies_to_dict(cookies):
cookies_dict = {}
for cookie in cookies.split(';'):
key, value = cookie.strip().split('=', 1) # 分割键和值
cookies_dict[key] = value
return cookies_dict
class Account(BaseModel): class Account(BaseModel):
uid: str = "100000" uid: str = "100000"
"""账户ID 非账户用户名或手机号""" """账户ID 非账户用户名或手机号"""
password: str = "" password: str = ""
"""账户密码或其MD5哈希""" """账户密码或其MD5哈希"""
cookies: Union[dict, str] = {}
"""账户登录后的cookies"""
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: 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""" """登录社区时所用浏览器的 User-Agent"""
@ -47,14 +55,20 @@ class Account(BaseModel):
"""社区拔萝卜,启用功能意味着你愿意自行承担相关风险""" """社区拔萝卜,启用功能意味着你愿意自行承担相关风险"""
@validator("password", allow_reuse=True) @validator("password", allow_reuse=True)
def _(cls, v: Optional[str]): def _password(cls, v: Optional[str]):
if len(v) == 32: if len(v) == 32:
return v return v
return md5_crypto(v) return md5_crypto(v)
@validator("cookies", allow_reuse=True)
def _cookies(cls, v: Union[dict, str]):
if type(v) == str:
return cookies_to_dict(v)
return v
class OnePush(BaseModel): class OnePush(BaseModel):
notifier: str = "" notifier: Union[str, bool] = ""
"""是否开启消息推送""" """是否开启消息推送"""
params: Dict = { params: Dict = {
"title": "", "title": "",