lastfm-client 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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