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.
This commit is contained in:
Glenn Thompson 2025-10-01 15:02:09 +03:00
parent 2689ae690f
commit e61a5a51df
7 changed files with 809 additions and 25 deletions

View File

@ -283,7 +283,7 @@
:track-count (format nil "~d" track-count)
:library-path "/home/glenn/Projects/Code/asteroid/music/library/")))
(define-page player #@"/player/" ()
(define-page player #@"/player" ()
(let ((template-path (merge-pathnames "template/player.chtml"
(asdf:system-source-directory :asteroid))))
(clip:process-to-string

View File

@ -1,5 +1,5 @@
# Use official Liquidsoap Docker image from Savonet team
FROM savonet/liquidsoap:v2.2.5
FROM savonet/liquidsoap:792d8bf
# Switch to root for setup
USER root

View File

@ -23,28 +23,27 @@ Fade requested setting up Liquidsoap in Docker for the Asteroid Radio project, a
- *Audio*: Currently playing "Lorde - Ribs" from the music library
- *Streaming*: Both quality streams are active
- *Metadata*: Track information is being broadcast
- *Playlist*: Randomized playback from =/music/library/= directory
* 🚀 Quick Start Commands
* Quick Start Commands
** Start Streaming
#+BEGIN_SRC bash
./start-streaming.sh
./start.sh
#+END_SRC
** Test Everything
** Check Status
#+BEGIN_SRC bash
./test-streaming.sh
docker-compose ps
#+END_SRC
** View Logs
#+BEGIN_SRC bash
docker compose logs -f
docker-compose logs -f
#+END_SRC
** Stop Services
#+BEGIN_SRC bash
docker compose down
./stop.sh
#+END_SRC
* 🔧 Admin Access
@ -115,12 +114,8 @@ asteroid/docker/
├── docker-streaming.org # Detailed documentation
└── setup-complete.org # This summary
~/asteroid-scripts/
├── start-streaming-fixed.sh # Full startup script (works from anywhere)
├── stop-streaming-fixed.sh # Full stop script
├── test-streaming.sh # Testing and verification script
├── setup-remote-music.sh # Remote storage setup
└── update-docker-remote-music.sh # Update config for remote music
asteroid/
└── run-asteroid.sh # Main Asteroid Radio application launcher
#+END_EXAMPLE
* 🎯 Mission Accomplished

View File

@ -13,13 +13,13 @@ fi
# Start services
echo "🔧 Starting services..."
docker compose up -d
docker-compose up -d
# Wait and show status
sleep 3
echo ""
echo "📊 Service Status:"
docker compose ps
docker-compose ps
echo ""
echo "🎵 Asteroid Radio is now streaming!"

View File

@ -6,7 +6,7 @@
echo "🛑 Stopping Asteroid Radio Docker Services..."
# Stop services
docker compose down
docker-compose down
echo ""
echo "✅ Services stopped."

File diff suppressed because one or more lines are too long

View File

@ -42,8 +42,9 @@
(users nil))
(dolist (user all-users)
(format t "Comparing ~a with ~a~%" (gethash "username" user) username)
(when (equal (first (gethash "username" user)) username)
(push user users)))
(let ((stored-username (gethash "username" user)))
(when (equal (if (listp stored-username) (first stored-username) stored-username) username)
(push user users))))
(format t "Query returned ~a users~%" (length users))
(when users
(format t "First user: ~a~%" (first users))
@ -197,14 +198,22 @@
(let ((all-users (get-all-users)))
`(("total-users" . ,(length all-users))
("active-users" . ,(count-if (lambda (user) (gethash "active" user)) all-users))
("listeners" . ,(count-if (lambda (user) (string= (gethash "role" user) "listener")) all-users))
("djs" . ,(count-if (lambda (user) (string= (gethash "role" user) "dj")) all-users))
("admins" . ,(count-if (lambda (user) (string= (gethash "role" user) "admin")) all-users)))))
("listeners" . ,(count-if (lambda (user)
(let ((role (gethash "role" user)))
(string= (if (listp role) (first role) role) "listener"))) all-users))
("djs" . ,(count-if (lambda (user)
(let ((role (gethash "role" user)))
(string= (if (listp role) (first role) role) "dj"))) all-users))
("admins" . ,(count-if (lambda (user)
(let ((role (gethash "role" user)))
(string= (if (listp role) (first role) role) "admin"))) all-users)))))
(defun create-default-admin ()
"Create default admin user if no admin exists"
(let ((existing-admins (remove-if-not
(lambda (user) (string= (gethash "role" user) "admin"))
(lambda (user)
(let ((role (gethash "role" user)))
(string= (if (listp role) (first role) role) "admin")))
(get-all-users))))
(unless existing-admins
(format t "~%Creating default admin user...~%")