scrobbler2 0.0.4
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.
- data/.gitignore +1 -0
- data/README.rdoc +155 -0
- data/Rakefile +8 -0
- data/TODO +23 -0
- data/VERSION.yml +4 -0
- data/generators/acceptance_test/USAGE +9 -0
- data/generators/acceptance_test/acceptance_test_generator.rb +57 -0
- data/generators/acceptance_test/templates/acceptance_test.rb.erb +14 -0
- data/generators/resource/USAGE +8 -0
- data/generators/resource/resource_generator.rb +47 -0
- data/generators/resource/templates/resource.rb.erb +11 -0
- data/generators/resource/templates/spec.rb.erb +22 -0
- data/lib/scrobbler2.rb +23 -0
- data/lib/scrobbler2/album.rb +11 -0
- data/lib/scrobbler2/artist.rb +26 -0
- data/lib/scrobbler2/auth.rb +19 -0
- data/lib/scrobbler2/base.rb +100 -0
- data/lib/scrobbler2/event.rb +12 -0
- data/lib/scrobbler2/geo.rb +15 -0
- data/lib/scrobbler2/group.rb +14 -0
- data/lib/scrobbler2/library.rb +12 -0
- data/lib/scrobbler2/playlist.rb +10 -0
- data/lib/scrobbler2/tag.rb +18 -0
- data/lib/scrobbler2/track.rb +13 -0
- data/lib/scrobbler2/user.rb +29 -0
- data/lib/scrobbler2/venue.rb +12 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/scrobbler2.gemspec +243 -0
- data/tasks/jeweler.rake +15 -0
- data/tasks/rcov.rake +9 -0
- data/tasks/rdoc.rake +7 -0
- data/tasks/tests.rake +10 -0
- data/test/acceptance/album/info_test.rb +56 -0
- data/test/acceptance/artist/add_tags_test.rb +14 -0
- data/test/acceptance/artist/events_test.rb +47 -0
- data/test/acceptance/artist/info_test.rb +53 -0
- data/test/acceptance/artist/shouts_test.rb +48 -0
- data/test/acceptance/artist/similar_artists_test.rb +20 -0
- data/test/acceptance/artist/tags_test.rb +24 -0
- data/test/acceptance/artist/top_albums_test.rb +34 -0
- data/test/acceptance/artist/top_fans.rb +19 -0
- data/test/acceptance/artist/top_tags.rb +18 -0
- data/test/acceptance/artist/top_tracks.rb +47 -0
- data/test/acceptance/auth/auth_test.rb +21 -0
- data/test/acceptance/event/info_test.rb +66 -0
- data/test/acceptance/event/shouts_test.rb +49 -0
- data/test/acceptance/geo/events_test.rb +14 -0
- data/test/acceptance/geo/top_artists_test.rb +16 -0
- data/test/acceptance/geo/top_tracks_test.rb +16 -0
- data/test/acceptance/group/members_test.rb +60 -0
- data/test/acceptance/group/weekly_album_chart_test.rb +61 -0
- data/test/acceptance/group/weekly_artist_chart_test.rb +54 -0
- data/test/acceptance/group/weekly_chart_list_test.rb +39 -0
- data/test/acceptance/group/weekly_track_chart_test.rb +61 -0
- data/test/acceptance/library/albums_test.rb +34 -0
- data/test/acceptance/library/artists_test.rb +33 -0
- data/test/acceptance/library/tracks_test.rb +33 -0
- data/test/acceptance/playlist/fetch_test.rb +68 -0
- data/test/acceptance/shared/album.rb +41 -0
- data/test/acceptance/shared/artist.rb +16 -0
- data/test/acceptance/shared/paged_result.rb +16 -0
- data/test/acceptance/shared/top_fans.rb +29 -0
- data/test/acceptance/shared/top_tags.rb +23 -0
- data/test/acceptance/shared/track.rb +23 -0
- data/test/acceptance/tag/similar_test.rb +15 -0
- data/test/acceptance/tag/top_albums_test.rb +37 -0
- data/test/acceptance/tag/top_artists_test.rb +31 -0
- data/test/acceptance/tag/top_tags_test.rb +32 -0
- data/test/acceptance/tag/top_tracks_test.rb +33 -0
- data/test/acceptance/tag/weekly_artist_chart.rb +54 -0
- data/test/acceptance/tag/weekly_chart_list.rb +39 -0
- data/test/acceptance/test_helper.rb +15 -0
- data/test/acceptance/track/info_test.rb +47 -0
- data/test/acceptance/track/similar_test.rb +22 -0
- data/test/acceptance/track/top_fans_test.rb +23 -0
- data/test/acceptance/track/top_tags_test.rb +24 -0
- data/test/acceptance/user/events_test.rb +27 -0
- data/test/acceptance/user/friends_test.rb +14 -0
- data/test/acceptance/user/info_test.rb +19 -0
- data/test/acceptance/user/loved_tracks_test.rb +14 -0
- data/test/acceptance/user/neighbours_test.rb +14 -0
- data/test/acceptance/user/past_events_test.rb +14 -0
- data/test/acceptance/user/playlists_test.rb +14 -0
- data/test/acceptance/user/recent_tracks_test.rb +14 -0
- data/test/acceptance/user/recommended_artists_test.rb +16 -0
- data/test/acceptance/user/recommended_events_test.rb +16 -0
- data/test/acceptance/user/shouts_test.rb +14 -0
- data/test/acceptance/user/top_albums_test.rb +14 -0
- data/test/acceptance/user/top_artists_test.rb +14 -0
- data/test/acceptance/user/top_tags_test.rb +14 -0
- data/test/acceptance/user/top_tracks_test.rb +14 -0
- data/test/acceptance/user/weekly_album_chart_test.rb +14 -0
- data/test/acceptance/user/weekly_artist_chart_test.rb +14 -0
- data/test/acceptance/user/weekly_chart_list_test.rb +14 -0
- data/test/acceptance/user/weekly_track_chart_test.rb +14 -0
- data/test/acceptance/venue/events_test.rb +14 -0
- data/test/acceptance/venue/past_events_test.rb +14 -0
- data/test/generators/test_acceptance_test_generator.rb +46 -0
- data/test/generators/test_generator_helper.rb +29 -0
- data/test/generators/test_resource_generator.rb +71 -0
- data/test/unit/album_spec.rb +17 -0
- data/test/unit/artist_spec.rb +62 -0
- data/test/unit/auth_spec.rb +22 -0
- data/test/unit/base_spec.rb +193 -0
- data/test/unit/event_spec.rb +23 -0
- data/test/unit/geo_spec.rb +36 -0
- data/test/unit/group_spec.rb +38 -0
- data/test/unit/library_spec.rb +27 -0
- data/test/unit/playlist_spec.rb +18 -0
- data/test/unit/spec_helper.rb +7 -0
- data/test/unit/tag_spec.rb +50 -0
- data/test/unit/track_spec.rb +33 -0
- data/test/unit/user_spec.rb +148 -0
- data/test/unit/venue_spec.rb +29 -0
- metadata +272 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg
|
data/README.rdoc
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
= Scrobbler2
|
2
|
+
|
3
|
+
Scrobbler2 is a wrapper for the Last.fm web services (http://www.last.fm/api), inspired by Jnunemaker's Original Scrobbler Gem (http://github.com/jnunemaker/scrobbler).
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
Install via ruby-gems
|
8
|
+
sudo gem install gingerhendrix-scrobbler2 --source http://gems.github.com
|
9
|
+
|
10
|
+
== Requirements
|
11
|
+
|
12
|
+
Scrobbler2 requires
|
13
|
+
* HTTParty (http://github.com/jnunemaker/httparty)
|
14
|
+
* ActiveSupport (http://rubyforge.org/projects/activesupport/).
|
15
|
+
|
16
|
+
= Usage
|
17
|
+
|
18
|
+
== API Key
|
19
|
+
|
20
|
+
All last.fm requests require an API Key. Register for an API key at http://www.last.fm/api
|
21
|
+
|
22
|
+
Scrobbler2::Base.api_key = "abcdefghijklmnopqrstuvwxyz123456"
|
23
|
+
|
24
|
+
== Authentication
|
25
|
+
|
26
|
+
Some requests (eg. write requests) require authentication. Authenticated request require an api secret (provided with your api key) and a session key.
|
27
|
+
|
28
|
+
Scrobbler2::Base.api_secret = "9876543210zyxwvutsrqponmlkjihgfe"
|
29
|
+
Scrobbler2::Base.session_key = "qwertyuioplkjhgfdsamnbvcxz"
|
30
|
+
|
31
|
+
=== Obtaining a session key
|
32
|
+
|
33
|
+
scrobbler2 currently supports last.fm's desktop authentication protocol. In this process
|
34
|
+
1. The app requests a authentication token
|
35
|
+
2. The app sends the user to a last.fm authentication page
|
36
|
+
3. The user agrees to allow the the app acess to their data.
|
37
|
+
4. The app requests a session key.
|
38
|
+
5. The app makes an authenticated request with the session key.
|
39
|
+
|
40
|
+
auth = Scrobbler2::Auth.new
|
41
|
+
token = auth.token
|
42
|
+
puts "Auth Token #{token} \n"
|
43
|
+
token.should_not be_nil
|
44
|
+
puts "Now go to #{auth.url} and authorise\n"
|
45
|
+
|
46
|
+
gets #Wait for enter
|
47
|
+
|
48
|
+
session = auth.session
|
49
|
+
puts "Session: #{session.inspect} \n"
|
50
|
+
session.should be_kind_of(Hash)
|
51
|
+
session['key'].should_not be_nil
|
52
|
+
|
53
|
+
Scrobbler2::Base.session_key = session['key']
|
54
|
+
user = Scrobbler2::User.new(username)
|
55
|
+
user.info
|
56
|
+
|
57
|
+
== Users
|
58
|
+
|
59
|
+
username = 'gingerhendrix'
|
60
|
+
user = Scrobbler2::User.new(username)
|
61
|
+
|
62
|
+
puts "#{username}'s Recent Tracks"
|
63
|
+
puts "=" * (username.length + 16)
|
64
|
+
user.recent_tracks["track"].each { |t| puts t["name"] }
|
65
|
+
|
66
|
+
puts
|
67
|
+
puts
|
68
|
+
|
69
|
+
puts "#{username}'s Top Tracks"
|
70
|
+
puts "=" * (username.length + 13)
|
71
|
+
user.top_tracks["track"].each { |t| puts "(#{t["playcount"]} plays) #{t["name"]}" }
|
72
|
+
|
73
|
+
== Albums
|
74
|
+
|
75
|
+
album = Scrobbler2::Album.new('Carrie Underwood', 'Some Hearts')
|
76
|
+
|
77
|
+
puts "Album: #{album.info["name"]}"
|
78
|
+
puts "Artist: #{album.info["artist"]}"
|
79
|
+
puts "Listeners: #{album.info["listeners"]}"
|
80
|
+
puts "URL: #{album.info["url"]}"
|
81
|
+
puts "Release Date: #{album.info["releasedate"]}"
|
82
|
+
|
83
|
+
puts
|
84
|
+
puts
|
85
|
+
|
86
|
+
puts "Album Tags"
|
87
|
+
longest_tag_name = album.info["toptags"]["tag"].collect {|t| t["name"] }.sort {|x, y| y.length <=> x.length }.first.length
|
88
|
+
puts "=" * longest_tag_name
|
89
|
+
album.info["toptags"]["tag"].each { |t| puts t["name"] }
|
90
|
+
|
91
|
+
== Artists
|
92
|
+
|
93
|
+
artist = Scrobbler2::Artist.new('Carrie Underwood')
|
94
|
+
|
95
|
+
puts 'Top Tracks'
|
96
|
+
puts "=" * 10
|
97
|
+
artist.top_tracks["track"].each { |t| puts "(#{t["playcount"]} plays) #{t["name"]}" }
|
98
|
+
|
99
|
+
puts
|
100
|
+
|
101
|
+
puts 'Similar Artists'
|
102
|
+
puts "=" * 15
|
103
|
+
artist.info["similar"]["artist"].each { |a| puts "#{a["name"]}" }
|
104
|
+
|
105
|
+
== Tags
|
106
|
+
|
107
|
+
tag = Scrobbler2::Tag.new('country')
|
108
|
+
|
109
|
+
puts 'Top Albums'
|
110
|
+
tag.top_albums["album"].each { |a| puts "(#{a["tagcount"]} tags) '#{a["name"]}' by #{a["artist"]["name"]}" }
|
111
|
+
|
112
|
+
puts
|
113
|
+
|
114
|
+
puts 'Top Tracks'
|
115
|
+
tag.top_tracks.each { |t| puts "(#{t["tagcount"]} tags) '#{t["name"]}' by #{t["artist"]["name"]}" }
|
116
|
+
|
117
|
+
== Tracks
|
118
|
+
|
119
|
+
track = Scrobbler2::Track.new('Carrie Underwood', 'Before He Cheats')
|
120
|
+
puts 'Fans'
|
121
|
+
puts "=" * 4
|
122
|
+
puts track.info["listeners"]
|
123
|
+
|
124
|
+
= Development
|
125
|
+
|
126
|
+
Scrobbler2 is still in development. If you want to help out please feel free to fork the project on github (http://github.com/gingerhendrix/scrobbler2).
|
127
|
+
|
128
|
+
== Build and install
|
129
|
+
The scrobbler2 gem can be built and installed via rake.
|
130
|
+
|
131
|
+
rake build # builds the gem (in pkg/)
|
132
|
+
rake install # builds and installs the gem (using sudo gem install)
|
133
|
+
|
134
|
+
== Tests
|
135
|
+
|
136
|
+
Scrobbler2 has unit and acceptance tests written using RSpec. The tests can be run using rake.
|
137
|
+
|
138
|
+
rake test:unit # runs the unit tests
|
139
|
+
rake test:acceptance # runs the acceptance tests
|
140
|
+
|
141
|
+
The acceptance tests run against the live last.fm api. You will need to set the api_key and authentication parameters in test/acceptance/test_helper.rb before
|
142
|
+
running these tests. You can obtain a session key by running the auth_test, this test is not invoked with the rest of the acceptance suite.
|
143
|
+
|
144
|
+
ruby test/acceptance/auth/auth_test.rb
|
145
|
+
|
146
|
+
== Internals
|
147
|
+
|
148
|
+
Scrobbler2 api methods use a simple set of macros to implement the api. All the hard work goes on in Scrobbler2::Base.
|
149
|
+
|
150
|
+
== TODO
|
151
|
+
|
152
|
+
* Write requests.
|
153
|
+
* Submissions
|
154
|
+
* Radio API
|
155
|
+
|
data/Rakefile
ADDED
data/TODO
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
0.0.5 Release
|
2
|
+
Add README
|
3
|
+
Merge from VxJasonxV
|
4
|
+
Copy examples to /examples
|
5
|
+
Add a development section with info about rake tasks etc.
|
6
|
+
Look at api_key and secret_key
|
7
|
+
Simple website
|
8
|
+
Release
|
9
|
+
0.0.6 Release
|
10
|
+
Fix auth (so user.getInfo works at least)
|
11
|
+
0.1.0 Release
|
12
|
+
Finish API
|
13
|
+
Post and Auth Requests
|
14
|
+
user.{getInfo|getRemommendedArtists|getRecommendedEvents}
|
15
|
+
{artist|album|track}.{get|add|remove}Tag
|
16
|
+
{artist|track|event}.share
|
17
|
+
track.{love|ban}
|
18
|
+
library.add{Artist|Album|Track}
|
19
|
+
playlist.{create|addTrack}
|
20
|
+
event.attend
|
21
|
+
Search Requests
|
22
|
+
{album|artist|tag|track|venue}.search
|
23
|
+
Release
|
data/VERSION.yml
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
class AcceptanceTestGenerator < RubiGen::Base
|
2
|
+
|
3
|
+
# default_options :author => nil
|
4
|
+
|
5
|
+
attr_reader :resource
|
6
|
+
attr_reader :func
|
7
|
+
|
8
|
+
def initialize(runtime_args, runtime_options = {})
|
9
|
+
super
|
10
|
+
usage if args.empty? || args.length < 2
|
11
|
+
@resource = args.shift
|
12
|
+
@func = args.shift
|
13
|
+
extract_options
|
14
|
+
end
|
15
|
+
|
16
|
+
def manifest
|
17
|
+
record do |m|
|
18
|
+
# Ensure appropriate folder(s) exists
|
19
|
+
m.directory "test/acceptance/#{@resource}"
|
20
|
+
|
21
|
+
# Create stubs
|
22
|
+
m.template "acceptance_test.rb.erb", "test/acceptance/#{@resource}/#{@func}_test.rb"
|
23
|
+
# m.template_copy_each ["template.rb", "template2.rb"]
|
24
|
+
# m.template_copy_each ["template.rb", "template2.rb"], "some/path"
|
25
|
+
# m.file "file", "some_file_copied"
|
26
|
+
# m.file_copy_each ["path/to/file", "path/to/file2"]
|
27
|
+
# m.file_copy_each ["path/to/file", "path/to/file2"], "some/path"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
def banner
|
33
|
+
<<-EOS
|
34
|
+
Creates a scrobbler2 acceptance test
|
35
|
+
|
36
|
+
USAGE: #{$0} #{spec.name} resource func
|
37
|
+
EOS
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_options!(opts)
|
41
|
+
# opts.separator ''
|
42
|
+
# opts.separator 'Options:'
|
43
|
+
# For each option below, place the default
|
44
|
+
# at the top of the file next to "default_options"
|
45
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
46
|
+
# "Some comment about this option",
|
47
|
+
# "Default: none") { |options[:author]| }
|
48
|
+
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
49
|
+
end
|
50
|
+
|
51
|
+
def extract_options
|
52
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
53
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
54
|
+
# raw instance variable value.
|
55
|
+
# @author = options[:author]
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper.rb'
|
2
|
+
|
3
|
+
describe "<%=func%> for <%=resource%> ..." do
|
4
|
+
|
5
|
+
before(:all) do #We only want to hit the webservice once.
|
6
|
+
@<%=resource%> = Scrobbler2::<%=resource.classify%>.new "..."
|
7
|
+
@<%=func%> = @<%=resource%>.<%=func%>
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should be hash" do
|
11
|
+
@<%=func%>.should be_kind_of Hash
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class ResourceGenerator < RubiGen::Base
|
2
|
+
|
3
|
+
default_options :author => nil
|
4
|
+
|
5
|
+
attr_reader :name
|
6
|
+
attr_reader :funcs
|
7
|
+
|
8
|
+
def initialize(runtime_args, runtime_options = {})
|
9
|
+
super
|
10
|
+
usage if args.empty?
|
11
|
+
@name = args.shift
|
12
|
+
@funcs = args
|
13
|
+
extract_options
|
14
|
+
end
|
15
|
+
|
16
|
+
def manifest
|
17
|
+
record do |m|
|
18
|
+
# Ensure appropriate folder(s) exists
|
19
|
+
m.directory 'lib/scrobbler2'
|
20
|
+
m.directory 'test/unit'
|
21
|
+
|
22
|
+
# Create stubs
|
23
|
+
m.template "resource.rb.erb", "lib/scrobbler2/#{name}.rb"
|
24
|
+
m.template "spec.rb.erb", "test/unit/#{name}_spec.rb"
|
25
|
+
|
26
|
+
# Create acceptance tests
|
27
|
+
funcs.each do |func|
|
28
|
+
m.dependency "acceptance_test", [name, func]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
def banner
|
35
|
+
<<-EOS
|
36
|
+
Creates a scrobbler2 resource
|
37
|
+
|
38
|
+
USAGE: #{$0} #{spec.name} name funcs
|
39
|
+
EOS
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_options!(opts)
|
43
|
+
end
|
44
|
+
|
45
|
+
def extract_options
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Scrobbler2
|
2
|
+
class <%= name.classify %> < Base
|
3
|
+
|
4
|
+
def initialize()
|
5
|
+
@query = {}#TODO eg. {:artist => artist, :track => track}
|
6
|
+
end
|
7
|
+
<% funcs.each do |func| %>
|
8
|
+
has_resource :<%=func%>, :root => "<%=func.camelize.downcase%>"
|
9
|
+
<% end %>
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper.rb"
|
2
|
+
|
3
|
+
describe "<%=name.classify%>" do
|
4
|
+
before(:each) do
|
5
|
+
@<%=name%> = Scrobbler2::<%=name.classify%>.new "..."
|
6
|
+
@<%=name%>.class.stub!(:get).and_return Hash.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have a default query {TODO}" do
|
10
|
+
@<%=name%>.instance_variable_get(:@query).should == {}
|
11
|
+
end
|
12
|
+
|
13
|
+
<% funcs.each do |func| %>
|
14
|
+
|
15
|
+
it "<%=func%> should call get with '<%=name%>.get<%=func%>'" do
|
16
|
+
@<%=name%>.class.should_receive(:get).with('<%=name%>.get<%=func%>', anything(), anything()).and_return Hash.new
|
17
|
+
@<%=name%>.<%=func%>
|
18
|
+
end
|
19
|
+
|
20
|
+
<% end %>
|
21
|
+
|
22
|
+
end
|
data/lib/scrobbler2.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'activesupport'
|
3
|
+
require 'httparty'
|
4
|
+
$: << File.dirname(__FILE__)
|
5
|
+
|
6
|
+
module Scrobbler2
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'scrobbler2/base.rb'
|
11
|
+
require 'scrobbler2/auth.rb'
|
12
|
+
require 'scrobbler2/album.rb'
|
13
|
+
require 'scrobbler2/artist.rb'
|
14
|
+
require 'scrobbler2/event.rb'
|
15
|
+
require 'scrobbler2/geo.rb'
|
16
|
+
require 'scrobbler2/group.rb'
|
17
|
+
require 'scrobbler2/library.rb'
|
18
|
+
require 'scrobbler2/playlist.rb'
|
19
|
+
require 'scrobbler2/tag.rb'
|
20
|
+
require 'scrobbler2/track.rb'
|
21
|
+
require 'scrobbler2/user.rb'
|
22
|
+
require 'scrobbler2/venue.rb'
|
23
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
module Scrobbler2
|
3
|
+
class Artist < Base
|
4
|
+
|
5
|
+
def initialize(artist)
|
6
|
+
@query = {:artist => artist}
|
7
|
+
end
|
8
|
+
|
9
|
+
has_resource :events, :root => 'events'
|
10
|
+
has_resource :info, :root => 'artist'
|
11
|
+
has_resource :shouts, :root => 'shouts'
|
12
|
+
has_resource :similar, :root => 'similarartists'
|
13
|
+
has_resource :top_albums, :root => 'topalbums'
|
14
|
+
has_resource :top_fans, :root => 'topfans'
|
15
|
+
has_resource :top_tags, :root => 'toptags'
|
16
|
+
has_resource :top_tracks, :root => 'toptracks'
|
17
|
+
|
18
|
+
has_resource :tags, :root=> "tags", :auth => true
|
19
|
+
|
20
|
+
def add_tags(tags)
|
21
|
+
query = @query.merge :tags => tags.join(",")
|
22
|
+
self.class.post_with_auth("artist.addtags", query)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|