Fix projects page to handle dataclass objects instead of dicts

Project and Generation are dataclasses, not dicts. Added _get_attr helper
to access attributes from both dict and object types.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-27 16:22:04 +01:00
parent f3b5894e0e
commit 0a27d7c227

View File

@@ -5,6 +5,15 @@ from typing import Any, Callable, Optional
from datetime import datetime 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( def create_projects_page(
get_projects: Callable[[], list[dict]], get_projects: Callable[[], list[dict]],
get_generations: Callable[[str, int, int], list[dict]], get_generations: Callable[[str, int, int], list[dict]],
@@ -158,9 +167,9 @@ def create_projects_page(
data = [] data = []
for p in projects: for p in projects:
data.append([ data.append([
p.get("id", ""), _get_attr(p, "id", ""),
p.get("name", "Untitled"), _get_attr(p, "name", "Untitled"),
p.get("generation_count", 0), _get_attr(p, "generation_count", 0),
]) ])
return data return data
@@ -193,31 +202,31 @@ def create_projects_page(
# Filter by model if needed # Filter by model if needed
if model != "all": 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 # Filter by search
if search: if search:
search_lower = search.lower() 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 # Sort
if sort == "oldest": 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": 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": 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) # Default is newest first (already sorted from DB)
# Build gallery items (using waveform images if available) # Build gallery items (using waveform images if available)
gallery_items = [] gallery_items = []
for g in gens: for g in gens:
waveform = g.get("waveform_path") waveform = _get_attr(g, "waveform_path")
if waveform: if waveform:
gallery_items.append((waveform, g.get("prompt", "")[:50])) gallery_items.append((waveform, _get_attr(g, "prompt", "")[:50]))
else: else:
# Placeholder # Placeholder
gallery_items.append((None, g.get("prompt", "")[:50])) gallery_items.append((None, _get_attr(g, "prompt", "")[:50]))
# Calculate total pages (estimate) # Calculate total pages (estimate)
total = offset + len(gens) + (1 if has_more else 0) 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) gens = get_generations(project_id, 100, 0)
if evt.index < len(gens): if evt.index < len(gens):
gen = gens[evt.index] 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 ( return (
gen.get("audio_path"), _get_attr(gen, "audio_path"),
gen.get("prompt", ""), _get_attr(gen, "prompt", ""),
gen.get("model", ""), _get_attr(gen, "model", ""),
f"{gen.get('duration_seconds', 0):.1f}s", f"{_get_attr(gen, 'duration_seconds', 0) or 0:.1f}s",
str(gen.get("seed", "")), str(_get_attr(gen, "seed", "")),
gen.get("created_at", "")[:19] if gen.get("created_at") else "", created,
) )
return None, "", "", "", "", "" return None, "", "", "", "", ""
@@ -262,8 +276,8 @@ def create_projects_page(
# Find generation by audio path # Find generation by audio path
gens = get_generations(project_id, 100, 0) gens = get_generations(project_id, 100, 0)
for g in gens: for g in gens:
if g.get("audio_path") == audio_path: if _get_attr(g, "audio_path") == audio_path:
if delete_generation(g.get("id")): if delete_generation(_get_attr(g, "id")):
return "Generation deleted" return "Generation deleted"
else: else:
return "Failed to delete" return "Failed to delete"