Manage local JSON-backed account state.
| 43 | self.tasks_store = JsonFileStore(settings.tasks_path, default_factory=list) |
| 44 | |
| 45 | def list_accounts(self) -> list[PublicAccountRecord]: |
| 46 | accounts = [AccountRecord.model_validate(item) for item in self.accounts_store.read()] |
| 47 | accounts.sort(key=lambda item: item.updated_at, reverse=True) |
| 48 | return [self.to_public_account(account) for account in accounts] |
| 49 | |
| 50 | def get_account(self, account_id: str) -> AccountRecord: |
| 51 | for item in self.accounts_store.read(): |
| 52 | account = AccountRecord.model_validate(item) |
| 53 | if account.id == account_id: |
| 54 | return account |
| 55 | raise NotFoundError("账号不存在", details={"account_id": account_id}) |
| 56 | |
| 57 | def import_account(self, request: AccountImportRequest) -> PublicAccountRecord: |
| 58 | cookies = self._merge_cookies(request.token, request.cookie_header, request.cookies) |
| 59 | token = (request.token or "").strip() or cookies.get(TOKEN_COOKIE_KEY, "") |
| 60 | if not token: |
| 61 | raise BadRequestError( |
| 62 | f"凭据里缺少 `{TOKEN_COOKIE_KEY}`,后续请求没法发,别整这没头没尾的半截登录态。", |
| 63 | ) |
| 64 | |
| 65 | cookie_header = (request.cookie_header or "").strip() or self._cookies_to_header(cookies) |
| 66 | now = utc_now_iso() |
| 67 | resolved_account_id = {"value": (request.id or "").strip()} |
| 68 | |
| 69 | def updater(records: list[dict[str, Any]]) -> list[dict[str, Any]]: |
| 70 | account_id = resolved_account_id["value"] |
| 71 | index = -1 |
| 72 | if account_id: |
| 73 | for idx, item in enumerate(records): |
| 74 | if item.get("id") == account_id: |
| 75 | index = idx |
| 76 | break |
| 77 | else: |
| 78 | for idx, item in enumerate(records): |
| 79 | if item.get("label") == request.label: |
| 80 | index = idx |
| 81 | account_id = str(item.get("id") or "") |
| 82 | break |
| 83 | if not account_id: |
| 84 | account_id = make_id("acct") |
| 85 | resolved_account_id["value"] = account_id |
| 86 | |
| 87 | existing = records[index] if index >= 0 else None |
| 88 | created_at = str(existing.get("created_at")) if existing else now |
| 89 | last_bootstrap_at = existing.get("last_bootstrap_at") if existing else None |
| 90 | existing_impersonate = str(existing.get("browser_impersonate") or "") if existing else "" |
| 91 | requested_impersonate = (request.browser_impersonate or "").strip() |
| 92 | if requested_impersonate: |
| 93 | browser_impersonate = resolve_browser_impersonate(requested_impersonate) |
| 94 | elif existing_impersonate: |
| 95 | browser_impersonate = resolve_browser_impersonate(existing_impersonate) |
| 96 | else: |
| 97 | browser_impersonate = random_browser_impersonate() |
| 98 | record = AccountRecord( |
| 99 | id=account_id, |
| 100 | label=request.label, |
| 101 | token=token, |
| 102 | cookie_header=cookie_header, |
no outgoing calls
no test coverage detected