Commit Graph

59 Commits

Author SHA1 Message Date
Glenn Thompson c4120de9fc Add listener statistics feature
- Add database schema for listener snapshots, sessions, and aggregates
- Implement background polling of Icecast admin XML stats
- Add API endpoints for current, daily, and geo stats
- Add listener stats section to admin dashboard with auto-refresh
- GDPR compliant: IP hashing, data retention cleanup
2025-12-08 08:25:06 +03:00
Glenn Thompson 373ca04eb0 Add status page for frameset mode and fix navigation 2025-12-08 07:01:46 +03:00
Glenn Thompson 2ed92ba003 Fix wedged player with reconnect button and volume preservation
- Add reconnect button (🔄) to frameset player bar
- Recreate audio element on reconnect to fix wedged MediaElementSource
- Properly close and reinitialize AudioContext for spectrum analyzer
- Preserve volume and muted state when reconnecting
- Show status messages for connection issues
- Reduce Now Playing update interval to 5 seconds
- Add front-page.js to player-content.ctml for Now Playing updates
- Create About pages (about.ctml and about-content.ctml)
- Add About link to navigation in both modes
2025-12-08 05:01:15 +03:00
Brian O'Reilly 9cbc0a7780 the db is connected, so init the users. 2025-12-07 19:44:04 -05:00
Brian O'Reilly 7a4e9c208a creating the users table all caps style gives us duplicates in postgres. 2025-12-07 19:44:04 -05:00
Brian O'Reilly 9bb31ec88c many things, almost working, but not quite. 2025-12-07 19:44:04 -05:00
Brian O'Reilly d2508451d0 Delete the music/library directory which held an erroneous path to a softlink that doesn't exist in prod. 2025-12-07 19:44:04 -05:00
Glenn Thompson 51387bddba Add spectrum analyzer theming and visualization styles
- Add 6 color themes: green, blue, purple, red, amber, rainbow
- Add 3 visualization styles: bars, wave, dots
- Add UI controls (dropdowns) to change theme and style
- Persist user preferences in localStorage
- Remove debug logging from parenscript serving and Icecast stats
- Fix dots visualization with proper Math.PI handling
2025-12-06 11:55:24 -05:00
Glenn Thompson b6be0ebab1 feat: Convert JavaScript to Parenscript with stream fixes and UX improvements
Major Changes:
- Convert all JavaScript files to Parenscript for better maintainability
- Move spectrum-analyzer to parenscript/ directory structure
- Add parenscript-utils.lisp for shared utilities
- Convert admin.js, player.js, front-page.js, auth-ui.js to Parenscript
- Convert profile.js, users.js, recently-played.js to Parenscript

Stream Reconnect Fixes (from merged PR):
- Add reset-spectrum-analyzer function to properly clean up Web Audio API
- Implement reconnect logic for pauses longer than 10 seconds
- Detect stale audio in 'playing' event and force stream reconnection
- Prevent 'Now Playing' updates while stream is paused
- Reduce reconnect delay to 200ms for faster response
- Add proper spectrum analyzer reset/reinit during reconnection

UX Improvements:
- Change live indicator from blink to smooth pulse (2s ease-in-out)
- Pulse animation like old PowerBook/MacBook sleep indicator
- Add MUTED indicator to spectrum analyzer when audio is muted
- Spectrum continues to flow even when muted (data still streaming)
- Red 'MUTED' text displayed in top-right corner of canvas

Technical Details:
- Parenscript files generate JavaScript via API endpoints
- All player modes updated: main player, front page, popout, frame player
- Improved audio context handling to only create once per element
- Added comprehensive error handling and logging
- Updated asteroid.asd to include parenscript module structure

Documentation:
- Updated all documentation dates to 2025-12-06
- Added PARENSCRIPT-EXPERIMENT.org documenting the conversion
- Updated PROJECT-HISTORY.org with Phase 9 (Visual Audio Features)
- Added comprehensive project statistics (408 commits, 9,300 LOC)

This conversion improves code maintainability by using Lisp throughout
the stack and makes it easier to share code between frontend and backend.
2025-12-06 11:55:24 -05:00
Glenn Thompson 6bf19ade01 Add recently played tracks feature with MusicBrainz integration
- Display last 3 played tracks on front page
- Auto-updates every 30 seconds
- Shows track title, artist, and time ago
- Links to MusicBrainz search for each track
- Thread-safe in-memory storage
- Works in both normal and frameset modes
- Hacker-themed green styling

Implements feature request from fade to show recently played tracks
with linkage to track info at music database.
2025-11-22 09:06:05 -05:00
Glenn Thompson 79ab87436e Refine recently played styling and MusicBrainz search
- Use 2-column grid layout: track/artist left, time/link right
- Match color scheme with now-playing section (blue text)
- Tighter row spacing (6px padding)
- Simplified MusicBrainz search query (no field prefixes)
- Fix CSS selector for proper link styling
- Right-align time and MusicBrainz link
2025-11-20 17:05:35 -05:00
Glenn Thompson 0a7d5c3de5 Add recently played tracks feature with MusicBrainz integration
- Display last 3 played tracks on front page
- Auto-updates every 30 seconds
- Shows track title, artist, and time ago
- Links to MusicBrainz search for each track
- Thread-safe in-memory storage
- Works in both normal and frameset modes
- Hacker-themed green styling

Implements feature request from fade to show recently played tracks
with linkage to track info at music database.
2025-11-20 17:05:35 -05:00
Luis Pereira a1fa5b0b51 fix: tracks and playlist db interation through data-model 2025-11-19 18:00:02 -05:00
Glenn Thompson 2a505e482d Fix scan-library path to work in both development and production
- Auto-detect music library path based on environment
- Check for music/library/ directory for local development
- Default to /app/music/ for production Docker deployment
- Allow MUSIC_LIBRARY_PATH environment variable override
- Fixes scan-library function failing on production server
2025-11-17 18:06:14 -05:00
Glenn Thompson 19b9deccf5 fix: Use /app/music/ as default music library path for production
- Changed hardcoded music/library/ path to /app/music/ (production path)
- Added MUSIC_LIBRARY_PATH environment variable for local dev override
- Fixes scan library function on production server
- Aligns with path structure used in M3U playlists and liquidsoap config
2025-11-17 18:06:14 -05:00
Luis Pereira c5804641b8 fix: move user database methods to data-model 2025-11-16 09:38:04 -05:00
Luis Pereira 8b33968011 fix: failed register error messages 2025-11-15 08:23:31 -05:00
Brian O'Reilly 0d68c9cc82 build info updates, curated playlist 2025-11-11 17:12:32 -05:00
Brian O'Reilly 7c569ca4f6 startup toggles 2025-11-11 12:04:06 -05:00
Brian O'Reilly 69b0b2ca9e it really is best not to rewrite history. bring this back from the dead. 2025-11-04 17:42:41 -05:00
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
Brian O'Reilly 0bb93c53a4 Update template paths in calling code. 2025-11-01 15:19:22 -04:00
glenneth a795680e99 feat: Add hybrid player with frameset and pop-out options
- Add frameset mode with persistent audio player in bottom frame
- Add localStorage preference system for user choice
- Update all page navigation to work in both regular and frameset modes
- Add enable/disable buttons for frameset mode
- Fix redirect loops and template parameter issues
2025-10-22 18:01:48 -04:00
glenneth d8abd9661d feat: Add pop-out player and queue management improvements
- Add pop-out player window (400x300px) with auto-reconnect on stream errors
- Add queue reordering with up/down buttons in admin panel
- Add 'Load Queue from M3U' functionality
- Remove Play/Stream buttons from track management
- Fix Liquidsoap audio quality issues:
  - Remove ReplayGain and compression to prevent pulsing
  - Change reload_mode to 'seconds' to prevent playlist exhaustion
  - Reduce crossfade to 3 seconds
  - Add audio buffering settings for stability
- Add auto-reconnect logic for both front page and pop-out players
2025-10-22 18:01:48 -04:00
Luis Pereira 136fa2fa74 fix: avoid icecast xml to be shown on frontend when there is no artist 2025-10-15 06:41:07 -04:00
glenneth b64d101f8a Add stream queue control system
- New stream-control.lisp for queue management backend
- M3U playlist generation with Docker path mapping
- API endpoints for add/remove/clear/reorder queue
- Fix library scan deduplication
- Add stream control documentation
2025-10-15 06:38:53 -04:00
Luis Pereira 70263fbfbc feat: stream base url as variable on templates 2025-10-12 09:56:08 -04:00
glenneth 5362c86f9f fix: Complete UI fixes for page flow feature
- Fix api-output wrapper handling in all JavaScript files
- Add profile page API endpoints (profile, listening-stats, recent-tracks, top-artists)
- Fix session persistence - auth-ui.js now correctly detects login status
- Fix user stats display - now shows correct counts (3 users, 1 admin)
- Fix View All Users table - properly displays all users
- Handle empty arrays gracefully in profile.js (no errors for missing data)

All UI issues resolved:
✓ User management page fully functional
✓ Session persists across navigation
✓ Profile page loads without errors
✓ Correct nav links shown based on role
✓ Admin sees Admin link, regular users don't
2025-10-12 09:47:38 -04:00
glenneth 4b8a3a064c feat: Implement role-based page flow and user management APIs
Core Features:
- Login redirects based on user role (admin -> /admin, users -> /profile)
- User registration redirects to /profile page
- Convert user management APIs to use define-api (Radiance standard)
- Add user statistics API endpoint
- Add create user API endpoint
- Add list users API endpoint

Authentication & Authorization:
- Update require-role to return proper JSON for API requests
- Fix password verification with debug logging
- Add reset-user-password function for admin use

API Endpoints (using define-api):
- /api/asteroid/users - Get all users (admin only)
- /api/asteroid/user-stats - Get user statistics (admin only)
- /api/asteroid/users/create - Create new user (admin only)

Bug Fixes:
- Fix JavaScript API path for user-stats endpoint
- Remove dependency on non-existent radiance:api-output
- Use api-output for proper JSON responses

Testing:
- Admin login redirects to /asteroid/admin ✓
- Regular user login redirects to /asteroid/profile ✓
- User creation working (testuser created successfully) ✓
- User statistics loading correctly ✓

Known Issues (non-blocking):
- User table display needs UI fixes
- Profile page needs additional API endpoints
- Session persistence on navigation needs investigation
2025-10-12 09:47:38 -04:00
glenneth e0c1eac408 Refactor API endpoints to use Radiance's define-api macro
- Converted 15 API endpoints from define-page to define-api
- Added JSON API format configuration for proper JSON responses
- Updated all frontend JavaScript files to use new API URLs
- Maintained define-page for HTML pages and static file serving
- Added comprehensive documentation of changes

Benefits:
- Framework compliance with Radiance best practices
- Automatic routing at /api/asteroid/<name>
- Clean lambda-list parameter handling
- Built-in browser/API dual usage support
- Proper HTTP status codes for errors

All API endpoints tested and working correctly.
2025-10-08 22:56:54 -04:00
glenneth dde8027b5c WORKING: API-aware authentication returns JSON for API routes
 Solution:
- require-authentication returns T on success, api-output value on failure
- Endpoints check result: if T, execute body; else return api-output value
- api-output sets response data which gets returned to client

 Results:
- API routes return JSON errors (not HTML redirects)
- Page routes still redirect to login
- Player page handles auth errors gracefully
- Shows 'Error loading tracks' instead of crashing

 Pattern:
  (let ((auth-result (require-authentication)))
    (if (eq auth-result t)
        ;; authenticated - execute endpoint
        ...
        ;; not authenticated - return api-output value
        auth-result))

Thanks to easilokx for the guidance on Radiance patterns!
2025-10-07 18:39:49 -04:00
glenneth 5d31763e85 Add user registration and authentication UI improvements
- Add registration page with form validation
- Add login/register/logout navigation with conditional display
- Add auth-status API endpoint for session checking
- Add auth-ui.js for dynamic nav based on login state
- Update navigation across all pages (front, admin, profile, player)
- Style logout button with subtle red color
- Auto-login after successful registration
2025-10-07 18:39:49 -04:00
glenneth f7bc30f18c Add user profile page with edit functionality 2025-10-07 18:39:49 -04:00
glenneth 1b1445e25f Add user profile page with clip template styling
- Created profile.chtml template with listening statistics, recent tracks, and top artists
- Added profile.js for dynamic data loading and user interactions
- Extended LASS styles for profile-specific elements (artist stats, track items, activity charts)
- Implemented /profile route with authentication and template rendering
- Added profile API endpoints for user data, stats, recent tracks, and top artists
- Added profile link to main navigation
- Includes placeholder functionality for future listening metrics implementation
2025-10-07 18:39:49 -04:00
Glenn Thompson b31800a7db Fix playlist schema mismatch - use track-ids field consistently
- Fixed field name mismatch: schema uses 'track-ids' not 'tracks'
- Handle Radiance DB storing text fields as lists
- Parse/format comma-separated track IDs properly
- Code is now correct but db:update still doesn't persist (i-lambdalite limitation)
- Requires PostgreSQL for full functionality
2025-10-07 18:39:49 -04:00
Luis Pereira 8589b774ed fix: add user management page 2025-10-04 16:10:50 -04:00
Brian O'Reilly 439da74bb3 remove duplicated code. 2025-10-04 10:31:46 -04:00
Glenn Thompson 803555b8b1 Complete Templates section: CLIP refactoring, user management, pagination, playlists, UI fixes, PostgreSQL setup
 CLIP Template Refactoring:
- Centralized template rendering in template-utils.lisp
- Template caching for performance
- Eliminated code duplication

 User Management:
- Dedicated /admin/users page
- User creation, roles, activation
- Comprehensive API endpoints
- Full test suite

 Track Pagination:
- Admin dashboard: 10/20/50/100 per page
- Web player: 10/20/50 per page
- Smart navigation controls

⚠️ Playlist System (PARTIAL):
- Create empty playlists 
- View playlists 
- Save/load playlists  (database UPDATE fails)
- Audio playback fixed 
- Database limitations documented

 PostgreSQL Setup:
- Docker container configuration
- Complete database schema
- Persistent storage
- Radiance configuration
- Ready for Fade to integrate

 Streaming Infrastructure:
- All 3 streams working (MP3 128k, AAC 96k, MP3 64k)
- Fixed AAC stream (Docker caching issue)
- NAS music mount configured

 UI Fixes:
- Green live stream indicators
- Correct stream quality display
- Now Playing verified working
- Missing API endpoints added

📚 Documentation:
- 6 comprehensive org files
- Complete technical documentation
- Known issues documented

Note: Playlist editing requires PostgreSQL migration (Fade's task)
2025-10-04 09:54:04 -04:00
Glenn Thompson b39b54adcb feat: Add live Icecast/Liquidsoap status checks to admin dashboard
- Implement check-icecast-status() to query Icecast API
- Implement check-liquidsoap-status() to check Docker container status
- Update admin page to show real-time streaming infrastructure status
- Note: Auto-scan on startup deferred due to database timing issues
2025-10-04 09:54:04 -04:00
Glenn Thompson 24feeddfa8 feat: Add auto-scan on startup and live Icecast/Liquidsoap status checks
- Auto-scan music library on startup to load existing tracks
- Add check-icecast-status() function to query Icecast API
- Add check-liquidsoap-status() function to check Docker container
- Update admin dashboard to show real-time streaming status
- Eliminates need to manually copy files from incoming on every restart
2025-10-04 09:54:04 -04:00
Brian O'Reilly ce39a0ca1a nullify this duplicate code prior to deletion. 2025-10-03 13:14:04 -04:00
Glenn Thompson 88762d3bfc fix: Restore live stream metadata display on web interface
- Fix Icecast API endpoint to use proper HTTP basic authentication
- Handle both string and byte responses from drakma:http-request
- Parse XML response to extract track title and listener count
- Return JSON in format expected by frontend JavaScript

Now Playing info now updates correctly on both front page and player page:
- Shows current track (e.g. 'Vector Lovers - Boulevard')
- Updates every 10 seconds automatically
- Displays real-time listener counts

AAC streaming feature is now complete with full live metadata integration.
2025-10-02 16:51:59 +03:00
Glenn Thompson d8306f0585 feat: Complete Docker streaming integration with web interface
- Add live stream integration to both front page and player page
- Add /api/icecast-status endpoint to fetch real-time stream data
- Add drakma dependency for HTTP requests to Icecast
- Fix JavaScript errors on player page with proper error handling
- Add auto-updating 'Now Playing' info every 10 seconds
- Update .gitignore to preserve docker/music/ directory structure
- Add .gitkeep to maintain docker/music/ folder in repository
- Improve user experience with separate public/registered user flows

Integration now complete:
- Front page: Public live stream access
- Player page: Live stream + playlist management for registered users
- Real-time metadata from Icecast JSON API
- Graceful error handling for missing stream backend
2025-10-02 16:51:03 +03:00
Glenn Thompson e61a5a51df Complete Docker streaming infrastructure and user management fixes
## Docker Infrastructure Improvements
- **Liquidsoap Upgrade**: Updated to latest savonet/liquidsoap:792d8bf tag
- **Port Configuration**: Resolved port conflicts, standardized on port 8000 for streaming
- **Service Integration**: Docker Icecast (8000) + Asteroid web app (8080) architecture
- **Script Updates**: Fixed docker-compose commands for legacy compatibility
- **Documentation**: Comprehensive updates to setup-complete.org with correct URLs

## User Management System Fixes
- **Database Field Handling**: Fixed list vs string format inconsistencies in RADIANCE i-lambdalite
- **Authentication Flow**: Resolved "string designator" errors in user initialization
- **Admin Creation**: Fixed default admin user detection and creation logic
- **Session Management**: Proper handling of user ID storage and retrieval

## Web Interface Improvements
- **Navigation Routes**: Fixed /player/ → /player route mismatch
- **Link Consistency**: All navigation links now match defined routes
- **Template Integration**: Proper CLIP template processing with corrected data types

## Configuration Management
- **RADIANCE Config**: Fixed r-simple-wsessions typo in startup modules
- **Domain Setup**: Added "asteroid" domain to RADIANCE configuration
- **Service Dependencies**: Proper module loading order and error handling

## System Integration
- **Dual-Port Architecture**: Streaming (8000) + Web Interface (8080) separation
- **Service Status**: Integration points for Docker service monitoring
- **Audio Pipeline**: Liquidsoap → Icecast → Web Player workflow established

## Testing & Validation
- **Stream Verification**: Confirmed http://localhost:8000/asteroid.mp3 streaming
- **Web Access**: Validated http://localhost:8080/asteroid/ interface
- **User Authentication**: Tested login/logout and admin panel access
- **Database Operations**: Verified track metadata and user management

This commit establishes a fully functional internet radio streaming platform
with containerized audio services and integrated web management interface.
2025-10-02 16:50:06 +03:00
Glenn Thompson 84d0bc4ce4 Fix Asteroid Radio authentication system
- Fix database query syntax for RADIANCE hash table returns
- Handle RADIANCE field storage format (lists instead of strings)
- Configure r-simple-sessions module for session management
- Update login page styling to match main site theme
- Implement working authentication with admin/asteroid123
- Add proper error handling and debug logging
- Ensure session persistence and redirects work correctly
2025-09-30 14:11:46 -04:00
Brian O'Reilly 16f3592e97 recursively scan the music directory to implicit depth 2
it is likely that the music library will contain directories of
albums, read the files inside those dirs.
2025-09-30 14:11:46 -04:00
Brian O'Reilly 7ce119cabd Some new dependencies
start up a slynk server in the binary entry point so we can attach Sly
to it and work live without pfaffing about in the threading library,
hiding radiance from Sly/Slynk running inside emacs.
2025-09-30 14:11:46 -04:00
Brian O'Reilly 873b2903cc refactor glenn's database feature into discrete files. 2025-09-11 10:33:26 -04:00
Glenn Thompson cb1d6e5596 Implement complete internet radio streaming system
- Add live streaming with Icecast2 and Liquidsoap integration
- Fix track streaming endpoints with proper RADIANCE database queries
- Implement music library management with metadata extraction
- Add web player interface with HTML5 audio controls
- Fix admin panel functionality for file management
- Create playlist system for continuous radio broadcasting
- Add live stream URL to web interface
- Support MP3 streaming at 128kbps with proper audio processing
- Enable network access for internal radio broadcasting
- Add comprehensive README.org documentation
- Create start/stop scripts for service management
- Use secure random password for streaming authentication
2025-09-11 15:30:01 +03:00
Glenn Thompson 9f1524da02 Implement complete metadata extraction and database integration
- Add taglib dependency for ID3/audio metadata extraction
- Implement extract-metadata-with-taglib function with fallback to basic metadata
- Fix database field access using gethash for RADIANCE hash table records
- Add /admin/scan-library API endpoint for triggering music library scans
- Add /admin/tracks API endpoint for retrieving stored track metadata
- Support MP3, FLAC, OGG, and WAV audio formats
- Implement recursive directory scanning with cl-fad
- Add comprehensive error handling and progress reporting
- Create music directory structure (library/, incoming/, temp/)
- Test metadata extraction workflow with sample files

All core metadata extraction and database functionality now working.
2025-09-11 10:47:57 +03:00