feat: Flask 애플리케이션 모듈화 및 웹 대시보드 구현
- Flask Blueprint 아키텍처로 전환 (dashboard, upload, backup, status) - app.py 681줄 95줄로 축소 (86% 감소) - HTML 템플릿 모듈화 (base.html + 기능별 templates) - CSS/JS 파일 분리 (common + 기능별 파일) - 대시보드 기능 추가 (통계, 주간 예보, 방문객 추이) - 파일 업로드 웹 인터페이스 구현 - 백업/복구 관리 UI 구현 - Docker 배포 환경 개선 - .gitignore 업데이트 (uploads, backups, cache 등)
This commit is contained in:
129
app/blueprints/backup.py
Normal file
129
app/blueprints/backup.py
Normal file
@ -0,0 +1,129 @@
|
||||
# app/blueprints/backup.py
|
||||
"""
|
||||
백업 관리 블루프린트
|
||||
|
||||
역할:
|
||||
- 데이터베이스 백업 생성
|
||||
- 백업 복구
|
||||
- 백업 목록 조회
|
||||
"""
|
||||
|
||||
from flask import Blueprint, render_template, request, jsonify
|
||||
import sys
|
||||
import os
|
||||
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
|
||||
|
||||
from app.file_processor import FileProcessor
|
||||
|
||||
backup_bp = Blueprint('backup', __name__, url_prefix='/api')
|
||||
|
||||
|
||||
def get_file_processor(upload_folder):
|
||||
"""파일 프로세서 인스턴스 반환"""
|
||||
return FileProcessor(upload_folder)
|
||||
|
||||
|
||||
@backup_bp.route('/backup-page')
|
||||
def index():
|
||||
"""백업 관리 페이지"""
|
||||
return render_template('backup.html')
|
||||
|
||||
|
||||
@backup_bp.route('/backup', methods=['POST'])
|
||||
def create_backup():
|
||||
"""
|
||||
새 백업 생성
|
||||
|
||||
응답:
|
||||
{
|
||||
'success': bool,
|
||||
'message': str,
|
||||
'filename': str (선택사항)
|
||||
}
|
||||
"""
|
||||
try:
|
||||
backup_folder = os.path.join(os.path.dirname(__file__), '..', '..', 'backups')
|
||||
os.makedirs(backup_folder, exist_ok=True)
|
||||
|
||||
file_processor = get_file_processor(backup_folder)
|
||||
backup_info = file_processor.create_database_backup()
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': '백업이 생성되었습니다.',
|
||||
'filename': backup_info.get('filename')
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': f'백업 생성 실패: {str(e)}'
|
||||
}), 500
|
||||
|
||||
|
||||
@backup_bp.route('/backups', methods=['GET'])
|
||||
def get_backups():
|
||||
"""
|
||||
백업 목록 조회
|
||||
|
||||
응답:
|
||||
{
|
||||
'backups': List[dict] - [{'filename': str, 'size': int, 'created': str}, ...]
|
||||
}
|
||||
"""
|
||||
try:
|
||||
backup_folder = os.path.join(os.path.dirname(__file__), '..', '..', 'backups')
|
||||
os.makedirs(backup_folder, exist_ok=True)
|
||||
|
||||
file_processor = get_file_processor(backup_folder)
|
||||
backups = file_processor.list_database_backups()
|
||||
|
||||
return jsonify({'backups': backups})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'error': str(e)
|
||||
}), 500
|
||||
|
||||
|
||||
@backup_bp.route('/restore', methods=['POST'])
|
||||
def restore_backup():
|
||||
"""
|
||||
백업 복구
|
||||
|
||||
요청:
|
||||
{
|
||||
'filename': str - 복구할 백업 파일명
|
||||
}
|
||||
|
||||
응답:
|
||||
{
|
||||
'success': bool,
|
||||
'message': str
|
||||
}
|
||||
"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
filename = data.get('filename')
|
||||
|
||||
if not filename:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': '파일명을 지정하세요.'
|
||||
}), 400
|
||||
|
||||
backup_folder = os.path.join(os.path.dirname(__file__), '..', '..', 'backups')
|
||||
file_processor = get_file_processor(backup_folder)
|
||||
file_processor.restore_database_backup(filename)
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': '데이터베이스가 복구되었습니다.'
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': f'복구 실패: {str(e)}'
|
||||
}), 500
|
||||
Reference in New Issue
Block a user