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