76 lines
2.6 KiB
Markdown
76 lines
2.6 KiB
Markdown
|
|
# CLAUDE.md
|
||
|
|
|
||
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
|
|
||
|
|
## Project Overview
|
||
|
|
|
||
|
|
Diora is a Django-based internet radio player with user accounts, track history, Last.fm scrobbling, and PWA support. No build tools or bundlers — pure Django with vanilla JavaScript.
|
||
|
|
|
||
|
|
## Development Commands
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Setup
|
||
|
|
pip install -r requirements.txt
|
||
|
|
cp .env.example .env # then edit with your values
|
||
|
|
python manage.py migrate
|
||
|
|
python manage.py createsuperuser
|
||
|
|
|
||
|
|
# Run
|
||
|
|
python manage.py runserver
|
||
|
|
|
||
|
|
# Database
|
||
|
|
python manage.py makemigrations
|
||
|
|
python manage.py migrate
|
||
|
|
```
|
||
|
|
|
||
|
|
There is no test suite configured. Django's built-in test runner would be used if tests are added: `python manage.py test`.
|
||
|
|
|
||
|
|
## Environment Variables (`.env`)
|
||
|
|
|
||
|
|
```
|
||
|
|
SECRET_KEY=change-me
|
||
|
|
DEBUG=True
|
||
|
|
AMAZON_AFFILIATE_TAG=diora-20
|
||
|
|
LASTFM_API_KEY=
|
||
|
|
LASTFM_API_SECRET=
|
||
|
|
```
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
Two Django apps:
|
||
|
|
|
||
|
|
**`radio/`** — Core player functionality
|
||
|
|
- `models.py`: `SavedStation`, `StationPlay`, `TrackHistory`, `FocusSession`
|
||
|
|
- `icy.py`: Parses ICY metadata from streaming HTTP responses (extracts track titles from radio streams)
|
||
|
|
- `lastfm.py`: Last.fm API wrapper (scrobbling, track love/unlove)
|
||
|
|
- `views.py`: Player page, SSE endpoint for real-time metadata, track recording, station CRUD
|
||
|
|
|
||
|
|
**`accounts/`** — Authentication and user profiles
|
||
|
|
- `models.py`: `UserProfile` (extends Django's `User` via signal; stores Last.fm session key, background image, scrobble preference)
|
||
|
|
- `views.py`: Registration, login, Last.fm OAuth flow, background image upload
|
||
|
|
|
||
|
|
**Frontend (`static/js/`)**
|
||
|
|
- `app.js`: All client-side logic — HTML5 Audio playback, SSE connection for live metadata, station management UI, focus timer
|
||
|
|
- `sw.js`: Service worker for PWA installability
|
||
|
|
- No build step — files are served directly
|
||
|
|
|
||
|
|
**Templates (`templates/`)**
|
||
|
|
- `base.html`: Main layout with navbar
|
||
|
|
- `radio/player.html`: Single-page player UI
|
||
|
|
- `accounts/`: Auth and settings pages
|
||
|
|
|
||
|
|
## Key Data Flows
|
||
|
|
|
||
|
|
**ICY Metadata (real-time track info):**
|
||
|
|
Browser → `GET /radio/sse/?url=<stream_url>` → Django SSE view → `icy.py` opens stream → yields `StreamingHttpResponse` events → `app.js` `EventSource` updates UI
|
||
|
|
|
||
|
|
**Last.fm Scrobbling:**
|
||
|
|
Track recorded via `POST /radio/record/` → `TrackHistory` created → `lastfm.py` scrobbles if user has session key and opt-in enabled
|
||
|
|
|
||
|
|
**Station Persistence:**
|
||
|
|
All station CRUD is JSON API (save/remove/favorite/notes) consumed by `app.js` — no page reloads
|
||
|
|
|
||
|
|
## Static Files
|
||
|
|
|
||
|
|
WhiteNoise serves static files with `CompressedManifestStaticFilesStorage` (cache-busting hashes). Run `python manage.py collectstatic` before production deployment.
|