shop-old/modules/import/image_processing_service.py
2026-04-20 01:03:43 +02:00

151 lines
4.9 KiB
Python

#!/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()