103 lines
2.9 KiB
Python
103 lines
2.9 KiB
Python
"""Routes for exporting and importing trivia questions"""
|
|
import os
|
|
import tempfile
|
|
from flask import Blueprint, jsonify, Response, request
|
|
from werkzeug.utils import secure_filename
|
|
|
|
from backend.auth.middleware import require_auth
|
|
from backend.services.export_import_service import (
|
|
export_questions_to_zip,
|
|
import_questions_from_zip
|
|
)
|
|
|
|
bp = Blueprint('export_import', __name__, url_prefix='/api/admin')
|
|
|
|
|
|
@bp.route('/export', methods=['POST'])
|
|
@require_auth
|
|
def export_data():
|
|
"""
|
|
Export all questions and categories to a ZIP file.
|
|
|
|
Returns:
|
|
ZIP file containing manifest.json and all media files
|
|
"""
|
|
try:
|
|
# Generate export ZIP
|
|
zip_bytes, zip_filename = export_questions_to_zip()
|
|
|
|
# Create response with ZIP file
|
|
response = Response(
|
|
zip_bytes,
|
|
mimetype='application/zip',
|
|
headers={
|
|
'Content-Disposition': f'attachment; filename={zip_filename}',
|
|
'Content-Length': str(len(zip_bytes))
|
|
}
|
|
)
|
|
|
|
return response
|
|
|
|
except Exception as e:
|
|
return jsonify({'error': f'Export failed: {str(e)}'}), 500
|
|
|
|
|
|
@bp.route('/import', methods=['POST'])
|
|
@require_auth
|
|
def import_data():
|
|
"""
|
|
Import questions and categories from a ZIP file.
|
|
|
|
Expects:
|
|
multipart/form-data with 'file' key containing ZIP file
|
|
|
|
Returns:
|
|
JSON with import summary
|
|
"""
|
|
# Check if file was uploaded
|
|
if 'file' not in request.files:
|
|
return jsonify({'error': 'No file provided'}), 400
|
|
|
|
file = request.files['file']
|
|
|
|
# Check if filename is present
|
|
if file.filename == '':
|
|
return jsonify({'error': 'No file selected'}), 400
|
|
|
|
# Check if file is a ZIP
|
|
if not file.filename.lower().endswith('.zip'):
|
|
return jsonify({'error': 'File must be a ZIP archive'}), 400
|
|
|
|
temp_path = None
|
|
|
|
try:
|
|
# Save uploaded file to temporary location
|
|
temp_dir = tempfile.mkdtemp()
|
|
temp_path = os.path.join(temp_dir, secure_filename(file.filename))
|
|
file.save(temp_path)
|
|
|
|
# Import from ZIP
|
|
result = import_questions_from_zip(temp_path)
|
|
|
|
return jsonify(result), 200
|
|
|
|
except ValueError as e:
|
|
# Validation errors
|
|
return jsonify({'error': str(e)}), 400
|
|
|
|
except Exception as e:
|
|
# Other errors
|
|
return jsonify({'error': f'Import failed: {str(e)}'}), 500
|
|
|
|
finally:
|
|
# Clean up uploaded file
|
|
if temp_path and os.path.exists(temp_path):
|
|
try:
|
|
os.remove(temp_path)
|
|
# Remove temp directory if empty
|
|
temp_dir = os.path.dirname(temp_path)
|
|
if os.path.exists(temp_dir) and not os.listdir(temp_dir):
|
|
os.rmdir(temp_dir)
|
|
except Exception as e:
|
|
print(f"Warning: Failed to clean up temp file {temp_path}: {e}")
|