Files
account-manager/scripts/service/chrome_profile_prefs.py
chendelian b93b2ea36e
Some checks failed
技能自动化发布 / release (push) Has been cancelled
fix: reuse browser, harden session restore without URL clash (v2.0.27)
2026-09-15 11:46:08 +08:00

129 lines
4.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Chrome/Edge 独立 Profile:启用「继续上次会话」,让 Session Cookie 可跨次打开保留。"""
from __future__ import annotations
import json
import os
from typing import Any, Dict
from util.logging_config import get_skill_logger
RESTORE_CONTINUE_WHERE_LEFT_OFF = 1
def preferences_path(profile_dir: str) -> str:
return os.path.join(os.path.abspath(profile_dir), "Default", "Preferences")
def local_state_path(profile_dir: str) -> str:
return os.path.join(os.path.abspath(profile_dir), "Local State")
def _patch_preferences_dict(data: Dict[str, Any]) -> Dict[str, Any]:
before = int((data.get("session") or {}).get("restore_on_startup") or 0)
exit_before = str((data.get("profile") or {}).get("exit_type") or "")
session = data.setdefault("session", {})
session["restore_on_startup"] = RESTORE_CONTINUE_WHERE_LEFT_OFF
session.pop("startup_urls", None)
profile = data.setdefault("profile", {})
if str(profile.get("exit_type") or "").lower() == "crashed":
profile["exit_type"] = "Normal"
profile["exited_cleanly"] = True
browser = data.setdefault("browser", {})
browser["has_seen_welcome_page"] = True
browser["check_default_browser"] = False
return {"restore_before": before, "exit_type_before": exit_before}
def _patch_local_state(profile_dir: str, log) -> Dict[str, Any]:
path = local_state_path(profile_dir)
if not os.path.isfile(path):
return {"ok": True, "skipped": True, "path": path}
try:
with open(path, "r", encoding="utf-8") as fh:
data = json.load(fh)
except Exception as exc:
log.warning("chrome_local_state_read_failed path=%s err=%s", path, exc)
return {"ok": False, "path": path, "error": str(exc)}
profile = data.setdefault("profile", {})
info = profile.setdefault("info_cache", {}).setdefault("Default", {})
info["active_time"] = float(info.get("active_time") or 0.0) or 1.0
exited = profile.get("exited_cleanly", True)
profile["exited_cleanly"] = True
try:
with open(path, "w", encoding="utf-8") as fh:
json.dump(data, fh, ensure_ascii=False, separators=(",", ":"))
except Exception as exc:
log.warning("chrome_local_state_write_failed path=%s err=%s", path, exc)
return {"ok": False, "path": path, "error": str(exc), "exited_cleanly_before": exited}
log.info("chrome_local_state_patched path=%s exited_cleanly %s->True", path, exited)
return {"ok": True, "path": path, "exited_cleanly_before": exited}
def ensure_session_restore(profile_dir: str) -> Dict[str, Any]:
"""启动浏览器前写入 session.restore_on_startup=1;清 startup_urls;Local State 干净退出。"""
log = get_skill_logger()
profile_abs = os.path.abspath(profile_dir)
prefs = preferences_path(profile_abs)
os.makedirs(os.path.dirname(prefs), exist_ok=True)
data: Dict[str, Any] = {}
existed = os.path.isfile(prefs)
if existed:
try:
with open(prefs, "r", encoding="utf-8") as fh:
data = json.load(fh)
except Exception:
log.exception("chrome_prefs_read_failed path=%s", prefs)
data = {}
meta = _patch_preferences_dict(data)
before = int(meta["restore_before"])
exit_before = str(meta["exit_type_before"] or "")
try:
with open(prefs, "w", encoding="utf-8") as fh:
json.dump(data, fh, ensure_ascii=False, separators=(",", ":"))
except Exception as exc:
log.warning("chrome_prefs_write_failed path=%s err=%s", prefs, exc)
return {
"ok": False,
"path": prefs,
"existed": existed,
"restore_before": before,
"restore_after": before,
"exit_type_before": exit_before,
"error": str(exc),
}
after = int((data.get("session") or {}).get("restore_on_startup") or 0)
exit_after = str((data.get("profile") or {}).get("exit_type") or "")
local = _patch_local_state(profile_abs, log)
log.info(
"chrome_session_restore_ensured profile_dir=%s prefs=%s existed=%s "
"restore_on_startup %s->%s exit_type %s->%s local_state=%s",
profile_abs,
prefs,
existed,
before,
after,
exit_before or "-",
exit_after or "-",
local,
)
return {
"ok": True,
"path": prefs,
"existed": existed,
"restore_before": before,
"restore_after": after,
"exit_type_before": exit_before,
"exit_type_after": exit_after,
"local_state": local,
}