chore: exclude chat-summaries from version control
Add chat-summaries/ to .gitignore and remove tracked files from index. Made-with: Cursor
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -23,3 +23,6 @@ build/
|
|||||||
# Environment / secrets
|
# Environment / secrets
|
||||||
.env
|
.env
|
||||||
.env.*
|
.env.*
|
||||||
|
|
||||||
|
# AI session artifacts
|
||||||
|
chat-summaries/
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
# NtR SoundCloud Fetcher — Full Implementation
|
|
||||||
|
|
||||||
## Task Description
|
|
||||||
|
|
||||||
Designed and implemented a Python service that polls NicktheRat's SoundCloud likes, builds weekly playlists aligned to the Wednesday 22:00 ET show schedule, and serves them via a JSON API for an IRC bot.
|
|
||||||
|
|
||||||
## Changes Made
|
|
||||||
|
|
||||||
### Design Phase
|
|
||||||
- Brainstormed requirements through 6 clarifying questions
|
|
||||||
- Evaluated 3 architectural approaches, selected single-process daemon
|
|
||||||
- Produced design doc covering architecture, data model, API, poller logic
|
|
||||||
- Produced 13-task TDD implementation plan
|
|
||||||
|
|
||||||
### Implementation (42 tests, all passing, lint clean)
|
|
||||||
|
|
||||||
| Module | File | Purpose |
|
|
||||||
|--------|------|---------|
|
|
||||||
| Config | `src/ntr_fetcher/config.py` | Pydantic settings with `NTR_` env prefix |
|
|
||||||
| Week | `src/ntr_fetcher/week.py` | DST-aware Wednesday 22:00 ET boundary computation |
|
|
||||||
| Models | `src/ntr_fetcher/models.py` | Track, Show, ShowTrack dataclasses |
|
|
||||||
| Database | `src/ntr_fetcher/db.py` | SQLite schema, CRUD, track sync with unlike removal |
|
|
||||||
| SoundCloud | `src/ntr_fetcher/soundcloud.py` | client_id extraction, user resolution, likes fetching |
|
|
||||||
| Poller | `src/ntr_fetcher/poller.py` | Hourly polling with supervised restart |
|
|
||||||
| API | `src/ntr_fetcher/api.py` | FastAPI routes for playlist, shows, admin, health |
|
|
||||||
| Main | `src/ntr_fetcher/main.py` | Entry point wiring everything together |
|
|
||||||
|
|
||||||
### Key Design Decisions
|
|
||||||
- Tracks removed when Nick unlikes them (positions re-compact)
|
|
||||||
- Cursor-seeking for efficient SoundCloud API pagination
|
|
||||||
- Automatic client_id rotation on 401
|
|
||||||
- Supervisor restarts poller on failure without affecting API
|
|
||||||
|
|
||||||
## Follow-up Items
|
|
||||||
|
|
||||||
- **Incremental fetching**: Currently fetches full week every poll; could optimize to stop at known tracks
|
|
||||||
- **Retry/backoff for non-401 errors**: 429, 5xx, timeouts not yet handled with retries
|
|
||||||
- **`full` parameter**: Accepted but currently equivalent to normal poll (no incremental to differentiate from)
|
|
||||||
- **`soundcloud_url` in admin add track**: Removed from API; only `track_id` supported
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
# IRC Bot Plugins — Sopel + Limnoria
|
|
||||||
|
|
||||||
**Date**: 2026-03-12
|
|
||||||
**Task**: Design and implement two functionally-identical IRC bot plugins (Sopel and Limnoria) that query the NtR SoundCloud Fetcher API.
|
|
||||||
|
|
||||||
## Changes Made
|
|
||||||
|
|
||||||
### New files
|
|
||||||
- `plugins/sopel/ntr_playlist.py` — Single-file Sopel plugin
|
|
||||||
- `plugins/limnoria/NtrPlaylist/__init__.py` — Limnoria plugin package init
|
|
||||||
- `plugins/limnoria/NtrPlaylist/config.py` — Limnoria registry config
|
|
||||||
- `plugins/limnoria/NtrPlaylist/plugin.py` — Limnoria command handlers
|
|
||||||
- `plugins/limnoria/NtrPlaylist/test.py` — Limnoria test stub
|
|
||||||
- `tests/test_plugin_helpers.py` — 13 tests for formatting and API helpers
|
|
||||||
- `docs/plans/2026-03-12-irc-plugins-design.md` — Design document
|
|
||||||
- `docs/plans/2026-03-12-irc-plugins-implementation.md` — Implementation plan
|
|
||||||
|
|
||||||
### Commands implemented (identical in both)
|
|
||||||
- `!1`, `!2`, etc. — Track by position (regex catch-all)
|
|
||||||
- `!song <episode> <position>` — Track from specific episode
|
|
||||||
- `!playlist [episode]` — Full playlist (comma-separated, truncated for IRC)
|
|
||||||
- `!status` — API health info
|
|
||||||
- `!refresh` — Admin-only manual refresh
|
|
||||||
|
|
||||||
### Design decisions
|
|
||||||
- Fully independent plugins (no shared code) for easy deployment
|
|
||||||
- stdlib `urllib.request` only — zero external dependencies
|
|
||||||
- Admin check via plugin-config nickname list (case-insensitive)
|
|
||||||
- No caching — always fetch fresh from API
|
|
||||||
- Playlist output truncated at 430 chars for IRC line limits
|
|
||||||
|
|
||||||
## Commits
|
|
||||||
- `2a00cc2` feat(sopel): add NtR playlist IRC plugin
|
|
||||||
- `6dd7aee` feat(limnoria): add NtrPlaylist IRC plugin
|
|
||||||
- `5c22776` test: add tests for IRC plugin formatting and API helpers
|
|
||||||
- `b63c851` docs: add IRC bot plugins design and implementation plan
|
|
||||||
- `05bcf18` fix: playlist truncation overflow and align logging across plugins
|
|
||||||
|
|
||||||
## Follow-up items
|
|
||||||
- Limnoria `test.py` is a stub — could add real PluginTestCase tests if Limnoria is a test dependency
|
|
||||||
- Both plugins log API errors; Sopel uses `LOGGER` (defined but previously unused)
|
|
||||||
- The `!N` regex command uses `!` explicitly; named commands use the bot's configured prefix (Sopel default is `.`, so configure `core.command_prefix = "!"` for consistency)
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
# Historical Backfill (--init) Feature
|
|
||||||
|
|
||||||
## Task
|
|
||||||
Add CLI-based historical show backfill with episode numbering throughout the system.
|
|
||||||
|
|
||||||
## Changes Made
|
|
||||||
|
|
||||||
### New file
|
|
||||||
- `src/ntr_fetcher/backfill.py` — Computes show weeks from an anchor episode/date, batch-fetches all likes from SoundCloud, partitions them into weekly buckets, and populates the DB.
|
|
||||||
|
|
||||||
### Modified files
|
|
||||||
- `src/ntr_fetcher/models.py` — Added `episode_number: int | None` to `Show` dataclass.
|
|
||||||
- `src/ntr_fetcher/db.py` — Added `episode_number` column to schema, ALTER TABLE migration for existing DBs, updated `get_or_create_show` to accept/store episode numbers, added `get_latest_episode_number()` and `update_show_episode_number()`, changed `list_shows` ordering to `week_start DESC`.
|
|
||||||
- `src/ntr_fetcher/main.py` — Added `argparse` with `--init`, `--show`, `--aired` flags. `--init` runs backfill then exits; default starts the server as before.
|
|
||||||
- `src/ntr_fetcher/poller.py` — Auto-assigns episode number (latest + 1) when creating a new show if historical data exists.
|
|
||||||
- `src/ntr_fetcher/api.py` — Added `episode_number` to `/playlist`, `/shows`, `/shows/{show_id}` responses.
|
|
||||||
|
|
||||||
### New/updated tests
|
|
||||||
- `tests/test_backfill.py` — Week computation, batch partitioning, empty data, idempotency.
|
|
||||||
- `tests/test_db.py` — Episode number creation, update, and `get_latest_episode_number`.
|
|
||||||
- `tests/test_poller.py` — Auto-numbering when history exists, skips when no history, skips when already assigned.
|
|
||||||
- `tests/test_api.py` — `episode_number` present in show responses.
|
|
||||||
|
|
||||||
## Results
|
|
||||||
- 58 tests passing (up from 42), ruff clean.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
```
|
|
||||||
NTR_ADMIN_TOKEN=token ntr-fetcher --init --show 521 --aired 2026-01-07
|
|
||||||
```
|
|
||||||
Reference in New Issue
Block a user