Major Features: - Complete Ferrero ↔ CreativeX mapping system with 93 brands - Automated Box.com folder monitoring service - Email notifications with score breakdowns - Database integration for result storage Mapping System (v2.0.0): - mappings.json: 93 brand mappings, 44+ channel mappings - core/mapping_resolver.py: Translates Ferrero codes to CreativeX format - scripts/validate_mappings.py: Validation tool for brand/channel support - scripts/generate_brand_mappings.py: Auto-mapping tool - scripts/download_reports.py: Scorecard PDF download tool - Updated scripts/upload.py: Integrated mapping validation - Updated scripts/check_status.py: Added detailed score display with guidelines Documentation: - Updated README.md: Complete user guide with mapping system - Updated STATUS.md: Production-ready status with test results - MAPPINGS_GUIDE.md: Complete mapping documentation - MAPPING_IMPLEMENTATION.md: Implementation summary - BRAND_MAPPINGS_REVIEW.md: Brand mapping validation guide - PRODUCTION_BRANDS_SUMMARY.md: Production brand catalog - PRODUCTION_MAPPING_COMPLETE.md: Mapping completion summary Automation Service (New): - creativex-automation/: Complete automated Box monitoring service - Monitors Box Ferrero-In folder (363284027140) for new files - Automatically uploads to CreativeX - Polls for completion (30 min intervals) - Extracts scores and stores in PostgreSQL creativex_scores table - Sends formatted emails to file uploader + daveporter@oliver.agency - Moves processed files to Processed subfolder Service Components: - automation/box_monitor.py: Box folder monitoring with uploader detection - automation/upload_processor.py: CreativeX upload integration - automation/status_poller.py: CreativeX status polling - automation/result_handler.py: Score extraction and email sending - automation/orchestrator.py: Service coordination - automation/processing_queue.py: JSON-based processing queue - service.py: Main service entry point - config.py: Service configuration loader - requirements.txt: All dependencies - deployment/systemd/: Systemd service unit file - Updated shared/notifier.py: Added creativex_upload_complete and creativex_upload_failed templates Testing: - Supports --dry-run mode for configuration testing - Supports --scan-once mode for Box folder testing - Manual run mode for development/testing - Comprehensive logging with rotation (10MB, 28 backups) Database Integration: - Uses existing creativex_scores table (no migrations needed) - Compatible with existing Ferrero-Opentext workflows - Stores full CreativeX API responses in JSONB Email Templates: - Matches Ferrero-Opentext styling (#9c27b0 purple for CreativeX) - Includes score, tier, guidelines breakdown, scorecard URL - Recipients: Box uploader + CC to daveporter@oliver.agency Deployment: - Runs locally for dev/testing - Systemd service for production - Auto-restart on failure - Complete documentation in creativex-automation/README.md Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
77 lines
2 KiB
Python
77 lines
2 KiB
Python
"""
|
|
Logging configuration for CreativeX API Integration
|
|
"""
|
|
|
|
import logging
|
|
import sys
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from typing import Optional
|
|
|
|
|
|
def setup_logger(
|
|
name: str,
|
|
log_dir: Optional[Path] = None,
|
|
log_level: str = "INFO",
|
|
console_output: bool = True
|
|
) -> logging.Logger:
|
|
"""
|
|
Configure and return a logger with file and console handlers
|
|
|
|
Args:
|
|
name: Logger name (typically __name__ from calling module)
|
|
log_dir: Directory for log files (None to skip file logging)
|
|
log_level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
|
|
console_output: Whether to output to console
|
|
|
|
Returns:
|
|
logging.Logger: Configured logger instance
|
|
"""
|
|
# Create logger
|
|
logger = logging.getLogger(name)
|
|
logger.setLevel(getattr(logging, log_level.upper()))
|
|
|
|
# Prevent duplicate handlers
|
|
if logger.handlers:
|
|
return logger
|
|
|
|
# Create formatter
|
|
formatter = logging.Formatter(
|
|
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
datefmt='%Y-%m-%d %H:%M:%S'
|
|
)
|
|
|
|
# Console handler
|
|
if console_output:
|
|
console_handler = logging.StreamHandler(sys.stdout)
|
|
console_handler.setLevel(logging.INFO)
|
|
console_handler.setFormatter(formatter)
|
|
logger.addHandler(console_handler)
|
|
|
|
# File handler
|
|
if log_dir:
|
|
log_dir.mkdir(parents=True, exist_ok=True)
|
|
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
|
log_file = log_dir / f'creativex_{timestamp}.log'
|
|
|
|
file_handler = logging.FileHandler(log_file, encoding='utf-8')
|
|
file_handler.setLevel(logging.DEBUG) # File gets everything
|
|
file_handler.setFormatter(formatter)
|
|
logger.addHandler(file_handler)
|
|
|
|
logger.info(f"Logging to file: {log_file}")
|
|
|
|
return logger
|
|
|
|
|
|
def get_logger(name: str) -> logging.Logger:
|
|
"""
|
|
Get an existing logger or create a basic one
|
|
|
|
Args:
|
|
name: Logger name
|
|
|
|
Returns:
|
|
logging.Logger: Logger instance
|
|
"""
|
|
return logging.getLogger(name)
|