sync: auto-sync from GURU-BEAST-ROG at 2026-05-01 15:05:53
Author: Mike Swanson Machine: GURU-BEAST-ROG Timestamp: 2026-05-01 15:05:53
This commit is contained in:
@@ -549,7 +549,8 @@ def _episode_html(episode_id: int) -> str:
|
||||
# the segment stream chronologically.
|
||||
qa_rows = [dict(r) for r in qa]
|
||||
qa_starts = sorted(
|
||||
((r["question_start_sec"] or 0.0), r) for r in qa_rows
|
||||
(((r["question_start_sec"] or 0.0), r) for r in qa_rows),
|
||||
key=lambda x: x[0],
|
||||
)
|
||||
|
||||
# Right rail summary lists
|
||||
@@ -595,7 +596,8 @@ def _episode_html(episode_id: int) -> str:
|
||||
|
||||
# Intros also get inline anchors so the right-rail jump links work
|
||||
intro_by_time = sorted(
|
||||
((r["intro_time_sec"] or 0.0), r) for r in intros
|
||||
(((r["intro_time_sec"] or 0.0), r) for r in intros),
|
||||
key=lambda x: x[0],
|
||||
)
|
||||
intro_iter = iter(intro_by_time)
|
||||
next_intro = next(intro_iter, None)
|
||||
|
||||
@@ -151,3 +151,93 @@ git push origin main
|
||||
- Episode page (renders fine): `http://172.16.3.20:8765/episode/139`
|
||||
- Audio endpoint (404 — file not deployed): `http://172.16.3.20:8765/api/audio/139`
|
||||
- Mike's reported broken URL with hash: `http://172.16.3.20:8765/episode/139#qa-377`
|
||||
|
||||
---
|
||||
|
||||
## Update: 06:31 PT — Local deployment + intro/QA sort bug fix
|
||||
|
||||
### What happened
|
||||
|
||||
Mike was unclear on the relative status of the UI redesign vs. the audio-not-playing bug — they were two independent things and prior reports had conflated them. Clarified: redesign was committed (`d7ce9cb`) and pushed to Gitea but **never deployed to Jupiter**, so `172.16.3.20:8765` was still serving the prior visual design; and the audio 404 was a pre-existing Jupiter deployment gap (no `/data/episodes/` tree on that host) that was independent of any UI version.
|
||||
|
||||
Mike chose to defer the Jupiter audio-tree fix and instead **deploy the new interface locally** so he could see the redesign with working audio. Local probe found everything needed already on disk under `projects/radio-show/audio-processor/`:
|
||||
|
||||
- `.venv/Scripts/python.exe` (FastAPI 0.115.6, uvicorn 0.34.0 already installed)
|
||||
- `archive-data/archive.db` — 572 episodes (full archive, not just the 6 test episodes from the 2026-04-27 session)
|
||||
- `archive-data/episodes/` — full MP3 tree, including episode 139 (`2011/3 - March/3-26-11 HR 2.mp3`, 9.9 MB)
|
||||
|
||||
Booted uvicorn at `127.0.0.1:8765` in the background:
|
||||
|
||||
```bash
|
||||
cd c:/Users/guru/ClaudeTools/projects/radio-show/audio-processor
|
||||
ARCHIVE_DB=archive-data/archive.db EPISODES_DIR=archive-data/episodes PORT=8765 \
|
||||
.venv/Scripts/python.exe -m uvicorn server.main:app \
|
||||
--host 127.0.0.1 --port 8765 --log-level info
|
||||
```
|
||||
|
||||
Smoke tests confirmed the new UI was live and audio worked end-to-end:
|
||||
|
||||
```
|
||||
GET / : 200 (6 new-UI markers: --accent #c39733, browse-toggle, loading::after)
|
||||
GET /episode/139 : 200 (8 new-UI markers: now-playing, preload="metadata", qaBlocks)
|
||||
GET /api/audio/139 (0-127) : 206 audio/mpeg -- Range streaming working
|
||||
```
|
||||
|
||||
Mike then loaded `http://127.0.0.1:8765/episode/479#qa-1134` and got **500 Internal Server Error**. Server traceback pinpointed:
|
||||
|
||||
```
|
||||
File "server/main.py", line 597, in _episode_html
|
||||
intro_by_time = sorted(
|
||||
((r["intro_time_sec"] or 0.0), r) for r in intros
|
||||
)
|
||||
TypeError: '<' not supported between instances of 'sqlite3.Row' and 'sqlite3.Row'
|
||||
```
|
||||
|
||||
Root cause: `sorted()` over `(float, sqlite3.Row)` tuples with no `key=`. When two intros share the same `intro_time_sec`, Python's tuple comparison falls through to the second element — `sqlite3.Row` does not implement `__lt__`, so it raises. Episode 479 happens to have an intro-time collision; episode 139 didn't, which is why the bug surfaced now and not earlier. The bug is **not** caused by today's UI redesign — the offending `sorted()` call predates it. Same bug existed at line 551 for `qa_starts` (where the second element is a `dict` from `[dict(r) for r in qa]`; dict comparison is also unsupported in Python 3) — would have surfaced eventually on a QA timestamp collision.
|
||||
|
||||
Minimal fix: added `key=lambda x: x[0]` to both `sorted()` calls so the sort is strictly by timestamp. Ties are kept in DB-row order (stable sort), which is fine — the consumer (`_flush_inline_at`) only cares that items at-or-before the current segment time are flushed in non-decreasing order.
|
||||
|
||||
After restart, retested:
|
||||
|
||||
```
|
||||
GET /episode/479 : 200
|
||||
GET /episode/139 : 200 (regression check — still works)
|
||||
GET /api/audio/479 (range) : 206 audio/mpeg
|
||||
ep 479 page contains qa-1134 anchor: yes
|
||||
```
|
||||
|
||||
The fix is currently uncommitted in the working tree; Mike has not yet OK'd a commit for it.
|
||||
|
||||
### Key Decisions (this update)
|
||||
|
||||
- **Use port 8765 locally** to mirror Jupiter's port — preserves any browser bookmarks / muscle memory; no conflict because the local server binds `127.0.0.1` while Jupiter is `172.16.3.20`.
|
||||
- **`--host 127.0.0.1` (not `0.0.0.0`)** for the local server. No reason to expose this dev instance on the LAN; Jupiter is the canonical host.
|
||||
- **Minimal-diff bug fix (`key=lambda x: x[0]`) over a refactor.** The wider `sorted(...) for r in ...` shape is fine; the only defect is the tie-break behavior. Changing the data shape (e.g. dropping the tuple, using `key=lambda r: r["intro_time_sec"] or 0.0`) would have rippled into the `next_intro[0]` / `next_intro[1]` indexing further down. Two-line fix landed instead.
|
||||
|
||||
### Problems Encountered (this update)
|
||||
|
||||
- **`/episode/479` returned 500.** Root cause analyzed above — pre-existing `sorted()` tie-break bug in `_episode_html`, exposed by ep 479's intro-time collision. Fixed at lines 551 and 597 of `main.py` by adding `key=lambda x: x[0]`.
|
||||
|
||||
### Configuration Changes (this update)
|
||||
|
||||
#### Files modified (uncommitted)
|
||||
- `projects/radio-show/audio-processor/server/main.py` — added `key=lambda x: x[0]` to both `sorted()` calls at lines 551–554 (qa_starts) and 597–600 (intro_by_time). Net: +4 / −2.
|
||||
|
||||
#### Background process
|
||||
- `uvicorn` running locally on `127.0.0.1:8765`. Bash background task ID `bj1leiit0`. Log at `/tmp/radio-server.log`. Will need to be killed when Mike's done viewing (`taskkill //F //PID <pid>` or just close the terminal).
|
||||
|
||||
### Pending / Incomplete Tasks (this update)
|
||||
|
||||
- [ ] **Commit the intro/QA sort tie-break fix.** Two-line diff at lines 551 and 597 of `server/main.py`. Suggested commit subject: `radio: fix episode page 500 when intro/QA timestamps collide`. Awaiting Mike's OK.
|
||||
- [ ] **Kill the local uvicorn** (`bj1leiit0`) when Mike is done viewing. PID will be in `/tmp/radio-server.log` first line ("Started server process [N]").
|
||||
- [ ] **(Carried) Audio fix for Jupiter** — still deferred per Mike's "we'll deal with the Jupiter file tree later." Three options unchanged: rsync archive (~30–40 GB), proxy `/api/audio/{id}` to IX, point `<audio src>` at IX directly.
|
||||
|
||||
### Reference (this update)
|
||||
|
||||
- Local archive root: `c:/Users/guru/ClaudeTools/projects/radio-show/audio-processor/archive-data/`
|
||||
- DB: `archive-data/archive.db` (572 episodes, 10+ Q&A pairs across the indexed set)
|
||||
- MP3 tree: `archive-data/episodes/{YYYY}/{MM - Month}/<filename>.mp3`
|
||||
- Episode 139 file: `archive-data/episodes/2011/3 - March/3-26-11 HR 2.mp3`
|
||||
- Local server URL: `http://127.0.0.1:8765`
|
||||
- Smoke-test URL Mike was using: `http://127.0.0.1:8765/episode/479#qa-1134`
|
||||
- Server entry point: `server.main:app` (FastAPI app object); env vars `ARCHIVE_DB`, `EPISODES_DIR`, `PORT`
|
||||
|
||||
Reference in New Issue
Block a user