import glob from PIL import Image, ImageStat from iteration_utilities import duplicates from pathlib import Path import json import os import pytest def validate_brightness_image(working_path, theme_config, high_light, image_list, brightness_way): image_pattern = theme_config.get("imageFilename") image_filenames = {}.fromkeys(glob.glob(str(Path(working_path, image_pattern)))) # generate an image statistics for each images for an_imagefile in image_filenames: this_image = Image.open(an_imagefile).convert("L") this_image_stats = ImageStat.Stat(this_image) image_filenames[an_imagefile] = this_image_stats.mean[0] # get the brightest observed image from the list if high_light == "dayHighlight": actual_est_image = max(image_filenames, key=lambda key: image_filenames[key]) else: actual_est_image = min(image_filenames, key=lambda key: image_filenames[key]) # get the brightest referenced image OR in the daylist to compare to if theme_config.get(high_light): an_image = image_pattern.replace("*", str(theme_config.get(high_light))) ref_est_file = str(Path(working_path, an_image)) assert actual_est_image == ref_est_file, f"✖ {brightness_way} image is {actual_est_image}, but the {high_light} image is {ref_est_file}." else: # if not highlight is given in theme.json, we suppose that brightest images are in the daylist ref_est_files = [] for an_id in theme_config.get(image_list): an_image = image_pattern.replace('*', str(an_id)) ref_est_files.append(str(Path(working_path, an_image))) assert actual_est_image in ref_est_files, f"✖ {brightness_way} image {actual_est_image} was not found in the '{image_list}' attribute." @pytest.fixture def working_path(): # get the global variables containing gitlab-given project slug. project_slug = os.environ["PACKAGE_NAME"] root_folder = os.environ["ENTRY_FOLDER"] working_path = Path(root_folder, project_slug) if not working_path.is_dir(): raise FileNotFoundError(f"No project found for the given {working_path}.") return working_path @pytest.fixture def manifest(working_path): with open(Path(working_path, "theme.json"), 'r') as fileobj: return json.load(fileobj) def test_brightest_image(working_path, manifest): validate_brightness_image(working_path, manifest, "dayHighlight", "dayImageList", "Brightest") def test_darkest_image(working_path, manifest): validate_brightness_image(working_path, manifest, "nightHighlight", "nightImageList", "Darkest") def test_image_size(working_path, manifest): image_filename = manifest["imageFilename"].replace("*", str(manifest["dayImageList"][0])) w, h = Image.open(Path(working_path, image_filename)).size assert w >= 1920 and h >= 1080, f"✖ Image size is too small (must be at least 1920×1080, is {w}×{h})" assert w >= h, "✖ Image orientation is portrait (must be landscape or square)" def test_overlapping_images(manifest): jointed_lists = manifest.get("dayImageList") jointed_lists.extend(manifest.get("nightImageList")) jointed_lists.extend(manifest.get("sunriseImageList", [])) jointed_lists.extend(manifest.get("sunsetImageList", [])) dup_refs = list(duplicates(jointed_lists)) str_dup_refs = [manifest["imageFilename"].replace("*", str(int)) for int in dup_refs] separator = ", " assert not dup_refs, f"✖ Some images are referenced twice or more: {separator.join(str_dup_refs)}."