From 2ed2ae3d16136542bb78de724d1a25608aac977c Mon Sep 17 00:00:00 2001 From: Ferdinand Date: Tue, 7 Apr 2026 13:34:46 +0200 Subject: [PATCH] feat: analyze_folder orchestrates all checks --- analyzer.py | 57 +++++++++++++++++++++++++++++++++++++++++- tests/test_analyzer.py | 21 ++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/analyzer.py b/analyzer.py index 9b20114..9654746 100644 --- a/analyzer.py +++ b/analyzer.py @@ -2,7 +2,8 @@ import cv2 import numpy as np from PIL import Image import imagehash -from typing import List +import os +from typing import List, Optional def is_blurry(path: str, threshold: float = 100.0) -> bool: @@ -63,3 +64,57 @@ def find_duplicates(paths: List[str], threshold: int = 8) -> List[List[str]]: groups.append(group) return groups + + +SUPPORTED_EXTENSIONS = {".jpg", ".jpeg", ".png"} + + +def analyze_folder( + folder: str, + blur_threshold: float = 100.0, + over_threshold: float = 240.0, + under_threshold: float = 30.0, + dup_threshold: int = 8, + use_ai: bool = False, + api_key: Optional[str] = None, +) -> List[dict]: + """ + Analysiert alle Bilder im Ordner. + Gibt Liste zurueck: [{"path": "/foo/bar.jpg", "reasons": ["unscharf"]}, ...] + Nur Bilder mit mindestens einem Grund werden zurueckgegeben. + """ + paths = [ + os.path.join(folder, f) + for f in os.listdir(folder) + if os.path.splitext(f)[1].lower() in SUPPORTED_EXTENSIONS + ] + + results: dict = {path: [] for path in paths} + + for path in paths: + try: + if is_blurry(path, blur_threshold): + results[path].append("unscharf") + if is_overexposed(path, over_threshold): + results[path].append("ueberbelichtet") + if is_underexposed(path, under_threshold): + results[path].append("unterbelichtet") + except Exception: + continue + + dup_groups = find_duplicates(paths, dup_threshold) + for group in dup_groups: + original = os.path.basename(group[0]) + for dup_path in group[1:]: + results[dup_path].append(f"Duplikat von {original}") + + if use_ai and api_key: + ai_results = _analyze_with_ai(paths, api_key) + for path, ai_reasons in ai_results.items(): + results[path].extend(ai_reasons) + + return [ + {"path": path, "reasons": reasons} + for path, reasons in results.items() + if reasons + ] diff --git a/tests/test_analyzer.py b/tests/test_analyzer.py index 264dfbe..909b937 100644 --- a/tests/test_analyzer.py +++ b/tests/test_analyzer.py @@ -88,3 +88,24 @@ def test_different_images_are_not_duplicates(tmp_path): p2 = make_diagonal_image(tmp_path, "diagonal.jpg") groups = find_duplicates([p1, p2], threshold=8) assert len(groups) == 0 + + +from analyzer import analyze_folder + + +def test_analyze_folder_returns_results(tmp_path): + make_test_image(tmp_path, color=(128, 128, 128)) + from PIL import Image + white = tmp_path / "white.jpg" + Image.new("RGB", (100, 100), color=(255, 255, 255)).save(white) + + results = analyze_folder( + folder=str(tmp_path), + blur_threshold=100, + over_threshold=240, + under_threshold=30, + dup_threshold=8, + use_ai=False, + ) + reasons_flat = [r for item in results for r in item["reasons"]] + assert "ueberbelichtet" in reasons_flat