79 lines
2.9 KiB
Python
79 lines
2.9 KiB
Python
import json
|
|
import os
|
|
from contextlib import suppress
|
|
from selenium.webdriver.chromium.options import ChromiumOptions
|
|
|
|
|
|
class ChromeOptions(ChromiumOptions):
|
|
_session = None
|
|
_user_data_dir = None
|
|
|
|
@property
|
|
def user_data_dir(self):
|
|
return self._user_data_dir
|
|
|
|
@user_data_dir.setter
|
|
def user_data_dir(self, path):
|
|
"""Sets the browser profile folder to use. Creates one if missing."""
|
|
abs_path = os.path.abspath(path)
|
|
self._user_data_dir = os.path.normpath(abs_path)
|
|
|
|
@staticmethod
|
|
def _undot_key(key, value):
|
|
"""Turn a (dotted key, value) into a proper nested dict."""
|
|
if "." in key:
|
|
key, rest = key.split(".", 1)
|
|
value = ChromeOptions._undot_key(rest, value)
|
|
return {key: value}
|
|
|
|
@staticmethod
|
|
def _merge_nested(a, b):
|
|
"""Merges b into a, overwriting duplicate leaf values using b."""
|
|
for key in b:
|
|
if key in a:
|
|
if isinstance(a[key], dict) and isinstance(b[key], dict):
|
|
ChromeOptions._merge_nested(a[key], b[key])
|
|
continue
|
|
a[key] = b[key]
|
|
return a
|
|
|
|
def handle_prefs(self, user_data_dir):
|
|
prefs = self.experimental_options.get("prefs")
|
|
if prefs:
|
|
user_data_dir = user_data_dir or self._user_data_dir
|
|
default_path = os.path.join(user_data_dir, "Default")
|
|
os.makedirs(default_path, exist_ok=True)
|
|
undot_prefs = {}
|
|
for key, value in prefs.items():
|
|
undot_prefs = self._merge_nested(
|
|
undot_prefs, self._undot_key(key, value)
|
|
)
|
|
prefs_file = os.path.join(default_path, "Preferences")
|
|
with suppress(Exception):
|
|
if os.path.exists(prefs_file):
|
|
with open(
|
|
prefs_file, encoding="utf-8", mode="r", errors="ignore"
|
|
) as f:
|
|
undot_prefs = self._merge_nested(
|
|
json.load(f), undot_prefs
|
|
)
|
|
with suppress(Exception):
|
|
with open(
|
|
prefs_file, encoding="utf-8", mode="w", errors="ignore"
|
|
) as f:
|
|
json.dump(undot_prefs, f)
|
|
# Remove experimental_options to avoid errors
|
|
del self._experimental_options["prefs"]
|
|
exclude_switches = self.experimental_options.get("excludeSwitches")
|
|
if exclude_switches is not None:
|
|
del self._experimental_options["excludeSwitches"]
|
|
use_auto_ext = self.experimental_options.get("useAutomationExtension")
|
|
if use_auto_ext is not None:
|
|
del self._experimental_options["useAutomationExtension"]
|
|
|
|
@classmethod
|
|
def from_options(cls, options):
|
|
o = cls()
|
|
o.__dict__.update(options.__dict__)
|
|
return o
|