License        Version        Build Status   Maintainability Code Coverage

Pandoru

Pandoru is a Ruby port of the Python pydora library, providing a comprehensive client for the unofficial Pandora music streaming API. This gem allows you to interact with Pandora programmatically to manage stations, get playlists, search for music, and control playback.

⚠️ Note: This is an unofficial API client. Use at your own risk and respect Pandora's terms of service.


Features

  • Station Management: Get station lists, create/delete stations, rename stations
  • Playlist Access: Retrieve playlists with track metadata and audio URLs
  • Music Search: Search for songs, artists, and albums
  • User Interaction: Thumbs up/down, bookmarks, sleep songs
  • Feedback Management: Add/remove track feedback
  • Station Seeds & Genome Traits: Inspect a station's seed artists/songs/genres and a track's Music-Genome focus traits (explain_track)
  • Genre Exploration: Browse and create stations from genre seeds
  • Multiple Audio Qualities: Support for low, medium, and high quality audio streams
  • Ruby Idioms: Built with Ruby best practices and idiomatic patterns

Installation

Add this line to your application's Gemfile:

gem 'pandoru'

Then execute:

bundle install

Or install it yourself as:

gem install pandoru

Usage

Configuration

Pandoru requires Pandora partner credentials to function. You can configure these in several ways:

1. Using a Configuration Hash

require 'pandoru'

# Note: These are example credentials - you need real ones
settings = {
  "PARTNER_USER" => "your-partner-user",
  "PARTNER_PASSWORD" => "your-partner-password", 
  "DEVICE" => "your-device-type",
  "DECRYPTION_KEY" => "your-decryption-key",
  "ENCRYPTION_KEY" => "your-encryption-key"
}

client = Pandoru::ClientBuilder.from_settings_hash(settings)
client.("your_email@example.com", "your_password")

2. Using Configuration Files

Pandoru supports both pydora-style and pianobar-style configuration files:

# From a pydora config file
client = Pandoru::ClientBuilder.from_config_file("~/.pydora.cfg")

# From a pianobar config file  
client = Pandoru::ClientBuilder.from_config_file("~/.config/pianobar/config")

Basic Operations

Managing Stations

# Get all user stations
stations = client.get_station_list

# Create a new station from search results
search_results = client.search("Radiohead")
station = client.create_station(search_token: search_results.first.music_token)

# Rename a station
client.rename_station(station.token, "My Radiohead Station")

# Delete a station
client.delete_station(station.token)

Working with Playlists

# Get a playlist from a station
playlist = client.get_playlist(station.token)

playlist.each do |track|
  puts "#{track.artist_name} - #{track.song_name}"
  puts "Audio URL: #{track.audio_url}"

  # Rate the track
  track.thumbs_up if track.allow_feedback

  # Bookmark the song or artist
  track.bookmark_song
  track.bookmark_artist
end

Searching for Music

# Search for music
results = client.search("The Beatles", include_near_matches: true)

results.songs.each do |song|
  puts "Song: #{song.song_name} by #{song.artist_name}"
end

results.artists.each do |artist|
  puts "Artist: #{artist.artist_name}"
end

Managing Bookmarks

# Get user bookmarks
bookmarks = client.get_bookmarks

bookmarks.song_bookmarks.each do |bookmark|
  puts "Bookmarked song: #{bookmark.song_name} by #{bookmark.artist_name}"
end

bookmarks.artist_bookmarks.each do |bookmark|
  puts "Bookmarked artist: #{bookmark.artist_name}"
end

Advanced Features

Genre Stations

# Browse genre stations
genre_stations = client.get_genre_stations

genre_stations.categories.each do |category|
  puts "Category: #{category}"
  genre_stations.stations_for_category(category).each do |station|
    puts "  Station: #{station.name}"
  end
end

Audio Quality

# Set default audio quality when creating client
client = Pandoru::ClientBuilder.from_settings_hash(settings.merge(
  "AUDIO_QUALITY" => "highQuality"  # or "mediumQuality", "lowQuality"
))

# Get specific quality audio URL for a track
track = playlist.first
high_quality_url = track.audio_url("highQuality")
medium_quality_url = track.audio_url("mediumQuality")  
low_quality_url = track.audio_url("lowQuality")

Error Handling

begin
  client.("user@example.com", "password")
rescue Pandoru::Errors::InvalidUserLogin
  puts "Invalid username or password"
rescue Pandoru::Errors::PandoraException => e
  puts "Pandora API error: #{e.message} (Code: #{e.code})"
end

API Reference

Client Classes

  • Pandoru::Client::APIClient - High-level API client with all Pandora operations
  • Pandoru::Client::BaseAPIClient - Lower-level client for advanced usage

Models

  • Pandoru::Models::Station - Represents a Pandora station
  • Pandoru::Models::StationList - Collection of user stations
  • Pandoru::Models::Playlist - Collection of playlist items
  • Pandoru::Models::PlaylistItem - Individual track in a playlist
  • Pandoru::Models::SearchResult - Search results container
  • Pandoru::Models::BookmarkList - User's bookmarked songs and artists

Client Builders

  • Pandoru::ClientBuilder.from_settings_hash(hash) - Create client from settings hash
  • Pandoru::ClientBuilder.from_config_file(path) - Create client from config file
  • Pandoru::ClientBuilder.default_client() - Create client with default settings

Architecture

Pandoru is architected similarly to the original pydora library:

  • Transport Layer: Handles HTTP communication and encryption/decryption
  • Client Layer: Provides high-level API methods
  • Models Layer: Represents Pandora data structures with Ruby idioms
  • Builders Layer: Factory classes for creating configured clients

The Ruby port maintains compatibility with pydora's API while providing Ruby-style interfaces and error handling.


Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt.

To install this gem onto your local machine, run bundle exec rake install.


Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/TwilightCoders/pandoru.

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

License

The gem is available as open source under the terms of the MIT License.


Acknowledgments

This Ruby gem is a port of the excellent pydora Python library by Mike Crute and contributors. All credit for the original API reverse engineering and design goes to the pydora project.

Disclaimer

⚠️ This project is not affiliated with or endorsed by Pandora Media, Inc. Use of this library may violate Pandora's Terms of Service. Use at your own risk.