class Robut::Plugin::Rdio
A plugin that hooks into Rdio
, allowing you to queue songs from HipChat. key
and secret
must be set before we can deal with any Rdio
commands. Additionally, you must call start_server
in your Chatfile to start the Rdio
web server.
Constants
- RESULT_DISPLAYER
Attributes
The domain associated with token
. Defaults to localhost.
The host the Rdio
web player will run on. Defaults to localhost.
Your Rdio
API Key
The port the Rdio
web player will run on. Defaults to 4567.
Your Rdio
API app secret
The playback token for domain
. If you’re accessing Rdio
on localhost, you shouldn’t need to change this. Otherwise, download the rdio-python plugin:
https://github.com/rdio/rdio-python
and generate a new token for your domain:
./rdio-call --consumer-key=YOUR_CONSUMER_KEY --consumer-secret=YOUR_CONSUMER_SECRET getPlaybackToken domain=YOUR_DOMAIN
Public Class Methods
Starts a Robut::Plugin::Rdio::Server
server for communicating with the actual Rdio
web player. You must call this in the Chatfile if you plan on using this gem.
# File lib/robut-rdio.rb, line 43 def self.start_server @server = Thread.new { Server.run! :host => (host || "localhost"), :port => (port || 4567) } Server.token = self.token || "GAlNi78J_____zlyYWs5ZG02N2pkaHlhcWsyOWJtYjkyN2xvY2FsaG9zdEbwl7EHvbylWSWFWYMZwfc=" Server.domain = self.domain || "localhost" end
Public Instance Methods
@param [String,Array] request that is being evaluated as a command request @return [Boolean]
# File lib/robut-rdio.rb, line 145 def command?(request) Array(request).join(' ') =~ /^(?:play|(?:un)?pause|next|restart|back|clear)$/ end
Because an instance of this plugin is not created until the Robut
client has recieved at least one message. The server callbacks need to be created during the handle
request. This allows for the server to communicate back through the Robut
communication channel that it receives the messages.
# File lib/robut-rdio.rb, line 55 def establish_server_callbacks! Server.reply_callback ||= lambda{|message| reply(message, :room)} Server.state_callback ||= lambda{|message| reply("/me #{message}", :room)} end
Queues songs into the Rdio
web player. @nick play search query will queue the first search result matching ‘search query’ into the web player. It can be an artist, album, or song.
# File lib/robut-rdio.rb, line 160 def handle(time, sender_nick, message) establish_server_callbacks! words = words(message) if sent_to_me?(message) if play?(words) play_result *parse_tracks_to_play(words) elsif search_and_play?(words) search_and_play_criteria = words[1..-1].join(" ") unless search_and_play_result search_and_play_criteria reply("I couldn't find '#{search_and_play_criteria}' on Rdio.") end elsif search?(words) find words.join(' ')[search_regex,-1] elsif skip_album?(message) run_command("next_album") else command?(words) run_command(words.join("_")) end end end
@param [Array,String] track_request the play request that is going to be
parsed for available tracks.
@return [Array] track numbers that were identified.
@example Requesting multiple tracks
"play 1" "play 1 2" "play 1,2" "play 1-3" "play 1, 2 4-6" "play all"
# File lib/robut-rdio.rb, line 105 def parse_tracks_to_play(track_request) if Array(track_request).join(' ') =~ /play all/ [ 'all' ] else Array(track_request).join(' ')[play_results_regex,-1].to_s.split(/(?:\s|,\s?)/).map do |track| tracks = track.split("-") (tracks.first.to_i..tracks.last.to_i).to_a end.flatten end end
@param [String,Array] request that is being evaluated as a play request @return [Boolean]
# File lib/robut-rdio.rb, line 86 def play?(request) Array(request).join(' ') =~ play_results_regex end
@param [String,Array] request that is being evaluated as a play request @return [Boolean]
# File lib/robut-rdio.rb, line 78 def play_results_regex /^(?:play)?\s?(?:result)?\s?((?:\d[\s,-]*)+|all)$/ end
As the plugin is initialized each time a request is made, the plugin maintains the state of the results from the last search request to ensure that it will be available when someone makes another request.
# File lib/robut-rdio.rb, line 203 def results @@results end
@param [String,Array] request that is being evaluated as a search request @return [Boolean]
# File lib/robut-rdio.rb, line 128 def search?(request) Array(request).join(' ') =~ search_regex end
@param [String,Array] request that is being evaluated as a search and playback
request
@return [Boolean]
# File lib/robut-rdio.rb, line 137 def search_and_play?(request) Array(request).join(' ') =~ /^play\b[^\b]+/ end
@return [Regex] that is used to match searches for their parameters @see rubular.com/?regex=(find%7Cdo%20you%20have(%5Csany)%3F)%5Cs%3F(.%2B%5B%5E%3F%5D)%5C%3F%3F
# File lib/robut-rdio.rb, line 120 def search_regex /(find|do you have(\sany)?)\s?(.+[^?])\??/ end
@param [String,Array] request that is being evaluated as a skip album request @return [Boolean]
# File lib/robut-rdio.rb, line 153 def skip_album?(message) message =~ /(next|skip) album/ end
Returns a description of how to use this plugin
# File lib/robut-rdio.rb, line 61 def usage [ "#{at_nick} play <song> - queues <song> for playing", "#{at_nick} play album <album> - queues <album> for playing", "#{at_nick} play track <track> - queues <track> for playing", "#{at_nick} play/unpause - unpauses the track that is currently playing", "#{at_nick} next - move to the next track", "#{at_nick} next|skip album - skip all tracks in the current album group", "#{at_nick} restart - restart the current track" ] end
Private Instance Methods
# File lib/robut-rdio.rb, line 226 def find(query) reply("Searching for: #{query}...") @@results = search(query) result_display = format_results(@@results) reply(result_display) end
# File lib/robut-rdio.rb, line 298 def format_result(search_result, index) response = RESULT_DISPLAYER[search_result.class].call(search_result) puts response "#{index}: #{response}" end
# File lib/robut-rdio.rb, line 234 def format_results(results) result_display = "" results.each_with_index do |result, index| result_display += format_result(result, index) + "\n" end result_display end
# File lib/robut-rdio.rb, line 282 def has_result?(number) !@@results[number].nil? end
# File lib/robut-rdio.rb, line 278 def has_results? @@results && @@results.any? end
# File lib/robut-rdio.rb, line 242 def play_result(*requests) if !has_results? reply("I don't have any search results") and return end requests = requests.flatten.compact # Queue all the songs when the request is 'all' if requests.first == "all" results.length.times {|index| queue result_at(index) } return end requests.flatten.each do |request| if has_result?(request.to_i) queue result_at(request.to_i) else reply("I don't have that result") end end end
# File lib/robut-rdio.rb, line 290 def queue(result) Server.queue << result.key name = result.name name = "#{result.artist_name} - #{name}" if result.respond_to?(:artist_name) && result.artist_name reply("Queuing: #{name}") end
# File lib/robut-rdio.rb, line 286 def result_at(number) @@results[number] end
# File lib/robut-rdio.rb, line 222 def run_command(command) Server.command << command end
Searches Rdio
for sources matching words
.
Given an array of Strings, which are the search terms, use Rdio
to find any tracks that match. If the first word happens be ‘album` then search for albums that match the criteria.
# File lib/robut-rdio.rb, line 311 def search(words) ::Rdio.init(self.class.key, self.class.secret) api = ::Rdio::Api.new(self.class.key, self.class.secret) words = words.split(' ') if words.first == "album" query_string = words[1..-1].join(' ') results = api.search(query_string, "Album") elsif words.first == "track" query_string = words[1..-1].join(' ') results = api.search(query_string, "Track") elsif words.first == "artist" query_string = words[1..-1].join(' ') results = api.search(query_string, "Artist") else query_string = words.join(' ') results = api.search(query_string, "Track") end end
# File lib/robut-rdio.rb, line 269 def search_and_play_result(message) if result = Array(search(message)).first queue(result) true end end