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:
75
tools/ora_editor/services/file_browser.py
Normal file
75
tools/ora_editor/services/file_browser.py
Normal file
@@ -0,0 +1,75 @@
|
||||
"""File browsing service for project directory navigation."""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
class FileBrowserService:
|
||||
"""Service for browsing project files and directories."""
|
||||
|
||||
SUPPORTED_EXTENSIONS = {'.png', '.ora'}
|
||||
|
||||
def __init__(self, project_root: Path):
|
||||
self.project_root = project_root
|
||||
|
||||
def list_directory(self, relative_path: str = "") -> dict[str, Any]:
|
||||
"""List contents of a directory relative to project root."""
|
||||
if relative_path:
|
||||
dir_path = self.project_root / relative_path
|
||||
else:
|
||||
dir_path = self.project_root
|
||||
|
||||
if not dir_path.exists() or not dir_path.is_dir():
|
||||
return {
|
||||
'success': False,
|
||||
'error': f'Directory not found: {relative_path}'
|
||||
}
|
||||
|
||||
directories = []
|
||||
files = []
|
||||
|
||||
try:
|
||||
for entry in sorted(dir_path.iterdir(), key=lambda e: (not e.is_dir(), e.name.lower())):
|
||||
if entry.name.startswith('.'):
|
||||
continue
|
||||
|
||||
if entry.is_dir():
|
||||
rel_path = str(entry.relative_to(self.project_root))
|
||||
directories.append({
|
||||
'name': entry.name,
|
||||
'path': rel_path
|
||||
})
|
||||
elif entry.is_file():
|
||||
suffix = entry.suffix.lower()
|
||||
if suffix in self.SUPPORTED_EXTENSIONS:
|
||||
rel_path = str(entry.relative_to(self.project_root))
|
||||
files.append({
|
||||
'name': entry.name,
|
||||
'path': rel_path,
|
||||
'type': suffix[1:]
|
||||
})
|
||||
|
||||
parent_path = None
|
||||
if relative_path:
|
||||
parent = Path(relative_path).parent
|
||||
parent_path = str(parent) if parent != Path('.') else ""
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'current_path': relative_path,
|
||||
'parent_path': parent_path,
|
||||
'directories': directories,
|
||||
'files': files
|
||||
}
|
||||
|
||||
except PermissionError:
|
||||
return {
|
||||
'success': False,
|
||||
'error': f'Permission denied: {relative_path}'
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}
|
||||
Reference in New Issue
Block a user