# -*- coding: utf-8 -*- """account ensure-web — pick if present, otherwise add-web then pick.""" from typing import Optional from db.accounts_repo import count_active_accounts from db.connection import get_conn, init_db from service._svc_common import PlatformCallerMeta, _err_json, _resolve_or_auto_register, _say from service.account_add_commands import create_web_account_record from service.account_query_commands import cmd_account_pick_web from util.logging_config import get_skill_logger from util.platforms import seed_platforms def cmd_account_ensure_web( platform_input: str, *, login_id: Optional[str] = None, login_id_type: str = "unknown", label: Optional[str] = None, tenant_id: Optional[str] = None, environment: Optional[str] = None, role: Optional[str] = None, provider_code: Optional[str] = None, url: Optional[str] = None, extra_json_str: Optional[str] = None, profile_dir_override: Optional[str] = None, auth_strategy: Optional[str] = None, session_persistent: Optional[int] = None, device_fingerprint: Optional[str] = None, do_lease: bool = False, ttl_sec: int = 900, holder: Optional[str] = None, purpose: Optional[str] = None, platform_meta: Optional[PlatformCallerMeta] = None, ) -> None: """Pick a web account; if none exist for filters, create one then pick. Does NOT create a new account when matching accounts exist but are all leased. Success stdout matches ``account pick-web`` (plus ``account_ensured`` when created). """ log = get_skill_logger() log.info( "account_ensure_web_attempt platform=%s env=%s tenant=%s role=%s lease=%s", platform_input, environment, tenant_id, role, do_lease, ) key = _resolve_or_auto_register(platform_input, platform_meta) if not key: return init_db() conn = get_conn() try: seed_platforms(conn) finally: conn.close() existing_count = count_active_accounts( platform_key=key, environment=environment, tenant_id=tenant_id, role=role, ) created = False if existing_count == 0: create_env = (environment or "").strip() or "production" create_role = (role or "").strip() or "default" create_label = (label or "").strip() or None if not create_label: create_label = f"{key} 默认" created_payload = create_web_account_record( platform_input, login_id, login_id_type, create_label, tenant_id, create_env, create_role, provider_code, url, extra_json_str, profile_dir_override, auth_strategy=auth_strategy, session_persistent=session_persistent, device_fingerprint=device_fingerprint, platform_meta=platform_meta, platform_key=key, ) if not created_payload: return created = True log.info( "account_ensure_web_created id=%s platform=%s profile_dir=%s", created_payload.get("id"), key, created_payload.get("profile_dir"), ) else: log.info( "account_ensure_web_reuse platform=%s existing_active=%s", key, existing_count, ) # Capture pick output so we can annotate / remap lease-busy errors. import io import json import sys buf = io.StringIO() old_out = sys.stdout sys.stdout = buf try: cmd_account_pick_web( platform_input, environment=environment, tenant_id=tenant_id, role=role, do_lease=do_lease, ttl_sec=ttl_sec, holder=holder, purpose=purpose, platform_meta=platform_meta, ) finally: sys.stdout = old_out raw = buf.getvalue().strip() if not raw: _say(_err_json("ERROR:NO_ACCOUNT", "ensure 后未能挑选到账号。")) return try: payload = json.loads(raw) except json.JSONDecodeError: _say(raw) return if isinstance(payload, dict) and payload.get("success") is False: err = (payload.get("error") or {}) if isinstance(payload.get("error"), dict) else {} code = str(err.get("code") or "") if code == "ERROR:NO_ACCOUNT" and existing_count > 0 and not created: _say(_err_json( "ERROR:LEASE_CONFLICT", "该平台下已有账号,但均被其他任务占用。请稍后重试或释放租约;不会自动新建账号。", )) return _say(raw) return if isinstance(payload, dict) and created: payload["account_ensured"] = True _say(json.dumps(payload, ensure_ascii=False)) return _say(raw)