misc-csechet/frontools/screenshot.py

92 lines
2.6 KiB
Python

"""Pages screenshots"""
from datetime import datetime
from os.path import expandvars
from pathlib import Path
from re import compile as re_compile
from typing import Optional
from playwright.async_api import Error as PlaywrightError
from xdg import xdg_config_home
from frontools.config import Config
from frontools.sources import Browser
from frontools.utils import get_url_slug, report_progress
async def screenshot(
config: Config,
output_directory: Optional[str],
continue_: bool = False,
screen_width: Optional[int] = None,
) -> None:
"""Compare pages with or without local css"""
if output_directory is None:
output_path = _get_default_screenshot_directory()
else:
output_path = Path(output_directory)
output_path.mkdir(parents=True, exist_ok=True)
source = config.source
async with source.get_browser(width=screen_width) as browser:
await report_progress(
"Screenshoting",
[
(
url,
_screenshot_url(browser, output_path, url, theme_name, config.source_name, continue_),
)
for (theme_name, url) in config.urls
],
nb_workers=3,
)
async def _screenshot_url(
browser: Browser,
output_path: Path,
url: str,
theme_name: str,
source_name: str,
continue_: bool,
) -> None:
url_slug = get_url_slug(url)
filename = output_path / f"{theme_name}_{url_slug}_{source_name}.png"
if filename.is_file() and continue_:
return
async with browser.load_page(url) as page:
try:
screenshot = await page.screenshot(full_page=True)
except PlaywrightError:
# Exception raisen when taking a screenshot of a to large page, retry without full_page
screenshot = await page.screenshot()
with open(filename, "wb") as screenshot_file:
screenshot_file.write(screenshot)
def _get_default_screenshot_directory() -> Path:
pictures_dir_re = re_compile(r'\w*XDG_PICTURES_DIR\w*\="(?P<path>.*)"\w*$')
pictures_dir = None
with open(
Path(xdg_config_home()) / "user-dirs.dirs", encoding="utf-8"
) as user_dirs:
for line in user_dirs.readlines():
match = pictures_dir_re.match(line)
if match is None:
continue
path_string = match.group("path")
path_string = expandvars(path_string)
pictures_dir = Path(path_string)
break
if pictures_dir is None:
pictures_dir = Path.home()
return pictures_dir / datetime.now().strftime("%Y-%m-%d - %H-%M-%S")