Compare commits
2 Commits
aed413e21b
...
92c70626fe
| Author | SHA1 | Date |
|---|---|---|
|
|
92c70626fe | |
|
|
acd90b0e6f |
|
|
@ -44,6 +44,5 @@ docker-compose.yml.backup.*
|
|||
*.log
|
||||
logs/
|
||||
performance-logs/
|
||||
test-results-*.log
|
||||
|
||||
# Temporary files
|
||||
|
|
|
|||
73
README.org
73
README.org
|
|
@ -50,76 +50,19 @@ This branch implements a complete internet radio streaming system for Asteroid R
|
|||
asteroid/
|
||||
├── asteroid.lisp # Main server with RADIANCE routes
|
||||
├── asteroid.asd # System definition with dependencies
|
||||
├── asteroid # Compiled executable binary
|
||||
├── module.lisp # RADIANCE module definition
|
||||
├── database.lisp # Database abstraction layer
|
||||
├── auth-routes.lisp # Authentication and authorization routes
|
||||
├── user-management.lisp # User management system
|
||||
├── users.lisp # User utilities
|
||||
├── playlist-management.lisp # Playlist creation and management
|
||||
├── stream-media.lisp # Media streaming functionality
|
||||
├── app-utils.lisp # Application utilities
|
||||
├── template-utils.lisp # Template rendering utilities
|
||||
├── build-executable.lisp # Build script for binary
|
||||
├── setup-environment.lisp # Environment setup script
|
||||
├── asteroid-radio.liq # Liquidsoap streaming configuration
|
||||
├── playlist.m3u # Generated playlist for streaming
|
||||
├── Makefile # Build automation
|
||||
├── start-asteroid-radio.sh # Launch script for all services
|
||||
├── stop-asteroid-radio.sh # Stop script for all services
|
||||
├── template/ # CLIP HTML templates
|
||||
│ ├── front-page.chtml # Main page with live stream
|
||||
│ ├── admin.chtml # Admin dashboard
|
||||
│ ├── player.chtml # Web player interface
|
||||
│ ├── login.chtml # User login page
|
||||
│ ├── register.chtml # User registration page
|
||||
│ ├── profile.chtml # User profile management
|
||||
│ └── users.chtml # User management interface
|
||||
├── static/ # CSS, JavaScript, and assets
|
||||
│ ├── asteroid.lass # LASS stylesheet source
|
||||
│ ├── asteroid.css # Compiled CSS
|
||||
│ └── js/ # JavaScript modules
|
||||
│ ├── admin.js # Admin panel functionality
|
||||
│ ├── player.js # Audio player controls
|
||||
│ ├── front-page.js # Front page interactions
|
||||
│ ├── auth-ui.js # Authentication UI
|
||||
│ ├── profile.js # Profile management
|
||||
│ └── users.js # User management UI
|
||||
├── config/ # Configuration files
|
||||
│ └── radiance-postgres.lisp # PostgreSQL configuration
|
||||
├── data/ # Runtime data
|
||||
│ └── sessions/ # User session storage
|
||||
├── docs/ # Documentation
|
||||
│ ├── README.org # Documentation overview
|
||||
│ ├── API-ENDPOINTS.org # API endpoint reference
|
||||
│ ├── API-REFERENCE.org # Detailed API documentation
|
||||
│ ├── DEVELOPMENT.org # Development guide
|
||||
│ ├── INSTALLATION.org # Installation instructions
|
||||
│ ├── TESTING.org # Testing documentation
|
||||
│ ├── PROJECT-OVERVIEW.org # Project architecture overview
|
||||
│ ├── POSTGRESQL-SETUP.org # Database setup guide
|
||||
│ ├── DOCKER-STREAMING.org # Docker deployment guide
|
||||
│ ├── PLAYLIST-SYSTEM.org # Playlist system documentation
|
||||
│ ├── TRACK-PAGINATION-SYSTEM.org # Pagination documentation
|
||||
│ └── USER-MANAGEMENT-SYSTEM.org # User system documentation
|
||||
├── docker/ # Docker deployment
|
||||
│ ├── docker-compose.yml # Docker Compose configuration
|
||||
│ ├── Dockerfile.liquidsoap # Liquidsoap container
|
||||
│ ├── asteroid-radio-docker.liq # Docker Liquidsoap config
|
||||
│ ├── icecast.xml # Icecast configuration
|
||||
│ ├── init-db.sql # Database initialization
|
||||
│ ├── start.sh # Docker startup script
|
||||
│ └── stop.sh # Docker shutdown script
|
||||
├── music/ # Music library
|
||||
│ ├── incoming/ # Upload staging area
|
||||
│ └── library/ # Processed music files
|
||||
├── test-server.sh # Server testing script
|
||||
├── test-user-api.sh # User API testing script
|
||||
├── run-all-tests.sh # Comprehensive test suite
|
||||
├── comprehensive-performance-test.sh # Performance testing
|
||||
├── analyze-performance.py # Performance analysis tool
|
||||
├── simple-analysis.py # Simple analysis utilities
|
||||
├── design.org # Design documentation
|
||||
├── TODO.org # Project TODO list
|
||||
└── project-summary.org # Project summary and status
|
||||
│ └── player.chtml # Web player interface
|
||||
├── static/ # CSS and assets
|
||||
│ └── asteroid.lass # LASS stylesheet
|
||||
└── music/ # Music library
|
||||
├── incoming/ # Upload staging area
|
||||
└── library/ # Processed music files
|
||||
#+END_SRC
|
||||
|
||||
* Track Upload Workflow
|
||||
|
|
|
|||
20
TODO.org
20
TODO.org
|
|
@ -14,21 +14,11 @@
|
|||
- [ ] strip hard coded configurations out of the system
|
||||
- [ ] add configuration template file to the project
|
||||
|
||||
** [ ] Database [0/1]
|
||||
- [-] PostgresQL [1/3]
|
||||
- [X] Add a postgresql docker image to our docker-compose file.
|
||||
- [ ] Configure radiance for postres.
|
||||
- [ ] Migrate all schema to new database.
|
||||
|
||||
** Page Flow [0/0]
|
||||
- [ ] When a user logs in, their user profile page should become the
|
||||
root node of the app in their view.
|
||||
- [ ] When the admin user logs in, their view should become the admin
|
||||
profile page which should have panels for adminstering various
|
||||
aspects of the station.
|
||||
note: these two flow items probably shouldn't affect the current state
|
||||
of the front-page, except where some front-page elements are not
|
||||
displayed based on the user and their associated permissions.
|
||||
** [ ] Database [0/2]
|
||||
- [ ] PostgresQL [0/3]
|
||||
- [ ] Add a postgresql docker image to our docker-compose file.
|
||||
- [ ] Configure radiance for postres.
|
||||
- [ ] Migrate all schema to new database.
|
||||
|
||||
** [X] Templates: move our template hyrdration into the Clip machinery [4/4] ✅ COMPLETE
|
||||
- [X] Admin Dashboard [2/2]
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
:defsystem-depends-on (:radiance)
|
||||
:class "radiance:virtual-module"
|
||||
:depends-on (:slynk
|
||||
:lparallel
|
||||
:radiance
|
||||
:i-log4cl
|
||||
:r-clip
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@
|
|||
|
||||
(defun liquidsoap-queue-track (file-path)
|
||||
"Queue a specific track in Liquidsoap"
|
||||
(liquidsoap-telnet-command (format nil "queue.push ~A" file-path)))
|
||||
(liquidsoap-telnet-command (format nil "request.push ~A" file-path)))
|
||||
|
||||
(defun parse-liquidsoap-metadata (metadata-string)
|
||||
"Parse Liquidsoap metadata string into artist/title/album"
|
||||
|
|
|
|||
|
|
@ -14,21 +14,14 @@ settings.server.telnet.set(true)
|
|||
settings.server.telnet.port.set(1234)
|
||||
settings.server.telnet.bind_addr.set("0.0.0.0")
|
||||
|
||||
# Create request queue for dynamic track queuing
|
||||
queue = request.queue(id="queue")
|
||||
|
||||
# Create playlist source from mounted music directory
|
||||
# Use playlist.safe which starts playing immediately without full scan
|
||||
playlist_source = playlist.safe(
|
||||
id="music",
|
||||
radio = playlist.safe(
|
||||
mode="randomize",
|
||||
reload=3600,
|
||||
"/app/music/"
|
||||
)
|
||||
|
||||
# Combine queue and playlist - queue takes priority
|
||||
radio = fallback(track_sensitive=true, [queue, playlist_source])
|
||||
|
||||
# Add some audio processing
|
||||
radio = amplify(1.0, radio)
|
||||
radio = normalize(radio)
|
||||
|
|
|
|||
|
|
@ -928,4 +928,4 @@ body .stat-card .stat-label{
|
|||
color: #ccc;
|
||||
font-size: 0.875rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ NC='\033[0m' # No Color
|
|||
BASE_URL="${ASTEROID_URL:-http://localhost:8080}"
|
||||
API_BASE="${BASE_URL}/api/asteroid"
|
||||
VERBOSE="${VERBOSE:-0}"
|
||||
LOG_FILE="test-results-$(date +%Y%m%d-%H%M%S).log"
|
||||
|
||||
# Test counters
|
||||
TESTS_RUN=0
|
||||
|
|
@ -23,39 +22,28 @@ TESTS_PASSED=0
|
|||
TESTS_FAILED=0
|
||||
|
||||
# Helper functions
|
||||
log_to_file() {
|
||||
# Strip ANSI color codes for log file
|
||||
echo "$1" | sed 's/\x1b\[[0-9;]*m//g' >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
print_header() {
|
||||
local msg="\n========================================\n$1\n========================================\n"
|
||||
echo -e "\n${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE}$1${NC}"
|
||||
echo -e "${BLUE}========================================${NC}\n"
|
||||
log_to_file "$msg"
|
||||
}
|
||||
|
||||
print_test() {
|
||||
echo -e "${YELLOW}TEST:${NC} $1"
|
||||
log_to_file "TEST: $1"
|
||||
}
|
||||
|
||||
print_pass() {
|
||||
echo -e "${GREEN}✓ PASS:${NC} $1"
|
||||
log_to_file "✓ PASS: $1"
|
||||
TESTS_PASSED=$((TESTS_PASSED + 1))
|
||||
}
|
||||
|
||||
print_fail() {
|
||||
echo -e "${RED}✗ FAIL:${NC} $1"
|
||||
log_to_file "✗ FAIL: $1"
|
||||
TESTS_FAILED=$((TESTS_FAILED + 1))
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}INFO:${NC} $1"
|
||||
log_to_file "INFO: $1"
|
||||
}
|
||||
|
||||
# Test function wrapper
|
||||
|
|
@ -224,66 +212,6 @@ test_playlist_endpoints() {
|
|||
print_info "Note: Playlist creation requires authentication"
|
||||
}
|
||||
|
||||
# Test DJ Control Endpoints (Liquidsoap telnet integration)
|
||||
test_dj_control_endpoints() {
|
||||
print_header "Testing DJ Control Endpoints"
|
||||
|
||||
print_info "Note: DJ control endpoints require admin authentication"
|
||||
|
||||
# Test metadata endpoint (available to authenticated users)
|
||||
test_api_endpoint "/dj/metadata" \
|
||||
"DJ metadata endpoint" \
|
||||
"metadata"
|
||||
|
||||
# Test queue status endpoint
|
||||
test_api_endpoint "/dj/queue-status" \
|
||||
"DJ queue status endpoint" \
|
||||
"queue"
|
||||
|
||||
# Test skip track endpoint (requires admin)
|
||||
run_test "DJ skip track endpoint"
|
||||
local skip_response=$(curl -s -X POST "${API_BASE}/dj/skip")
|
||||
if echo "$skip_response" | grep -q "status"; then
|
||||
print_pass "DJ skip track endpoint responds"
|
||||
else
|
||||
print_fail "DJ skip track endpoint not responding"
|
||||
fi
|
||||
|
||||
# Test reload playlist endpoint (requires admin)
|
||||
run_test "DJ reload playlist endpoint"
|
||||
local reload_response=$(curl -s -X POST "${API_BASE}/dj/reload-playlist")
|
||||
if echo "$reload_response" | grep -q "status"; then
|
||||
print_pass "DJ reload playlist endpoint responds"
|
||||
else
|
||||
print_fail "DJ reload playlist endpoint not responding"
|
||||
fi
|
||||
|
||||
# Test queue track endpoint with dynamic track ID
|
||||
run_test "DJ queue track endpoint"
|
||||
|
||||
# Fetch a random track ID from the database
|
||||
local track_response=$(curl -s "${API_BASE}/tracks?page=1&per-page=1")
|
||||
|
||||
# Extract track ID using grep (works without jq)
|
||||
local track_id=$(echo "$track_response" | grep -o '"id":[0-9]*' | head -1 | grep -o '[0-9]*')
|
||||
|
||||
if [ -n "$track_id" ]; then
|
||||
print_info "Using track ID: $track_id for queue test"
|
||||
local queue_response=$(curl -s -X POST "${API_BASE}/dj/queue?track-id=${track_id}")
|
||||
|
||||
if echo "$queue_response" | grep -q "queued successfully\|Track not found"; then
|
||||
print_pass "DJ queue track endpoint responds (track ID: $track_id)"
|
||||
else
|
||||
print_fail "DJ queue track endpoint not responding properly"
|
||||
if [ $VERBOSE -eq 1 ]; then
|
||||
echo "Response: $queue_response"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
print_info "No tracks available in database, skipping queue test"
|
||||
fi
|
||||
}
|
||||
|
||||
# Test Page Endpoints (HTML pages)
|
||||
test_page_endpoints() {
|
||||
print_header "Testing HTML Page Endpoints"
|
||||
|
|
@ -350,42 +278,21 @@ test_api_format() {
|
|||
print_summary() {
|
||||
print_header "Test Summary"
|
||||
|
||||
local summary="Tests Run: $TESTS_RUN\nTests Passed: $TESTS_PASSED\nTests Failed: $TESTS_FAILED"
|
||||
|
||||
echo "Tests Run: $TESTS_RUN"
|
||||
echo -e "Tests Passed: ${GREEN}$TESTS_PASSED${NC}"
|
||||
echo -e "Tests Failed: ${RED}$TESTS_FAILED${NC}"
|
||||
log_to_file "$summary"
|
||||
|
||||
if [ $TESTS_FAILED -eq 0 ]; then
|
||||
echo -e "\n${GREEN}✓ All tests passed!${NC}\n"
|
||||
log_to_file "\n✓ All tests passed!\n"
|
||||
echo -e "${BLUE}Log file saved to: ${LOG_FILE}${NC}\n"
|
||||
exit 0
|
||||
else
|
||||
echo -e "\n${RED}✗ Some tests failed${NC}\n"
|
||||
log_to_file "\n✗ Some tests failed\n"
|
||||
echo -e "${BLUE}Log file saved to: ${LOG_FILE}${NC}\n"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main test execution
|
||||
main() {
|
||||
# Initialize log file with header
|
||||
cat > "$LOG_FILE" << EOF
|
||||
╔═══════════════════════════════════════════════════════════════╗
|
||||
║ Asteroid Radio Server Test Suite ║
|
||||
║ Test Results Log ║
|
||||
╚═══════════════════════════════════════════════════════════════╝
|
||||
|
||||
Test Run Date: $(date '+%Y-%m-%d %H:%M:%S')
|
||||
Server URL: ${BASE_URL}
|
||||
API Base: ${API_BASE}
|
||||
Verbose Mode: ${VERBOSE}
|
||||
|
||||
EOF
|
||||
|
||||
echo -e "${BLUE}"
|
||||
echo "╔═══════════════════════════════════════╗"
|
||||
echo "║ Asteroid Radio Server Test Suite ║"
|
||||
|
|
@ -394,7 +301,6 @@ EOF
|
|||
|
||||
print_info "Testing server at: ${BASE_URL}"
|
||||
print_info "Verbose mode: ${VERBOSE}"
|
||||
print_info "Log file: ${LOG_FILE}"
|
||||
echo ""
|
||||
|
||||
# Run all test suites
|
||||
|
|
@ -404,7 +310,6 @@ EOF
|
|||
test_track_endpoints
|
||||
test_player_endpoints
|
||||
test_playlist_endpoints
|
||||
test_dj_control_endpoints
|
||||
test_admin_endpoints
|
||||
test_page_endpoints
|
||||
test_static_files
|
||||
|
|
|
|||
Loading…
Reference in New Issue