docs: Comprehensive documentation update January 2026

- Update all #+DATE: and Last Updated lines to 2026-01-26
- Bump documentation version to 3.1
- Standardize author metadata (Glenn → Glenn Thompson where applicable)
- Add Phase 9: Production Launch & Feature Expansion (Nov-Dec 2025)
- Add Phase 10: Documentation Overhaul (January 2026)
- Update PROJECT-HISTORY.org with accurate contributor stats:
  - 614 total commits, 88 PRs merged
  - Glenn Thompson: 354 commits, 59 PRs
  - Brian O'Reilly: 148 commits, 3 PRs
  - Luis Pereira: 109 commits, 26 PRs
- Standardize API endpoints to /api/asteroid/ base path
- Update UI routes to reflect root / mounting
- Correct template extensions from .chtml to .ctml
- Fix Docker music library paths (music/library/)
- Update stream queue location to playlists/stream-queue.m3u
- Expand API-ENDPOINTS.org with playlist, stream control, admin APIs
This commit is contained in:
glenneth 2026-01-26 20:48:25 +03:00
parent d894964c20
commit 2730a1e05d
24 changed files with 498 additions and 182 deletions

View File

@ -1,6 +1,6 @@
#+TITLE: AAC Streaming Support
#+AUTHOR: Asteroid Radio Development Team
#+DATE: 2025-10-01
#+DATE: 2026-01-26
#+STARTUP: overview
* Overview

View File

@ -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*

View File

@ -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).

View File

@ -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.

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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
<!-- The data-text attribute gets replaced with the value from the plist -->
@ -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

View File

@ -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:
<max-listeners>50</max-listeners>
<public>1</public>
<stream-name>Asteroid Radio - High Quality</stream-name>
<stream-url>http://localhost:8080/asteroid/</stream-url>
<stream-url>http://localhost:8080/</stream-url>
<genre>Electronic/Alternative</genre>
<bitrate>128</bitrate>
</mount>
@ -155,7 +155,7 @@ networks:
<public>1</public>
<stream-name>Asteroid Radio - AAC</stream-name>
<stream-description>Music for Hackers - 96kbps AAC</stream-description>
<stream-url>http://localhost:8080/asteroid/</stream-url>
<stream-url>http://localhost:8080/</stream-url>
<genre>Electronic/Alternative</genre>
<bitrate>96</bitrate>
</mount>
@ -169,7 +169,7 @@ networks:
<public>1</public>
<stream-name>Asteroid Radio - Low Quality</stream-name>
<stream-description>Music for Hackers - 64kbps</stream-description>
<stream-url>http://localhost:8080/asteroid/</stream-url>
<stream-url>http://localhost:8080/</stream-url>
<genre>Electronic/Alternative</genre>
<bitrate>64</bitrate>
</mount>
@ -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

View File

@ -1,6 +1,6 @@
#+TITLE: Asteroid Radio - Installation Guide
#+AUTHOR: Asteroid Radio Development Team
#+DATE: 2025-10-26
#+DATE: 2026-01-26
* Installation Overview

View File

@ -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

View File

@ -1,6 +1,6 @@
#+TITLE: ParenScript Conversion Experiment
#+AUTHOR: Glenn
#+DATE: 2025-11-06
#+AUTHOR: Glenn Thompson
#+DATE: 2026-01-26
* Overview

View File

@ -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)

View File

@ -1,6 +1,6 @@
#+TITLE: PostgreSQL Setup for Asteroid Radio
#+AUTHOR: Asteroid Radio Development Team
#+DATE: 2025-10-26
#+DATE: 2026-01-26
* Overview

View File

@ -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*

View File

@ -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.

View File

@ -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*

View File

@ -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

View File

@ -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
<a lquery='(attr :href (eval (format nil "/asteroid/~a" status-href)) :target (when framesetp "_self"))'>
<a lquery='(attr :href (eval (format nil "/~a" status-href)) :target (when framesetp "_self"))'>
#+end_src

View File

@ -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

View File

@ -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.

View File

@ -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"

View File

@ -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

View File

@ -1,6 +1,6 @@
#+TITLE: Asteroid Low Orbit Playlist
#+AUTHOR: Glenn
#+DATE: 2025-11-06
#+AUTHOR: Glenn Thompson
#+DATE: 2026-01-26
* Files