ac-tool/backend/server/api/export.py
Vadym Samoilenko 72c50b2c92 Initial commit — AC Tool unified application
Merges ac-helper (PHP Activation Calendar) and brief-extractor (Python AI)
into a single Docker app with React/TypeScript frontend.

Features:
- Brief upload → AI extraction → review → Activation Calendar import
- Handsontable v17 spreadsheet with dependent dropdowns (148 categories)
- AI natural language commands via Gemini (YOLO mode, voice input)
- Azure AD MSAL SPA PKCE authentication, user roles (user/admin)
- CSV Activation Calendar export
- Real-time WebSocket job progress
- Admin: user management, dropdown Excel upload
- Multi-stage Dockerfile, docker-compose, nginx proxy instructions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 13:24:46 +00:00

62 lines
2 KiB
Python

"""
CSV export — Activation Calendar format.
Mirrors the export logic from script.js in ac-helper.
"""
import csv
import io
import logging
from quart import Blueprint, make_response
from ..auth.middleware import auth_required, get_user_id
from ..sheets.manager import load_sheet_data
logger = logging.getLogger(__name__)
export_bp = Blueprint('export', __name__, url_prefix='/api/sheets')
# Activation Calendar column order
AC_HEADERS = [
'Number', 'Title', 'Status', 'Category', 'Media', 'Sub media',
'Destination', 'Format', 'Supply date', 'Live date', 'End date',
'Special instructions', 'Language', 'Country', 'Quantity',
]
@export_bp.route('/<sheet_id>/export', methods=['GET'])
@auth_required
async def export_csv(sheet_id: str):
user_id = get_user_id()
data = load_sheet_data(user_id, sheet_id)
if data is None:
return {'error': 'not_found'}, 404
output = io.StringIO()
writer = csv.DictWriter(output, fieldnames=AC_HEADERS, extrasaction='ignore')
writer.writeheader()
for row in data:
writer.writerow({
'Number': '', # cleared on export
'Title': row.get('Title', ''),
'Status': row.get('Status', ''),
'Category': row.get('Category', ''),
'Media': row.get('Media', ''),
'Sub media': row.get('Sub-media', ''),
'Destination': '',
'Format': row.get('Format', ''),
'Supply date': row.get('Supply date', ''),
'Live date': row.get('Live date', ''),
'End date': '',
'Special instructions': '',
'Language': row.get('Language', ''),
'Country': row.get('Country', ''),
'Quantity': '1.00',
})
csv_content = output.getvalue()
response = await make_response(csv_content)
response.headers['Content-Type'] = 'text/csv'
response.headers['Content-Disposition'] = f'attachment; filename="activation_calendar_{sheet_id}.csv"'
return response