Restructure ORA editor into modular blueprints with browse dialog
- Split app.py into route blueprints (files, layers, images, polygon, mask, krita) - Create services layer (polygon_storage, comfyui, file_browser) - Extract config constants to config.py - Split templates into Jinja partials (base, components, modals) - Add browse dialog for visual file navigation - Add /api/browse endpoint for directory listing
This commit is contained in:
100
tools/ora_editor/routes/files.py
Normal file
100
tools/ora_editor/routes/files.py
Normal file
@@ -0,0 +1,100 @@
|
||||
"""File operations routes for ORA Editor."""
|
||||
|
||||
import zipfile
|
||||
from flask import Blueprint, request, jsonify
|
||||
from pathlib import Path
|
||||
|
||||
from ora_editor.config import PROJECT_ROOT, TEMP_DIR
|
||||
from ora_editor.ora_ops import (
|
||||
load_ora, create_ora_from_png, parse_stack_xml, save_ora
|
||||
)
|
||||
from ora_editor.services.file_browser import FileBrowserService
|
||||
from ora_editor.services import polygon_storage
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
files_bp = Blueprint('files', __name__)
|
||||
browser_service = FileBrowserService(PROJECT_ROOT)
|
||||
|
||||
|
||||
def ensure_ora_exists(input_path: str) -> str | None:
|
||||
"""Ensure an ORA file exists, creating from PNG if necessary."""
|
||||
full_path = PROJECT_ROOT / input_path
|
||||
|
||||
if not full_path.exists():
|
||||
return None
|
||||
|
||||
if full_path.suffix.lower() == '.png':
|
||||
ora_path = str(full_path.with_suffix('.ora'))
|
||||
result = create_ora_from_png(str(full_path), ora_path)
|
||||
if not result.get('success'):
|
||||
return None
|
||||
return ora_path
|
||||
|
||||
try:
|
||||
parse_stack_xml(str(full_path))
|
||||
return str(full_path)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
@files_bp.route('/api/browse')
|
||||
def api_browse():
|
||||
"""Browse project directory structure."""
|
||||
path = request.args.get('path', '')
|
||||
return jsonify(browser_service.list_directory(path))
|
||||
|
||||
|
||||
@files_bp.route('/api/open', methods=['POST'])
|
||||
def api_open():
|
||||
"""Open a file (PNG or ORA)."""
|
||||
data = request.get_json()
|
||||
|
||||
if not data or 'path' not in data:
|
||||
return jsonify({'success': False, 'error': 'Missing path parameter'}), 400
|
||||
|
||||
input_path = data['path']
|
||||
ora_path = ensure_ora_exists(input_path)
|
||||
|
||||
if not ora_path:
|
||||
return jsonify({'success': False, 'error': f'File not found or invalid: {input_path}'}), 404
|
||||
|
||||
try:
|
||||
loaded = load_ora(ora_path)
|
||||
|
||||
layers = []
|
||||
for layer in loaded['layers']:
|
||||
layers.append({
|
||||
'name': layer['name'],
|
||||
'src': layer['src'],
|
||||
'group': layer.get('group'),
|
||||
'visible': layer.get('visible', True)
|
||||
})
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'ora_path': ora_path,
|
||||
'width': loaded['width'],
|
||||
'height': loaded['height'],
|
||||
'layers': layers
|
||||
})
|
||||
except Exception as e:
|
||||
return jsonify({'success': False, 'error': f'Error loading ORA: {str(e)}'}), 500
|
||||
|
||||
|
||||
@files_bp.route('/api/save', methods=['POST'])
|
||||
def api_save():
|
||||
"""Save the current ORA state."""
|
||||
data = request.get_json()
|
||||
|
||||
if not data or 'ora_path' not in data:
|
||||
return jsonify({'success': False, 'error': 'Missing ora_path parameter'}), 400
|
||||
|
||||
ora_path = data['ora_path']
|
||||
result = save_ora(ora_path)
|
||||
|
||||
if result:
|
||||
return jsonify({'success': True, 'ora_path': ora_path})
|
||||
else:
|
||||
return jsonify({'success': False, 'error': 'Failed to save ORA'}), 500
|
||||
Reference in New Issue
Block a user