diff --git a/AAC-STREAMING.org b/AAC-STREAMING.org index a809a3c..d2e9a96 100644 --- a/AAC-STREAMING.org +++ b/AAC-STREAMING.org @@ -1,6 +1,6 @@ #+TITLE: AAC Streaming Support #+AUTHOR: Asteroid Radio Development Team -#+DATE: 2025-10-01 +#+DATE: 2026-01-26 #+STARTUP: overview * Overview diff --git a/README.org b/README.org index ec91aa0..7684900 100644 --- a/README.org +++ b/README.org @@ -1,6 +1,6 @@ #+TITLE: Asteroid Radio - Internet Radio Streaming Platform #+AUTHOR: Asteroid Radio Development Team -#+DATE: 2025-10-26 +#+DATE: 2026-01-26 * Overview @@ -71,10 +71,10 @@ asteroid/ │ ├── icecast.xml # Icecast configuration │ └── music/ # Music library mount ├── template/ # CLIP HTML templates -│ ├── front-page.chtml # Main page with live stream -│ ├── admin.chtml # Admin dashboard -│ ├── player.chtml # Web player interface -│ └── users.chtml # User management +│ ├── front-page.ctml # Main page with live stream +│ ├── admin.ctml # Admin dashboard +│ ├── player.ctml # Web player interface +│ └── users.ctml # User management ├── static/ # CSS and assets │ └── asteroid.lass # LASS stylesheet ├── docs/ # Comprehensive documentation @@ -104,8 +104,8 @@ curl -I http://localhost:8000/asteroid-low.mp3 #+END_SRC ** Access Points -- *Web Interface*: http://localhost:8080/asteroid/ -- *Admin Panel*: http://localhost:8080/asteroid/admin +- *Web Interface*: http://localhost:8080/ +- *Admin Panel*: http://localhost:8080/admin - *High Quality MP3*: http://localhost:8000/asteroid.mp3 (128kbps) - *High Quality AAC*: http://localhost:8000/asteroid.aac (96kbps) - *Low Quality MP3*: http://localhost:8000/asteroid-low.mp3 (64kbps) @@ -115,7 +115,7 @@ curl -I http://localhost:8000/asteroid-low.mp3 ** Adding Music 1. *Copy files*: Place MP3/FLAC files in =docker/music/= directory -2. *Access admin panel*: Navigate to =http://localhost:8080/asteroid/admin= +2. *Access admin panel*: Navigate to =http://localhost:8080/admin= 3. *Scan library*: Click "Scan Library" to index new tracks 4. *Metadata extraction*: Track information automatically extracted 5. *Stream queue*: Optionally add tracks to broadcast queue @@ -396,4 +396,4 @@ Special thanks to all contributors and the Common Lisp community. --- -*Last Updated: 2025-10-26* +*Last Updated: 2026-01-26* diff --git a/SPECTRUM-ANALYZER.org b/SPECTRUM-ANALYZER.org index f4e16b4..cd1ad77 100644 --- a/SPECTRUM-ANALYZER.org +++ b/SPECTRUM-ANALYZER.org @@ -1,6 +1,6 @@ #+TITLE: Spectrum Analyzer Implementation #+AUTHOR: Asteroid Radio -#+DATE: 2025-12-02 +#+DATE: 2026-01-26 * Overview Real-time audio spectrum analyzer for Asteroid Radio, implemented using Parenscript (Lisp-to-JavaScript compiler). diff --git a/docker/docker-streaming.org b/docker/docker-streaming.org index 3e99a2b..0b71516 100644 --- a/docker/docker-streaming.org +++ b/docker/docker-streaming.org @@ -1,6 +1,6 @@ #+TITLE: Asteroid Radio - Docker Streaming Setup #+AUTHOR: Asteroid Radio Team -#+DATE: 2025-09-30 +#+DATE: 2026-01-26 This setup provides a complete streaming solution using Docker with Liquidsoap and Icecast2. diff --git a/docker/setup-complete.org b/docker/setup-complete.org index be5e363..d5a0488 100644 --- a/docker/setup-complete.org +++ b/docker/setup-complete.org @@ -1,6 +1,6 @@ #+TITLE: 🎵 Asteroid Radio - Docker Streaming Setup Complete! #+AUTHOR: Asteroid Radio Team -#+DATE: 2025-09-30 +#+DATE: 2026-01-26 * ✅ What's Been Accomplished diff --git a/docs/API-ENDPOINTS.org b/docs/API-ENDPOINTS.org index 1e463ef..6705827 100644 --- a/docs/API-ENDPOINTS.org +++ b/docs/API-ENDPOINTS.org @@ -1,6 +1,6 @@ #+TITLE: Asteroid Radio - API Endpoints Reference #+AUTHOR: Asteroid Radio Development Team -#+DATE: 2025-10-26 +#+DATE: 2026-01-26 * Overview @@ -340,6 +340,43 @@ curl -X POST http://localhost:8080/api/asteroid/playlists/add-track \ } #+END_SRC +** POST /api/asteroid/playlists/remove-track + +Remove a track from a playlist. + +*** Authentication +Required + +*** Parameters +- =playlist-id= (required) - ID of the playlist +- =track-id= (required) - ID of the track to remove + +*** Response +#+BEGIN_SRC json +{ + "status": "success", + "message": "Track removed from playlist" +} +#+END_SRC + +** POST /api/asteroid/playlists/delete + +Delete a playlist. + +*** Authentication +Required + +*** Parameters +- =playlist-id= (required) - ID of the playlist + +*** Response +#+BEGIN_SRC json +{ + "status": "success", + "message": "Playlist deleted" +} +#+END_SRC + * Admin Endpoints ** POST /api/asteroid/admin/scan-library @@ -353,11 +390,168 @@ Required (Admin role) #+BEGIN_SRC json { "status": "success", - "message": "Library scan initiated", - "tracksFound": 42 + "message": "Library scan completed", + "tracks-added": 42 } #+END_SRC +** GET /api/asteroid/users + +Get all users. + +*** Authentication +Required (Admin role) + +*** Response +Returns a JSON object with a =users= array. + +** POST /api/asteroid/users/create + +Create a new user. + +*** Authentication +Required (Admin role) + +*** Parameters +- =username= (required) +- =email= (required) +- =password= (required) +- =role= (required) + +*** Response +Returns a JSON object indicating success or failure. + +* Stream Playlist File Endpoints (Admin Only) + +These endpoints manage playlist files in the =playlists/= directory, and control the currently active =playlists/stream-queue.m3u=. + +** GET /api/asteroid/stream/playlists + +List available playlist files in =playlists/= (excluding =stream-queue.m3u=). + +*** Authentication +Required (Admin role) + +*** Response +Returns a JSON object with a =playlists= array of filenames. + +** POST /api/asteroid/stream/playlists/load + +Load a playlist file into =playlists/stream-queue.m3u= and return its paths. + +*** Authentication +Required (Admin role) + +*** Parameters +- =name= (required) - Playlist filename to load + +** POST /api/asteroid/stream/playlists/save + +Save the in-memory stream queue to =playlists/stream-queue.m3u=. + +*** Authentication +Required (Admin role) + +** POST /api/asteroid/stream/playlists/save-as + +Save the current stream queue to a new playlist file. + +*** Authentication +Required (Admin role) + +*** Parameters +- =name= (required) - New playlist filename (=.m3u= suffix is optional) + +** POST /api/asteroid/stream/playlists/clear + +Clear =playlists/stream-queue.m3u= and empty the in-memory stream queue. + +*** Authentication +Required (Admin role) + +** GET /api/asteroid/stream/playlists/current + +Return the current =playlists/stream-queue.m3u= contents with best-effort track info. + +*** Authentication +Required (Admin role) + +* Liquidsoap Control Endpoints (Admin Only) + +** GET /api/asteroid/liquidsoap/status + +Get Liquidsoap status including uptime, current metadata, and remaining time. + +*** Authentication +Required (Admin role) + +** POST /api/asteroid/liquidsoap/skip + +Skip the current track in the stream queue. + +*** Authentication +Required (Admin role) + +** POST /api/asteroid/liquidsoap/reload + +Force Liquidsoap to reload the playlist. + +*** Authentication +Required (Admin role) + +** POST /api/asteroid/liquidsoap/restart + +Restart the Liquidsoap Docker container. + +*** Authentication +Required (Admin role) + +** POST /api/asteroid/icecast/restart + +Restart the Icecast Docker container. + +*** Authentication +Required (Admin role) + +* Listener Statistics Endpoints + +** GET /api/asteroid/stats/current + +Get the current listener statistics. + +*** Authentication +Not required + +** GET /api/asteroid/stats/daily + +Get the daily listener statistics. + +*** Authentication +Required (Admin role) + +*** Response +Returns a JSON object containing daily listener statistics. + +** GET /api/asteroid/stats/geo + +Get the geographical listener statistics. + +*** Authentication +Required (Admin role) + +*** Response +Returns a JSON object containing geographical listener statistics. + +** GET /api/asteroid/stats/geo/cities + +Get the listener statistics by city. + +*** Authentication +Required (Admin role) + +*** Response +Returns a JSON object containing the country and a =cities= array with per-city aggregates. + * Error Responses All endpoints may return error responses in this format: diff --git a/docs/API-REFERENCE.org b/docs/API-REFERENCE.org index 21fbea0..bdc7ca3 100644 --- a/docs/API-REFERENCE.org +++ b/docs/API-REFERENCE.org @@ -1,6 +1,6 @@ #+TITLE: Asteroid Radio - API Reference #+AUTHOR: Asteroid Radio Development Team -#+DATE: 2025-10-26 +#+DATE: 2026-01-26 * Current Interfaces @@ -37,7 +37,7 @@ curl -I http://localhost:8000/asteroid-low.mp3 # 64kbps MP3 #+END_SRC *** Playing Streams -#+BEGIN_SRC bashfutu +#+BEGIN_SRC bash # With VLC vlc http://localhost:8000/asteroid.mp3 @@ -146,8 +146,8 @@ docker compose restart ** Music Library Management #+BEGIN_SRC bash # Add music files (container will detect automatically) -cp ~/path/to/music/*.mp3 docker/music/ -cp ~/path/to/music/*.flac docker/music/ +cp ~/path/to/music/*.mp3 music/library/ +cp ~/path/to/music/*.flac music/library/ # Check what Liquidsoap is seeing echo "request.queue" | nc localhost 1234 diff --git a/docs/DEVELOPMENT.org b/docs/DEVELOPMENT.org index e607683..43eaa58 100644 --- a/docs/DEVELOPMENT.org +++ b/docs/DEVELOPMENT.org @@ -1,6 +1,6 @@ #+TITLE: Asteroid Radio - Development Guide #+AUTHOR: Asteroid Radio Development Team -#+DATE: 2025-10-26 +#+DATE: 2026-01-26 * Development Setup @@ -118,10 +118,10 @@ sbcl --eval "(ql:quickload :asteroid)" --eval "(asteroid:start-server)" #+END_SRC *** Development URLs -- *Web Interface*: http://localhost:8080/asteroid/ -- *Admin Panel*: http://localhost:8080/asteroid/admin -- *User Management*: http://localhost:8080/asteroid/admin/users -- *Web Player*: http://localhost:8080/asteroid/player +- *Web Interface*: http://localhost:8080/ +- *Admin Panel*: http://localhost:8080/admin +- *User Management*: http://localhost:8080/admin/user +- *Web Player*: http://localhost:8080/player - *API Base*: http://localhost:8080/api/asteroid/ - *Live Stream*: http://localhost:8000/asteroid.mp3 - *Icecast Admin*: http://localhost:8000/admin/ (admin/asteroid_admin_2024) @@ -228,7 +228,7 @@ We define a custom CLIP attribute processor in =template-utils.lisp= for dynamic **** Using =data-text= in Templates -In your HTML templates (=.chtml= files): +In your HTML templates (=.ctml= files): #+BEGIN_SRC html @@ -341,7 +341,7 @@ See [[file:API-ENDPOINTS.org][API Endpoints Reference]] for complete API documen - Check Docker container status: =docker compose ps= - Check Liquidsoap container logs: =docker compose logs liquidsoap= - Check Icecast2 container logs: =docker compose logs icecast= -- Verify music files exist in =docker/music/library/= +- Verify music files exist in =music/library/= - Restart containers: =docker compose restart= **** Database Errors @@ -418,11 +418,10 @@ docker compose logs -f icecast ** Performance Considerations *** Development vs Production -- Use smaller music libraries in =docker/music/= for faster testing +- Use smaller music libraries in =music/library/= for faster testing - Enable debug logging in Docker containers only when needed - Consider memory usage with large track collections in containers - Test with realistic concurrent user loads using Docker scaling -- Use =docker compose.dev.yml= for development-specific settings *** Optimization Tips - Cache database queries where appropriate @@ -475,17 +474,17 @@ docker compose down - Check port binding: =docker compose port icecast 8000= *** File Permission Issues -- Ensure =docker/music/= directory is accessible -- Check ownership: =ls -la docker/music/= -- Fix permissions: =sudo chown -R $USER:$USER docker/music/= +- Ensure =music/library/= directory is accessible +- Check ownership: =ls -la music/library/= +- Fix permissions: =sudo chown -R $USER:$USER music/library/= - Verify container volume mounts in =docker-compose.yml= - For remote mounts: ensure network storage is accessible *** Music Library Issues -- Check if music files exist: =find docker/music/ -name "*.mp3" -o -name "*.flac"= +- Check if music files exist: =find music/library/ -name "*.mp3" -o -name "*.flac"= - Verify supported formats: MP3, FLAC, OGG, WAV -- Test recursive scanning: =curl -X POST http://localhost:8080/asteroid/api/scan-library= -- Check database for tracks: =curl http://localhost:8080/asteroid/api/tracks= +- Test recursive scanning: =curl -X POST http://localhost:8080/api/asteroid/admin/scan-library= +- Check database for tracks: =curl http://localhost:8080/api/asteroid/tracks= - For large collections: avoid network mounts, use local storage (see memory about 175+ files causing timeouts) ** Getting Help diff --git a/docs/DOCKER-STREAMING.org b/docs/DOCKER-STREAMING.org index 75592ed..981637b 100644 --- a/docs/DOCKER-STREAMING.org +++ b/docs/DOCKER-STREAMING.org @@ -1,6 +1,6 @@ #+TITLE: Asteroid Radio - Docker Streaming Setup #+AUTHOR: Asteroid Radio Development Team -#+DATE: 2025-10-26 +#+DATE: 2026-01-26 * Docker Streaming Overview @@ -141,7 +141,7 @@ networks: 50 1 Asteroid Radio - High Quality - http://localhost:8080/asteroid/ + http://localhost:8080/ Electronic/Alternative 128 @@ -155,7 +155,7 @@ networks: 1 Asteroid Radio - AAC Music for Hackers - 96kbps AAC - http://localhost:8080/asteroid/ + http://localhost:8080/ Electronic/Alternative 96 @@ -169,7 +169,7 @@ networks: 1 Asteroid Radio - Low Quality Music for Hackers - 64kbps - http://localhost:8080/asteroid/ + http://localhost:8080/ Electronic/Alternative 64 @@ -250,7 +250,7 @@ output.icecast( name="Asteroid Radio", description="Music for Hackers - Streaming from the Asteroid", genre="Electronic/Alternative", - url="http://localhost:8080/asteroid/", + url="http://localhost:8080/", public=true, radio ) @@ -265,7 +265,7 @@ output.icecast( name="Asteroid Radio (AAC)", description="Music for Hackers - High efficiency AAC stream", genre="Electronic/Alternative", - url="http://localhost:8080/asteroid/", + url="http://localhost:8080/", public=true, radio ) @@ -280,7 +280,7 @@ output.icecast( name="Asteroid Radio (Low Quality)", description="Music for Hackers - Low bandwidth stream", genre="Electronic/Alternative", - url="http://localhost:8080/asteroid/", + url="http://localhost:8080/", public=true, radio ) @@ -447,11 +447,11 @@ docker compose logs --tail=10 liquidsoap #+BEGIN_SRC bash # Music directory already exists in repository # Copy sample music directly to the music directory -cp ~/path/to/music/*.mp3 docker/music/ +cp ~/path/to/music/*.mp3 music/library/ # Set permissions -chmod 755 docker/music/ -sudo chown -R $USER:$USER docker/music/ +chmod 755 music/library/ +sudo chown -R $USER:$USER music/library/ #+END_SRC ** Persistent Data @@ -586,8 +586,8 @@ echo "request.queue" | nc localhost 1234 *** Permission Issues #+BEGIN_SRC bash # Fix music directory permissions -sudo chown -R $USER:$USER docker/music/ -chmod 755 docker/music/ +sudo chown -R $USER:$USER music/library/ +chmod 755 music/library/ #+END_SRC ** Performance Tuning diff --git a/docs/INSTALLATION.org b/docs/INSTALLATION.org index 2bf289d..d1baaa1 100644 --- a/docs/INSTALLATION.org +++ b/docs/INSTALLATION.org @@ -1,6 +1,6 @@ #+TITLE: Asteroid Radio - Installation Guide #+AUTHOR: Asteroid Radio Development Team -#+DATE: 2025-10-26 +#+DATE: 2026-01-26 * Installation Overview diff --git a/docs/LISTENER-STATISTICS.org b/docs/LISTENER-STATISTICS.org index ec2a62c..29a34ae 100644 --- a/docs/LISTENER-STATISTICS.org +++ b/docs/LISTENER-STATISTICS.org @@ -1,6 +1,6 @@ #+TITLE: Listener Statistics Feature Design -#+AUTHOR: Glenn / Cascade -#+DATE: 2025-12-08 +#+AUTHOR: Glenn Thompson / Cascade +#+DATE: 2026-01-26 #+OPTIONS: toc:2 num:t * Overview @@ -273,10 +273,9 @@ New admin page showing: | Endpoint | Method | Description | |---------------------------------+--------+--------------------------------| | /api/asteroid/stats/current | GET | Current listener count | -| /api/asteroid/stats/daily | GET | Daily stats (date range) | -| /api/asteroid/stats/hourly | GET | Hourly breakdown | -| /api/asteroid/stats/geo | GET | Geographic distribution | -| /api/asteroid/stats/export | GET | Export as CSV/JSON | +| /api/asteroid/stats/daily | GET | Daily stats (admin only) | +| /api/asteroid/stats/geo | GET | Geographic distribution (admin only) | +| /api/asteroid/stats/geo/cities | GET | City breakdown for a country (admin only) | * Implementation Phases diff --git a/docs/PARENSCRIPT-EXPERIMENT.org b/docs/PARENSCRIPT-EXPERIMENT.org index 5d102c8..514c9b4 100644 --- a/docs/PARENSCRIPT-EXPERIMENT.org +++ b/docs/PARENSCRIPT-EXPERIMENT.org @@ -1,6 +1,6 @@ #+TITLE: ParenScript Conversion Experiment -#+AUTHOR: Glenn -#+DATE: 2025-11-06 +#+AUTHOR: Glenn Thompson +#+DATE: 2026-01-26 * Overview diff --git a/docs/PLAYLIST-SYSTEM.org b/docs/PLAYLIST-SYSTEM.org index 3835687..4b27b39 100644 --- a/docs/PLAYLIST-SYSTEM.org +++ b/docs/PLAYLIST-SYSTEM.org @@ -1,6 +1,6 @@ #+TITLE: Playlist System - Complete (MVP) #+AUTHOR: Asteroid Radio Development Team -#+DATE: 2025-10-26 +#+DATE: 2026-01-26 * Overview @@ -52,7 +52,7 @@ Implemented user playlist system with creation, storage, and playback functional ** API Endpoints -*** GET /api/playlists +*** GET /api/asteroid/playlists Get all playlists for current user #+BEGIN_SRC json { @@ -69,16 +69,16 @@ Get all playlists for current user } #+END_SRC -*** POST /api/playlists/create +*** POST /api/asteroid/playlists/create Create a new playlist #+BEGIN_SRC -POST /asteroid/api/playlists/create +POST /api/asteroid/playlists/create Content-Type: application/x-www-form-urlencoded name=My Playlist&description=Optional description #+END_SRC -*** GET /api/playlists/:id +*** GET /api/asteroid/playlists/get Get playlist details with tracks #+BEGIN_SRC json { @@ -98,10 +98,10 @@ Get playlist details with tracks } #+END_SRC -*** POST /api/playlists/add-track +*** POST /api/asteroid/playlists/add-track Add track to playlist (limited by database backend) #+BEGIN_SRC -POST /asteroid/api/playlists/add-track +POST /api/asteroid/playlists/add-track Content-Type: application/x-www-form-urlencoded playlist-id=12&track-id=1298 @@ -179,7 +179,7 @@ async function saveQueueAsPlaylist() { formData.append('name', name); formData.append('description', `Created from queue with ${playQueue.length} tracks`); - const response = await fetch('/asteroid/api/playlists/create', { + const response = await fetch('/api/asteroid/playlists/create', { method: 'POST', body: formData }); @@ -190,7 +190,7 @@ async function saveQueueAsPlaylist() { addFormData.append('playlist-id', newPlaylist.id); addFormData.append('track-id', track.id); - await fetch('/asteroid/api/playlists/add-track', { + await fetch('/api/asteroid/playlists/add-track', { method: 'POST', body: addFormData }); @@ -204,7 +204,7 @@ async function saveQueueAsPlaylist() { *** Load Playlist #+BEGIN_SRC javascript async function loadPlaylist(playlistId) { - const response = await fetch(`/asteroid/api/playlists/${playlistId}`); + const response = await fetch(`/api/asteroid/playlists/get?playlist-id=${playlistId}`); const result = await response.json(); if (result.status === 'success' && result.playlist) { @@ -301,7 +301,7 @@ Database stores some values as lists when they should be scalars: ** Modified Files - =asteroid.asd= - Added playlist-management.lisp - =asteroid.lisp= - Added playlist API endpoints -- =template/player.chtml= - Added playlist UI and functions +- =template/player.ctml= - Added playlist UI and functions - =database.lisp= - Playlists collection schema * Future Enhancements (Post-PostgreSQL) diff --git a/docs/POSTGRESQL-SETUP.org b/docs/POSTGRESQL-SETUP.org index 03d4ccc..c23c286 100644 --- a/docs/POSTGRESQL-SETUP.org +++ b/docs/POSTGRESQL-SETUP.org @@ -1,6 +1,6 @@ #+TITLE: PostgreSQL Setup for Asteroid Radio #+AUTHOR: Asteroid Radio Development Team -#+DATE: 2025-10-26 +#+DATE: 2026-01-26 * Overview diff --git a/docs/PROJECT-HISTORY.org b/docs/PROJECT-HISTORY.org index 6fdb7aa..ccb9e97 100644 --- a/docs/PROJECT-HISTORY.org +++ b/docs/PROJECT-HISTORY.org @@ -1,6 +1,6 @@ #+TITLE: Asteroid Radio - Project Development History #+AUTHOR: Asteroid Radio Development Team -#+DATE: 2025-10-26 +#+DATE: 2026-01-26 #+DESCRIPTION: Comprehensive history of the Asteroid Radio project from inception to present * Project Overview @@ -231,76 +231,178 @@ Asteroid Radio is a web-based internet radio station built with Common Lisp, fea - Synchronized with upstream/main - Prepared comprehensive documentation PR +** Phase 9: Production Launch & Feature Expansion (November - December 2025) + +*** Early November: Template & Deployment Stabilization +- *Lead*: Glenn Thompson, Brian O'Reilly +- Changed template extension to match CLIP documentation (.ctml) +- Updated all template paths in calling code +- Refactored for Lispy improvements (templates, strings, error handling) +- Deployment and post-deployment fixes +- Fixed redirection when navigating between frameset views +- Stream quality persistence in local storage +- Security: Removed hardcoded admin credentials from login page +- Stream service containers locked to localhost access + +*** Mid-November: Password Management & Data Model Refactoring +- *Lead*: Glenn Thompson, Luis Pereira +- Password management and listener count fixes +- Database schema bug fixes from upstream merge +- User database methods moved to data-model +- Admin button visibility restricted to admin accounts +- Profile password change fixes +- Playlist creation fixes on frontend + +*** Late November: Recently Played & MusicBrainz Integration +- *Lead*: Glenn Thompson +- Recently played tracks feature with MusicBrainz integration +- Favicon and asteroid.png graphics added to front page +- User activate/deactivate routes +- User role update routes +- Track name clickable with external link icon +- Audio player color matched to app panels +- Blinking live cursor added + +*** Late November: Spectrum Analyzer & Parenscript Conversion +- *Lead*: Glenn Thompson +- Real-time spectrum analyzer using Web Audio API +- Parenscript (Lisp-to-JavaScript) implementation +- Spectrum analyzer theming and visualization styles +- Monotone theme and dynamic border color +- HTML entity decoding fixes in now playing titles +- JavaScript converted to Parenscript with stream fixes + +*** Early December: PostgreSQL Integration & Database Work +- *Lead*: Brian O'Reilly, Glenn Thompson +- PostgreSQL interface integration (i-postmodern) +- Users table case sensitivity fixes +- Database credentials sourced from environment +- M3U files moved to dedicated playlists directory +- Database creation script corrections +- User dump/restore to CSV functionality + +*** Mid-December: Player Improvements & Listener Statistics +- *Lead*: Glenn Thompson / Cascade +- Wedged player fix with reconnect button and volume preservation +- Status page for frameset mode with navigation fixes +- Listener statistics feature with geo stats collection +- City-level tracking in geo stats +- Expandable city breakdown in admin view +- Liquidsoap/Icecast controls added +- Library scan fixes + +*** Mid-December: Shuffle Mount & Channel Selector +- *Lead*: Glenn Thompson +- Shuffle stream mount with separate recently-played tracking +- Channel/quality selector separation +- Dynamic playlist phase names +- Dynamic channel name updates +- Playlist crossfade transitions +- New playlists in support of variety + +*** Late December: Playlist Scheduler & User Features +- *Lead*: Glenn Thompson +- Automatic playlist scheduler with cl-cron +- Admin UI for playlist scheduler with server time display +- Database persistence for playlist schedule +- Track favorites feature with star button +- Listening history tracking +- Listening activity chart on profile page +- Avatar upload functionality +- Track requests and profile enhancements + +*** Late December: Custom Playlists & Rate Limiting +- *Lead*: Glenn Thompson, Luis Pereira +- Custom user playlists with submission and admin review +- YP directory listings for internet-radio.com and xiph.org +- Rate limiting macros for define-page and define-api +- Bigger rate limits for now-playing API routes +- Favorites sync between front page and frame player via postMessage +- Listening history refactored to data-model +- Timestamp normalization for PostgreSQL compatibility + +*** December 31: Version 1.0 & Operations +- *Lead*: Brian O'Reilly +- Declared "Version 1.0" milestone +- TODO.org updated to reflect production launch +- Operations procedures instituted +- Repository cleanup of interstitial files + * Development Statistics ** Contributors (by commit count) -1. Glenn Thompson (glenneth/Glenneth) - 135+ commits -2. Brian O'Reilly (Fade) - 55+ commits -3. Luis Pereira (easilok) - 23+ commits +1. Glenn Thompson (glenneth/Glenneth) - 354 commits +2. Brian O'Reilly (Fade) - 148 commits +3. Luis Pereira (easilok) - 109 commits -** Total Commits: 213+ commits +** Total Commits: 614 commits + +** Pull Requests Merged: 88 +1. Glenn Thompson (glenneth1) - 59 PRs +2. Luis Pereira (easilok) - 26 PRs +3. Brian O'Reilly (fade) - 3 PRs ** Active Development Period - Start: August 12, 2025 -- Current: November 1, 2025 -- Duration: ~2.75 months of active development +- Current: January 26, 2026 +- Duration: ~5.5 months of active development * Major Features Implemented ** Core Functionality -- ✅ Music library scanning and metadata extraction -- ✅ PostgreSQL database integration (configured, ready for migration) -- ✅ Track search and filtering -- ✅ Playlist management -- ✅ Stream queue control -- ✅ Live streaming via Icecast/Liquidsoap +- Music library scanning and metadata extraction +- PostgreSQL database integration (configured, ready for migration) +- Track search and filtering +- Playlist management +- Stream queue control +- Live streaming via Icecast/Liquidsoap ** User Management -- ✅ User registration and authentication -- ✅ Role-based access control (Admin, DJ, Listener) -- ✅ User profiles with edit functionality -- ✅ Session management -- ✅ Role-based page flow +- User registration and authentication +- Role-based access control (Admin, DJ, Listener) +- User profiles with edit functionality +- Session management +- Role-based page flow ** Streaming Features -- ✅ Multiple quality options (AAC 96k, MP3 128k, MP3 64k) -- ✅ ReplayGain volume normalization -- ✅ Live now-playing information -- ✅ Icecast integration -- ✅ Liquidsoap DJ controls -- ✅ Stream queue management +- Multiple quality options (AAC 96k, MP3 128k, MP3 64k) +- ReplayGain volume normalization +- Live now-playing information +- Icecast integration +- Liquidsoap DJ controls +- Stream queue management ** Player Options -- ✅ Inline web player -- ✅ Pop-out player window -- ✅ Persistent frameset player -- ✅ Hybrid player system -- ✅ Quality selector -- ✅ Auto-reconnect on errors +- Inline web player +- Pop-out player window +- Persistent frameset player +- Hybrid player system +- Quality selector +- Auto-reconnect on errors ** API & Integration -- ✅ RESTful JSON API -- ✅ API-aware authentication -- ✅ Comprehensive test suite -- ✅ Telnet integration with Liquidsoap -- ✅ Real-time status updates +- RESTful JSON API +- API-aware authentication +- Comprehensive test suite +- Telnet integration with Liquidsoap +- Real-time status updates ** UI/UX -- ✅ Retro terminal aesthetic (VT323 font) -- ✅ Responsive design -- ✅ CLIP templating system -- ✅ LASS CSS preprocessing -- ✅ Consistent navigation -- ✅ HTML partial hydration +- Retro terminal aesthetic (VT323 font) +- Responsive design +- CLIP templating system +- LASS CSS preprocessing +- Consistent navigation +- HTML partial hydration ** Infrastructure -- ✅ Docker containerization (streams and application) -- ✅ Docker Compose orchestration -- ✅ Dockerfile for Asteroid application -- ✅ Environment variable configuration -- ✅ PostgreSQL database (configured) -- ✅ Multi-environment support -- ✅ Dynamic URL detection +- Docker containerization (streams and application) +- Docker Compose orchestration +- Dockerfile for Asteroid application +- Environment variable configuration +- PostgreSQL database (configured) +- Multi-environment support +- Dynamic URL detection * Technical Milestones @@ -325,7 +427,22 @@ Asteroid Radio is a web-based internet radio station built with Common Lisp, fea - Parallel music scanning - Client-side caching -* Current State (November 2025) +** Phase 10: Documentation Overhaul (January 2026) + +*** 2026-01-26: Comprehensive Documentation Update +- *Lead*: Glenn Thompson / Cascade +- Major documentation alignment with current codebase +- Standardized all API endpoint references to `/api/asteroid/` base path +- Updated UI route documentation to reflect root `/` mounting +- Corrected template file extensions from `.chtml` to `.ctml` +- Fixed Docker music library paths (`music/library/` standardization) +- Updated stream queue file location to `playlists/stream-queue.m3u` +- Expanded API-ENDPOINTS.org with playlist management, stream control, and admin APIs +- Updated all metadata dates to 2026-01-26 +- Bumped documentation version to 3.1 +- Author metadata standardization (Glenn → Glenn Thompson where applicable) + +* Current State (January 2026) ** Production Ready Features - Full music streaming platform @@ -344,12 +461,12 @@ Asteroid Radio is a web-based internet radio station built with Common Lisp, fea - Performance optimization - Feature expansion based on user feedback -** Recent Achievements -- ✅ Complete Docker containerization -- ✅ Environment variable configuration -- ✅ Comprehensive documentation overhaul -- ✅ Cross-distribution package manager support -- ✅ Streamlined deployment process +** Recent Achievements (January 2026) +- Complete documentation overhaul aligning docs with codebase +- API endpoint standardization (`/api/asteroid/` base path) +- Docker deployment fully documented +- Documentation version 3.1 released +- All metadata updated and consistent ** Known Issues & Future Work - PostgreSQL migration (configured, pending data migration) @@ -392,7 +509,7 @@ Asteroid Radio is a web-based internet radio station built with Common Lisp, fea * Conclusion -Asteroid Radio has evolved from a simple concept into a full-featured internet radio platform in just 2.75 months of active development. The project demonstrates the power of Common Lisp for web development and the collaborative nature of open-source development. +Asteroid Radio has evolved from a simple concept into a full-featured internet radio platform over 5+ months of active development. The project demonstrates the power of Common Lisp for web development and the collaborative nature of open-source development. With complete Docker deployment, comprehensive documentation, and a growing feature set, Asteroid Radio is ready for production use while continuing to evolve with regular improvements, bug fixes, and new features based on user needs and technical requirements. @@ -403,4 +520,4 @@ With complete Docker deployment, comprehensive documentation, and a growing feat --- -*Last Updated: 2025-11-01* +*Last Updated: 2026-01-26* diff --git a/docs/PROJECT-OVERVIEW.org b/docs/PROJECT-OVERVIEW.org index 685d43d..a6728ad 100644 --- a/docs/PROJECT-OVERVIEW.org +++ b/docs/PROJECT-OVERVIEW.org @@ -1,12 +1,12 @@ #+TITLE: Asteroid Radio - Project Overview #+AUTHOR: Glenn Thompson & Brian O'Reilly (Fade) -#+DATE: 2025-10-26 +#+DATE: 2026-01-26 -* 🎯 Mission +* Mission Asteroid Radio is a modern, web-based music streaming platform designed for hackers and music enthusiasts. Built with Common Lisp and the Radiance web framework, it combines the power of functional programming with contemporary web technologies. -* 🏗️ Architecture +* Architecture ** Core Components @@ -30,9 +30,9 @@ Asteroid Radio is a modern, web-based music streaming platform designed for hack │ ├── User Accounts & Profiles │ │ └── Music Metadata │ └─────────────────────────────────────────────────────────────┘ -``` +#+END_EXAMPLE -### Technology Stack +* Technology Stack **Backend:** - **Common Lisp** (SBCL) - Core application language @@ -58,24 +58,29 @@ Asteroid Radio is a modern, web-based music streaming platform designed for hack - **Python** - Performance analysis tools - **Bash** - Testing and deployment scripts -## 🎨 Design Philosophy -### Visual Theme +* 🎨 Design Philosophy + + +** Visual Theme - **Dark terminal aesthetic** - Black background with colored text - **Hacker-friendly** - Monospace fonts and terminal-inspired UI - **Color scheme** - Black → Blue-grey → Cyan → Blue progression - **Minimalist** - Clean, functional interface without clutter -### Technical Principles + +** Technical Principles - **Functional programming** - Leveraging Lisp's strengths - **Modular architecture** - Radiance's interface system - **Performance first** - Sub-1% CPU usage for web app - **Self-contained** - Minimal external dependencies - **Docker-ready** - Containerized streaming infrastructure -## 🚀 Features -### Current Features +* 🚀 Features + + +** Current Features - ✅ **User Authentication** - Registration, login, profiles, role-based access (Admin/DJ/Listener) - ✅ **User Management** - Admin interface for user administration - ✅ **Music Library** - Track management with pagination, search, and filtering @@ -93,7 +98,8 @@ Asteroid Radio is a modern, web-based music streaming platform designed for hack - ✅ **Responsive Design** - Works on desktop and mobile - ✅ **Automated Testing** - Comprehensive test suite -### Planned Features + +** Planned Features - 🔄 **PostgreSQL Migration** - Full migration from Radiance DB to PostgreSQL - 🔄 **Enhanced Playlist Management** - Full CRUD operations with PostgreSQL - 🔄 **Social Features** - Playlist sharing and discovery @@ -104,7 +110,8 @@ Asteroid Radio is a modern, web-based music streaming platform designed for hack - 🔄 **Scheduled Programming** - Time-based queue switching -## 🔮 Vision + +* 🔮 Vision Asteroid Radio is the premier streaming platform for **Asteroid Music** - the perfect soundtrack for developers, hackers, and anyone who spends hours deep in code. Our mission is to curate and deliver music that enhances focus, creativity, and the flow state that every programmer knows. diff --git a/docs/README.org b/docs/README.org index 329643e..dfa6a2e 100644 --- a/docs/README.org +++ b/docs/README.org @@ -1,6 +1,6 @@ #+TITLE: Asteroid Radio - Documentation Index #+AUTHOR: Asteroid Radio Development Team -#+DATE: 2025-10-26 +#+DATE: 2026-01-26 * Welcome to Asteroid Radio Documentation @@ -147,5 +147,5 @@ For detailed technical information, see the **[[file:PROJECT-OVERVIEW.org][Proje --- -*Last Updated: 2025-10-26* -*Documentation Version: 3.0* +*Last Updated: 2026-01-26* +*Documentation Version: 3.1* diff --git a/docs/STREAM-CONTROL.org b/docs/STREAM-CONTROL.org index a49a497..244f291 100644 --- a/docs/STREAM-CONTROL.org +++ b/docs/STREAM-CONTROL.org @@ -1,6 +1,6 @@ #+TITLE: Stream Queue Control System #+AUTHOR: Asteroid Radio Development Team -#+DATE: 2025-10-26 +#+DATE: 2026-01-26 * Overview @@ -140,7 +140,7 @@ If you're working directly in the Lisp REPL: * File Locations -- *Stream Queue File*: =stream-queue.m3u= (in project root) +- *Stream Queue File*: =playlists/stream-queue.m3u= - *Docker Mount*: =/app/stream-queue.m3u= (inside Liquidsoap container) - *Liquidsoap Config*: =docker/asteroid-radio-docker.liq= @@ -184,7 +184,7 @@ The system also tracks recently played tracks: ** Queue changes not taking effect - Wait up to 60 seconds for Liquidsoap to reload -- Check that =stream-queue.m3u= was generated correctly +- Check that =playlists/stream-queue.m3u= was generated correctly - Verify Docker volume mount is working: =docker exec asteroid-liquidsoap ls -la /app/stream-queue.m3u= - Check Liquidsoap logs: =docker logs asteroid-liquidsoap= @@ -196,7 +196,7 @@ This is expected behavior. The system will play random tracks from the music lib - Ensure Asteroid server has write permissions to the project directory - Check that =regenerate-stream-playlist= is being called after queue modifications -- Verify the file exists: =ls -la stream-queue.m3u= +- Verify the file exists: =ls -la playlists/stream-queue.m3u= * Integration with Admin Interface diff --git a/docs/TEMPLATING_SYSTEM.org b/docs/TEMPLATING_SYSTEM.org index 200130a..d617480 100644 --- a/docs/TEMPLATING_SYSTEM.org +++ b/docs/TEMPLATING_SYSTEM.org @@ -156,5 +156,5 @@ The =attr= function of the =lquery= s-expression allows customization of any val - =target= which only has a value when the variable =framesetp= is true #+begin_src html - + #+end_src diff --git a/docs/TESTING.org b/docs/TESTING.org index 2ae88cc..8ca4754 100644 --- a/docs/TESTING.org +++ b/docs/TESTING.org @@ -1,6 +1,6 @@ #+TITLE: Asteroid Radio Testing Guide #+AUTHOR: Asteroid Radio Development Team -#+DATE: 2025-10-26 +#+DATE: 2026-01-26 * Overview @@ -83,15 +83,15 @@ VERBOSE=1 ./test-server.sh - =/api/asteroid/admin/scan-library= - Library scan *** 7. HTML Pages -- =/asteroid/= - Front page -- =/asteroid/admin= - Admin dashboard -- =/asteroid/player= - Web player -- =/asteroid/profile= - User profile -- =/asteroid/register= - Registration page +- =/= - Front page +- =/admin= - Admin dashboard +- =/player= - Web player +- =/profile= - User profile +- =/register= - Registration page *** 8. Static Files -- CSS files (=/asteroid/static/*.css=) -- JavaScript files (=/asteroid/static/js/*.js=) +- CSS files (=/static/*.css=) +- JavaScript files (=/static/js/*.js=) ** Example Output diff --git a/docs/TRACK-PAGINATION-SYSTEM.org b/docs/TRACK-PAGINATION-SYSTEM.org index 10bf150..a8ac78d 100644 --- a/docs/TRACK-PAGINATION-SYSTEM.org +++ b/docs/TRACK-PAGINATION-SYSTEM.org @@ -1,6 +1,6 @@ #+TITLE: Track Pagination System - Complete #+AUTHOR: Asteroid Radio Development Team -#+DATE: 2025-10-26 +#+DATE: 2026-01-26 * Overview @@ -52,7 +52,7 @@ Web player options: * Technical Implementation -** Admin Dashboard (admin.chtml) +** Admin Dashboard (admin.ctml) *** Pagination Variables #+BEGIN_SRC javascript @@ -109,7 +109,7 @@ function nextPage() { } #+END_SRC -** Web Player (player.chtml) +** Web Player (player.ctml) *** Track Index Management Critical fix for pagination with playback: @@ -184,25 +184,25 @@ This ensures correct track playback even when viewing paginated/filtered results * Testing Results ** Admin Dashboard -- ✅ 64 tracks paginated successfully -- ✅ 4 pages at 20 tracks/page -- ✅ All navigation buttons working -- ✅ Page size changes work correctly -- ✅ Search maintains pagination +- 64 tracks paginated successfully +- 4 pages at 20 tracks/page +- All navigation buttons working +- Page size changes work correctly +- Search maintains pagination ** Web Player -- ✅ Track library paginated -- ✅ Play button works on all pages -- ✅ Add to queue works on all pages -- ✅ Search resets to page 1 -- ✅ Correct track indices maintained +- Track library paginated +- Play button works on all pages +- Add to queue works on all pages +- Search resets to page 1 +- Correct track indices maintained * Files Modified -- =template/admin.chtml= - Admin pagination implementation -- =template/player.chtml= - Player pagination implementation +- =template/admin.ctml= - Admin pagination implementation +- =template/player.ctml= - Player pagination implementation - =asteroid.lisp= - No backend changes needed (client-side pagination) -* Status: ✅ COMPLETE +* Status: COMPLETE Track pagination fully implemented and tested in both admin dashboard and web player. Handles 64+ tracks efficiently with excellent UX. diff --git a/docs/USER-MANAGEMENT-SYSTEM.org b/docs/USER-MANAGEMENT-SYSTEM.org index f182ce2..4cadb64 100644 --- a/docs/USER-MANAGEMENT-SYSTEM.org +++ b/docs/USER-MANAGEMENT-SYSTEM.org @@ -1,6 +1,6 @@ #+TITLE: User Management System - Complete #+AUTHOR: Asteroid Radio Development Team -#+DATE: 2025-10-26 +#+DATE: 2026-01-26 * Overview @@ -9,7 +9,7 @@ Complete user management system with dedicated admin interface, user creation, r * What Was Completed ** User Management Page -- Created dedicated =/admin/users= route +- Created dedicated =/admin/user= route - Separate page from main admin dashboard - Clean, organized interface for user administration @@ -43,7 +43,7 @@ Complete user management system with dedicated admin interface, user creation, r ** API Endpoints -*** GET /api/users +*** GET /api/asteroid/users Returns all users in the system #+BEGIN_SRC json { @@ -61,7 +61,7 @@ Returns all users in the system } #+END_SRC -*** GET /api/users/stats +*** GET /api/asteroid/users/stats Returns user statistics #+BEGIN_SRC json { @@ -75,10 +75,10 @@ Returns user statistics } #+END_SRC -*** POST /api/users/create +*** POST /api/asteroid/users/create Creates a new user (requires admin authentication) #+BEGIN_SRC -POST /asteroid/api/users/create +POST /api/asteroid/users/create Content-Type: application/x-www-form-urlencoded username=newuser&email=user@example.com&password=pass123&role=listener @@ -87,7 +87,7 @@ username=newuser&email=user@example.com&password=pass123&role=listener ** Files Created/Modified *** New Files -- =template/users.chtml= - User management template +- =template/users.ctml= - User management template - =test-user-api.sh= - API testing script *** Modified Files @@ -125,10 +125,10 @@ Users stored in USERS collection with fields: Created =test-user-api.sh= for comprehensive testing: #+BEGIN_SRC bash # Test user statistics -curl -s http://localhost:8080/asteroid/api/users/stats | jq . +curl -s http://localhost:8080/api/asteroid/users/stats | jq . # Test user creation (with authentication) -curl -s -b cookies.txt -X POST http://localhost:8080/asteroid/api/users/create \ +curl -s -b cookies.txt -X POST http://localhost:8080/api/asteroid/users/create \ -d "username=testuser" \ -d "email=test@example.com" \ -d "password=testpass123" \ @@ -145,7 +145,7 @@ curl -s -b cookies.txt -X POST http://localhost:8080/asteroid/api/users/create \ * Usage ** Creating a User -1. Navigate to =/asteroid/admin/users= +1. Navigate to =/admin/user= 2. Fill in the user creation form 3. Select appropriate role 4. Click "Create User" diff --git a/project-summary.org b/project-summary.org index f29aeb5..b465d52 100644 --- a/project-summary.org +++ b/project-summary.org @@ -1,5 +1,5 @@ #+TITLE: Asteroid Radio Web Server Implementation Summary -#+DATE: 2025-08-20 +#+DATE: 2026-01-26 #+AUTHOR: Development Session Summary * Project Overview diff --git a/scripts/README-PLAYLIST.org b/scripts/README-PLAYLIST.org index 866db09..1e6f481 100644 --- a/scripts/README-PLAYLIST.org +++ b/scripts/README-PLAYLIST.org @@ -1,6 +1,6 @@ #+TITLE: Asteroid Low Orbit Playlist -#+AUTHOR: Glenn -#+DATE: 2025-11-06 +#+AUTHOR: Glenn Thompson +#+DATE: 2026-01-26 * Files