Go to file
glenneth 90bb9a1650 refactor: Implement Lispy improvements - templates, strings, and error handling
This commit implements three major refactorings to make the codebase more
idiomatic and maintainable:

1. Template Path Centralization
   - Add *template-directory* parameter and helper functions
   - Replace 11+ instances of repetitive template loading boilerplate
   - New functions: template-path, load-template in template-utils.lisp

2. String Construction with FORMAT
   - Replace concatenate with format for external URLs (Icecast, static files)
   - Maintain Radiance URI handling for internal routes
   - Applied to stream URLs, status endpoints, and API responses

3. Error Handling with Custom Conditions
   - NEW FILE: conditions.lisp with comprehensive error hierarchy
   - Custom conditions: not-found-error, authentication-error,
     authorization-error, validation-error, database-error, asteroid-stream-error
   - Helper macros: with-error-handling, with-db-error-handling
   - Helper functions: signal-not-found, signal-validation-error, etc.
   - Refactored 19 API endpoints and page routes
   - Proper HTTP status codes: 404, 401, 403, 400, 500

Changes:
- conditions.lisp: NEW (180+ lines of error handling infrastructure)
- asteroid.asd: Add conditions.lisp to system components
- asteroid.lisp: Refactor 30+ endpoints, eliminate 200+ lines of boilerplate
- template-utils.lisp: Add centralized template loading helpers
- frontend-partials.lisp: Update template loading and string construction

Net result: -97 lines of code, significantly improved error handling,
more maintainable and idiomatic Common Lisp.

All changes tested and verified:
- Clean build
- All endpoints functional
- Error handling returns proper HTTP codes
- No regressions
2025-11-02 12:05:23 -05:00
config Complete Templates section: CLIP refactoring, user management, pagination, playlists, UI fixes, PostgreSQL setup 2025-10-04 09:54:04 -04:00
data/sessions feat: Add auto-scan on startup and live Icecast/Liquidsoap status checks 2025-10-04 09:54:04 -04:00
docker feat: add docker setup for asteroid app 2025-10-30 19:08:46 -04:00
docs docs: Update PROJECT-HISTORY.org with Phase 8 and recent developments 2025-11-01 11:48:27 -04:00
music Small moves. delete some binary data and add users.lisp 2025-09-30 12:50:45 -04:00
static feat: Add hybrid player with frameset and pop-out options 2025-10-22 18:01:48 -04:00
template Change the template extension to match clip documentation 2025-11-01 15:04:32 -04:00
.dockerignore.asteroid feat: add docker setup for asteroid app 2025-10-30 19:08:46 -04:00
.gitignore feat: Add auto-scan on startup and live Icecast/Liquidsoap status checks 2025-10-04 09:54:04 -04:00
AAC-STREAMING.org docs: Convert AAC-STREAMING.md to org-mode format 2025-10-02 16:51:59 +03:00
Dockerfile.asteroid feat: add docker setup for asteroid app 2025-10-30 19:08:46 -04:00
LICENSE Initial commit 2025-08-12 10:42:34 -04:00
Makefile clean out the Makefile a bit. 2025-09-04 11:58:41 -04:00
README.org docs: Comprehensive documentation update for October 2025 2025-11-01 11:48:27 -04:00
TODO.org docs: Mark Page Flow feature as complete in TODO 2025-10-12 09:47:38 -04:00
analyze-performance.py feat: Add auto-scan on startup and live Icecast/Liquidsoap status checks 2025-10-04 09:54:04 -04:00
app-utils.lisp Project skeleton. 2025-08-12 10:59:34 -04:00
asteroid-radio.liq Implement complete internet radio streaming system 2025-09-11 15:30:01 +03:00
asteroid.asd refactor: Implement Lispy improvements - templates, strings, and error handling 2025-11-02 12:05:23 -05:00
asteroid.lisp refactor: Implement Lispy improvements - templates, strings, and error handling 2025-11-02 12:05:23 -05:00
auth-routes.lisp feat: Implement role-based page flow and user management APIs 2025-10-12 09:47:38 -04:00
build-executable.lisp Fix Asteroid Radio authentication system 2025-09-30 13:20:58 -04:00
comprehensive-performance-test.sh feat: Add auto-scan on startup and live Icecast/Liquidsoap status checks 2025-10-04 09:54:04 -04:00
conditions.lisp refactor: Implement Lispy improvements - templates, strings, and error handling 2025-11-02 12:05:23 -05:00
database.lisp Fix Asteroid Radio authentication system 2025-09-30 13:20:58 -04:00
design.org Add detailed design document for Asteroid Music radio station (#1) 2025-08-12 11:32:39 -04:00
frontend-partials.lisp refactor: Implement Lispy improvements - templates, strings, and error handling 2025-11-02 12:05:23 -05:00
module.lisp tiny cleanup. 2025-09-08 11:07:02 -04:00
playlist-management.lisp Fix playlist schema mismatch - use track-ids field consistently 2025-10-07 18:39:49 -04:00
playlist.m3u Implement complete internet radio streaming system 2025-09-11 15:30:01 +03:00
project-summary.org Migrate from Hunchentoot to RADIANCE framework 2025-08-20 09:40:14 -04:00
run-all-tests.sh feat: Add auto-scan on startup and live Icecast/Liquidsoap status checks 2025-10-04 09:54:04 -04:00
setup-environment.lisp feat: Add auto-scan on startup and live Icecast/Liquidsoap status checks 2025-10-04 09:54:04 -04:00
simple-analysis.py feat: Add auto-scan on startup and live Icecast/Liquidsoap status checks 2025-10-04 09:54:04 -04:00
stream-control.lisp feat: Add pop-out player and queue management improvements 2025-10-22 18:01:48 -04:00
stream-media.lisp Add stream queue control system 2025-10-15 06:38:53 -04:00
stream-queue.m3u feat: Add pop-out player and queue management improvements 2025-10-22 18:01:48 -04:00
template-utils.lisp refactor: Implement Lispy improvements - templates, strings, and error handling 2025-11-02 12:05:23 -05:00
test-server.sh Add comprehensive automated test suite 2025-10-08 22:56:54 -04:00
test-user-api.sh Complete CLIP template refactoring and all template features 2025-10-04 09:54:04 -04:00
user-management.lisp fix: retry user initialization 2025-10-30 19:08:46 -04:00
users.lisp feat: Add Docker streaming infrastructure for Liquidsoap and Icecast2 2025-10-02 16:50:06 +03:00

README.org

Asteroid Radio - Internet Radio Streaming Platform

Overview

Asteroid Radio is a complete internet radio streaming platform built with Common Lisp, featuring a hacker-themed terminal aesthetic. The project combines the Radiance web framework with Icecast/Liquidsoap streaming infrastructure to create a full-featured music streaming platform with live broadcasting capabilities.

Project Links

Key Features

Live Internet Radio Streaming

  • Multiple quality streams: 128kbps MP3, 96kbps AAC, 64kbps MP3
  • Professional audio processing with crossfading and ReplayGain normalization
  • Icecast2 streaming server integration
  • Liquidsoap audio pipeline for reliable broadcasting
  • Stream queue control for curated programming

Music Library Management

  • Database-backed track storage with metadata extraction
  • Support for MP3, FLAC, OGG, and WAV formats
  • Automatic metadata extraction using taglib
  • Track search, filtering, sorting, and pagination
  • Recursive directory scanning

Web Interface

  • RADIANCE framework with CLIP templating
  • Admin dashboard for library and user management
  • Multiple player modes: inline, pop-out, and persistent frameset
  • Live stream integration with embedded player
  • Responsive design for desktop and mobile
  • Role-based access control (Admin/DJ/Listener)

Network Broadcasting

  • Dynamic stream URL detection for multi-environment support
  • Professional streaming URLs for media players
  • Multi-listener support via Icecast2
  • Docker-based deployment for easy setup

Architecture Changes

Framework Migration

  • Migrated from Hunchentoot to RADIANCE web framework
  • Implemented proper domain routing (/asteroid/)
  • CLIP templating system for dynamic content
  • Database abstraction layer for track storage

Streaming Stack

  • Icecast2: Streaming server (port 8000) - Docker containerized
  • Liquidsoap: Audio processing and streaming pipeline - Docker containerized
  • RADIANCE: Web server and API (port 8080)
  • PostgreSQL: Database backend (configured, ready for migration)
  • Docker Compose: Container orchestration

File Structure

asteroid/
├── asteroid.lisp              # Main server with RADIANCE routes
├── asteroid.asd               # System definition with dependencies
├── stream-control.lisp        # Stream queue management
├── user-management.lisp       # User administration
├── playlist-management.lisp   # Playlist operations
├── test-server.sh             # Automated test suite
├── docker/                    # Docker infrastructure
│   ├── docker-compose.yml     # Container orchestration
│   ├── asteroid-radio-docker.liq  # Liquidsoap config
│   ├── 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
├── static/                    # CSS and assets
│   └── asteroid.lass          # LASS stylesheet
├── docs/                      # Comprehensive documentation
│   ├── README.org             # Documentation index
│   ├── PROJECT-OVERVIEW.org   # Architecture overview
│   ├── PROJECT-HISTORY.org    # Development timeline
│   ├── INSTALLATION.org       # Setup guide
│   └── ...                    # Additional guides
└── music/                     # Music library (local dev)

Quick Start

Docker Installation (Recommended)

# Clone repository
git clone https://github.com/fade/asteroid
cd asteroid/docker

# Start all services
docker compose up -d

# Verify streams are working
curl -I http://localhost:8000/asteroid.mp3
curl -I http://localhost:8000/asteroid.aac
curl -I http://localhost:8000/asteroid-low.mp3

Access Points

Music Library Management

Adding Music

  1. Copy files: Place MP3/FLAC files in docker/music/ directory
  2. Access admin panel: Navigate to http://localhost:8080/asteroid/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

Library Scanning

  1. Recursive directory scanning of music folder
  2. Metadata extracted using taglib (title, artist, album, duration)
  3. Database records created with file paths and metadata
  4. Tracks immediately available for playback and streaming
  5. Supports nested folder structures

Supported Formats

  • MP3: Primary format, best compatibility
  • FLAC: Lossless audio, high quality
  • OGG: Open source format
  • WAV: Uncompressed audio

Icecast2 Integration

Configuration

  • Server: localhost:8000 (Docker container)
  • Mount points: /asteroid.mp3, /asteroid.aac, /asteroid-low.mp3
  • Password: H1tn31EhsyLrfRmo (configured in Docker setup)
  • Formats: MP3 128kbps, AAC 96kbps, MP3 64kbps

Docker Setup

Icecast2 runs in a Docker container - no manual installation needed.

# Managed via docker-compose
cd docker
docker compose up -d icecast

Stream Access

  • 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)
  • Admin interface: http://localhost:8000/admin/ (admin/asteroid_admin_2024)
  • Statistics: http://localhost:8000/status.xsl

Liquidsoap Integration

Docker Configuration

Liquidsoap runs in a Docker container with configuration in docker/asteroid-radio-docker.liq

Key Features

  • Multiple outputs: Generates 3 simultaneous streams (MP3 128k, AAC 96k, MP3 64k)
  • Audio processing: Crossfading, normalization, ReplayGain
  • Stream queue: Reads from M3U playlist for curated programming
  • Telnet control: Remote control interface on port 1234
  • Metadata: Broadcasts track information to listeners

Management

# Start Liquidsoap container
cd docker
docker compose up -d liquidsoap

# View logs
docker compose logs -f liquidsoap

# Restart streaming
docker compose restart liquidsoap

Telnet Control

# Connect to Liquidsoap
telnet localhost 1234

# Or use netcat for scripting
echo "request.queue" | nc localhost 1234
echo "request.skip" | nc localhost 1234

User Management

Roles

  • Admin: Full system access, user management, stream control
  • DJ: Content management, playlist creation, library access
  • Listener: Basic playback and personal playlists

Default Credentials

  • Username: admin
  • Password: asteroid123
  • ⚠️ Change default password after first login

User Administration

  • Create/manage users via admin panel
  • Role-based access control
  • User profiles and preferences
  • Session management

Player Modes

Inline Player

  • Embedded in web pages
  • Standard HTML5 audio controls
  • Queue management

Pop-Out Player

  • Standalone player window
  • Independent from main browser window
  • Persistent across page navigation

Frameset Player

  • Bottom-frame persistent player
  • Audio continues during site navigation
  • Seamless listening experience

API Endpoints

Asteroid Radio provides a comprehensive REST API with 15+ endpoints.

Status & Authentication

  • GET /api/asteroid/status - Server status
  • GET /api/asteroid/auth-status - Authentication status
  • GET /api/asteroid/icecast-status - Streaming status

Track Management

  • GET /api/asteroid/tracks - List all tracks
  • GET /api/asteroid/admin/tracks - Admin track listing
  • POST /api/asteroid/admin/scan-library - Scan music library

Player Control

  • GET /api/asteroid/player/status - Player status
  • POST /api/asteroid/player/play - Play track
  • POST /api/asteroid/player/pause - Pause playback
  • POST /api/asteroid/player/stop - Stop playback
  • POST /api/asteroid/player/resume - Resume playback

Playlist Management

  • GET /api/asteroid/playlists - List user playlists
  • POST /api/asteroid/playlists/create - Create playlist
  • GET /api/asteroid/playlists/get - Get playlist details
  • POST /api/asteroid/playlists/add-track - Add track to playlist

Stream Queue Control (Admin)

  • GET /api/asteroid/stream/queue - Get broadcast queue
  • POST /api/asteroid/stream/queue/add - Add track to queue
  • POST /api/asteroid/stream/queue/remove - Remove from queue
  • POST /api/asteroid/stream/queue/clear - Clear queue

See docs/API-ENDPOINTS.org for complete API documentation.

Database

Current: Radiance DB

  • File-based database abstraction
  • Tracks, users, playlists, sessions
  • Suitable for development and small deployments

PostgreSQL (Configured)

  • Docker container ready
  • Full schema defined
  • Migration pending
  • See docs/POSTGRESQL-SETUP.org for details

Documentation

Comprehensive documentation available in the docs/ directory:

  • README.org - Documentation index
  • PROJECT-OVERVIEW.org - Architecture and features
  • PROJECT-HISTORY.org - Development timeline and milestones
  • INSTALLATION.org - Complete installation guide
  • DEVELOPMENT.org - Developer setup and guidelines
  • DOCKER-STREAMING.org - Docker streaming infrastructure
  • API-ENDPOINTS.org - REST API reference
  • STREAM-CONTROL.org - Stream queue management
  • USER-MANAGEMENT-SYSTEM.org - User administration
  • PLAYLIST-SYSTEM.org - Playlist functionality
  • TESTING.org - Automated testing guide
  • POSTGRESQL-SETUP.org - Database setup

Dependencies

Lisp Dependencies

  • radiance - Web framework
  • r-clip - CLIP templating
  • lass - CSS preprocessing
  • cl-json - JSON handling
  • alexandria - Common Lisp utilities
  • local-time - Time handling
  • taglib - Audio metadata extraction

System Dependencies (Docker)

  • Docker Engine 20.10+
  • Docker Compose 2.0+
  • All streaming components containerized

Testing

Automated Test Suite

# Run comprehensive tests
./test-server.sh

# Verbose mode
./test-server.sh -v

Test Coverage

  • 25+ automated tests
  • API endpoint validation
  • HTML page rendering
  • Static file serving
  • JSON response format
  • Authentication flows

Contributing

Development Workflow

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run test suite
  5. Submit pull request

Community

  • IRC: #asteroid.music on irc.libera.chat
  • Issues: GitHub issue tracker
  • Discussions: GitHub discussions

Core Team

  • Brian O'Reilly (Fade) - Project founder
  • Glenn Thompson (glenneth) - Core developer
  • Luis Pereira - UI/UX

Troubleshooting

Docker Issues

# Check container status
docker compose ps

# View logs
docker compose logs icecast
docker compose logs liquidsoap

# Restart services
docker compose restart

Stream Not Playing

  • Verify containers are running
  • Check music files exist in docker/music/
  • Test stream URLs with curl
  • Review Liquidsoap logs

Database Issues

  • Check Radiance DB file permissions
  • Verify database collections exist
  • Review application logs

For detailed troubleshooting, see documentation in docs/ directory.

License

See LICENSE file for details.

Acknowledgments

Built with:

  • Common Lisp (SBCL)
  • Radiance web framework
  • Icecast2 streaming server
  • Liquidsoap audio processing
  • Docker containerization

Special thanks to all contributors and the Common Lisp community.

Last Updated: 2025-10-26