import
This commit is contained in:
102
backend/routes/export_import.py
Normal file
102
backend/routes/export_import.py
Normal file
@@ -0,0 +1,102 @@
|
||||
"""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}")
|
||||
Reference in New Issue
Block a user