feat: expand module workflows, dynamic config, notifications and console API
This commit is contained in:
@@ -65,6 +65,11 @@ class BrowserCookieStore:
|
||||
|
||||
def load_cookies(self) -> list[dict[str, Any]]:
|
||||
payload = self._read(self.cookie_file, default=[])
|
||||
# A few legacy collectors persisted ``{"cookies": [...], ...}``
|
||||
# envelopes instead of the canonical Playwright list. Read those
|
||||
# envelopes compatibly, while all new writes remain canonical lists.
|
||||
if isinstance(payload, dict) and isinstance(payload.get("cookies"), list):
|
||||
payload = payload["cookies"]
|
||||
if not isinstance(payload, list) or not all(isinstance(item, dict) for item in payload):
|
||||
raise ValueError("browser cookie file must contain a list of objects")
|
||||
return payload
|
||||
@@ -95,3 +100,60 @@ class BrowserCookieStore:
|
||||
return json.loads(path.read_text(encoding="utf-8"))
|
||||
except (OSError, json.JSONDecodeError) as exc:
|
||||
raise ValueError(f"cannot read browser state file: {path.name}") from exc
|
||||
|
||||
|
||||
def restore_browser_state(
|
||||
context: Any,
|
||||
*,
|
||||
cookie_file: str | Path | None = None,
|
||||
storage_state_file: str | Path | None = None,
|
||||
restore_origins: bool = True,
|
||||
) -> None:
|
||||
"""Restore an account or binding snapshot into an existing context.
|
||||
|
||||
Persistent Scrapling contexts keep their own Profile, while account vaults
|
||||
are the shared login authority. Direct Scrapling scripts therefore need a
|
||||
small explicit restore step before their first authenticated navigation.
|
||||
"""
|
||||
|
||||
store = BrowserCookieStore(
|
||||
Path(cookie_file) if cookie_file else Path(),
|
||||
Path(storage_state_file) if storage_state_file else Path(),
|
||||
) if cookie_file and storage_state_file else None
|
||||
if store is None:
|
||||
return
|
||||
|
||||
state = store.load_storage_state() if store.storage_state_file.exists() else None
|
||||
setter = getattr(context, "set_storage_state", None)
|
||||
adder = getattr(context, "add_cookies", None)
|
||||
if state and callable(setter):
|
||||
state_to_restore = state
|
||||
if not restore_origins:
|
||||
state_to_restore = {
|
||||
"cookies": list(state.get("cookies", []))
|
||||
if isinstance(state.get("cookies"), list)
|
||||
else []
|
||||
}
|
||||
setter(state_to_restore)
|
||||
elif state and callable(adder) and isinstance(state.get("cookies"), list):
|
||||
adder(state["cookies"])
|
||||
|
||||
cookies = store.load_cookies() if store.cookie_file.exists() else []
|
||||
if cookies and callable(adder):
|
||||
adder(cookies)
|
||||
|
||||
|
||||
def persist_browser_state(
|
||||
context: Any,
|
||||
*,
|
||||
cookie_file: str | Path,
|
||||
storage_state_file: str | Path,
|
||||
) -> int:
|
||||
"""Persist a verified context snapshot and return its cookie count."""
|
||||
|
||||
cookies = context.cookies()
|
||||
storage_state = context.storage_state()
|
||||
store = BrowserCookieStore(Path(cookie_file), Path(storage_state_file))
|
||||
store.save_cookies(cookies)
|
||||
store.save_storage_state(storage_state)
|
||||
return len(cookies)
|
||||
|
||||
Reference in New Issue
Block a user