优化 gui 不急
This commit is contained in:
+115
@@ -0,0 +1,115 @@
|
||||
"""GUI本地状态存储。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from douyu.config import Account, ProxyConfig
|
||||
from douyu.email_verifier import get_email_config_for_account
|
||||
|
||||
|
||||
DEFAULT_STATE_PATH = Path("data/gui_state.json")
|
||||
|
||||
|
||||
def account_to_dict(account: Account) -> dict[str, Any]:
|
||||
"""把账号对象转换成可保存的字典。"""
|
||||
return {
|
||||
"username": account.username,
|
||||
"password": account.password,
|
||||
"email": account.email,
|
||||
"email_password": account.email_password,
|
||||
"email_imap_server": account.email_imap_server,
|
||||
"email_imap_port": account.email_imap_port,
|
||||
}
|
||||
|
||||
|
||||
def account_from_dict(data: dict[str, Any]) -> Account | None:
|
||||
"""从本地状态恢复账号对象。"""
|
||||
username = str(data.get("username", "")).strip()
|
||||
password = str(data.get("password", "")).strip()
|
||||
email = str(data.get("email", "")).strip()
|
||||
email_password = str(data.get("email_password", "")).strip()
|
||||
|
||||
if not all([username, password, email, email_password]):
|
||||
return None
|
||||
|
||||
email_config = get_email_config_for_account(email)
|
||||
imap_server = str(data.get("email_imap_server") or email_config["server"]).strip()
|
||||
try:
|
||||
imap_port = int(data.get("email_imap_port") or email_config["port"])
|
||||
except (TypeError, ValueError):
|
||||
imap_port = int(email_config["port"])
|
||||
|
||||
return Account(
|
||||
username=username,
|
||||
password=password,
|
||||
email=email,
|
||||
email_password=email_password,
|
||||
email_imap_server=imap_server,
|
||||
email_imap_port=imap_port,
|
||||
)
|
||||
|
||||
|
||||
class GuiStateStore:
|
||||
"""负责保存和读取GUI状态。"""
|
||||
|
||||
def __init__(self, path: str | Path = DEFAULT_STATE_PATH):
|
||||
self.path = Path(path)
|
||||
|
||||
def load(self) -> dict[str, Any]:
|
||||
"""读取本地状态文件。"""
|
||||
if not self.path.exists():
|
||||
return {}
|
||||
|
||||
try:
|
||||
with self.path.open("r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
return data if isinstance(data, dict) else {}
|
||||
except Exception as exc:
|
||||
logger.warning(f"读取GUI状态失败,将使用默认值: {exc}")
|
||||
return {}
|
||||
|
||||
def save(self, state: dict[str, Any]) -> None:
|
||||
"""原子写入本地状态文件。"""
|
||||
self.path.parent.mkdir(parents=True, exist_ok=True)
|
||||
tmp_path = self.path.with_suffix(f"{self.path.suffix}.tmp")
|
||||
|
||||
with tmp_path.open("w", encoding="utf-8") as f:
|
||||
json.dump(state, f, ensure_ascii=False, indent=2)
|
||||
|
||||
tmp_path.replace(self.path)
|
||||
|
||||
@staticmethod
|
||||
def accounts_from_state(state: dict[str, Any]) -> list[Account]:
|
||||
"""从状态字典恢复账号列表。"""
|
||||
accounts = []
|
||||
raw_accounts = state.get("accounts", [])
|
||||
if not isinstance(raw_accounts, list):
|
||||
return accounts
|
||||
|
||||
for raw_account in raw_accounts:
|
||||
if not isinstance(raw_account, dict):
|
||||
continue
|
||||
account = account_from_dict(raw_account)
|
||||
if account:
|
||||
accounts.append(account)
|
||||
|
||||
return accounts
|
||||
|
||||
@staticmethod
|
||||
def proxy_from_state(state: dict[str, Any]) -> ProxyConfig:
|
||||
"""从状态字典恢复代理配置。"""
|
||||
proxy = state.get("proxy", {})
|
||||
if not isinstance(proxy, dict):
|
||||
return ProxyConfig()
|
||||
|
||||
return ProxyConfig(
|
||||
enabled=bool(proxy.get("enabled", False)),
|
||||
api_url=str(proxy.get("api_url", "")).strip(),
|
||||
http=str(proxy.get("http", "")).strip(),
|
||||
https=str(proxy.get("https", "")).strip(),
|
||||
)
|
||||
Reference in New Issue
Block a user