Updated script that can be controled by Nodejs web app
This commit is contained in:
@ -0,0 +1 @@
|
||||
__version__ = "4.0.2"
|
Binary file not shown.
Binary file not shown.
55
lib/python3.13/site-packages/webdriver_manager/chrome.py
Normal file
55
lib/python3.13/site-packages/webdriver_manager/chrome.py
Normal file
@ -0,0 +1,55 @@
|
||||
import os
|
||||
from typing import Optional
|
||||
|
||||
from webdriver_manager.core.download_manager import DownloadManager
|
||||
from webdriver_manager.core.driver_cache import DriverCacheManager
|
||||
from webdriver_manager.core.manager import DriverManager
|
||||
from webdriver_manager.core.os_manager import OperationSystemManager, ChromeType
|
||||
from webdriver_manager.drivers.chrome import ChromeDriver
|
||||
|
||||
|
||||
class ChromeDriverManager(DriverManager):
|
||||
def __init__(
|
||||
self,
|
||||
driver_version: Optional[str] = None,
|
||||
name: str = "chromedriver",
|
||||
url: str = "https://chromedriver.storage.googleapis.com",
|
||||
latest_release_url: str = "https://chromedriver.storage.googleapis.com/LATEST_RELEASE",
|
||||
chrome_type: str = ChromeType.GOOGLE,
|
||||
download_manager: Optional[DownloadManager] = None,
|
||||
cache_manager: Optional[DriverCacheManager] = None,
|
||||
os_system_manager: Optional[OperationSystemManager] = None
|
||||
):
|
||||
super().__init__(
|
||||
download_manager=download_manager,
|
||||
cache_manager=cache_manager,
|
||||
os_system_manager=os_system_manager
|
||||
)
|
||||
|
||||
self.driver = ChromeDriver(
|
||||
name=name,
|
||||
driver_version=driver_version,
|
||||
url=url,
|
||||
latest_release_url=latest_release_url,
|
||||
chrome_type=chrome_type,
|
||||
http_client=self.http_client,
|
||||
os_system_manager=os_system_manager
|
||||
)
|
||||
|
||||
def install(self) -> str:
|
||||
driver_path = self._get_driver_binary_path(self.driver)
|
||||
os.chmod(driver_path, 0o755)
|
||||
return driver_path
|
||||
|
||||
def get_os_type(self):
|
||||
os_type = super().get_os_type()
|
||||
if "win" in os_type:
|
||||
return "win32"
|
||||
|
||||
if not self._os_system_manager.is_mac_os(os_type):
|
||||
return os_type
|
||||
|
||||
if self._os_system_manager.is_arch(os_type):
|
||||
return "mac_arm64"
|
||||
|
||||
return os_type
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,23 @@
|
||||
import os
|
||||
import zipfile
|
||||
|
||||
|
||||
class LinuxZipFileWithPermissions(zipfile.ZipFile):
|
||||
"""Class for extract files in linux with right permissions"""
|
||||
|
||||
def extract(self, member, path=None, pwd=None):
|
||||
if not isinstance(member, zipfile.ZipInfo):
|
||||
member = self.getinfo(member)
|
||||
|
||||
if path is None:
|
||||
path = os.getcwd()
|
||||
|
||||
ret_val = self._extract_member(member, path, pwd) # noqa
|
||||
attr = member.external_attr >> 16
|
||||
os.chmod(ret_val, attr)
|
||||
return ret_val
|
||||
|
||||
|
||||
class Archive(object):
|
||||
def __init__(self, path: str):
|
||||
self.file_path = path
|
@ -0,0 +1,41 @@
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
|
||||
def str2bool(value):
|
||||
return value.lower() in ['true', '1']
|
||||
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
||||
def ssl_verify():
|
||||
return str2bool(os.getenv("WDM_SSL_VERIFY", "true"))
|
||||
|
||||
|
||||
def gh_token():
|
||||
return os.getenv("GH_TOKEN", None)
|
||||
|
||||
|
||||
def wdm_local():
|
||||
return str2bool(os.getenv("WDM_LOCAL", "false"))
|
||||
|
||||
|
||||
def wdm_log_level():
|
||||
default_level = 20
|
||||
try:
|
||||
return int(os.getenv("WDM_LOG", default_level))
|
||||
except Exception:
|
||||
return default_level
|
||||
|
||||
|
||||
def wdm_progress_bar():
|
||||
default_level = 1
|
||||
try:
|
||||
return int(os.getenv("WDM_PROGRESS_BAR", default_level))
|
||||
except Exception:
|
||||
return default_level
|
||||
|
||||
|
||||
def get_xdist_worker_id():
|
||||
return os.getenv("PYTEST_XDIST_WORKER", '')
|
@ -0,0 +1,7 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
ROOT_FOLDER_NAME = ".wdm"
|
||||
DEFAULT_PROJECT_ROOT_CACHE_PATH = os.path.join(sys.path[0], ROOT_FOLDER_NAME)
|
||||
DEFAULT_USER_HOME_CACHE_PATH = os.path.join(
|
||||
os.path.expanduser("~"), ROOT_FOLDER_NAME)
|
@ -0,0 +1,42 @@
|
||||
import os
|
||||
from abc import ABC
|
||||
|
||||
from webdriver_manager.core.file_manager import File
|
||||
from webdriver_manager.core.http import WDMHttpClient
|
||||
from webdriver_manager.core.logger import log
|
||||
|
||||
|
||||
class DownloadManager(ABC):
|
||||
def __init__(self, http_client):
|
||||
self._http_client = http_client
|
||||
|
||||
def download_file(self, url: str) -> File:
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
def http_client(self):
|
||||
return self._http_client
|
||||
|
||||
|
||||
class WDMDownloadManager(DownloadManager):
|
||||
def __init__(self, http_client=None):
|
||||
if http_client is None:
|
||||
http_client = WDMHttpClient()
|
||||
super().__init__(http_client)
|
||||
|
||||
def download_file(self, url: str) -> File:
|
||||
log(f"About to download new driver from {url}")
|
||||
response = self._http_client.get(url)
|
||||
log(f"Driver downloading response is {response.status_code}")
|
||||
file_name = self.extract_filename_from_url(url)
|
||||
return File(response, file_name)
|
||||
|
||||
@staticmethod
|
||||
def extract_filename_from_url(url):
|
||||
# Split the URL by '/'
|
||||
url_parts = url.split('/')
|
||||
# Get the last part of the URL, which should be the filename
|
||||
filename = url_parts[-1]
|
||||
# Decode the URL-encoded filename
|
||||
filename = os.path.basename(filename)
|
||||
return filename
|
@ -0,0 +1,77 @@
|
||||
from webdriver_manager.core.logger import log
|
||||
from webdriver_manager.core.config import gh_token
|
||||
from webdriver_manager.core.os_manager import OperationSystemManager
|
||||
|
||||
|
||||
class Driver(object):
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
driver_version_to_download,
|
||||
url,
|
||||
latest_release_url,
|
||||
http_client,
|
||||
os_system_manager):
|
||||
self._name = name
|
||||
self._url = url
|
||||
self._latest_release_url = latest_release_url
|
||||
self._http_client = http_client
|
||||
self._browser_version = None
|
||||
self._driver_version_to_download = driver_version_to_download
|
||||
self._os_system_manager = os_system_manager
|
||||
if not self._os_system_manager:
|
||||
self._os_system_manager = OperationSystemManager()
|
||||
|
||||
@property
|
||||
def auth_header(self):
|
||||
token = gh_token()
|
||||
if token:
|
||||
log("GH_TOKEN will be used to perform requests")
|
||||
return {"Authorization": f"token {token}"}
|
||||
return None
|
||||
|
||||
def get_name(self):
|
||||
return self._name
|
||||
|
||||
def get_driver_download_url(self, os_type):
|
||||
return f"{self._url}/{self.get_driver_version_to_download()}/{self._name}_{os_type}.zip"
|
||||
|
||||
def get_driver_version_to_download(self):
|
||||
"""
|
||||
Downloads version from parameter if version not None or "latest".
|
||||
Downloads latest, if version is "latest" or browser could not been determined.
|
||||
Downloads determined browser version driver in all other ways as a bonus fallback for lazy users.
|
||||
"""
|
||||
if self._driver_version_to_download:
|
||||
return self._driver_version_to_download
|
||||
|
||||
return self.get_latest_release_version()
|
||||
|
||||
def get_latest_release_version(self):
|
||||
# type: () -> str
|
||||
raise NotImplementedError("Please implement this method")
|
||||
|
||||
def get_browser_version_from_os(self):
|
||||
"""
|
||||
Use-cases:
|
||||
- for key in metadata;
|
||||
- for printing nice logs;
|
||||
- for fallback if version was not set at all.
|
||||
Note: the fallback may have collisions in user cases when previous browser was not uninstalled properly.
|
||||
"""
|
||||
if self._browser_version is None:
|
||||
self._browser_version = self._os_system_manager.get_browser_version_from_os(self.get_browser_type())
|
||||
return self._browser_version
|
||||
|
||||
def get_browser_type(self):
|
||||
raise NotImplementedError("Please implement this method")
|
||||
|
||||
def get_binary_name(self, os_type):
|
||||
driver_name = self.get_name()
|
||||
driver_binary_name = (
|
||||
"msedgedriver" if driver_name == "edgedriver" else driver_name
|
||||
)
|
||||
driver_binary_name = (
|
||||
f"{driver_binary_name}.exe" if "win" in os_type else driver_binary_name
|
||||
)
|
||||
return driver_binary_name
|
@ -0,0 +1,164 @@
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
|
||||
from webdriver_manager.core.config import wdm_local, get_xdist_worker_id
|
||||
from webdriver_manager.core.constants import (
|
||||
DEFAULT_PROJECT_ROOT_CACHE_PATH,
|
||||
DEFAULT_USER_HOME_CACHE_PATH, ROOT_FOLDER_NAME,
|
||||
)
|
||||
from webdriver_manager.core.driver import Driver
|
||||
from webdriver_manager.core.file_manager import FileManager, File
|
||||
from webdriver_manager.core.logger import log
|
||||
from webdriver_manager.core.os_manager import OperationSystemManager
|
||||
from webdriver_manager.core.utils import get_date_diff
|
||||
|
||||
|
||||
class DriverCacheManager(object):
|
||||
def __init__(self, root_dir=None, valid_range=1, file_manager=None):
|
||||
self._root_dir = DEFAULT_USER_HOME_CACHE_PATH
|
||||
is_wdm_local = wdm_local()
|
||||
xdist_worker_id = get_xdist_worker_id()
|
||||
if xdist_worker_id:
|
||||
log(f"xdist worker is: {xdist_worker_id}")
|
||||
self._root_dir = os.path.join(self._root_dir, xdist_worker_id)
|
||||
|
||||
if root_dir:
|
||||
self._root_dir = os.path.join(root_dir, ROOT_FOLDER_NAME, xdist_worker_id)
|
||||
|
||||
if is_wdm_local:
|
||||
self._root_dir = os.path.join(DEFAULT_PROJECT_ROOT_CACHE_PATH, xdist_worker_id)
|
||||
|
||||
self._drivers_root = "drivers"
|
||||
self._drivers_json_path = os.path.join(self._root_dir, "drivers.json")
|
||||
self._date_format = "%d/%m/%Y"
|
||||
self._drivers_directory = os.path.join(self._root_dir, self._drivers_root)
|
||||
self._cache_valid_days_range = valid_range
|
||||
self._cache_key_driver_version = None
|
||||
self._metadata_key = None
|
||||
self._driver_binary_path = None
|
||||
self._file_manager = file_manager
|
||||
self._os_system_manager = OperationSystemManager()
|
||||
if not self._file_manager:
|
||||
self._file_manager = FileManager(self._os_system_manager)
|
||||
|
||||
def save_archive_file(self, file: File, path):
|
||||
return self._file_manager.save_archive_file(file, path)
|
||||
|
||||
def unpack_archive(self, archive, path):
|
||||
return self._file_manager.unpack_archive(archive, path)
|
||||
|
||||
def save_file_to_cache(self, driver: Driver, file: File):
|
||||
path = self.__get_path(driver)
|
||||
archive = self.save_archive_file(file, path)
|
||||
files = self.unpack_archive(archive, path)
|
||||
binary = self.__get_binary(files, driver.get_name())
|
||||
binary_path = os.path.join(path, binary)
|
||||
self.__save_metadata(driver, binary_path)
|
||||
log(f"Driver has been saved in cache [{path}]")
|
||||
return binary_path
|
||||
|
||||
def __get_binary(self, files, driver_name):
|
||||
if not files:
|
||||
raise Exception(f"Can't find binary for {driver_name} among {files}")
|
||||
|
||||
if len(files) == 1:
|
||||
return files[0]
|
||||
|
||||
for f in files:
|
||||
if 'LICENSE' in f:
|
||||
continue
|
||||
if 'THIRD_PARTY' in f:
|
||||
continue
|
||||
if driver_name in f:
|
||||
return f
|
||||
|
||||
raise Exception(f"Can't find binary for {driver_name} among {files}")
|
||||
|
||||
def __save_metadata(self, driver: Driver, binary_path, date=None):
|
||||
if date is None:
|
||||
date = datetime.date.today()
|
||||
|
||||
metadata = self.load_metadata_content()
|
||||
key = self.__get_metadata_key(driver)
|
||||
data = {
|
||||
key: {
|
||||
"timestamp": date.strftime(self._date_format),
|
||||
"binary_path": binary_path,
|
||||
}
|
||||
}
|
||||
|
||||
metadata.update(data)
|
||||
with open(self._drivers_json_path, "w+") as outfile:
|
||||
json.dump(metadata, outfile, indent=4)
|
||||
|
||||
def get_os_type(self):
|
||||
return self._os_system_manager.get_os_type()
|
||||
|
||||
def find_driver(self, driver: Driver):
|
||||
"""Find driver by '{os_type}_{driver_name}_{driver_version}_{browser_version}'."""
|
||||
os_type = self.get_os_type()
|
||||
driver_name = driver.get_name()
|
||||
browser_type = driver.get_browser_type()
|
||||
browser_version = self._os_system_manager.get_browser_version_from_os(browser_type)
|
||||
if not browser_version:
|
||||
return None
|
||||
|
||||
driver_version = self.get_cache_key_driver_version(driver)
|
||||
metadata = self.load_metadata_content()
|
||||
|
||||
key = self.__get_metadata_key(driver)
|
||||
if key not in metadata:
|
||||
log(f'There is no [{os_type}] {driver_name} "{driver_version}" for browser {browser_type} '
|
||||
f'"{browser_version}" in cache')
|
||||
return None
|
||||
|
||||
driver_info = metadata[key]
|
||||
path = driver_info["binary_path"]
|
||||
if not os.path.exists(path):
|
||||
return None
|
||||
|
||||
if not self.__is_valid(driver_info):
|
||||
return None
|
||||
|
||||
path = driver_info["binary_path"]
|
||||
log(f"Driver [{path}] found in cache")
|
||||
return path
|
||||
|
||||
def __is_valid(self, driver_info):
|
||||
dates_diff = get_date_diff(
|
||||
driver_info["timestamp"], datetime.date.today(), self._date_format
|
||||
)
|
||||
return dates_diff < self._cache_valid_days_range
|
||||
|
||||
def load_metadata_content(self):
|
||||
if os.path.exists(self._drivers_json_path):
|
||||
with open(self._drivers_json_path, "r") as outfile:
|
||||
return json.load(outfile)
|
||||
return {}
|
||||
|
||||
def __get_metadata_key(self, driver: Driver):
|
||||
if self._metadata_key:
|
||||
return self._metadata_key
|
||||
|
||||
driver_version = self.get_cache_key_driver_version(driver)
|
||||
browser_version = driver.get_browser_version_from_os()
|
||||
browser_version = browser_version if browser_version else ""
|
||||
self._metadata_key = f"{self.get_os_type()}_{driver.get_name()}_{driver_version}" \
|
||||
f"_for_{browser_version}"
|
||||
return self._metadata_key
|
||||
|
||||
def get_cache_key_driver_version(self, driver: Driver):
|
||||
if self._cache_key_driver_version:
|
||||
return self._cache_key_driver_version
|
||||
return driver.get_driver_version_to_download()
|
||||
|
||||
def __get_path(self, driver: Driver):
|
||||
if self._driver_binary_path is None:
|
||||
self._driver_binary_path = os.path.join(
|
||||
self._drivers_directory,
|
||||
driver.get_name(),
|
||||
self.get_os_type(),
|
||||
driver.get_driver_version_to_download(),
|
||||
)
|
||||
return self._driver_binary_path
|
@ -0,0 +1,94 @@
|
||||
import os
|
||||
import re
|
||||
import tarfile
|
||||
import zipfile
|
||||
|
||||
from webdriver_manager.core.archive import Archive, LinuxZipFileWithPermissions
|
||||
from webdriver_manager.core.os_manager import OperationSystemManager
|
||||
|
||||
|
||||
class File(object):
|
||||
def __init__(self, stream, file_name):
|
||||
self.content = stream.content
|
||||
self.__stream = stream
|
||||
self.file_name = file_name
|
||||
self.__temp_name = "driver"
|
||||
self.__regex_filename = r"""filename.+"(.+)"|filename.+''(.+)|filename=([\w.-]+)"""
|
||||
|
||||
@property
|
||||
def filename(self) -> str:
|
||||
if self.file_name:
|
||||
return self.file_name
|
||||
try:
|
||||
content = self.__stream.headers["content-disposition"]
|
||||
|
||||
content_disposition_list = re.split(";", content)
|
||||
filenames = [re.findall(self.__regex_filename, element) for element in content_disposition_list]
|
||||
filename = next(filter(None, next(filter(None, next(filter(None, filenames))))))
|
||||
except KeyError:
|
||||
filename = f"{self.__temp_name}.zip"
|
||||
except (IndexError, StopIteration):
|
||||
filename = f"{self.__temp_name}.exe"
|
||||
|
||||
if '"' in filename:
|
||||
filename = filename.replace('"', "")
|
||||
|
||||
return filename
|
||||
|
||||
|
||||
class FileManager(object):
|
||||
|
||||
def __init__(self, os_system_manager: OperationSystemManager):
|
||||
self._os_system_manager = os_system_manager
|
||||
|
||||
def save_archive_file(self, file: File, directory: str):
|
||||
os.makedirs(directory, exist_ok=True)
|
||||
|
||||
archive_path = f"{directory}{os.sep}{file.filename}"
|
||||
with open(archive_path, "wb") as code:
|
||||
code.write(file.content)
|
||||
if not os.path.exists(archive_path):
|
||||
raise FileExistsError(f"No file has been saved on such path {archive_path}")
|
||||
return Archive(archive_path)
|
||||
|
||||
def unpack_archive(self, archive_file: Archive, target_dir):
|
||||
file_path = archive_file.file_path
|
||||
if file_path.endswith(".zip"):
|
||||
return self.__extract_zip(archive_file, target_dir)
|
||||
elif file_path.endswith(".tar.gz"):
|
||||
return self.__extract_tar_file(archive_file, target_dir)
|
||||
|
||||
def __extract_zip(self, archive_file, to_directory):
|
||||
zip_class = (LinuxZipFileWithPermissions if self._os_system_manager.get_os_name() == "linux" else zipfile.ZipFile)
|
||||
archive = zip_class(archive_file.file_path)
|
||||
try:
|
||||
archive.extractall(to_directory)
|
||||
except Exception as e:
|
||||
if e.args[0] not in [26, 13] and e.args[1] not in [
|
||||
"Text file busy",
|
||||
"Permission denied",
|
||||
]:
|
||||
raise e
|
||||
file_names = []
|
||||
for n in archive.namelist():
|
||||
if "/" not in n:
|
||||
file_names.append(n)
|
||||
else:
|
||||
file_path, file_name = n.split("/")
|
||||
full_file_path = os.path.join(to_directory, file_path)
|
||||
source = os.path.join(full_file_path, file_name)
|
||||
destination = os.path.join(to_directory, file_name)
|
||||
os.replace(source, destination)
|
||||
file_names.append(file_name)
|
||||
return sorted(file_names, key=lambda x: x.lower())
|
||||
return archive.namelist()
|
||||
|
||||
def __extract_tar_file(self, archive_file, to_directory):
|
||||
try:
|
||||
tar = tarfile.open(archive_file.file_path, mode="r:gz")
|
||||
except tarfile.ReadError:
|
||||
tar = tarfile.open(archive_file.file_path, mode="r:bz2")
|
||||
members = tar.getmembers()
|
||||
tar.extractall(to_directory)
|
||||
tar.close()
|
||||
return [x.name for x in members]
|
38
lib/python3.13/site-packages/webdriver_manager/core/http.py
Normal file
38
lib/python3.13/site-packages/webdriver_manager/core/http.py
Normal file
@ -0,0 +1,38 @@
|
||||
import requests
|
||||
from requests import Response, exceptions
|
||||
|
||||
from webdriver_manager.core.config import ssl_verify
|
||||
|
||||
|
||||
class HttpClient:
|
||||
def get(self, url, params=None, **kwargs) -> Response:
|
||||
raise NotImplementedError
|
||||
|
||||
@staticmethod
|
||||
def validate_response(resp: requests.Response):
|
||||
status_code = resp.status_code
|
||||
if status_code == 404:
|
||||
raise ValueError(f"There is no such driver by url {resp.url}")
|
||||
elif status_code == 401:
|
||||
raise ValueError(f"API Rate limit exceeded. You have to add GH_TOKEN!!!")
|
||||
elif resp.status_code != 200:
|
||||
raise ValueError(
|
||||
f"response body:\n{resp.text}\n"
|
||||
f"request url:\n{resp.request.url}\n"
|
||||
f"response headers:\n{dict(resp.headers)}\n"
|
||||
)
|
||||
|
||||
|
||||
class WDMHttpClient(HttpClient):
|
||||
def __init__(self):
|
||||
self._ssl_verify = ssl_verify()
|
||||
|
||||
def get(self, url, **kwargs) -> Response:
|
||||
try:
|
||||
resp = requests.get(
|
||||
url=url, verify=self._ssl_verify, stream=True, **kwargs)
|
||||
except exceptions.ConnectionError:
|
||||
raise exceptions.ConnectionError(f"Could not reach host. Are you offline?")
|
||||
self.validate_response(resp)
|
||||
return resp
|
||||
|
@ -0,0 +1,32 @@
|
||||
import logging
|
||||
|
||||
from webdriver_manager.core.config import wdm_log_level
|
||||
|
||||
__logger = logging.getLogger("WDM")
|
||||
__logger.addHandler(logging.NullHandler())
|
||||
|
||||
|
||||
def log(text):
|
||||
"""Emitting the log message."""
|
||||
__logger.log(wdm_log_level(), text)
|
||||
|
||||
|
||||
def set_logger(logger):
|
||||
"""
|
||||
Set the global logger.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
logger : logging.Logger
|
||||
The custom logger to use.
|
||||
|
||||
Returns None
|
||||
"""
|
||||
|
||||
# Check if the logger is a valid logger
|
||||
if not isinstance(logger, logging.Logger):
|
||||
raise ValueError("The logger must be an instance of logging.Logger")
|
||||
|
||||
# Bind the logger input to the global logger
|
||||
global __logger
|
||||
__logger = logger
|
@ -0,0 +1,45 @@
|
||||
from webdriver_manager.core.download_manager import WDMDownloadManager
|
||||
from webdriver_manager.core.driver_cache import DriverCacheManager
|
||||
from webdriver_manager.core.logger import log
|
||||
from webdriver_manager.core.os_manager import OperationSystemManager
|
||||
|
||||
|
||||
class DriverManager(object):
|
||||
def __init__(
|
||||
self,
|
||||
download_manager=None,
|
||||
cache_manager=None,
|
||||
os_system_manager=None
|
||||
):
|
||||
self._cache_manager = cache_manager
|
||||
if not self._cache_manager:
|
||||
self._cache_manager = DriverCacheManager()
|
||||
|
||||
self._download_manager = download_manager
|
||||
if self._download_manager is None:
|
||||
self._download_manager = WDMDownloadManager()
|
||||
|
||||
self._os_system_manager = os_system_manager
|
||||
if not self._os_system_manager:
|
||||
self._os_system_manager = OperationSystemManager()
|
||||
log("====== WebDriver manager ======")
|
||||
|
||||
@property
|
||||
def http_client(self):
|
||||
return self._download_manager.http_client
|
||||
|
||||
def install(self) -> str:
|
||||
raise NotImplementedError("Please Implement this method")
|
||||
|
||||
def _get_driver_binary_path(self, driver):
|
||||
binary_path = self._cache_manager.find_driver(driver)
|
||||
if binary_path:
|
||||
return binary_path
|
||||
|
||||
os_type = self.get_os_type()
|
||||
file = self._download_manager.download_file(driver.get_driver_download_url(os_type))
|
||||
binary_path = self._cache_manager.save_file_to_cache(driver, file)
|
||||
return binary_path
|
||||
|
||||
def get_os_type(self):
|
||||
return self._os_system_manager.get_os_type()
|
@ -0,0 +1,163 @@
|
||||
import platform
|
||||
import sys
|
||||
|
||||
from webdriver_manager.core.utils import linux_browser_apps_to_cmd, windows_browser_apps_to_cmd, \
|
||||
read_version_from_cmd
|
||||
|
||||
|
||||
class ChromeType(object):
|
||||
GOOGLE = "google-chrome"
|
||||
CHROMIUM = "chromium"
|
||||
BRAVE = "brave-browser"
|
||||
MSEDGE = "edge"
|
||||
|
||||
|
||||
class OSType(object):
|
||||
LINUX = "linux"
|
||||
MAC = "mac"
|
||||
WIN = "win"
|
||||
|
||||
|
||||
PATTERN = {
|
||||
ChromeType.CHROMIUM: r"\d+\.\d+\.\d+",
|
||||
ChromeType.GOOGLE: r"\d+\.\d+\.\d+",
|
||||
ChromeType.MSEDGE: r"\d+\.\d+\.\d+",
|
||||
"brave-browser": r"\d+\.\d+\.\d+(\.\d+)?",
|
||||
"firefox": r"(\d+.\d+)",
|
||||
}
|
||||
|
||||
|
||||
class OperationSystemManager(object):
|
||||
|
||||
def __init__(self, os_type=None):
|
||||
self._os_type = os_type
|
||||
|
||||
@staticmethod
|
||||
def get_os_name():
|
||||
pl = sys.platform
|
||||
if pl == "linux" or pl == "linux2":
|
||||
return OSType.LINUX
|
||||
elif pl == "darwin":
|
||||
return OSType.MAC
|
||||
elif pl == "win32" or pl == "cygwin":
|
||||
return OSType.WIN
|
||||
|
||||
@staticmethod
|
||||
def get_os_architecture():
|
||||
if platform.machine().endswith("64"):
|
||||
return 64
|
||||
else:
|
||||
return 32
|
||||
|
||||
def get_os_type(self):
|
||||
if self._os_type:
|
||||
return self._os_type
|
||||
return f"{self.get_os_name()}{self.get_os_architecture()}"
|
||||
|
||||
@staticmethod
|
||||
def is_arch(os_sys_type):
|
||||
if '_m1' in os_sys_type:
|
||||
return True
|
||||
return platform.processor() != 'i386'
|
||||
|
||||
@staticmethod
|
||||
def is_mac_os(os_sys_type):
|
||||
return OSType.MAC in os_sys_type
|
||||
|
||||
def get_browser_version_from_os(self, browser_type=None):
|
||||
"""Return installed browser version."""
|
||||
cmd_mapping = {
|
||||
ChromeType.GOOGLE: {
|
||||
OSType.LINUX: linux_browser_apps_to_cmd(
|
||||
"google-chrome",
|
||||
"google-chrome-stable",
|
||||
"google-chrome-beta",
|
||||
"google-chrome-dev",
|
||||
),
|
||||
OSType.MAC: r"/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version",
|
||||
OSType.WIN: windows_browser_apps_to_cmd(
|
||||
r'(Get-Item -Path "$env:PROGRAMFILES\Google\Chrome\Application\chrome.exe").VersionInfo.FileVersion',
|
||||
r'(Get-Item -Path "$env:PROGRAMFILES (x86)\Google\Chrome\Application\chrome.exe").VersionInfo.FileVersion',
|
||||
r'(Get-Item -Path "$env:LOCALAPPDATA\Google\Chrome\Application\chrome.exe").VersionInfo.FileVersion',
|
||||
r'(Get-ItemProperty -Path Registry::"HKCU\SOFTWARE\Google\Chrome\BLBeacon").version',
|
||||
r'(Get-ItemProperty -Path Registry::"HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Google Chrome").version',
|
||||
),
|
||||
},
|
||||
ChromeType.CHROMIUM: {
|
||||
OSType.LINUX: linux_browser_apps_to_cmd("chromium", "chromium-browser"),
|
||||
OSType.MAC: r"/Applications/Chromium.app/Contents/MacOS/Chromium --version",
|
||||
OSType.WIN: windows_browser_apps_to_cmd(
|
||||
r'(Get-Item -Path "$env:PROGRAMFILES\Chromium\Application\chrome.exe").VersionInfo.FileVersion',
|
||||
r'(Get-Item -Path "$env:PROGRAMFILES (x86)\Chromium\Application\chrome.exe").VersionInfo.FileVersion',
|
||||
r'(Get-Item -Path "$env:LOCALAPPDATA\Chromium\Application\chrome.exe").VersionInfo.FileVersion',
|
||||
r'(Get-ItemProperty -Path Registry::"HKCU\SOFTWARE\Chromium\BLBeacon").version',
|
||||
r'(Get-ItemProperty -Path Registry::"HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Chromium").version',
|
||||
),
|
||||
},
|
||||
ChromeType.BRAVE: {
|
||||
OSType.LINUX: linux_browser_apps_to_cmd(
|
||||
"brave-browser", "brave-browser-beta", "brave-browser-nightly"
|
||||
),
|
||||
OSType.MAC: r"/Applications/Brave\ Browser.app/Contents/MacOS/Brave\ Browser --version",
|
||||
OSType.WIN: windows_browser_apps_to_cmd(
|
||||
r'(Get-Item -Path "$env:PROGRAMFILES\BraveSoftware\Brave-Browser\Application\brave.exe").VersionInfo.FileVersion',
|
||||
r'(Get-Item -Path "$env:PROGRAMFILES (x86)\BraveSoftware\Brave-Browser\Application\brave.exe").VersionInfo.FileVersion',
|
||||
r'(Get-Item -Path "$env:LOCALAPPDATA\BraveSoftware\Brave-Browser\Application\brave.exe").VersionInfo.FileVersion',
|
||||
r'(Get-ItemProperty -Path Registry::"HKCU\SOFTWARE\BraveSoftware\Brave-Browser\BLBeacon").version',
|
||||
r'(Get-ItemProperty -Path Registry::"HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\BraveSoftware Brave-Browser").version',
|
||||
),
|
||||
},
|
||||
ChromeType.MSEDGE: {
|
||||
OSType.LINUX: linux_browser_apps_to_cmd(
|
||||
"microsoft-edge",
|
||||
"microsoft-edge-stable",
|
||||
"microsoft-edge-beta",
|
||||
"microsoft-edge-dev",
|
||||
),
|
||||
OSType.MAC: r"/Applications/Microsoft\ Edge.app/Contents/MacOS/Microsoft\ Edge --version",
|
||||
OSType.WIN: windows_browser_apps_to_cmd(
|
||||
# stable edge
|
||||
r'(Get-Item -Path "$env:PROGRAMFILES\Microsoft\Edge\Application\msedge.exe").VersionInfo.FileVersion',
|
||||
r'(Get-Item -Path "$env:PROGRAMFILES (x86)\Microsoft\Edge\Application\msedge.exe").VersionInfo.FileVersion',
|
||||
r'(Get-ItemProperty -Path Registry::"HKCU\SOFTWARE\Microsoft\Edge\BLBeacon").version',
|
||||
r'(Get-ItemProperty -Path Registry::"HKLM\SOFTWARE\Microsoft\EdgeUpdate\Clients\{56EB18F8-8008-4CBD-B6D2-8C97FE7E9062}").pv',
|
||||
# beta edge
|
||||
r'(Get-Item -Path "$env:LOCALAPPDATA\Microsoft\Edge Beta\Application\msedge.exe").VersionInfo.FileVersion',
|
||||
r'(Get-Item -Path "$env:PROGRAMFILES\Microsoft\Edge Beta\Application\msedge.exe").VersionInfo.FileVersion',
|
||||
r'(Get-Item -Path "$env:PROGRAMFILES (x86)\Microsoft\Edge Beta\Application\msedge.exe").VersionInfo.FileVersion',
|
||||
r'(Get-ItemProperty -Path Registry::"HKCU\SOFTWARE\Microsoft\Edge Beta\BLBeacon").version',
|
||||
# dev edge
|
||||
r'(Get-Item -Path "$env:LOCALAPPDATA\Microsoft\Edge Dev\Application\msedge.exe").VersionInfo.FileVersion',
|
||||
r'(Get-Item -Path "$env:PROGRAMFILES\Microsoft\Edge Dev\Application\msedge.exe").VersionInfo.FileVersion',
|
||||
r'(Get-Item -Path "$env:PROGRAMFILES (x86)\Microsoft\Edge Dev\Application\msedge.exe").VersionInfo.FileVersion',
|
||||
r'(Get-ItemProperty -Path Registry::"HKCU\SOFTWARE\Microsoft\Edge Dev\BLBeacon").version',
|
||||
# canary edge
|
||||
r'(Get-Item -Path "$env:LOCALAPPDATA\Microsoft\Edge SxS\Application\msedge.exe").VersionInfo.FileVersion',
|
||||
r'(Get-ItemProperty -Path Registry::"HKCU\SOFTWARE\Microsoft\Edge SxS\BLBeacon").version',
|
||||
# highest edge
|
||||
r"(Get-Item (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\msedge.exe').'(Default)').VersionInfo.ProductVersion",
|
||||
r"[System.Diagnostics.FileVersionInfo]::GetVersionInfo((Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\msedge.exe').'(Default)').ProductVersion",
|
||||
r"Get-AppxPackage -Name *MicrosoftEdge.* | Foreach Version",
|
||||
r'(Get-ItemProperty -Path Registry::"HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Microsoft Edge").version',
|
||||
),
|
||||
},
|
||||
"firefox": {
|
||||
OSType.LINUX: linux_browser_apps_to_cmd("firefox"),
|
||||
OSType.MAC: r"/Applications/Firefox.app/Contents/MacOS/firefox --version",
|
||||
OSType.WIN: windows_browser_apps_to_cmd(
|
||||
r'(Get-Item -Path "$env:PROGRAMFILES\Mozilla Firefox\firefox.exe").VersionInfo.FileVersion',
|
||||
r'(Get-Item -Path "$env:PROGRAMFILES (x86)\Mozilla Firefox\firefox.exe").VersionInfo.FileVersion',
|
||||
r"(Get-Item (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\firefox.exe').'(Default)').VersionInfo.ProductVersion",
|
||||
r'(Get-ItemProperty -Path Registry::"HKLM\SOFTWARE\Mozilla\Mozilla Firefox").CurrentVersion',
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
try:
|
||||
cmd_mapping = cmd_mapping[browser_type][OperationSystemManager.get_os_name()]
|
||||
pattern = PATTERN[browser_type]
|
||||
version = read_version_from_cmd(cmd_mapping, pattern)
|
||||
return version
|
||||
except Exception:
|
||||
return None
|
||||
# raise Exception("Can not get browser version from OS")
|
63
lib/python3.13/site-packages/webdriver_manager/core/utils.py
Normal file
63
lib/python3.13/site-packages/webdriver_manager/core/utils.py
Normal file
@ -0,0 +1,63 @@
|
||||
import datetime
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
|
||||
def get_date_diff(date1, date2, date_format):
|
||||
a = datetime.datetime.strptime(date1, date_format)
|
||||
b = datetime.datetime.strptime(
|
||||
str(date2.strftime(date_format)), date_format)
|
||||
|
||||
return (b - a).days
|
||||
|
||||
|
||||
def linux_browser_apps_to_cmd(*apps: str) -> str:
|
||||
"""Create 'browser --version' command from browser app names.
|
||||
|
||||
Result command example:
|
||||
chromium --version || chromium-browser --version
|
||||
"""
|
||||
ignore_errors_cmd_part = " 2>/dev/null" if os.getenv(
|
||||
"WDM_LOG_LEVEL") == "0" else ""
|
||||
return " || ".join(f"{i} --version{ignore_errors_cmd_part}" for i in apps)
|
||||
|
||||
|
||||
def windows_browser_apps_to_cmd(*apps: str) -> str:
|
||||
"""Create analogue of browser --version command for windows."""
|
||||
powershell = determine_powershell()
|
||||
|
||||
first_hit_template = """$tmp = {expression}; if ($tmp) {{echo $tmp; Exit;}};"""
|
||||
script = "$ErrorActionPreference='silentlycontinue'; " + " ".join(
|
||||
first_hit_template.format(expression=e) for e in apps
|
||||
)
|
||||
|
||||
return f'{powershell} -NoProfile "{script}"'
|
||||
|
||||
|
||||
def read_version_from_cmd(cmd, pattern):
|
||||
with subprocess.Popen(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stdin=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
shell=True,
|
||||
) as stream:
|
||||
stdout = stream.communicate()[0].decode()
|
||||
version = re.search(pattern, stdout)
|
||||
version = version.group(0) if version else None
|
||||
return version
|
||||
|
||||
|
||||
def determine_powershell():
|
||||
"""Returns "True" if runs in Powershell and "False" if another console."""
|
||||
cmd = "(dir 2>&1 *`|echo CMD);&<# rem #>echo powershell"
|
||||
with subprocess.Popen(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.DEVNULL,
|
||||
stdin=subprocess.DEVNULL,
|
||||
shell=True,
|
||||
) as stream:
|
||||
stdout = stream.communicate()[0].decode()
|
||||
return "" if stdout == "powershell" else "powershell"
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,97 @@
|
||||
from packaging import version
|
||||
|
||||
from webdriver_manager.core.driver import Driver
|
||||
from webdriver_manager.core.logger import log
|
||||
from webdriver_manager.core.os_manager import ChromeType
|
||||
import json
|
||||
|
||||
|
||||
class ChromeDriver(Driver):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
driver_version,
|
||||
url,
|
||||
latest_release_url,
|
||||
http_client,
|
||||
os_system_manager,
|
||||
chrome_type=ChromeType.GOOGLE
|
||||
):
|
||||
super(ChromeDriver, self).__init__(
|
||||
name,
|
||||
driver_version,
|
||||
url,
|
||||
latest_release_url,
|
||||
http_client,
|
||||
os_system_manager
|
||||
)
|
||||
self._browser_type = chrome_type
|
||||
|
||||
def get_driver_download_url(self, os_type):
|
||||
driver_version_to_download = self.get_driver_version_to_download()
|
||||
# For Mac ARM CPUs after version 106.0.5249.61 the format of OS type changed
|
||||
# to more unified "mac_arm64". For newer versions, it'll be "mac_arm64"
|
||||
# by default, for lower versions we replace "mac_arm64" to old format - "mac64_m1".
|
||||
if version.parse(driver_version_to_download) < version.parse("106.0.5249.61"):
|
||||
os_type = os_type.replace("mac_arm64", "mac64_m1")
|
||||
|
||||
if version.parse(driver_version_to_download) >= version.parse("115"):
|
||||
if os_type == "mac64":
|
||||
os_type = "mac-x64"
|
||||
if os_type in ["mac_64", "mac64_m1", "mac_arm64"]:
|
||||
os_type = "mac-arm64"
|
||||
|
||||
modern_version_url = self.get_url_for_version_and_platform(driver_version_to_download, os_type)
|
||||
log(f"Modern chrome version {modern_version_url}")
|
||||
return modern_version_url
|
||||
|
||||
return f"{self._url}/{driver_version_to_download}/{self.get_name()}_{os_type}.zip"
|
||||
|
||||
def get_browser_type(self):
|
||||
return self._browser_type
|
||||
|
||||
def get_latest_release_version(self):
|
||||
determined_browser_version = self.get_browser_version_from_os()
|
||||
log(f"Get LATEST {self._name} version for {self._browser_type}")
|
||||
if determined_browser_version is not None and version.parse(determined_browser_version) >= version.parse("115"):
|
||||
url = "https://googlechromelabs.github.io/chrome-for-testing/latest-patch-versions-per-build.json"
|
||||
response = self._http_client.get(url)
|
||||
response_dict = json.loads(response.text)
|
||||
determined_browser_version = response_dict.get("builds").get(determined_browser_version).get("version")
|
||||
return determined_browser_version
|
||||
elif determined_browser_version is not None:
|
||||
# Remove the build version (the last segment) from determined_browser_version for version < 113
|
||||
determined_browser_version = ".".join(determined_browser_version.split(".")[:3])
|
||||
latest_release_url = f"{self._latest_release_url}_{determined_browser_version}"
|
||||
else:
|
||||
latest_release_url = self._latest_release_url
|
||||
|
||||
resp = self._http_client.get(url=latest_release_url)
|
||||
return resp.text.rstrip()
|
||||
|
||||
def get_url_for_version_and_platform(self, browser_version, platform):
|
||||
url = "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json"
|
||||
response = self._http_client.get(url)
|
||||
data = response.json()
|
||||
versions = data["versions"]
|
||||
|
||||
if version.parse(browser_version) >= version.parse("115"):
|
||||
short_version = ".".join(browser_version.split(".")[:3])
|
||||
compatible_versions = [v for v in versions if short_version in v["version"]]
|
||||
if compatible_versions:
|
||||
latest_version = compatible_versions[-1]
|
||||
log(f"WebDriver version {latest_version['version']} selected")
|
||||
downloads = latest_version["downloads"]["chromedriver"]
|
||||
for d in downloads:
|
||||
if d["platform"] == platform:
|
||||
return d["url"]
|
||||
else:
|
||||
for v in versions:
|
||||
if v["version"] == browser_version:
|
||||
downloads = v["downloads"]["chromedriver"]
|
||||
for d in downloads:
|
||||
if d["platform"] == platform:
|
||||
return d["url"]
|
||||
|
||||
raise Exception(f"No such driver version {browser_version} for {platform}")
|
@ -0,0 +1,55 @@
|
||||
from webdriver_manager.core.driver import Driver
|
||||
from webdriver_manager.core.logger import log
|
||||
from webdriver_manager.core.os_manager import OSType, ChromeType
|
||||
|
||||
|
||||
class EdgeChromiumDriver(Driver):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
driver_version,
|
||||
url,
|
||||
latest_release_url,
|
||||
http_client,
|
||||
os_system_manager
|
||||
):
|
||||
super(EdgeChromiumDriver, self).__init__(
|
||||
name,
|
||||
driver_version,
|
||||
url,
|
||||
latest_release_url,
|
||||
http_client,
|
||||
os_system_manager
|
||||
)
|
||||
|
||||
def get_stable_release_version(self):
|
||||
"""Stable driver version when browser version was not determined."""
|
||||
stable_url = self._latest_release_url.replace("LATEST_RELEASE", "LATEST_STABLE")
|
||||
resp = self._http_client.get(url=stable_url)
|
||||
return resp.text.rstrip()
|
||||
|
||||
def get_latest_release_version(self) -> str:
|
||||
determined_browser_version = self.get_browser_version_from_os()
|
||||
log(f"Get LATEST {self._name} version for Edge {determined_browser_version}")
|
||||
|
||||
edge_driver_version_to_download = (
|
||||
self.get_stable_release_version()
|
||||
if (determined_browser_version is None)
|
||||
else determined_browser_version
|
||||
)
|
||||
major_edge_version = edge_driver_version_to_download.split(".")[0]
|
||||
os_type = self._os_system_manager.get_os_type()
|
||||
latest_release_url = {
|
||||
OSType.WIN
|
||||
in os_type: f"{self._latest_release_url}_{major_edge_version}_WINDOWS",
|
||||
OSType.MAC
|
||||
in os_type: f"{self._latest_release_url}_{major_edge_version}_MACOS",
|
||||
OSType.LINUX
|
||||
in os_type: f"{self._latest_release_url}_{major_edge_version}_LINUX",
|
||||
}[True]
|
||||
resp = self._http_client.get(url=latest_release_url)
|
||||
return resp.text.rstrip()
|
||||
|
||||
def get_browser_type(self):
|
||||
return ChromeType.MSEDGE
|
@ -0,0 +1,57 @@
|
||||
from webdriver_manager.core.driver import Driver
|
||||
from webdriver_manager.core.logger import log
|
||||
|
||||
|
||||
class GeckoDriver(Driver):
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
driver_version,
|
||||
url,
|
||||
latest_release_url,
|
||||
mozila_release_tag,
|
||||
http_client,
|
||||
os_system_manager
|
||||
):
|
||||
super(GeckoDriver, self).__init__(
|
||||
name,
|
||||
driver_version,
|
||||
url,
|
||||
latest_release_url,
|
||||
http_client,
|
||||
os_system_manager,
|
||||
)
|
||||
self._mozila_release_tag = mozila_release_tag
|
||||
|
||||
def get_latest_release_version(self) -> str:
|
||||
determined_browser_version = self.get_browser_version_from_os()
|
||||
log(f"Get LATEST {self._name} version for {determined_browser_version} firefox")
|
||||
resp = self._http_client.get(
|
||||
url=self.latest_release_url,
|
||||
headers=self.auth_header
|
||||
)
|
||||
return resp.json()["tag_name"]
|
||||
|
||||
def get_driver_download_url(self, os_type):
|
||||
"""Like https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-linux64.tar.gz"""
|
||||
driver_version_to_download = self.get_driver_version_to_download()
|
||||
log(f"Getting latest mozilla release info for {driver_version_to_download}")
|
||||
resp = self._http_client.get(
|
||||
url=self.tagged_release_url(driver_version_to_download),
|
||||
headers=self.auth_header
|
||||
)
|
||||
assets = resp.json()["assets"]
|
||||
name = f"{self.get_name()}-{driver_version_to_download}-{os_type}."
|
||||
output_dict = [
|
||||
asset for asset in assets if asset["name"].startswith(name)]
|
||||
return output_dict[0]["browser_download_url"]
|
||||
|
||||
@property
|
||||
def latest_release_url(self):
|
||||
return self._latest_release_url
|
||||
|
||||
def tagged_release_url(self, version):
|
||||
return self._mozila_release_tag.format(version)
|
||||
|
||||
def get_browser_type(self):
|
||||
return "firefox"
|
82
lib/python3.13/site-packages/webdriver_manager/drivers/ie.py
Normal file
82
lib/python3.13/site-packages/webdriver_manager/drivers/ie.py
Normal file
@ -0,0 +1,82 @@
|
||||
from webdriver_manager.core.driver import Driver
|
||||
from webdriver_manager.core.logger import log
|
||||
|
||||
|
||||
class IEDriver(Driver):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
driver_version,
|
||||
url,
|
||||
latest_release_url,
|
||||
ie_release_tag,
|
||||
http_client,
|
||||
os_system_manager
|
||||
):
|
||||
super(IEDriver, self).__init__(
|
||||
name,
|
||||
driver_version,
|
||||
url,
|
||||
latest_release_url,
|
||||
http_client,
|
||||
os_system_manager
|
||||
)
|
||||
self._ie_release_tag = ie_release_tag
|
||||
# todo: for 'browser_version' implement installed IE version detection
|
||||
# like chrome or firefox
|
||||
|
||||
def get_latest_release_version(self) -> str:
|
||||
log(f"Get LATEST driver version for Internet Explorer")
|
||||
resp = self._http_client.get(
|
||||
url=self.latest_release_url,
|
||||
headers=self.auth_header
|
||||
)
|
||||
|
||||
releases = resp.json()
|
||||
release = next(
|
||||
release
|
||||
for release in releases
|
||||
for asset in release["assets"]
|
||||
if asset["name"].startswith(self.get_name())
|
||||
)
|
||||
return release["tag_name"].replace("selenium-", "")
|
||||
|
||||
def get_driver_download_url(self, os_type):
|
||||
"""Like https://github.com/seleniumhq/selenium/releases/download/3.141.59/IEDriverServer_Win32_3.141.59.zip"""
|
||||
driver_version_to_download = self.get_driver_version_to_download()
|
||||
log(f"Getting latest ie release info for {driver_version_to_download}")
|
||||
resp = self._http_client.get(
|
||||
url=self.tagged_release_url(driver_version_to_download),
|
||||
headers=self.auth_header
|
||||
)
|
||||
|
||||
assets = resp.json()["assets"]
|
||||
|
||||
name = f"{self._name}_{os_type}_{driver_version_to_download}" + "."
|
||||
output_dict = [
|
||||
asset for asset in assets if asset["name"].startswith(name)]
|
||||
return output_dict[0]["browser_download_url"]
|
||||
|
||||
@property
|
||||
def latest_release_url(self):
|
||||
return self._latest_release_url
|
||||
|
||||
def tagged_release_url(self, version):
|
||||
version = self.__get_divided_version(version)
|
||||
return self._ie_release_tag.format(version)
|
||||
|
||||
def __get_divided_version(self, version):
|
||||
divided_version = version.split(".")
|
||||
if len(divided_version) == 2:
|
||||
return f"{version}.0"
|
||||
elif len(divided_version) == 3:
|
||||
return version
|
||||
else:
|
||||
raise ValueError(
|
||||
"Version must consist of major, minor and/or patch, "
|
||||
"but given was: '{version}'".format(version=version)
|
||||
)
|
||||
|
||||
def get_browser_type(self):
|
||||
return "msie"
|
@ -0,0 +1,55 @@
|
||||
from webdriver_manager.core.driver import Driver
|
||||
from webdriver_manager.core.logger import log
|
||||
|
||||
|
||||
class OperaDriver(Driver):
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
driver_version,
|
||||
url,
|
||||
latest_release_url,
|
||||
opera_release_tag,
|
||||
http_client,
|
||||
os_system_manager
|
||||
):
|
||||
super(OperaDriver, self).__init__(
|
||||
name,
|
||||
driver_version,
|
||||
url,
|
||||
latest_release_url,
|
||||
http_client,
|
||||
os_system_manager
|
||||
)
|
||||
self.opera_release_tag = opera_release_tag
|
||||
|
||||
def get_latest_release_version(self) -> str:
|
||||
resp = self._http_client.get(
|
||||
url=self.latest_release_url,
|
||||
headers=self.auth_header
|
||||
)
|
||||
return resp.json()["tag_name"]
|
||||
|
||||
def get_driver_download_url(self, os_type) -> str:
|
||||
"""Like https://github.com/operasoftware/operachromiumdriver/releases/download/v.2.45/operadriver_linux64.zip"""
|
||||
driver_version_to_download = self.get_driver_version_to_download()
|
||||
log(f"Getting latest opera release info for {driver_version_to_download}")
|
||||
resp = self._http_client.get(
|
||||
url=self.tagged_release_url(driver_version_to_download),
|
||||
headers=self.auth_header
|
||||
)
|
||||
assets = resp.json()["assets"]
|
||||
name = "{0}_{1}".format(self.get_name(), os_type)
|
||||
output_dict = [
|
||||
asset for asset in assets if asset["name"].startswith(name)]
|
||||
return output_dict[0]["browser_download_url"]
|
||||
|
||||
@property
|
||||
def latest_release_url(self):
|
||||
return self._latest_release_url
|
||||
|
||||
def tagged_release_url(self, version):
|
||||
return self.opera_release_tag.format(version)
|
||||
|
||||
def get_browser_type(self):
|
||||
return "opera"
|
51
lib/python3.13/site-packages/webdriver_manager/firefox.py
Normal file
51
lib/python3.13/site-packages/webdriver_manager/firefox.py
Normal file
@ -0,0 +1,51 @@
|
||||
import os
|
||||
from typing import Optional
|
||||
|
||||
from webdriver_manager.core.download_manager import DownloadManager
|
||||
from webdriver_manager.core.driver_cache import DriverCacheManager
|
||||
from webdriver_manager.core.manager import DriverManager
|
||||
from webdriver_manager.core.os_manager import OperationSystemManager
|
||||
from webdriver_manager.drivers.firefox import GeckoDriver
|
||||
|
||||
|
||||
class GeckoDriverManager(DriverManager):
|
||||
def __init__(
|
||||
self,
|
||||
version: Optional[str] = None,
|
||||
name: str = "geckodriver",
|
||||
url: str = "https://github.com/mozilla/geckodriver/releases/download",
|
||||
latest_release_url: str = "https://api.github.com/repos/mozilla/geckodriver/releases/latest",
|
||||
mozila_release_tag: str = "https://api.github.com/repos/mozilla/geckodriver/releases/tags/{0}",
|
||||
download_manager: Optional[DownloadManager] = None,
|
||||
cache_manager: Optional[DriverCacheManager] = None,
|
||||
os_system_manager: Optional[OperationSystemManager] = None
|
||||
):
|
||||
super(GeckoDriverManager, self).__init__(
|
||||
download_manager=download_manager,
|
||||
cache_manager=cache_manager
|
||||
)
|
||||
|
||||
self.driver = GeckoDriver(
|
||||
driver_version=version,
|
||||
name=name,
|
||||
url=url,
|
||||
latest_release_url=latest_release_url,
|
||||
mozila_release_tag=mozila_release_tag,
|
||||
http_client=self.http_client,
|
||||
os_system_manager=os_system_manager
|
||||
)
|
||||
|
||||
def install(self) -> str:
|
||||
driver_path = self._get_driver_binary_path(self.driver)
|
||||
os.chmod(driver_path, 0o755)
|
||||
return driver_path
|
||||
|
||||
def get_os_type(self):
|
||||
os_type = super().get_os_type()
|
||||
if not self._os_system_manager.is_mac_os(os_type):
|
||||
return os_type
|
||||
|
||||
macos = 'macos'
|
||||
if self._os_system_manager.is_arch(os_type):
|
||||
return f"{macos}-aarch64"
|
||||
return macos
|
75
lib/python3.13/site-packages/webdriver_manager/microsoft.py
Normal file
75
lib/python3.13/site-packages/webdriver_manager/microsoft.py
Normal file
@ -0,0 +1,75 @@
|
||||
import os
|
||||
from typing import Optional
|
||||
|
||||
from webdriver_manager.core.download_manager import DownloadManager
|
||||
from webdriver_manager.core.driver_cache import DriverCacheManager
|
||||
from webdriver_manager.core.os_manager import OperationSystemManager
|
||||
from webdriver_manager.drivers.edge import EdgeChromiumDriver
|
||||
from webdriver_manager.drivers.ie import IEDriver
|
||||
from webdriver_manager.core.manager import DriverManager
|
||||
|
||||
|
||||
class IEDriverManager(DriverManager):
|
||||
def __init__(
|
||||
self,
|
||||
version: Optional[str] = None,
|
||||
name: str = "IEDriverServer",
|
||||
url: str = "https://github.com/seleniumhq/selenium/releases/download",
|
||||
latest_release_url: str = "https://api.github.com/repos/seleniumhq/selenium/releases",
|
||||
ie_release_tag: str = "https://api.github.com/repos/seleniumhq/selenium/releases/tags/selenium-{0}",
|
||||
download_manager: Optional[DownloadManager] = None,
|
||||
cache_manager: Optional[DriverCacheManager] = None,
|
||||
os_system_manager: Optional[OperationSystemManager] = None
|
||||
):
|
||||
super().__init__(
|
||||
download_manager=download_manager,
|
||||
cache_manager=cache_manager
|
||||
)
|
||||
|
||||
self.driver = IEDriver(
|
||||
driver_version=version,
|
||||
name=name,
|
||||
url=url,
|
||||
latest_release_url=latest_release_url,
|
||||
ie_release_tag=ie_release_tag,
|
||||
http_client=self.http_client,
|
||||
os_system_manager=os_system_manager
|
||||
)
|
||||
|
||||
def install(self) -> str:
|
||||
return self._get_driver_binary_path(self.driver)
|
||||
|
||||
def get_os_type(self):
|
||||
return "x64" if self._os_system_manager.get_os_type() == "win64" else "Win32"
|
||||
|
||||
|
||||
class EdgeChromiumDriverManager(DriverManager):
|
||||
def __init__(
|
||||
self,
|
||||
version: Optional[str] = None,
|
||||
name: str = "edgedriver",
|
||||
url: str = "https://msedgedriver.azureedge.net",
|
||||
latest_release_url: str = "https://msedgedriver.azureedge.net/LATEST_RELEASE",
|
||||
download_manager: Optional[DownloadManager] = None,
|
||||
cache_manager: Optional[DriverCacheManager] = None,
|
||||
os_system_manager: Optional[OperationSystemManager] = None
|
||||
):
|
||||
super().__init__(
|
||||
download_manager=download_manager,
|
||||
cache_manager=cache_manager,
|
||||
os_system_manager=os_system_manager
|
||||
)
|
||||
|
||||
self.driver = EdgeChromiumDriver(
|
||||
driver_version=version,
|
||||
name=name,
|
||||
url=url,
|
||||
latest_release_url=latest_release_url,
|
||||
http_client=self.http_client,
|
||||
os_system_manager=os_system_manager
|
||||
)
|
||||
|
||||
def install(self) -> str:
|
||||
driver_path = self._get_driver_binary_path(self.driver)
|
||||
os.chmod(driver_path, 0o755)
|
||||
return driver_path
|
50
lib/python3.13/site-packages/webdriver_manager/opera.py
Normal file
50
lib/python3.13/site-packages/webdriver_manager/opera.py
Normal file
@ -0,0 +1,50 @@
|
||||
import os
|
||||
from typing import Optional
|
||||
|
||||
from webdriver_manager.core.download_manager import DownloadManager
|
||||
from webdriver_manager.core.driver_cache import DriverCacheManager
|
||||
from webdriver_manager.core.manager import DriverManager
|
||||
from webdriver_manager.core.os_manager import OperationSystemManager
|
||||
from webdriver_manager.drivers.opera import OperaDriver
|
||||
|
||||
|
||||
class OperaDriverManager(DriverManager):
|
||||
def __init__(
|
||||
self,
|
||||
version: Optional[str] = None,
|
||||
name: str = "operadriver",
|
||||
url: str = "https://github.com/operasoftware/operachromiumdriver/"
|
||||
"releases/",
|
||||
latest_release_url: str = "https://api.github.com/repos/"
|
||||
"operasoftware/operachromiumdriver/releases/latest",
|
||||
opera_release_tag: str = "https://api.github.com/repos/"
|
||||
"operasoftware/operachromiumdriver/releases/tags/{0}",
|
||||
download_manager: Optional[DownloadManager] = None,
|
||||
cache_manager: Optional[DriverCacheManager] = None,
|
||||
os_system_manager: Optional[OperationSystemManager] = None
|
||||
):
|
||||
super().__init__(
|
||||
download_manager=download_manager,
|
||||
cache_manager=cache_manager
|
||||
)
|
||||
|
||||
self.driver = OperaDriver(
|
||||
name=name,
|
||||
driver_version=version,
|
||||
url=url,
|
||||
latest_release_url=latest_release_url,
|
||||
opera_release_tag=opera_release_tag,
|
||||
http_client=self.http_client,
|
||||
os_system_manager=os_system_manager
|
||||
)
|
||||
|
||||
def install(self) -> str:
|
||||
driver_path = self._get_driver_binary_path(self.driver)
|
||||
if not os.path.isfile(driver_path):
|
||||
for name in os.listdir(driver_path):
|
||||
if "sha512_sum" in name:
|
||||
os.remove(os.path.join(driver_path, name))
|
||||
break
|
||||
driver_path = os.path.join(driver_path, os.listdir(driver_path)[0])
|
||||
os.chmod(driver_path, 0o755)
|
||||
return driver_path
|
Reference in New Issue
Block a user