config.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. """持久化网页配置:账号数 / 接码 URL / 邮件助手 / CPA 等。"""
  2. from __future__ import annotations
  3. import json
  4. import os
  5. import threading
  6. from dataclasses import asdict, dataclass, field, fields
  7. CONFIG_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "config.local.json")
  8. _LOCK = threading.Lock()
  9. @dataclass
  10. class AppConfig:
  11. # 注册控制
  12. account_count: int = 1
  13. headless: bool = False
  14. # 邮件
  15. mail_helper_url: str = "http://ali.ss5.xyz:17373"
  16. mail_domain: str = "edu.a4sky.com"
  17. mail_poll_interval_sec: int = 4
  18. mail_poll_max_attempts: int = 60 # 4s * 60 = 4min
  19. # PayPal / 接码
  20. phone_e164: str = "+15822201173"
  21. sms_api_url: str = "http://a.62-us.com/api/get_sms?key=a5d3262e05efaba982aba7cfae20b8bc"
  22. # CPA
  23. cpa_url: str = ""
  24. cpa_management_key: str = ""
  25. # 调试
  26. use_promo: bool = True
  27. @classmethod
  28. def load(cls) -> "AppConfig":
  29. if not os.path.exists(CONFIG_PATH):
  30. return cls()
  31. try:
  32. with open(CONFIG_PATH, "r", encoding="utf-8") as f:
  33. raw = json.load(f)
  34. except Exception:
  35. return cls()
  36. valid = {f.name for f in fields(cls)}
  37. cleaned = {k: v for k, v in (raw or {}).items() if k in valid}
  38. return cls(**cleaned)
  39. def save(self):
  40. with _LOCK:
  41. with open(CONFIG_PATH, "w", encoding="utf-8") as f:
  42. json.dump(asdict(self), f, ensure_ascii=False, indent=2)
  43. def update(self, patch: dict) -> "AppConfig":
  44. valid = {f.name for f in fields(self)}
  45. for k, v in (patch or {}).items():
  46. if k not in valid:
  47. continue
  48. current = getattr(self, k)
  49. if isinstance(current, bool):
  50. setattr(self, k, bool(v) if not isinstance(v, str) else v.lower() in ("1", "true", "yes", "on"))
  51. elif isinstance(current, int):
  52. try:
  53. setattr(self, k, int(v))
  54. except Exception:
  55. pass
  56. else:
  57. setattr(self, k, "" if v is None else str(v))
  58. self.save()
  59. return self