Skip to content

Add Airable streaming support: Radio, Podcasts, and UPnP#20

Merged
hilli merged 9 commits intomainfrom
airable
Feb 1, 2026
Merged

Add Airable streaming support: Radio, Podcasts, and UPnP#20
hilli merged 9 commits intomainfrom
airable

Conversation

@hilli
Copy link
Copy Markdown
Owner

@hilli hilli commented Feb 1, 2026

Summary

This PR adds comprehensive streaming support via KEF's Airable integration, including:

  • Internet Radio - Browse, search, and play radio stations (favorites, popular, local, trending, HQ, new)
  • Podcasts - Browse, search, and play podcast episodes (favorites, popular, trending, history)
  • UPnP/DLNA - Browse and play media from local network media servers

New Commands

Radio (kefw2 radio)

  • radio play <station> - Play a radio station
  • radio favorites - List favorite stations
  • radio popular, local, trending, hq, new - Browse radio categories
  • radio search <query> - Search for stations
  • Full tab completion with hierarchical path navigation

Podcasts (kefw2 podcast)

  • podcast play <show/episode> - Play a podcast episode
  • podcast favorites - List favorite podcasts
  • podcast popular, trending, history - Browse podcast categories
  • podcast search <query> - Search for podcasts
  • Full tab completion with Show Name/Episode Name syntax

UPnP (kefw2 upnp)

  • upnp browse [path] - Browse UPnP media servers
  • upnp play <path> - Play media from UPnP server
  • upnp servers - List available media servers
  • Tab completion for server/folder/file navigation

Queue Management (kefw2 queue)

  • queue list - Show current play queue
  • queue add <item> - Add items to queue
  • queue clear - Clear the queue
  • queue save/load - Save and load queue presets
  • queue playmode - Set repeat/shuffle modes

Cache Configuration (kefw2 config cache)

  • config cache - Show all cache settings
  • config cache enable/disable - Toggle caching
  • config cache ttl-* - Configure TTL per service type
  • New ttl-default setting for future services

Technical Highlights

  • Airable API integration (kefw2/airable.go, airable_*.go) - Full client for KEF's Airable service
  • Intelligent caching (kefw2/cache.go, cmd/cache.go) - Configurable per-service TTL caching for fast tab completion
  • Hierarchical path completion (cmd/completion_helpers.go) - Smart path-based tab completion with colon escaping for zsh compatibility
  • Interactive content picker (cmd/content_picker.go) - TUI browser for content selection

Files Changed

  • 25 files changed, ~10,000 lines added
  • New library files: kefw2/airable*.go, kefw2/queue.go, kefw2/cache.go
  • New CLI commands: cmd/kefw2/cmd/{radio,podcast,upnp,queue,cache}.go
  • Comprehensive tab completion support throughout

@hilli hilli self-assigned this Feb 1, 2026
hilli added 8 commits February 1, 2026 20:16
- Add MakeCategoryCommand factory for radio category commands
- Add MakePodcastCategoryCommand factory for podcast category commands
- Add MakeStationCompletion and MakePodcastCompletion factories
- Add HandlePickerResult shared result handler
- Replace 5 radio commands and 3 podcast commands with factory calls
- Net reduction of ~930 lines of duplicated code
Removed unused code:
- cacheConfigSettings variable (config_cache.go)
- loadingMsg type (radio.go)
- upnpContainerStyle, upnpAudioStyle variables (upnp.go)
- FilterItemsByType function (completion_helpers.go)
- DiscoverSpeakersLegacy function (kefw2/discover.go)
- RadioStation, Podcast, PodcastEpisode, MediaServer, UPnPTrack type structs
- GetRadioHistory, GetRadioRecommendations methods (kefw2/airable_radio.go)

Consolidated duplicates:
- parseDisplayPath: merged radio and podcast versions into airable.go
- findItemByName: replaced findStationByName and findPodcastByName

Net reduction: 119 lines (71 added, 190 removed)
- Create airable_service.go with unified service abstraction for radio/podcast
- Reduce airable_radio.go from 622 to 221 lines (-64%)
- Reduce airable_podcast.go from 537 to 185 lines (-66%)
- Add exitOnError/exitWithError helpers to reduce CLI boilerplate
- Apply error helpers across 10 CLI command files
- Consolidate findItemByName with optional type filtering
- Remove unused pp dependency and clean up examples
- Remove commented scaffolding code from root.go
…thError helpers

- Convert os.Exit(1) patterns across 10 CLI command files
- Use centralized exitOnError() for error checking with message
- Use exitWithError() for unconditional error exits
- Remove 289 lines of boilerplate error handling code
- Build and tests pass
@hilli hilli merged commit 21e60a3 into main Feb 1, 2026
3 checks passed
@hilli hilli deleted the airable branch February 1, 2026 21:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant