ferrero-opentext/Python-Version/scripts/reset_campaign_to_a1.py
DJP a2e1058d20 Add interactive campaign status management scripts
Created 2 new interactive scripts for manual campaign status control:

1. reset_campaign_to_a1.py
   - Resets any campaign from any A# status back to A1
   - Allows filtering by specific status (--status A2, A3, A4, etc.)
   - Interactive yes/no confirmation for each campaign
   - Shows campaign name, number, and current status
   - Processes one at a time, waits for user input
   - Summary statistics at the end

2. advance_a1_to_a3.py
   - Advances A1 campaigns directly to A3 (skips A2)
   - Useful for testing A2→A3 upload workflow
   - Interactive yes/no confirmation for each campaign
   - Shows campaign details before advancing
   - Summary statistics at the end

Both scripts:
- Support --auth-pfx flag for mTLS authentication
- Process campaigns one at a time (not batch)
- Wait for user input before proceeding
- Provide clear feedback on success/failure
- Useful for testing and manual workflow control

Updated README.md with complete documentation and examples

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 15:23:26 -05:00

171 lines
5.2 KiB
Python
Executable file

#!/usr/bin/env python3
"""
Interactive Campaign Status Reset to A1
Allows user to reset any campaign from any A# status back to A1
Shows campaign details and asks for confirmation for each one
Compatible with Python 3.6+
"""
import sys
import os
import logging
import argparse
# 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.dam_client import DAMClient
# Setup simple console logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger('ResetToA1')
def get_user_confirmation(campaign_name, campaign_number, current_status):
"""
Ask user if they want to reset this campaign to A1
Args:
campaign_name: Campaign name
campaign_number: Campaign number (e.g., C000000078)
current_status: Current status (A2, A3, A4, etc.)
Returns:
bool: True if user says yes, False if no
"""
print("")
print("=" * 70)
print("Campaign: {}".format(campaign_name))
print("Number: {}".format(campaign_number if campaign_number else 'N/A'))
print("Current: {}".format(current_status))
print("=" * 70)
while True:
response = input("Reset this campaign to A1? (yes/no): ").strip().lower()
if response in ['yes', 'y']:
return True
elif response in ['no', 'n']:
return False
else:
print("Please enter 'yes' or 'no'")
def main():
"""Main interactive loop"""
# Parse command-line arguments
parser = argparse.ArgumentParser(description='Interactive Campaign Status Reset to A1')
parser.add_argument('--auth-pfx', action='store_true',
help='Use mTLS certificate authentication instead of OAuth2')
parser.add_argument('--status', type=str, default=None,
help='Filter for specific status (e.g., A2, A3, A4). If not specified, shows all A# statuses')
args = parser.parse_args()
print("")
print("=" * 70)
print("Ferrero Campaign Status Reset to A1")
if args.auth_pfx:
print("Authentication: mTLS Certificate (--auth-pfx)")
else:
print("Authentication: OAuth2 (default)")
if args.status:
print("Filter: Showing only {} campaigns".format(args.status))
else:
print("Filter: Showing all A# status campaigns (A2, A3, A4, A5, A6, etc.)")
print("=" * 70)
print("")
# Load configuration
config = load_config('config/config.yaml')
# Initialize DAM client
dam = DAMClient(config, use_mtls=args.auth_pfx)
# Test connection
logger.info("Testing DAM connection...")
if not dam.test_connection():
logger.error("DAM connection failed - exiting")
sys.exit(1)
logger.info("DAM connection OK")
print("")
# Get all campaigns with A# status
logger.info("Searching for campaigns...")
print("")
# If specific status specified, search for that
if args.status:
statuses_to_check = [args.status.upper()]
else:
# Check common A# statuses
statuses_to_check = ['A2', 'A3', 'A4', 'A5', 'A6']
all_campaigns = []
for status in statuses_to_check:
campaigns = dam.search_campaigns(status=status)
if campaigns:
logger.info("Found {} campaigns with status {}".format(len(campaigns), status))
all_campaigns.extend(campaigns)
if not all_campaigns:
print("")
print("No campaigns found with A# status")
print("Exiting...")
sys.exit(0)
print("")
print("=" * 70)
print("Found {} total campaign(s) to review".format(len(all_campaigns)))
print("=" * 70)
print("")
# Process each campaign
reset_count = 0
skipped_count = 0
for i, campaign in enumerate(all_campaigns, 1):
campaign_id = campaign['asset_id']
campaign_name = campaign['campaign_name']
campaign_number = campaign.get('campaign_id', 'N/A')
current_status = campaign.get('status', 'Unknown')
print("")
print("Campaign {}/{}".format(i, len(all_campaigns)))
# Ask user for confirmation
if get_user_confirmation(campaign_name, campaign_number, current_status):
# User said yes - reset to A1
print("")
print("Resetting campaign to A1...")
result = dam.update_campaign_status(campaign_id, 'A1')
if result['success']:
print("✓ SUCCESS: Campaign reset to A1")
reset_count += 1
else:
print("✗ FAILED: {}".format(result.get('error', 'Unknown error')))
print("Continuing to next campaign...")
else:
# User said no - skip
print("Skipped (no change)")
skipped_count += 1
# Final summary
print("")
print("=" * 70)
print("Summary")
print("=" * 70)
print("Total campaigns reviewed: {}".format(len(all_campaigns)))
print("Reset to A1: {}".format(reset_count))
print("Skipped: {}".format(skipped_count))
print("=" * 70)
print("")
print("Done!")
if __name__ == '__main__':
main()