#!/usr/bin/env python3 """ Manual CSV Regenerator Force-generates and uploads the live campaigns CSV to Box. Useful for updating the report format for all existing campaigns. """ import sys import os import logging import csv from datetime import datetime, timezone # Add shared library to path sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) from shared.config_loader import load_config from shared.box_client import BoxClient from shared.database import Database # Setup logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger('ManualCSV') def generate_and_upload_csv(db, box, config): """ Generate CSV of all live campaigns and upload to Box """ try: logger.info("Generating live campaigns CSV...") # 1. Get all live campaigns from DB campaigns = db.get_all_live_campaigns() if not campaigns: logger.warning("No live campaigns found to report") logger.info("Found {} live campaigns".format(len(campaigns))) # 2. Generate CSV file timestamp = datetime.now(timezone.utc).strftime('%Y-%m-%d_%H%M%S_UTC') csv_filename = 'live_campaigns_{}.csv'.format(timestamp) csv_path = os.path.join('temp', csv_filename) os.makedirs('temp', exist_ok=True) with open(csv_path, 'w', newline='') as csvfile: fieldnames = ['code', 'description'] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() for camp in campaigns: # UPDATED FORMAT: CampaignNumber-CampaignName writer.writerow({ 'code': "{}-{}".format(camp['campaign_number'], camp['campaign_name']), 'description': camp['campaign_name'] }) logger.info("Generated CSV: {}".format(csv_path)) # 3. Upload to Box folder_id = config['box'].get('live_campaigns_folder_id') if not folder_id: logger.error("Box live_campaigns_folder_id not configured") return False upload_result = box.upload_file( file_path=csv_path, folder_id=folder_id, target_filename=csv_filename ) logger.info("Uploaded CSV to Box: {} (File ID: {})".format( csv_filename, upload_result['file_id'] )) # Clean up os.remove(csv_path) return True except Exception as e: logger.error("Failed to generate/upload CSV: {}".format(str(e))) return False def main(): logger.info("=" * 60) logger.info("Manual CSV Regenerator Starting") logger.info("=" * 60) # Load configuration config = load_config('config/config.yaml') # Initialize clients box = BoxClient(config) db = Database(config) # Test connections logger.info("Testing connections...") if not box.test_connection(): logger.error("Box connection failed - exiting") sys.exit(1) if not db.test_connection(): logger.error("Database connection failed - exiting") sys.exit(1) logger.info("Connections OK") logger.info("") # Run generation success = generate_and_upload_csv(db, box, config) db.close() if success: logger.info("✓ CSV regeneration completed successfully") sys.exit(0) else: logger.error("✗ CSV regeneration failed") sys.exit(1) if __name__ == '__main__': main()