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:
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user