lastfm-client 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.DS_Store +0 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +7 -0
  5. data/LICENSE +20 -0
  6. data/README.md +60 -0
  7. data/Rakefile +6 -0
  8. data/lastfm.gemspec +21 -0
  9. data/lib/.DS_Store +0 -0
  10. data/lib/lastfm-client.rb +130 -0
  11. data/lib/lastfm-client/.DS_Store +0 -0
  12. data/lib/lastfm-client/api_class.rb +57 -0
  13. data/lib/lastfm-client/api_classes/album.rb +9 -0
  14. data/lib/lastfm-client/api_classes/artist.rb +12 -0
  15. data/lib/lastfm-client/api_classes/auth.rb +6 -0
  16. data/lib/lastfm-client/api_classes/chart.rb +6 -0
  17. data/lib/lastfm-client/api_classes/event.rb +9 -0
  18. data/lib/lastfm-client/api_classes/geo.rb +7 -0
  19. data/lib/lastfm-client/api_classes/group.rb +6 -0
  20. data/lib/lastfm-client/api_classes/library.rb +9 -0
  21. data/lib/lastfm-client/api_classes/playlist.rb +9 -0
  22. data/lib/lastfm-client/api_classes/radio.rb +10 -0
  23. data/lib/lastfm-client/api_classes/tag.rb +6 -0
  24. data/lib/lastfm-client/api_classes/tasteometer.rb +5 -0
  25. data/lib/lastfm-client/api_classes/track.rb +11 -0
  26. data/lib/lastfm-client/api_classes/user.rb +15 -0
  27. data/lib/lastfm-client/api_classes/venue.rb +5 -0
  28. data/lib/lastfm-client/version.rb +3 -0
  29. data/spec/api_class_spec.rb +33 -0
  30. data/spec/api_classes/album_spec.rb +28 -0
  31. data/spec/api_classes/artist_spec.rb +15 -0
  32. data/spec/api_classes/auth_spec.rb +11 -0
  33. data/spec/api_classes/chart_spec.rb +7 -0
  34. data/spec/api_classes/event_spec.rb +11 -0
  35. data/spec/api_classes/geo_spec.rb +7 -0
  36. data/spec/api_classes/group_spec.rb +10 -0
  37. data/spec/api_classes/library_spec.rb +11 -0
  38. data/spec/api_classes/playlist_spec.rb +11 -0
  39. data/spec/api_classes/radio_spec.rb +11 -0
  40. data/spec/api_classes/tag_spec.rb +7 -0
  41. data/spec/api_classes/tasteometer_spec.rb +7 -0
  42. data/spec/api_classes/track_spec.rb +17 -0
  43. data/spec/api_classes/user_spec.rb +18 -0
  44. data/spec/api_classes/venue_spec.rb +7 -0
  45. data/spec/lastfm-client_spec.rb +101 -0
  46. data/spec/spec_helper.rb +4 -0
  47. metadata +120 -0
Binary file
@@ -0,0 +1,4 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in lastfm.gemspec
4
+ gemspec
5
+
6
+ gem "rake"
7
+ gem "rspec", "~>2.0.0"
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Piotr Chmolowski
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,60 @@
1
+ # Last.fm API Ruby Client
2
+
3
+ LastFM is a Ruby wrapper for [Last.fm API](http://www.last.fm/api).
4
+
5
+ ## Installation
6
+
7
+ Add the following line to your Gemfile and run `bundle install`:
8
+
9
+ ```ruby
10
+ gem 'lastfm-client', :git => 'http://github.com/pch/lastfm-client.git'
11
+ ```
12
+
13
+ You also need to set up your API key and client name, e.g.:
14
+
15
+ ```ruby
16
+ LastFM.api_key = "7234655fd87556209fa94ca6f5e7ad0a8b47f394"
17
+ LastFM.client_name = "My awesome app"
18
+ ```
19
+
20
+ If you're using Rails, you can add the above lines to an initalizer file, e.g. `config/initializers/lastfm.rb`
21
+
22
+ ## Usage examples
23
+
24
+ ```ruby
25
+ LastFM::Album.get_info(:artist => "Red Hot Chili Peppers", :album => "Mother's Milk")
26
+ LastFM::Artist.get_top_fans(:artist => "Gorillaz")
27
+ LastFM::Geo.get_events(:location => "Warsaw")
28
+ LastFM::User.get_top_albums(:user => "some_user")
29
+ ```
30
+
31
+ ### Authentication
32
+
33
+ For some methods Last.fm requires authentication, which is somewhat similar to oAuth:
34
+
35
+ ```ruby
36
+ class SessionsController < ApplicationController
37
+ def new
38
+ redirect_to LastFM.auth_url
39
+ end
40
+
41
+ def create
42
+ token = params[:token]
43
+ redirect_to root_path and return if !token || token == ""
44
+
45
+ api_session = LastFM::Auth.get_session(:token => token, :api_sig => true)
46
+ api_session = api_session["session"]
47
+
48
+ user = User.find_by_username(api_session["name"])
49
+ unless user
50
+ # new user
51
+ user = User.create(:username => api_session["name"])
52
+ end
53
+
54
+ session[:user_id] = user.id
55
+ session[:session_key] = api_session["key"]
56
+
57
+ redirect_to root_path
58
+ end
59
+ end
60
+ ```
@@ -0,0 +1,6 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require "rspec"
5
+ require "rspec/core/rake_task"
6
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "lastfm-client/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "lastfm-client"
7
+ s.version = LastFM::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Piotr Chmolowski"]
10
+ s.email = ["piotr@chmolowski.pl"]
11
+ s.homepage = "http://github.com/pch/lastfm-client"
12
+ s.summary = "Last.fm API client"
13
+ s.description = "Last.fm API client"
14
+
15
+ s.add_dependency "json", ">= 1.4.6"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
Binary file
@@ -0,0 +1,130 @@
1
+ require "open-uri"
2
+ require "uri"
3
+ require "json"
4
+ require "digest/md5"
5
+ require "net/http"
6
+ require "cgi"
7
+
8
+ module LastFM
9
+ class APIException < StandardError; end
10
+ class InvalidData < APIException; end
11
+
12
+ extend self
13
+
14
+ autoload :APIClass, 'lastfm-client/api_class'
15
+ autoload :Album, 'lastfm-client/api_classes/album'
16
+ autoload :Artist, 'lastfm-client/api_classes/artist'
17
+ autoload :Auth, 'lastfm-client/api_classes/auth'
18
+ autoload :Chart, 'lastfm-client/api_classes/chart'
19
+ autoload :Event, 'lastfm-client/api_classes/event'
20
+ autoload :Geo, 'lastfm-client/api_classes/geo'
21
+ autoload :Group, 'lastfm-client/api_classes/group'
22
+ autoload :Library, 'lastfm-client/api_classes/library'
23
+ autoload :Playlist, 'lastfm-client/api_classes/playlist'
24
+ autoload :Radio, 'lastfm-client/api_classes/radio'
25
+ autoload :Tag, 'lastfm-client/api_classes/tag'
26
+ autoload :Tasteometer, 'lastfm-client/api_classes/tasteometer'
27
+ autoload :Track, 'lastfm-client/api_classes/track'
28
+ autoload :User, 'lastfm-client/api_classes/user'
29
+ autoload :Venue, 'lastfm-client/api_classes/venue'
30
+
31
+ DEFAULT_API_URL = 'http://ws.audioscrobbler.com/2.0/'
32
+ DEFAULT_AUTH_URL = 'http://www.last.fm/api/auth/'
33
+
34
+ def api_url
35
+ @api_url || DEFAULT_API_URL
36
+ end
37
+
38
+ def api_url=(url)
39
+ @api_url = url
40
+ end
41
+
42
+ def api_key
43
+ @api_key or raise "API Key is not set"
44
+ end
45
+
46
+ def api_key=(key)
47
+ @api_key = key
48
+ end
49
+
50
+ def secret
51
+ @secret or raise "Secret is not set"
52
+ end
53
+
54
+ def secret=(secret)
55
+ @secret = secret
56
+ end
57
+
58
+ def client_name
59
+ @client_name or raise "Client name is not set"
60
+ end
61
+
62
+ def client_name=(name)
63
+ @client_name = name
64
+ end
65
+
66
+ def auth_url
67
+ (@auth_url || DEFAULT_AUTH_URL) + "?api_key=#{self.api_key}"
68
+ end
69
+
70
+ def auth_url=(url)
71
+ @auth_url = url
72
+ end
73
+
74
+ def send_api_request(method, params, request_method = :get)
75
+ raise "Invalid params" unless params.is_a?(Hash)
76
+
77
+ params[:method] = method
78
+ params[:api_key] = self.api_key
79
+
80
+ if params[:api_sig] == true
81
+ params.delete(:api_sig)
82
+ params[:api_sig] = generate_signature(params)
83
+ end
84
+
85
+ params[:format] = "json"
86
+
87
+ if request_method == :post
88
+ post_data(self.api_url, params)
89
+ else
90
+ fetch_data(self.api_url + "?" + hash_to_params(params))
91
+ end
92
+ end
93
+
94
+ def fetch_data(url)
95
+ open(url, "User-Agent" => client_name) do |page|
96
+ ::JSON.parse(page.read)
97
+ end
98
+ end
99
+
100
+ #
101
+ # FIXME: returns either 403 or bad signature errors
102
+ #
103
+ def post_data(url, params)
104
+ url = URI.parse(url)
105
+ req = Net::HTTP::Post.new(url.path)
106
+ req.set_form_data(params)
107
+
108
+ res = Net::HTTP.new(url.host, url.port).start { |http| http.request(req) }
109
+
110
+ case res
111
+ when Net::HTTPSuccess, Net::HTTPRedirection
112
+ return ::JSON.parse(res.body)
113
+ when Net::HTTPClientError
114
+ raise LastFM::InvalidData, res.body if res.code == "422" # unprocessable entity
115
+ end
116
+
117
+ raise LastFM::APIException, res.error!
118
+ end
119
+
120
+ def generate_signature(params)
121
+ params = params.sort_by { |k,v| k.to_s }
122
+ signature = params.map { |param| "#{param[0].to_s}#{param[1].to_s}" }.join('')
123
+
124
+ Digest::MD5.hexdigest(signature + self.secret)
125
+ end
126
+
127
+ def hash_to_params(hash)
128
+ hash.map { |key, value| "#{key.to_s}=#{::CGI.escape(value.to_s)}" }.join('&')
129
+ end
130
+ end
@@ -0,0 +1,57 @@
1
+ module LastFM
2
+ class APIClass
3
+
4
+ def self.unrestricted_methods(*args)
5
+ args.each do |method|
6
+ define_api_method(method) do |params|
7
+ raise ArgumentError, "Params should be a hash" unless params.is_a?(Hash)
8
+ send_request(method, params)
9
+ end
10
+ end
11
+ end
12
+
13
+ def self.restricted_methods(*args, &block)
14
+ if block_given?
15
+ yield
16
+ else
17
+ read(*args)
18
+ end
19
+ end
20
+
21
+ def self.read(*args)
22
+ args.each do |method|
23
+ define_api_method(method) do |params|
24
+ restricted_method(method, params)
25
+ end
26
+ end
27
+ end
28
+
29
+ def self.write(*args)
30
+ args.each do |method|
31
+ define_api_method(method) do |params|
32
+ restricted_method(method, params, :post)
33
+ end
34
+ end
35
+ end
36
+
37
+ def self.restricted_method(method, params, request_method = :get)
38
+ raise ArgumentError, "Params should be a hash" unless params.is_a?(Hash)
39
+
40
+ params[:api_sig] = true
41
+ send_request(method, params, request_method)
42
+ end
43
+
44
+ def self.send_request(method, params, request_method = :get)
45
+ api_method = self.to_s.split("::").last + "." # LastFM::Album => Album
46
+ api_method += method.to_s.tr('_', '') # get_info => getinfo
47
+
48
+ LastFM.send_api_request(api_method.downcase, params, request_method)
49
+ end
50
+
51
+ def self.define_api_method(method, &block)
52
+ (class << self; self; end).instance_eval do
53
+ define_method(method, &block)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,9 @@
1
+ module LastFM
2
+ class Album < APIClass
3
+ unrestricted_methods :get_buy_links, :get_info, :get_shouts, :get_tags, :get_top_tags, :search
4
+
5
+ restricted_methods do
6
+ write :add_tags, :remove_tag, :share
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ module LastFM
2
+ class Artist < APIClass
3
+ unrestricted_methods :get_correction, :get_events, :get_images, :get_info, :get_past_events,
4
+ :get_podcast, :get_shouts, :get_similar, :get_top_albums, :get_top_fans,
5
+ :get_top_tags, :get_top_tracks, :search
6
+
7
+ restricted_methods do
8
+ read :get_tags
9
+ write :add_tags, :remove_tag, :share, :shout
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,6 @@
1
+ module LastFM
2
+ class Auth < APIClass
3
+ unrestricted_methods :get_token
4
+ restricted_methods :get_mobile_session, :get_session
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module LastFM
2
+ class Chart < APIClass
3
+ unrestricted_methods :get_hyped_artists, :get_hyped_tracks, :get_loved_tracks,
4
+ :get_top_artists, :get_top_tags, :get_top_tracks
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ module LastFM
2
+ class Event < APIClass
3
+ unrestricted_methods :get_attendees, :get_info, :get_shouts
4
+
5
+ restricted_methods do
6
+ write :attend, :share, :shout
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module LastFM
2
+ class Geo < APIClass
3
+ unrestricted_methods :get_events, :get_metro_artist_chart, :get_metro_hype_artist_chart, :get_metro_hype_track_chart,
4
+ :get_metro_track_chart, :get_metro_unique_artist_chart, :get_metro_unique_track_chart,
5
+ :get_metro_weekly_chartlist, :get_metros, :get_top_artists, :get_top_tracks
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ module LastFM
2
+ class Group < APIClass
3
+ unrestricted_methods :get_hype, :get_members, :get_weekly_album_chart, :get_weekly_artist_chart,
4
+ :get_weekly_chart_list, :get_weekly_trackchart
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ module LastFM
2
+ class Library < APIClass
3
+ unrestricted_methods :get_albums, :get_artists, :get_tracks
4
+
5
+ restricted_methods do
6
+ write :add_album, :add_artist, :add_track
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module LastFM
2
+ class Playlist < APIClass
3
+ unrestricted_methods :fetch
4
+
5
+ restricted_methods do
6
+ write :add_track, :create
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module LastFM
2
+ class Radio < APIClass
3
+ unrestricted_methods :search
4
+
5
+ restricted_methods do
6
+ read :get_playlist
7
+ write :tune
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ module LastFM
2
+ class Tag < APIClass
3
+ unrestricted_methods :get_info, :get_similar, :get_top_albums, :get_top_artists, :get_top_tags,
4
+ :get_top_tracks, :get_weekly_artist_chart, :get_weekly_chart_list, :search
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module LastFM
2
+ class Tasteometer < APIClass
3
+ unrestricted_methods :compare
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ module LastFM
2
+ class Track < APIClass
3
+ unrestricted_methods :get_buy_links, :get_correction, :get_fingerprint_metadata, :get_info,
4
+ :get_similar, :get_top_fans, :get_top_tags, :search
5
+
6
+ restricted_methods do
7
+ read :get_tags
8
+ write :add_tags, :ban, :love, :remove_tag, :scrobble, :share, :unban, :unlove, :update_now_playing
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ module LastFM
2
+ class User < APIClass
3
+ unrestricted_methods :get_artist_tracks, :get_banned_tracks, :get_events, :get_friends,
4
+ :get_info, :get_loved_tracks, :get_neighbours, :get_new_releases,
5
+ :get_past_events, :get_playlists, :get_recent_tracks, :get_shouts,
6
+ :get_top_albums, :get_top_artists, :get_top_tags, :get_top_tracks,
7
+ :get_weekly_album_chart, :get_weekly_artist_chart, :get_weekly_chart_list,
8
+ :get_weekly_track_chart
9
+
10
+ restricted_methods do
11
+ read :get_recent_stations, :get_recommended_artists, :get_recommended_events
12
+ write :shout
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ module LastFM
2
+ class Venue < APIClass
3
+ unrestricted_methods :get_events, :get_past_events, :search
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module LastFM
2
+ VERSION = "0.0.3"
3
+ end
@@ -0,0 +1,33 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::APIClass do
4
+ it "should define unrestricted methods" do
5
+ LastFM::APIClass.unrestricted_methods(:foo, :bar, :baz)
6
+ LastFM::APIClass.unrestricted_methods.should be_an(Array)
7
+ end
8
+
9
+ it "should not allow to call an undefined method" do
10
+ lambda { LastFM::APIClass.i_wasnt_defined }.should raise_error(NoMethodError)
11
+ end
12
+
13
+ it "should not allow to call a method with invalid params" do
14
+ lambda { LastFM::APIClass.foo("not a hash") }.should raise_error(ArgumentError, "Params should be a hash")
15
+ end
16
+
17
+ it "should respond to unrestricted methods" do
18
+ LastFM.should_receive(:send_api_request).with("apiclass.foo", {:bar => :baz}, :get).and_return({})
19
+ LastFM::APIClass.foo(:bar => :baz).should be_a(Hash)
20
+ end
21
+
22
+ it "should define restricted methods" do
23
+ LastFM::APIClass.restricted_methods(:foo1, :bar1, :baz1)
24
+ LastFM::APIClass.should respond_to(:foo1)
25
+ LastFM::APIClass.should respond_to(:bar1)
26
+ LastFM::APIClass.should respond_to(:baz1)
27
+ end
28
+
29
+ it "should respond to restricted methods" do
30
+ LastFM.should_receive(:send_api_request).with("apiclass.foo1", {:bar => :baz, :api_sig => true}, :get).and_return({})
31
+ LastFM::APIClass.foo1(:bar => :baz).should be_a(Hash)
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::Album do
4
+ it "should define unrestricted methods" do
5
+ LastFM::Album.should respond_to(:get_buy_links, :get_info, :get_top_tags, :search)
6
+ end
7
+
8
+ it "should respond to unrestricted methods" do
9
+ LastFM.should_receive(:send_api_request).with("album.getinfo", {:bar => :baz}, :get).and_return({})
10
+ LastFM::Album.get_info(:bar => :baz).should be_a(Hash)
11
+ end
12
+
13
+ describe "restricted methods" do
14
+ it "should define restricted methods" do
15
+ LastFM::Album.should respond_to(:get_tags, :add_tags, :remove_tag, :share)
16
+ end
17
+
18
+ it "should respond to restricted read methods" do
19
+ LastFM.should_receive(:send_api_request).with("album.gettags", {:bar => :baz}, :get).and_return({})
20
+ LastFM::Album.get_tags(:bar => :baz).should be_a(Hash)
21
+ end
22
+
23
+ it "should respond to restricted write methods" do
24
+ LastFM.should_receive(:send_api_request).with("album.addtags", {:bar => :baz, :api_sig => true}, :post).and_return({})
25
+ LastFM::Album.add_tags(:bar => :baz).should be_a(Hash)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,15 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::Artist do
4
+ it "should define unrestricted methods" do
5
+ LastFM::Artist.should respond_to(
6
+ :get_correction, :get_events, :get_images, :get_info, :get_past_events,
7
+ :get_podcast, :get_shouts, :get_similar, :get_top_albums, :get_top_fans,
8
+ :get_top_tags, :get_top_tracks, :search
9
+ )
10
+ end
11
+
12
+ it "should define restricted methods" do
13
+ LastFM::Artist.should respond_to(:add_tags, :get_tags, :remove_tag, :share, :shout)
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::Auth do
4
+ it "should define unrestricted methods" do
5
+ LastFM::Auth.should respond_to(:get_token)
6
+ end
7
+
8
+ it "should define restricted methods" do
9
+ LastFM::Auth.should respond_to(:get_mobile_session, :get_session)
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::Chart do
4
+ it "should define unrestricted methods" do
5
+ LastFM::Chart.should respond_to(:get_hyped_artists, :get_hyped_tracks, :get_loved_tracks, :get_top_artists, :get_top_tags, :get_top_tracks)
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::Event do
4
+ it "should define unrestricted methods" do
5
+ LastFM::Event.should respond_to(:get_attendees, :get_info, :get_shouts)
6
+ end
7
+
8
+ it "should define restricted methods" do
9
+ LastFM::Event.should respond_to(:attend, :share, :shout)
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::Geo do
4
+ it "should define unrestricted methods" do
5
+ LastFM::Geo.should respond_to(:get_events, :get_metro_artist_chart, :get_metro_hype_artist_chart, :get_metro_hype_track_chart, :get_metro_track_chart, :get_metro_unique_artist_chart, :get_metro_unique_track_chart, :get_metro_weekly_chartlist, :get_metros, :get_top_artists, :get_top_tracks)
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::Group do
4
+ it "should define unrestricted methods" do
5
+ LastFM::Group.should respond_to(
6
+ :get_hype, :get_members, :get_weekly_album_chart, :get_weekly_artist_chart,
7
+ :get_weekly_chart_list, :get_weekly_trackchart
8
+ )
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::Library do
4
+ it "should define unrestricted methods" do
5
+ LastFM::Library.should respond_to(:get_albums, :get_artists, :get_tracks)
6
+ end
7
+
8
+ it "should define restricted methods" do
9
+ LastFM::Library.should respond_to(:add_album, :add_artist, :add_track)
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::Playlist do
4
+ it "should define unrestricted methods" do
5
+ LastFM::Playlist.should respond_to(:fetch)
6
+ end
7
+
8
+ it "should define restricted methods" do
9
+ LastFM::Playlist.should respond_to(:add_track, :create)
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::Radio do
4
+ it "should define unrestricted methods" do
5
+ LastFM::Radio.should respond_to(:search)
6
+ end
7
+
8
+ it "should define restricted methods" do
9
+ LastFM::Radio.should respond_to(:get_playlist, :tune)
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::Tag do
4
+ it "should define unrestricted methods" do
5
+ LastFM::Tag.should respond_to(:get_similar, :get_top_albums, :get_top_artists, :get_top_tags, :get_top_tracks, :get_weekly_artist_chart, :get_weekly_chart_list, :search)
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::Tasteometer do
4
+ it "should define unrestricted methods" do
5
+ LastFM::Tasteometer.should respond_to(:compare)
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::Track do
4
+ it "should define unrestricted methods" do
5
+ LastFM::Track.should respond_to(
6
+ :get_buy_links, :get_correction, :get_fingerprint_metadata, :get_info,
7
+ :get_similar, :get_top_fans, :get_top_tags, :search
8
+ )
9
+ end
10
+
11
+ it "should define restricted methods" do
12
+ LastFM::Track.should respond_to(
13
+ :get_tags, :add_tags, :ban, :love, :remove_tag, :scrobble, :share, :unban,
14
+ :unlove, :update_now_playing
15
+ )
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::User do
4
+ it "should define unrestricted methods" do
5
+ LastFM::User.should respond_to(
6
+ :get_artist_tracks, :get_banned_tracks, :get_events, :get_friends,
7
+ :get_info, :get_loved_tracks, :get_neighbours, :get_new_releases,
8
+ :get_past_events, :get_playlists, :get_recent_tracks, :get_shouts,
9
+ :get_top_albums, :get_top_artists, :get_top_tags, :get_top_tracks,
10
+ :get_weekly_album_chart, :get_weekly_artist_chart, :get_weekly_chart_list,
11
+ :get_weekly_track_chart
12
+ )
13
+ end
14
+
15
+ it "should define restricted methods" do
16
+ LastFM::User.should respond_to(:get_recent_stations, :get_recommended_artists, :get_recommended_events, :shout)
17
+ end
18
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM::Venue do
4
+ it "should define unrestricted methods" do
5
+ LastFM::Venue.should respond_to(:get_events, :get_past_events, :search)
6
+ end
7
+ end
@@ -0,0 +1,101 @@
1
+ require "spec_helper"
2
+
3
+ describe LastFM do
4
+ it "should have a default API URL" do
5
+ LastFM.api_url.should == LastFM::DEFAULT_API_URL
6
+ end
7
+
8
+ it "should allow to set a custom API URL" do
9
+ custom_url = "http://foobar.com"
10
+
11
+ LastFM.api_url = custom_url
12
+ LastFM.api_url.should == custom_url
13
+ end
14
+
15
+ it "should set API key" do
16
+ LastFM.api_key = "1234"
17
+ LastFM.api_key.should == "1234"
18
+ end
19
+
20
+ it "should raise error when trying to read empty token" do
21
+ LastFM.api_key = nil
22
+ lambda { LastFM.api_key }.should raise_error(RuntimeError, "API Key is not set")
23
+ end
24
+
25
+ it "should set secret" do
26
+ LastFM.secret = "123456"
27
+ LastFM.secret.should == "123456"
28
+ end
29
+
30
+ it "should raise error when trying to read empty secret" do
31
+ LastFM.secret = nil
32
+ lambda { LastFM.secret }.should raise_error(RuntimeError, "Secret is not set")
33
+ end
34
+
35
+ it "should set client name" do
36
+ LastFM.client_name = "Foobar"
37
+ LastFM.client_name.should == "Foobar"
38
+ end
39
+
40
+ it "should raise error when trying to read empty client name" do
41
+ LastFM.client_name = nil
42
+ lambda { LastFM.client_name }.should raise_error(RuntimeError, "Client name is not set")
43
+ end
44
+
45
+ it "should have a default Auth URL" do
46
+ LastFM.api_key = "1234"
47
+ LastFM.auth_url.should == LastFM::DEFAULT_AUTH_URL + "?api_key=1234"
48
+ end
49
+
50
+ it "should allow to set a custom Auth URL" do
51
+ custom_url = "http://foobarbaz.com"
52
+
53
+ LastFM.auth_url = custom_url
54
+ LastFM.auth_url.should == custom_url + "?api_key=1234"
55
+ end
56
+
57
+ describe "API requests" do
58
+ it "should raise error when trying to supply invalid params" do
59
+ lambda { LastFM.send_api_request("test", nil) }.should raise_error(RuntimeError, "Invalid params")
60
+ end
61
+
62
+ it "should generate key signature" do
63
+ LastFM.secret = "test"
64
+ signature = LastFM.generate_signature(:foo => "hey", :bar => "hi", :baz => "hello")
65
+ signature.should == "46bfc3df86f175c869101e1c8c171589"
66
+ end
67
+
68
+ it "should send request" do
69
+ LastFM.api_url = LastFM::DEFAULT_API_URL
70
+ LastFM.api_key = "7fbc71d4b818dc1277e273ac1ef92b07"
71
+ LastFM.client_name = "Last.fm Ruby gem"
72
+
73
+ LastFM.should_receive(:fetch_data).with("http://ws.audioscrobbler.com/2.0/?artist=Cher&album=Believe&method=album.getinfo&api_key=7fbc71d4b818dc1277e273ac1ef92b07&format=json").and_return({})
74
+
75
+ response = LastFM.send_api_request("album.getinfo", :artist => "Cher", :album => "Believe")
76
+ response.should be_a(Hash)
77
+ end
78
+
79
+ it "should send GET request by default" do
80
+ LastFM.should_receive(:fetch_data).with("http://ws.audioscrobbler.com/2.0/?artist=Cher&album=Believe&method=album.getinfo&api_key=7fbc71d4b818dc1277e273ac1ef92b07&format=json").and_return({})
81
+
82
+ response = LastFM.send_api_request("album.getinfo", :artist => "Cher", :album => "Believe")
83
+ response.should be_a(Hash)
84
+ end
85
+
86
+ it "should send request with key signature" do
87
+ LastFM.secret = "test"
88
+ LastFM.should_receive(:fetch_data).with("http://ws.audioscrobbler.com/2.0/?artist=Cher&album=Believe&method=album.getinfo&api_key=7fbc71d4b818dc1277e273ac1ef92b07&api_sig=b796a3385c59872367f31fc510a4ee21&format=json").and_return({})
89
+
90
+ response = LastFM.send_api_request("album.getinfo", :artist => "Cher", :album => "Believe", :api_sig => true)
91
+ response.should be_a(Hash)
92
+ end
93
+
94
+ it "should send POST requests" do
95
+ LastFM.should_receive(:post_data).with("http://ws.audioscrobbler.com/2.0/", {:user => "jeff", :message => "hi Jeff!", :method => "user.shout", :api_key => "7fbc71d4b818dc1277e273ac1ef92b07", :api_sig => "83c66301079de9f515be5e0206ddbb18", :format => "json"}).and_return({})
96
+
97
+ response = LastFM.send_api_request("user.shout", {:user => "jeff", :message => "hi Jeff!", :api_sig => true}, :post)
98
+ response.should be_a(Hash)
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,4 @@
1
+ require "bundler"
2
+ Bundler.setup
3
+
4
+ require "lastfm-client"
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lastfm-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Piotr Chmolowski
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-05 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ requirement: &70293269416280 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.4.6
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70293269416280
25
+ description: Last.fm API client
26
+ email:
27
+ - piotr@chmolowski.pl
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .DS_Store
33
+ - .gitignore
34
+ - .rspec
35
+ - Gemfile
36
+ - LICENSE
37
+ - README.md
38
+ - Rakefile
39
+ - lastfm.gemspec
40
+ - lib/.DS_Store
41
+ - lib/lastfm-client.rb
42
+ - lib/lastfm-client/.DS_Store
43
+ - lib/lastfm-client/api_class.rb
44
+ - lib/lastfm-client/api_classes/album.rb
45
+ - lib/lastfm-client/api_classes/artist.rb
46
+ - lib/lastfm-client/api_classes/auth.rb
47
+ - lib/lastfm-client/api_classes/chart.rb
48
+ - lib/lastfm-client/api_classes/event.rb
49
+ - lib/lastfm-client/api_classes/geo.rb
50
+ - lib/lastfm-client/api_classes/group.rb
51
+ - lib/lastfm-client/api_classes/library.rb
52
+ - lib/lastfm-client/api_classes/playlist.rb
53
+ - lib/lastfm-client/api_classes/radio.rb
54
+ - lib/lastfm-client/api_classes/tag.rb
55
+ - lib/lastfm-client/api_classes/tasteometer.rb
56
+ - lib/lastfm-client/api_classes/track.rb
57
+ - lib/lastfm-client/api_classes/user.rb
58
+ - lib/lastfm-client/api_classes/venue.rb
59
+ - lib/lastfm-client/version.rb
60
+ - spec/api_class_spec.rb
61
+ - spec/api_classes/album_spec.rb
62
+ - spec/api_classes/artist_spec.rb
63
+ - spec/api_classes/auth_spec.rb
64
+ - spec/api_classes/chart_spec.rb
65
+ - spec/api_classes/event_spec.rb
66
+ - spec/api_classes/geo_spec.rb
67
+ - spec/api_classes/group_spec.rb
68
+ - spec/api_classes/library_spec.rb
69
+ - spec/api_classes/playlist_spec.rb
70
+ - spec/api_classes/radio_spec.rb
71
+ - spec/api_classes/tag_spec.rb
72
+ - spec/api_classes/tasteometer_spec.rb
73
+ - spec/api_classes/track_spec.rb
74
+ - spec/api_classes/user_spec.rb
75
+ - spec/api_classes/venue_spec.rb
76
+ - spec/lastfm-client_spec.rb
77
+ - spec/spec_helper.rb
78
+ homepage: http://github.com/pch/lastfm-client
79
+ licenses: []
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 1.8.11
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: Last.fm API client
102
+ test_files:
103
+ - spec/api_class_spec.rb
104
+ - spec/api_classes/album_spec.rb
105
+ - spec/api_classes/artist_spec.rb
106
+ - spec/api_classes/auth_spec.rb
107
+ - spec/api_classes/chart_spec.rb
108
+ - spec/api_classes/event_spec.rb
109
+ - spec/api_classes/geo_spec.rb
110
+ - spec/api_classes/group_spec.rb
111
+ - spec/api_classes/library_spec.rb
112
+ - spec/api_classes/playlist_spec.rb
113
+ - spec/api_classes/radio_spec.rb
114
+ - spec/api_classes/tag_spec.rb
115
+ - spec/api_classes/tasteometer_spec.rb
116
+ - spec/api_classes/track_spec.rb
117
+ - spec/api_classes/user_spec.rb
118
+ - spec/api_classes/venue_spec.rb
119
+ - spec/lastfm-client_spec.rb
120
+ - spec/spec_helper.rb