/lib/lastfm/lastfm.rb

https://github.com/jarretth/LastfmForRoku · Ruby · 96 lines · 87 code · 9 blank · 0 comment · 3 complexity · 93258dab1e1339e23fda5c61d0e9def9 MD5 · raw file

  1. require 'net/http'
  2. require 'uri'
  3. require 'digest/md5'
  4. require 'rexml/document'
  5. class LastFM
  6. @@api_base = "http://ws.audioscrobbler.com/2.0/"
  7. def initialize(apikey,secret)
  8. @apikey = apikey
  9. @secret = secret #not so secret anymore
  10. @sessionkey = nil
  11. @username = nil
  12. end
  13. def domethod(method,*hash)
  14. args = "method=#{method}"
  15. params=hash[0]
  16. sendparams = {}
  17. params.each { |k,v| sendparams[k.to_s] = v }
  18. sendparams['method'] = method
  19. sendparams['api_key'] = @apikey
  20. url = URI.parse(@@api_base)
  21. req = Net::HTTP::Post.new(url.path)
  22. req.set_form_data(sendparams)
  23. res = Net::HTTP.new(url.host,url.port).start { |http| http.request(req) }
  24. REXML::Document.new res.body
  25. end
  26. def auth(username,password,authstring)
  27. key = authstring.nil? ? auth_key(username,password) : authstring
  28. @sessionkey = nil
  29. params = {:username => username, :authToken => key}
  30. params[:api_sig] = methodSignature("auth.getMobileSession",params)
  31. doc = domethod("auth.getMobileSession",params)
  32. return doc.root.elements["error"].text if !(doc.root.attributes['status'].eql? "ok")
  33. @sessionkey = doc.root.elements["session"].elements["key"].text
  34. @username = username
  35. end
  36. def updateNowPlaying(songInfo)
  37. return false if @sessionkey.nil?
  38. params = {
  39. :track => songInfo[:title],
  40. :artist => songInfo[:artist],
  41. :album => songInfo[:album],
  42. :trackNumber => songInfo[:trackNumber],
  43. :duration => songInfo[:totaltime],
  44. :sk => @sessionkey
  45. }
  46. params[:api_sig] = methodSignature("track.updateNowPlaying",params)
  47. doc = domethod("track.updateNowPlaying",params)
  48. unless doc.root.attributes['status'].eql? "ok"
  49. puts doc.root.elements['error'].text
  50. return false
  51. end
  52. return true
  53. end
  54. def scrobble(songInfo)
  55. return false if @sessionkey.nil?
  56. params = {
  57. :track => songInfo[:title],
  58. :timestamp => (Time.now.to_i - songInfo[:elapsedtime]),
  59. :artist => songInfo[:artist],
  60. :album => songInfo[:album],
  61. :trackNumber => songInfo[:trackNumber],
  62. :duration => songInfo[:totaltime],
  63. :sk => @sessionkey
  64. }
  65. params[:api_sig] = methodSignature("track.scrobble",params)
  66. doc = domethod("track.scrobble",params)
  67. unless doc.root.attributes['status'].eql? "ok"
  68. puts doc.root.elements['error'].text
  69. return false
  70. end
  71. true
  72. end
  73. def methodSignature(method,params)
  74. params = params.dup
  75. params[:method] = method
  76. params[:api_key] = @apikey
  77. params = params.inject({}){ |res,(k,v)| res[k.to_s]=v; res }
  78. api_sig=""
  79. params.sort.each { |a| api_sig += "#{a[0]}#{a[1]}" }
  80. Digest::MD5.hexdigest(api_sig+@secret)
  81. end
  82. def auth_key(username,password)
  83. key = Digest::MD5.hexdigest(username.downcase + Digest::MD5.hexdigest(password))
  84. puts "You may want to put authstring = \"{key}\" in your config/config.rb instead of your password"
  85. key
  86. end
  87. end