Files
ai-game-2/tools/ora_editor/services/file_browser.py
Bryce fb812e57bc 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
2026-03-27 21:29:27 -07:00

76 lines
2.5 KiB
Python

"""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)
}