diff --git a/src/ui/pages/projects_page.py b/src/ui/pages/projects_page.py index ee41249..4901f94 100644 --- a/src/ui/pages/projects_page.py +++ b/src/ui/pages/projects_page.py @@ -5,6 +5,15 @@ from typing import Any, Callable, Optional from datetime import datetime +def _get_attr(obj, key, default=None): + """Get attribute from dict or object.""" + if hasattr(obj, key): + return getattr(obj, key, default) + elif isinstance(obj, dict): + return obj.get(key, default) + return default + + def create_projects_page( get_projects: Callable[[], list[dict]], get_generations: Callable[[str, int, int], list[dict]], @@ -158,9 +167,9 @@ def create_projects_page( data = [] for p in projects: data.append([ - p.get("id", ""), - p.get("name", "Untitled"), - p.get("generation_count", 0), + _get_attr(p, "id", ""), + _get_attr(p, "name", "Untitled"), + _get_attr(p, "generation_count", 0), ]) return data @@ -193,31 +202,31 @@ def create_projects_page( # Filter by model if needed if model != "all": - gens = [g for g in gens if g.get("model") == model] + gens = [g for g in gens if _get_attr(g, "model") == model] # Filter by search if search: search_lower = search.lower() - gens = [g for g in gens if search_lower in g.get("prompt", "").lower()] + gens = [g for g in gens if search_lower in _get_attr(g, "prompt", "").lower()] # Sort if sort == "oldest": - gens = sorted(gens, key=lambda x: x.get("created_at", "")) + gens = sorted(gens, key=lambda x: _get_attr(x, "created_at", "")) elif sort == "duration_desc": - gens = sorted(gens, key=lambda x: x.get("duration_seconds", 0), reverse=True) + gens = sorted(gens, key=lambda x: _get_attr(x, "duration_seconds", 0) or 0, reverse=True) elif sort == "duration_asc": - gens = sorted(gens, key=lambda x: x.get("duration_seconds", 0)) + gens = sorted(gens, key=lambda x: _get_attr(x, "duration_seconds", 0) or 0) # Default is newest first (already sorted from DB) # Build gallery items (using waveform images if available) gallery_items = [] for g in gens: - waveform = g.get("waveform_path") + waveform = _get_attr(g, "waveform_path") if waveform: - gallery_items.append((waveform, g.get("prompt", "")[:50])) + gallery_items.append((waveform, _get_attr(g, "prompt", "")[:50])) else: # Placeholder - gallery_items.append((None, g.get("prompt", "")[:50])) + gallery_items.append((None, _get_attr(g, "prompt", "")[:50])) # Calculate total pages (estimate) total = offset + len(gens) + (1 if has_more else 0) @@ -234,13 +243,18 @@ def create_projects_page( gens = get_generations(project_id, 100, 0) if evt.index < len(gens): gen = gens[evt.index] + created = _get_attr(gen, "created_at", "") + if hasattr(created, 'isoformat'): + created = created.isoformat()[:19] + elif created: + created = str(created)[:19] return ( - gen.get("audio_path"), - gen.get("prompt", ""), - gen.get("model", ""), - f"{gen.get('duration_seconds', 0):.1f}s", - str(gen.get("seed", "")), - gen.get("created_at", "")[:19] if gen.get("created_at") else "", + _get_attr(gen, "audio_path"), + _get_attr(gen, "prompt", ""), + _get_attr(gen, "model", ""), + f"{_get_attr(gen, 'duration_seconds', 0) or 0:.1f}s", + str(_get_attr(gen, "seed", "")), + created, ) return None, "", "", "", "", "" @@ -262,8 +276,8 @@ def create_projects_page( # Find generation by audio path gens = get_generations(project_id, 100, 0) for g in gens: - if g.get("audio_path") == audio_path: - if delete_generation(g.get("id")): + if _get_attr(g, "audio_path") == audio_path: + if delete_generation(_get_attr(g, "id")): return "Generation deleted" else: return "Failed to delete"