#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Image Processing Service für Intelectra WebShop EINFACH & SCHNELL - erstellt nur Thumbnails! Kompatibel mit Legacy PHP item.class.php """ import json import sys import os from PIL import Image import logging # Logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler('/var/www/vhosts/intelectra.de/httpdocs/logs/image_processing.log'), logging.StreamHandler() ] ) logger = logging.getLogger('image_processing') class ImageProcessingService: """Einfacher Thumbnail-Generator - keine DB, keine Komplexität!""" def __init__(self, config): """ config = { 'source_file': '/full/path/to/original.jpg', 'watermark': 0 oder 1, 'shop_system': 'intelectra_shop', 'document_root': '/var/www/...', 'image_sizes': [['thumb_', 90], ['overview_', 150], ...] # Von PHP übergeben! } """ self.source_file = config.get('source_file') self.watermark_enabled = config.get('watermark', 0) == 1 self.document_root = config.get('document_root', '') # Bildgrößen von PHP übernehmen (aus DB-Konfiguration!) # PHP übergibt: [['overview_', 150], ['thumb_', 90], ['details_', 330], ['detaildefault_', 600]] php_image_sizes = config.get('image_sizes', []) # In Python-Format konvertieren: [('prefix', size), ...] self.image_sizes = [] # Original resized (falls konfiguriert) self.image_sizes.append(('', 800)) # Thumbnails von PHP config for img_config in php_image_sizes: if isinstance(img_config, (list, tuple)) and len(img_config) >= 2: prefix = img_config[0] size = int(img_config[1]) self.image_sizes.append((prefix, size)) logger.info(f"Service initialized for: {self.source_file}") logger.info(f"Image sizes: {self.image_sizes}") def process(self): """Hauptfunktion: Erstellt alle Thumbnails""" try: if not os.path.exists(self.source_file): logger.error(f"Source file not found: {self.source_file}") return False # Original-Bild öffnen with Image.open(self.source_file) as img: # Original Format beibehalten (JPG/PNG/GIF) img_format = img.format # Alle Größen generieren for prefix, size in self.image_sizes: self.create_thumbnail(img, prefix, size, img_format) logger.info(f"✅ Successfully processed: {self.source_file}") return True except Exception as e: logger.error(f"❌ Error processing {self.source_file}: {str(e)}") return False def create_thumbnail(self, img, prefix, max_size, img_format): """Erstellt ein Thumbnail mit gegebener Größe""" try: # Dateiname mit Präfix source_dir = os.path.dirname(self.source_file) source_filename = os.path.basename(self.source_file) target_filename = f"{prefix}{source_filename}" target_path = os.path.join(source_dir, target_filename) # Kopie erstellen für Resize thumb = img.copy() # Proportional auf max_size verkleinern (behält Aspect Ratio!) thumb.thumbnail((max_size, max_size), Image.Resampling.LANCZOS) # Speichern im Original-Format if img_format == 'JPEG': thumb.save(target_path, 'JPEG', quality=85, optimize=True) elif img_format == 'PNG': thumb.save(target_path, 'PNG', optimize=True) elif img_format == 'GIF': thumb.save(target_path, 'GIF') else: thumb.save(target_path) logger.debug(f"Created: {target_filename} ({max_size}px)") except Exception as e: logger.warning(f"Could not create {prefix} thumbnail: {str(e)}") def main(): """Entry Point - wird von PHP aufgerufen""" try: if len(sys.argv) < 2: logger.error("No config provided!") sys.exit(1) # JSON Config von PHP config_json = sys.argv[1] config = json.loads(config_json) logger.info("=" * 60) logger.info("🚀 Image Processing Service STARTED") logger.info(f"Source: {config.get('source_file', 'unknown')}") # Service starten service = ImageProcessingService(config) success = service.process() if success: logger.info("✅ Processing completed successfully") sys.exit(0) else: logger.error("❌ Processing failed") sys.exit(1) except Exception as e: logger.error(f"FATAL ERROR: {str(e)}") sys.exit(1) if __name__ == "__main__": main()