from dotenv import load_dotenv load_dotenv(".env") import logging import os import time from multiprocessing import Pool from pathlib import Path import cv2 import typer from app.parser import get_files_by_extension from app.read_settings import read_settings logger = logging.getLogger(__name__) app = typer.Typer() # TODO this can be done better! # we're re-reading the git-repo path instead of assuming # we're currently in there, though empirical testing shows # doign Path.cwd() returns git repo path cwd = Path(__file__).parent settings = read_settings(f"{cwd}/settings.toml") git_repo = Path(settings.git_repo).expanduser() IMAGE_CACHE_PATH = f"{cwd}/static/images/cache" SIZES = { ".": [ (320,), (640,), (760,), (1024,), (1366,), (1600,), (1920,), (2400,), (2880,), (3840,), ], "products": [ (120, 120), (240, 240), # -- checkout (220, 220), (440, 440), (320,), (640,), # - product-grid (380,), (760,), (256,), (512,), (340,), (683,), (400,), (800,), (480,), (960,), (460,), (920,), (560,), (1120,), (1024,), # -- product specific sizes (1200,), (1366,), (1920,), (2400,), ], "pages": [(320,), (640,), (760,), (1024,), (1366,), (1600,), (1920,), (2400,)], } def calculate_height_on_width(img, input_width: int) -> int: """Calculate thumbnail's height value of given image by using the desired width. """ width_percent = input_width / float(img.shape[1]) return int((float(img.shape[0]) * float(width_percent))) def make_thumb(size_type: str, img, fp: os.PathLike): """Make a thumbnail image for each defined size.""" try: new_filepath = Path(f"{fp.parent.stem}__{fp.stem}_{size_type[0]}{fp.suffix}") if Path(f"{IMAGE_CACHE_PATH}/{new_filepath}").exists(): pass else: # check if size_type is a full tuple or is missing the # height value if len(size_type) == 2: img = cv2.resize(img, size_type) else: img_height = calculate_height_on_width(img, size_type[0]) img = cv2.resize(img, (size_type[0], img_height)) # save it to disk cv2.imwrite(f"{IMAGE_CACHE_PATH}/{new_filepath}", img) except OSError as e: logging.error(f"image-resize error => {e}") def image_resize(image: tuple[str, str]): """Resize an image at given preset, if it does not exist yet. We're saving each thumbnail in static/images/cache/, in the format //_. """ template, filepath = image fp = Path(filepath) selected_size = SIZES[template] # read image and keep it in memory img = cv2.imread(f"{git_repo}/{filepath}") # copy also image as is to the cache copy_filepath = Path(f"{fp.parent.stem}__{fp.stem}_{img.shape[1]}{fp.suffix}") if not Path(f"{IMAGE_CACHE_PATH}/{copy_filepath}").exists(): cv2.imwrite(f"{IMAGE_CACHE_PATH}/{copy_filepath}", img) for size_type in selected_size: if img.shape[1] > size_type[0]: make_thumb(size_type, img, fp) @app.command() def build_all_images(repo: str): """Build set of defined thumbnails for each image in the list. Ref: """ pool = Pool(int(os.getenv("CPU_CORE"))) repo = Path(repo).expanduser() pattern_matching = ["*.png", "*.jpg"] filepaths = get_files_by_extension(repo, pattern_matching, True) images = [ (str(Path(filepath).parent).split("/")[0], filepath) for filepath in filepaths ] if len(images) > 0: start_time = time.time() pool.map(image_resize, images) logging.info("--- %s seconds ---" % (time.time() - start_time)) else: logging.info("build-images: no images in the repo.") @app.command() def build_images(repo: str, oldrev: str, newrev: str): """Build set of defined thumbnails for each image in the list. Ref: """ pool = Pool(int(os.getenv("CPU_CORE"))) repo = Path(repo).expanduser() pattern_matching = [".png", ".jpg"] filepaths = get_files_by_extension(repo, pattern_matching, True) images = [ (str(Path(filepath).parent).split("/")[0], filepath) for filepath in filepaths ] if len(images) > 0: start_time = time.time() pool.map(image_resize, images) logging.info("--- %s seconds ---" % (time.time() - start_time)) else: logging.info("build-images: no image in this commit.") if __name__ == "__main__": app()