Commit Graph

365 Commits

Author SHA1 Message Date
Luis Pereira d894964c20 fix: increase now-playing rate limit to 10 per second 2026-01-23 21:17:44 -05:00
Luis Pereira 6b56a17b4a fix: restore AUTHSTATE object when there is no login 2026-01-23 21:17:44 -05:00
Luis Pereira 0def454077 feat: use navbar partial on all page templates 2026-01-21 17:32:41 -05:00
Luis Pereira 7c6eaa1fe0 feat: adds templating system docs 2026-01-21 17:32:41 -05:00
Luis Pereira 2992822010 feat: replace global auth state variable with template injected object 2026-01-21 17:32:41 -05:00
Luis Pereira 6ab7489f9b feat: allows for navbar menu exclution with exclude list 2026-01-21 17:32:41 -05:00
Luis Pereira cffb3cf384 feat: reusable navbar with auth check in render 2026-01-21 17:32:41 -05:00
Luis Pereira 732ff0858e fix: hide analyzer when in frame player mode 2026-01-21 17:32:41 -05:00
glenneth 55eafa943f Fix rate limiter corruption: cleanup negative amounts on startup
The r-simple-rate library has a bug where rate limit counters can go
negative and never reset. This happens because the reset condition
only triggers when amount >= 0, so negative amounts are permanently
stuck.

This fix adds:
- cleanup-corrupted-rate-limits function to delete corrupted entries
- db:connected trigger to run cleanup automatically on startup

This prevents the 429 error loops that occurred when counters became
corrupted with large negative values.
2026-01-18 12:58:35 -05:00
glenneth a9c48e59c9 Increase rate limits to 180 req/min for polling endpoints 2026-01-18 10:55:33 -05:00
glenneth 4622ae2440 Fix notification icon path to use existing asteroid.png 2026-01-18 10:21:21 -05:00
glenneth 849c1c2716 Increase rate limits on polling endpoints
Fix 429 errors caused by aggressive rate limiting on now-playing APIs.
Changed from 2-3 req/sec to 60 req/min for:
- asteroid/partial/now-playing
- asteroid/partial/now-playing-inline
- asteroid/partial/now-playing-json
- asteroid/channel-name

This fixes notifications not working and may resolve auto-reconnect issues.
2026-01-18 10:09:52 -05:00
glenneth 6d4169b707 Add system notifications for track changes
- Implement Web Notifications API in ParenScript
- Add notification toggle button (🔔/🔕) to player frame
- Show 'Artist - Track' notification when track changes
- Store notification preference in localStorage
- Auto-close notifications after 5 seconds
- Click notification to focus browser window
2026-01-18 08:55:53 -05:00
glenneth 7ed11ae2f4 Add sort dropdown for admin geo stats (minutes vs listeners)
- Add dropdown to admin template to choose sort order
- Update get-geo-stats to accept order-by parameter
- Update API endpoint to pass sort-by parameter
- Update ParenScript to read dropdown and pass to API
- Default sort is by minutes (engagement time)
2026-01-18 08:48:34 -05:00
glenneth b68fce817d Fix geo stats ordering to sort by total_minutes instead of total_listeners
Countries with high engagement (listen time) should appear at the top,
not countries with just high unique listener counts.
2026-01-18 08:48:34 -05:00
Luis Pereira ff651e6a36 fix: merged status and status-content 2026-01-15 12:58:45 -05:00
Luis Pereira 2118f4ed5a fix: merged about and about-content 2026-01-15 12:58:45 -05:00
Luis Pereira b862097ca2 fix: merged player and player-content 2026-01-15 12:58:45 -05:00
Luis Pereira 01cb0366c0 fix: merged frontend and frontend-content 2026-01-15 12:58:45 -05:00
Glenn Thompson 151f6c5569 Replace Autechre tracks with flow-state alternatives, add Underworld
- Replace jarring Autechre tracks with smoother ambient alternatives:
  - Labradford, Biosphere, Tycho, Marconi Union, arovane, Four Tet, Brian Eno, Alva Noto, Proem
- Add Underworld - Everything, Everything to all updated playlists
- Improves listener experience for coding/hacking flow state

Affected playlists:
- afternoon-orbit.m3u
- Asteroid-Low-Orbit.m3u
- Asteroid-Low-Orbit-DOCKER.m3u
- escape-velocity.m3u
- geostationary_stream_queue.m3u
- midnight-ambient.m3u
- new-years-eve-2025.m3u
2026-01-12 20:31:46 -05:00
glenneth 249844160f Fix listener minutes tracking for accurate geo stats
- Add register-web-listener to now-playing-json API endpoint
  This keeps listeners registered during continuous playback instead of
  timing out after 5 minutes of inactivity

- Fix listen_minutes calculation to increment by listener_count per poll
  Previously incremented by 1 regardless of how many listeners, now properly
  tracks listener-minutes (1 minute per listener per 60s poll interval)

- Add migration 009 documenting the calculation fix
2026-01-11 13:25:55 -05:00
glenneth 8b6209e4e0 Add mini spectrum analyzer to player frame with theme/style sync
- Remove cross-frame audio access that was breaking audio on navigation
- Add mini spectrum visualizer to persistent player frame
- Mini analyzer syncs theme and style with main analyzer via localStorage
- Add MusicBrainz search link to player frame (updates with track changes)
- Reduce quality selector width from 140px to 55px
- Add search_url to now-playing-json API response

The main analyzer is disabled in frameset mode due to browser restrictions
on cross-frame MediaElementSource, but the mini analyzer in the player
frame provides visualization that persists across content navigation.
2026-01-11 13:25:55 -05:00
Luis Pereira bad9d4294b fix: add api catch all route with 404 2026-01-07 17:39:26 -05:00
glenneth 8e60563e9d Fix stream stall reconnection failure
- Reset *is-reconnecting* flag before play attempt so error handler can
  catch failures and trigger retry with exponential backoff
- Always reconnect on stall event - ready-state check was unreliable
- Add retry logic with backoff when reconnect fails (up to 5 attempts)
- Store stalled timeout reference for proper cancellation

Fixes issue where stream would show 'Stream stalled - reconnecting...'
but never actually reconnect, requiring manual intervention.
2026-01-05 08:35:50 -05:00
glenneth f476b83cbe fix: Preserve playlist selection in scheduler dropdown on refresh 2026-01-04 14:11:15 -05:00
Brian O'Reilly f0f2dd93a4 patch bad change to Makefile to restore build.
take 2.
2026-01-02 19:07:43 -05:00
Luis Pereira f4468212de fix: docker image build configured with posgres 2026-01-02 07:43:47 -05:00
Luis Pereira abb6d97a61 fix: update db seed to match current schema 2026-01-02 07:43:47 -05:00
glenneth be0b622901 fix: Use head/cat instead of sed for multi-line YP snippet insertion 2026-01-02 07:42:11 -05:00
glenneth a52602afda feat: Address PR feedback - rename XML files and add STATION_URL config
- Rename icecast.xml.base -> icecast-base.xml for editor highlighting
- Rename icecast-yp.xml.snippet -> icecast-yp-snippet.xml for editor highlighting
- Add STATION_URL env var to Liquidsoap for YP directory station link
- Production sets STATION_URL=https://asteroid.radio
- Update docker-compose.yml to pass both ICECAST_HOSTNAME and STATION_URL
- Update environment.sh.template with STATION_URL documentation
2026-01-02 07:42:11 -05:00
glenneth 821352edb7 feat: Add ICECAST_HOSTNAME config for YP directory registration
- Add hostname substitution in icecast-entrypoint.sh
- Update environment.sh.template with ICECAST_HOSTNAME option
- Defaults to localhost for dev, production sets ice.asteroid.radio
- Fixes YP directories showing localhost:8000 as stream URL
2026-01-02 07:42:11 -05:00
glenneth 1760fa5768 feat: Make YP directory publishing configurable via ICECAST_ENABLE_YP env var
- Add Dockerfile.icecast with custom entrypoint
- Add icecast-entrypoint.sh to conditionally insert YP config
- Add icecast.xml.base (without YP blocks)
- Add icecast-yp.xml.snippet (YP directory blocks)
- Update docker-compose.yml to build custom icecast image
- Update environment.sh.template with documentation

Dev environments default to YP disabled.
Production sets ICECAST_ENABLE_YP=true to publish to internet-radio.com
2026-01-02 07:42:11 -05:00
Brian O'Reilly 8cbdaef217 we are at a point where there's lots of interstitial files...
ignore them.
2025-12-30 15:26:09 -05:00
Brian O'Reilly 6721d57550 Unneeded things...
no need for the postgres/docker env, and we don't track
playlists/stream-queue.m3u because it is dynamically generated.
2025-12-30 15:24:13 -05:00
Brian O'Reilly 3851857787 update our ignorance. 2025-12-30 15:20:44 -05:00
Brian O'Reilly a8bf864499 Lets institute some operations around here
A directory for ops scripts, plus a script to backup the posgres
database that holds up asteroid.radio.
2025-12-30 13:07:30 -05:00
Glenn Thompson de70fbde5a refactor: Address PR review feedback for timestamp handling
- Rename format-timestamp-for-postgres to format-timestamp-iso8601 (database-agnostic)
- Reuse format-timestamp-iso8601 in authenticate-user instead of inline formatting
- Change listened_at field type from integer to timestamp for consistency
2025-12-29 09:39:51 -05:00
Glenn Thompson debf47c9c7 fix: Use correct table name user_listening_history in user-profile.lisp
- Update all references from listening_history to user_listening_history
- Use correct column names: user_id, listened_at, duration_seconds, track_artist
- Update database.lisp collection definition to match PostgreSQL schema
2025-12-29 09:39:51 -05:00
Glenn Thompson 4b49f63991 fix: Normalize USERS table timestamps before dm:save to prevent PostgreSQL type errors
- Add format-timestamp-for-postgres and normalize-user-timestamps functions in database.lisp
- data-model-save now normalizes timestamp fields for USERS table before saving
- Fix authenticate-user to use data-model-save instead of dm:save directly
- Add global auth state in auth-ui.lisp for other scripts to check login status
- Add auth checks in front-page.lisp and stream-player.lisp to skip API calls when not logged in
- Fix ParenScript parentheses structure in stream-player.lisp DOMContentLoaded handler

Fixes password reset, role update, and last-login update failures caused by
integer timestamps being sent to PostgreSQL TIMESTAMP columns.
2025-12-29 09:39:51 -05:00
glenneth eb03947f7f refactor: Listening history to data-model + frame player favorites sync
- Refactor listening history functions to use data-model interface:
  - record-listen, get-listening-history, get-listening-stats
  - get-top-artists, clear-listening-history, get-listening-activity
  - Updated API endpoints to use dm:field
- Refactor get-user-avatar to use data-model
- Add postMessage sync between front page and frame player for favorites
- Add credentials:include to frame player fetch calls for session cookies
2025-12-28 09:58:33 -05:00
glenneth ccce10db50 feat: Sync favorites between front page and frame player via postMessage 2025-12-28 09:58:33 -05:00
Luis Pereira 2effe3bdef fix: listening history using integers 2025-12-27 17:02:31 -05:00
Luis Pereira 554f23ac40 fix: move playlist functions to data-model 2025-12-27 17:02:31 -05:00
Brian O'Reilly 4a79558c75 Merge branch 'glenneth1-glenneth/user-profile-enhancements'
Summary

This PR fixes several issues with the favorites feature:
Fixes

    Favorites star UI - Star now stays solid after favoriting a track (both main player and frame player)
        Fixed race condition where cache was checked before reload completed
        Cache now calls check-favorite-status after loading

    Track-id lookup - find-track-by-title now parses 'Artist - Title' format from Icecast metadata and searches both artist and title columns

    NIL user-id guards - All favorites functions now return early if user-id is NIL, preventing PostgreSQL errors when API is called without authentication

    Favorites API alist keys - Fixed Postmodern key names (TRACK-TITLE not TRACK_TITLE)

Files Changed

    user-profile.lisp - NIL guards and aget-profile helper
    frontend-partials.lisp - find-track-by-title improvement
    parenscript/front-page.lisp - Cache loading fix
    parenscript/stream-player.lisp - Cache loading fix for frame player
2025-12-27 14:00:02 -05:00
glenneth 9a767a7550 Merge remote-tracking branch 'upstream/main' into glenneth/user-profile-enhancements 2025-12-27 21:37:35 +03:00
Luis Pereira 820228bac1 feat: set bigger rate limit for now-playing api route 2025-12-27 13:28:10 -05:00
Luis Pereira b32e0bdbb0 fix: include http error code on json api format 2025-12-27 13:28:10 -05:00
Luis Pereira 6499c0a9ab feat: move routes to use rate-limit macros 2025-12-27 13:28:10 -05:00
Luis Pereira 8ae905a2c1 feat: add limit extension macros for define-page and define-api 2025-12-27 13:28:10 -05:00
Luis Pereira 1a39e0c6d2 fix: move copy files to admin role 2025-12-27 13:28:10 -05:00