yuru-yuri/manga-py

View on GitHub
manga_py/base_classes/web_driver/web_driver.py

Summary

Maintainability
A
2 hrs
Test Coverage
from abc import ABCMeta, abstractmethod
from pathlib import Path
from sys import platform

from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webdriver import WebDriver as BrowserDriver
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support.expected_conditions import (
    presence_of_all_elements_located as locate,
    presence_of_element_located as locate_one
)
from selenium.webdriver.support.ui import WebDriverWait
from typing import List
from time import sleep

from manga_py.fs import get_util_home_path

class UnsupportedOsException(Exception):
    def __init__(self, os=platform, *args, **kwargs):
        super().__init__(os, *args, **kwargs)


def _is_win():
    return platform.startswith('win32') or platform.startswith('cygwin')


def _is_mac():
    return platform.startswith('darwin')


def _is_linux():
    return platform.startswith('linux')


def _supported() -> bool:
    return _is_win() or _is_mac() or _is_linux()


class WebDriver(metaclass=ABCMeta):
    driver_version = None
    home_path = None
    _re = None
    _driver = None
    _default_timeout = 10
    __visible = True
    __freq = 1.0

    def __init__(self, version: str, _re):
        self.driver_version = version
        self._re = _re
        self.home_path = Path(get_util_home_path())

    @property
    def visible(self) -> bool:
        return self.__visible

    @visible.setter
    def visible(self, visible: bool):
        self.__visible = visible

    @staticmethod
    @abstractmethod
    def driver_archive() -> str:
        raise NotImplementedError

    @abstractmethod
    def driver_path(self) -> Path:
        raise NotImplementedError

    @abstractmethod
    def download_driver(self) -> None:
        raise NotImplementedError

    @abstractmethod
    def _make_driver(self) -> None:
        raise NotImplementedError

    @abstractmethod
    def get_available_versions(self) -> set:
        raise NotImplementedError

    def _version(self, version: str) -> str:
        return self._re.search(version).group(1)

    @property
    def initialized(self) -> bool:
        return self._driver is not None

    def init_driver(self):
        if not self.initialized:
            self._make_driver()
        return self

    @property
    def freq(self) -> float:
        return float(self.__freq)

    @freq.setter
    def freq(self, freq: float):
        self.__freq = freq

    @property
    def driver(self) -> BrowserDriver:
        if not self.initialized:
            self.init_driver()
        return self._driver

    def get(self, url):
        self.driver.get(url)

    @property
    def valid_url(self):
        if self.initialized:
            url = self._driver.current_url
            if url and url.startswith('http'):
                return True
        return False

    @property
    def _wait(self):
        return WebDriverWait(self._driver, self._default_timeout, poll_frequency=self.freq)

    def find_element(self, selector: str, by=By.CSS_SELECTOR) -> List[WebElement]:
        sleep(1)
        return self._wait.until(locate_one((by, selector)))

    def find_all_elements(self, selector: str, by=By.CSS_SELECTOR) -> List[WebElement]:
        sleep(1)
        self._wait.until(locate_one((by, selector)))  # wait for first element
        sleep(1)
        return self._wait.until(locate((by, selector)))

    def add_cookie(self, key, value, **kwargs):
        _cookie = {
            'name': key,
            'value': value,
            'expiry': 1898789118,
            'secure': False,
            'path': '/',
            'httpOnly': False,
        }

        _cookie.update(kwargs)

        self._driver.add_cookie(_cookie)

    def close(self):
        if self.initialized:
            self._driver.quit()


__all__ = ['WebDriver', '_is_win', '_is_mac', '_is_linux', '_supported', 'UnsupportedOsException']