Initial import: Carteasy Shop (Dev-Stand)
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user