rockstar-custom 0.6.1

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 (97) hide show
  1. data/.travis.yml +6 -0
  2. data/Gemfile +11 -0
  3. data/Gemfile.lock +22 -0
  4. data/History.txt +6 -0
  5. data/MIT-LICENSE +19 -0
  6. data/Manifest +72 -0
  7. data/README.md +135 -0
  8. data/Rakefile +34 -0
  9. data/VERSION +1 -0
  10. data/examples/.gitignore +1 -0
  11. data/examples/album.rb +16 -0
  12. data/examples/artist.rb +23 -0
  13. data/examples/geo.rb +9 -0
  14. data/examples/lastfm.yml_example +3 -0
  15. data/examples/scrobble.rb +45 -0
  16. data/examples/tag.rb +20 -0
  17. data/examples/track.rb +14 -0
  18. data/examples/user.rb +18 -0
  19. data/lib/rockstar.rb +50 -0
  20. data/lib/rockstar/album.rb +109 -0
  21. data/lib/rockstar/artist.rb +182 -0
  22. data/lib/rockstar/auth.rb +21 -0
  23. data/lib/rockstar/base.rb +48 -0
  24. data/lib/rockstar/chart.rb +31 -0
  25. data/lib/rockstar/event.rb +73 -0
  26. data/lib/rockstar/geo.rb +22 -0
  27. data/lib/rockstar/metro.rb +26 -0
  28. data/lib/rockstar/playing.rb +50 -0
  29. data/lib/rockstar/rest.rb +66 -0
  30. data/lib/rockstar/scrobble.rb +68 -0
  31. data/lib/rockstar/session.rb +19 -0
  32. data/lib/rockstar/simpleauth.rb +62 -0
  33. data/lib/rockstar/tag.rb +100 -0
  34. data/lib/rockstar/tokenauth.rb +84 -0
  35. data/lib/rockstar/track.rb +260 -0
  36. data/lib/rockstar/user.rb +200 -0
  37. data/lib/rockstar/venue.rb +59 -0
  38. data/lib/rockstar/version.rb +3 -0
  39. data/rockstar.gemspec +174 -0
  40. data/test/fixtures/xml/album/getinfo_album_Radio_Retalation_artist_Thievery_Corporation.xml +21 -0
  41. data/test/fixtures/xml/album/getinfo_album_Some_Hearts_artist_Carrie_Underwood.xml +63 -0
  42. data/test/fixtures/xml/artist/getevents_artist_Metallica.xml +1064 -0
  43. data/test/fixtures/xml/artist/getimages_artist_Metallica_page_2.xml +1074 -0
  44. data/test/fixtures/xml/artist/getinfo_artist_Metallica.xml +115 -0
  45. data/test/fixtures/xml/artist/getsimilar_artist_Metallica.xml +1203 -0
  46. data/test/fixtures/xml/artist/gettopalbums_artist_Metallica.xml +704 -0
  47. data/test/fixtures/xml/artist/gettopfans_artist_Metallica.xml +504 -0
  48. data/test/fixtures/xml/artist/gettoptags_artist_Metallica.xml +403 -0
  49. data/test/fixtures/xml/artist/gettoptracks_artist_Metallica.xml +800 -0
  50. data/test/fixtures/xml/geo/getevents_location_london.xml +531 -0
  51. data/test/fixtures/xml/geo/getmetros_country_germany.xml +44 -0
  52. data/test/fixtures/xml/tag/gettopalbums_tag_rock.xml +654 -0
  53. data/test/fixtures/xml/tag/gettopartists_tag_rock.xml +504 -0
  54. data/test/fixtures/xml/tag/gettoptags.xml +1253 -0
  55. data/test/fixtures/xml/tag/gettoptracks_tag_rock.xml +704 -0
  56. data/test/fixtures/xml/track/getinfo_artist_Carrie_Underwood_track_Before_He_Cheats.xml +55 -0
  57. data/test/fixtures/xml/track/gettopfans_artist_Carrie_Underwood_track_Before_He_Cheats.xml +504 -0
  58. data/test/fixtures/xml/track/gettoptags_artist_Carrie_Underwood_track_Before_He_Cheats.xml +403 -0
  59. data/test/fixtures/xml/track/love_artist_Carrie_Underwood_sk_tag_track_Before_He_Cheats.xml +2 -0
  60. data/test/fixtures/xml/track/updatenowplaying_artist_Carrie_Underwood_sk_tag_track_Before_He_Cheats.xml +10 -0
  61. data/test/fixtures/xml/user/getevents_sk_token_user_bodot.xml +513 -0
  62. data/test/fixtures/xml/user/getfriends_user_jnunemaker.xml +173 -0
  63. data/test/fixtures/xml/user/getinfo_user_jnunemaker.xml +22 -0
  64. data/test/fixtures/xml/user/getinfo_user_oaknd1.xml +22 -0
  65. data/test/fixtures/xml/user/getinfo_user_wharle.xml +22 -0
  66. data/test/fixtures/xml/user/getlovedtracks_user_jnunemaker.xml +775 -0
  67. data/test/fixtures/xml/user/getneighbours_user_jnunemaker.xml +503 -0
  68. data/test/fixtures/xml/user/getrecenttracks_user_jnunemaker.xml +133 -0
  69. data/test/fixtures/xml/user/getrecommendedartists_sk_token_user_jnunemaker.xml +553 -0
  70. data/test/fixtures/xml/user/gettopalbums_user_jnunemaker.xml +704 -0
  71. data/test/fixtures/xml/user/gettopartists_period_overall_user_jnunemaker.xml +554 -0
  72. data/test/fixtures/xml/user/gettoptags_user_jnunemaker.xml +63 -0
  73. data/test/fixtures/xml/user/gettoptracks_user_jnunemaker.xml +750 -0
  74. data/test/fixtures/xml/user/getweeklyalbumchart_from_1138536002_to_1139140802_user_jnunemaker.xml +143 -0
  75. data/test/fixtures/xml/user/getweeklyalbumchart_from__to__user_jnunemaker.xml +31 -0
  76. data/test/fixtures/xml/user/getweeklyartistchart_from_1138536002_to_1139140802_user_jnunemaker.xml +201 -0
  77. data/test/fixtures/xml/user/getweeklyartistchart_from__to__user_jnunemaker.xml +21 -0
  78. data/test/fixtures/xml/user/getweeklychartlist_user_jnunemaker.xml +232 -0
  79. data/test/fixtures/xml/user/getweeklytrackchart_from_1138536002_to_1139140802_user_jnunemaker.xml +883 -0
  80. data/test/fixtures/xml/user/getweeklytrackchart_from__to__user_jnunemaker.xml +423 -0
  81. data/test/fixtures/xml/venue/getevents_venue_8807850.xml +280 -0
  82. data/test/fixtures/xml/venue/search_country__limit__page__venue_country_DE_venue_cotton.xml +72 -0
  83. data/test/mocks/rest.rb +67 -0
  84. data/test/test_helper.rb +18 -0
  85. data/test/unit/test_album.rb +76 -0
  86. data/test/unit/test_artist.rb +102 -0
  87. data/test/unit/test_chart.rb +35 -0
  88. data/test/unit/test_geo.rb +25 -0
  89. data/test/unit/test_playing.rb +53 -0
  90. data/test/unit/test_scrobble.rb +69 -0
  91. data/test/unit/test_simpleauth.rb +45 -0
  92. data/test/unit/test_tag.rb +57 -0
  93. data/test/unit/test_tokenauth.rb +45 -0
  94. data/test/unit/test_track.rb +82 -0
  95. data/test/unit/test_user.rb +299 -0
  96. data/test/unit/test_venue.rb +20 -0
  97. metadata +269 -0
data/examples/track.rb ADDED
@@ -0,0 +1,14 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'rockstar'))
2
+ require 'pp'
3
+
4
+ # Please enter your API-Keys into lastfm.yml first.
5
+ # You can find them here : http://www.lastfm.de/api/account
6
+ Rockstar.lastfm = YAML.load_file(File.join(File.dirname(__FILE__), 'lastfm.yml'))
7
+
8
+ track = Rockstar::Track.new('Carrie Underwood', 'Before He Cheats')
9
+ puts 'Fans'
10
+ puts "=" * 4
11
+ track.fans.each { |u| puts "(#{u.weight}) #{u.username}" }
12
+
13
+ track = Rockstar::Track.new('U2 & Green Day', 'The Saints Are Coming')
14
+ pp track.tags
data/examples/user.rb ADDED
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'rockstar'))
2
+
3
+ # Please enter your API-Keys into lastfm.yml first.
4
+ # You can find them here : http://www.lastfm.de/api/account
5
+ Rockstar.lastfm = YAML.load_file(File.join(File.dirname(__FILE__), 'lastfm.yml'))
6
+
7
+ user = Rockstar::User.new('jnunemaker')
8
+
9
+ puts "#{user.username}'s Recent Tracks"
10
+ puts "=" * (user.username.length + 16)
11
+ user.recent_tracks.each { |t| puts t.name }
12
+
13
+ puts
14
+ puts
15
+
16
+ puts "#{user.username}'s Top Tracks"
17
+ puts "=" * (user.username.length + 13)
18
+ user.top_tracks.each { |t| puts "(#{t.playcount}) #{t.name}" }
data/lib/rockstar.rb ADDED
@@ -0,0 +1,50 @@
1
+ $: << File.expand_path(File.dirname(__FILE__))
2
+
3
+ require 'rubygems'
4
+ require 'cgi'
5
+ require 'hpricot'
6
+ require 'active_support'
7
+ require 'active_support/core_ext/object/blank'
8
+ require 'active_support/core_ext/string/inflections'
9
+ require 'time'
10
+ require 'yaml'
11
+
12
+ require 'rockstar/base'
13
+ require 'rockstar/version'
14
+
15
+ require 'rockstar/album'
16
+ require 'rockstar/artist'
17
+ require 'rockstar/chart'
18
+ require 'rockstar/event'
19
+ require 'rockstar/geo'
20
+ require 'rockstar/metro'
21
+ require 'rockstar/user'
22
+ require 'rockstar/tag'
23
+ require 'rockstar/track'
24
+ require 'rockstar/venue'
25
+
26
+ require 'rockstar/simpleauth'
27
+ require 'rockstar/auth'
28
+ require 'rockstar/session'
29
+ require 'rockstar/tokenauth'
30
+ require 'rockstar/scrobble'
31
+ require 'rockstar/playing'
32
+
33
+ require 'rockstar/rest'
34
+
35
+ module Rockstar
36
+ extend self
37
+
38
+ def lastfm=(args)
39
+ @api_key = args["api_key"]
40
+ @api_secret = args["api_secret"]
41
+ end
42
+
43
+ def lastfm_api_key
44
+ @api_key
45
+ end
46
+
47
+ def lastfm_api_secret
48
+ @api_secret
49
+ end
50
+ end
@@ -0,0 +1,109 @@
1
+ # Getting information about an album such as release date and the summary or description on it is very easy.
2
+ #
3
+ # album = Rockstar::Album.new('Carrie Underwood', 'Some Hearts', :include_info => true)
4
+ #
5
+ # puts "Album: #{album.name}"
6
+ # puts "Artist: #{album.artist}"
7
+ # puts "URL: #{album.url}"
8
+ # puts "Release Date: #{album.release_date.strftime('%m/%d/%Y')}"
9
+ #
10
+ # Would output:
11
+ #
12
+ # Album: Some Hearts
13
+ # Artist: Carrie Underwood
14
+ # URL: http://www.last.fm/music/Carrie+Underwood/Some+Hearts
15
+ # Release Date: 11/15/2005
16
+ #
17
+ module Rockstar
18
+ class Album < Base
19
+ attr_accessor :artist, :artist_mbid, :name, :mbid, :playcount, :rank, :url, :release_date
20
+ attr_accessor :image_large, :image_medium, :image_small, :summary, :content, :images
21
+
22
+ # needed on top albums for tag
23
+ attr_accessor :count, :streamable
24
+
25
+ # needed for weekly album charts
26
+ attr_accessor :chartposition
27
+
28
+ class << self
29
+ def find(artist, name, o={})
30
+ new(artist, name, o)
31
+ end
32
+
33
+ def new_from_xml(xml, doc=nil)
34
+ name = (xml).at(:name).inner_html if (xml).at(:name)
35
+ name = xml['name'] if name.nil? && xml['name']
36
+ name = xml.at(:title).inner_html if name.nil? && (xml).at(:title)
37
+ artist = (xml).at(:artist).at(:name).inner_html if (xml).at(:artist) && (xml).at(:artist).at(:name)
38
+ artist = (xml).at(:artist).inner_html if artist.nil? && (xml).at(:artist)
39
+ artist = doc.root['artist'] if artist.nil? && doc && doc.root['artist']
40
+
41
+ album = Album.new(artist, name)
42
+ album.load_info(xml)
43
+ album
44
+ end
45
+ end
46
+
47
+ def initialize(artist, name, o={})
48
+ raise ArgumentError, "Artist is required" if artist.blank?
49
+ raise ArgumentError, "Name is required" if name.blank?
50
+ @artist = artist
51
+ @name = name
52
+
53
+ options = {:include_info => false}.merge(o)
54
+ load_info if options[:include_info]
55
+ end
56
+
57
+ def load_info(xml=nil)
58
+ unless xml
59
+ doc = self.class.fetch_and_parse("album.getInfo", {:artist => @artist, :album =>@name})
60
+ xml = (doc / :album).first
61
+ end
62
+
63
+ return self if xml.nil?
64
+
65
+ self.artist_mbid = (xml).at(:artist)['mbid'] if (xml).at(:artist) && (xml).at(:artist)['mbid']
66
+ self.artist_mbid = (xml).at(:artist).at(:mbid).inner_html if artist_mbid.nil? && (xml).at(:artist) && (xml).at(:artist).at(:mbid)
67
+ self.mbid = (xml).at(:mbid).inner_html if (xml).at(:mbid)
68
+ self.playcount = (xml).at(:playcount).inner_html if (xml).at(:playcount)
69
+ self.rank = xml['rank'] if xml['rank']
70
+ self.rank = (xml).at(:rank).inner_html if (xml).at(:rank) if rank.nil?
71
+ self.url = Base.fix_url((xml).at(:url).inner_html) if (xml).at(:url)
72
+
73
+ self.summary = (xml).at(:summary).to_plain_text if (xml).at(:summary)
74
+ self.content = (xml).at(:content).to_plain_text if (xml).at(:content)
75
+
76
+ self.release_date = Base.parse_time((xml).at(:releasedate).inner_html.strip) if (xml).at(:releasedate)
77
+ self.chartposition = rank
78
+
79
+ self.images = {}
80
+ (xml/'image').each {|image|
81
+ self.images[image['size']] = image.inner_html if self.images[image['size']].nil?
82
+ }
83
+
84
+ self.image_large = images['large']
85
+ self.image_medium = images['medium']
86
+ self.image_small = images['small']
87
+
88
+ # needed on top albums for tag
89
+ self.count = xml['count'] if xml['count']
90
+ self.streamable = xml['streamable'] if xml['streamable']
91
+
92
+ self
93
+ end
94
+
95
+ def tracks
96
+ warn "[DEPRECATION] `tracks` is deprecated. The current api doesn't offer this function"
97
+ []
98
+ end
99
+
100
+ def image(which=:small)
101
+ which = which.to_s
102
+ raise ArgumentError unless ['small', 'medium', 'large', 'extralarge'].include?(which)
103
+ if (self.images.nil?)
104
+ load_info
105
+ end
106
+ self.images[which]
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,182 @@
1
+ # Below are examples of how to find an artists top tracks and similar artists.
2
+ #
3
+ # artist = Rockstar::Artist.new('Carrie Underwood')
4
+ #
5
+ # puts 'Top Tracks'
6
+ # puts "=" * 10
7
+ # artist.top_tracks.each { |t| puts "#{t.name}" }
8
+ #
9
+ # puts
10
+ #
11
+ # puts 'Similar Artists'
12
+ # puts "=" * 15
13
+ # artist.similar.each { |a| puts "(#{a.match}%) #{a.name}" }
14
+ #
15
+ # Would output something similar to:
16
+ #
17
+ # Top Tracks
18
+ # ==========
19
+ # (8797) Before He Cheats
20
+ # (3574) Don't Forget to Remember Me
21
+ # (3569) Wasted
22
+ # (3246) Some Hearts
23
+ # (3142) Jesus, Take the Wheel
24
+ # (2600) Starts With Goodbye
25
+ # (2511) Jesus Take The Wheel
26
+ # (2423) Inside Your Heaven
27
+ # (2328) Lessons Learned
28
+ # (2040) I Just Can't Live a Lie
29
+ # (1899) Whenever You Remember
30
+ # (1882) We're Young and Beautiful
31
+ # (1854) That's Where It Is
32
+ # (1786) I Ain't in Checotah Anymore
33
+ # (1596) The Night Before (Life Goes On)
34
+ #
35
+ # Similar Artists
36
+ # ===============
37
+ # (100%) Rascal Flatts
38
+ # (84.985%) Keith Urban
39
+ # (84.007%) Kellie Pickler
40
+ # (82.694%) Katharine McPhee
41
+ # (81.213%) Martina McBride
42
+ # (79.397%) Faith Hill
43
+ # (77.121%) Tim McGraw
44
+ # (75.191%) Jessica Simpson
45
+ # (75.182%) Sara Evans
46
+ # (75.144%) The Wreckers
47
+ # (73.034%) Kenny Chesney
48
+ # (71.765%) Dixie Chicks
49
+ # (71.084%) Kelly Clarkson
50
+ # (69.535%) Miranda Lambert
51
+ # (66.952%) LeAnn Rimes
52
+ # (66.398%) Mandy Moore
53
+ # (65.817%) Bo Bice
54
+ # (65.279%) Diana DeGarmo
55
+ # (65.115%) Gretchen Wilson
56
+ # (62.982%) Clay Aiken
57
+ # (62.436%) Ashlee Simpson
58
+ # (62.160%) Christina Aguilera
59
+ module Rockstar
60
+ class Artist < Base
61
+ attr_accessor :name, :mbid, :listenercount, :playcount, :rank, :url, :thumbnail
62
+ attr_accessor :summary, :content, :images, :count, :streamable
63
+ attr_accessor :chartposition
64
+
65
+ # used for similar artists
66
+ attr_accessor :match
67
+
68
+ class << self
69
+ def new_from_xml(xml, doc=nil)
70
+ # occasionally name can be found in root of artist element (<artist name="">) rather than as an element (<name>)
71
+ name = (xml).at(:name).inner_html if (xml).at(:name)
72
+ name = xml['name'] if name.nil? && xml['name']
73
+
74
+ artist = Artist.new(name)
75
+ artist.load_info(xml)
76
+ artist
77
+ end
78
+ end
79
+
80
+ def initialize(name, o={})
81
+ raise ArgumentError, "Name is required" if name.blank?
82
+ @name = name
83
+
84
+ options = {:include_info => false}.merge(o)
85
+ load_info if options[:include_info]
86
+ end
87
+
88
+ def load_info(xml=nil)
89
+ unless xml
90
+ doc = self.class.fetch_and_parse("artist.getInfo", {:artist => @name})
91
+ xml = (doc / :artist).first
92
+ end
93
+
94
+ return self if xml.nil?
95
+
96
+ self.mbid = (xml).at(:mbid).inner_html if (xml).at(:mbid)
97
+ self.listenercount = (xml).at(:listeners).inner_html if (xml).at(:listeners)
98
+ self.playcount = (xml).at(:playcount).inner_html if (xml).at(:playcount)
99
+ self.chartposition = self.rank = xml['rank'] if xml['rank']
100
+ self.chartposition = self.rank = (xml).at(:rank).inner_html if (xml).at(:rank) if self.rank.nil?
101
+ self.url = Base.fix_url((xml).at(:url).inner_html) if (xml).at(:url)
102
+
103
+ if bio_xml = xml.at(:bio)
104
+ self.summary = bio_xml.at(:summary).to_plain_text if bio_xml.at(:summary)
105
+ self.content = bio_xml.at(:content).to_plain_text if bio_xml.at(:content)
106
+ end
107
+
108
+ self.images = {}
109
+ (xml/'image').each {|image|
110
+ self.images[image['size']] = image.inner_html if self.images[image['size']].nil?
111
+ }
112
+
113
+ self.thumbnail = self.images['small']
114
+ self.match = (xml).at(:match).inner_html if (xml).at(:match)
115
+
116
+ # in top artists for tag
117
+ self.count = xml['count'] if xml['count']
118
+ self.streamable = xml['streamable'] if xml['streamable']
119
+
120
+ self.streamable = (xml).at(:streamable).inner_html == '1' ? 'yes' : 'no' if self.streamable.nil? && (xml).at(:streamable)
121
+
122
+ self
123
+ end
124
+
125
+ def current_events(format=:ics)
126
+ warn "[DEPRECATION] the `current_events` method is deprecated. Please use artist.events"
127
+ events
128
+ end
129
+
130
+ def events(force=false)
131
+ get_instance("artist.getEvents", :events, :event, {:artist => @name}, force)
132
+ end
133
+
134
+ def similar(force=false)
135
+ get_instance("artist.getSimilar", :similar, :artist, {:artist => @name}, force)
136
+ end
137
+
138
+ def top_fans(force=false)
139
+ get_instance("artist.getTopFans", :top_fans, :user, {:artist => @name}, force)
140
+ end
141
+
142
+ def top_tracks(force=false)
143
+ get_instance("artist.getTopTracks", :top_tracks, :track, {:artist => @name}, force)
144
+ end
145
+
146
+ def top_albums(force=false)
147
+ get_instance("artist.getTopAlbums", :top_albums, :album, {:artist => @name}, force)
148
+ end
149
+
150
+ def top_tags(force=false)
151
+ get_instance("artist.getTopTags", :top_tags, :tag, {:artist => @name}, force)
152
+ end
153
+
154
+ def image(which=:medium)
155
+ which = which.to_s
156
+ raise ArgumentError unless ['small', 'medium', 'large', 'extralarge'].include?(which)
157
+ load_info if self.images.nil?
158
+ self.images[which]
159
+ end
160
+
161
+ def user_images(opts={})
162
+ if mbid.nil?
163
+ opts[:artist] = name
164
+ else
165
+ opts[:mbid] = mbid
166
+ end
167
+
168
+ images = []
169
+ image_doc = self.class.fetch_and_parse("artist.getImages", opts, false)
170
+ (image_doc/'image').each do |xml|
171
+ image_sizes = {}
172
+ xml.search('/sizes/size').each do |image|
173
+ image_sizes[image['name']] = image.inner_html
174
+ end
175
+
176
+ images << image_sizes
177
+ end
178
+
179
+ images
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,21 @@
1
+ module Rockstar
2
+
3
+ class Auth < Base
4
+ # Returns the token for a session. You have to use
5
+ # TokenAuth first and then use this class with the token
6
+ # that is given by last.fm to create a session token
7
+ # This session token can be stored in your database, it is
8
+ # not expiring.
9
+ # See Rockstar::TokenAuth for a detailed example
10
+ def session(token)
11
+ doc = self.class.fetch_and_parse("auth.getSession", {:token => token}, true)
12
+ Rockstar::Session.new_from_xml(doc)
13
+ end
14
+
15
+ def token
16
+ doc = self.class.fetch_and_parse("auth.getToken", {}, true)
17
+ token = (doc).at(:token).inner_html if (doc).at(:token)
18
+ token
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,48 @@
1
+ module Rockstar
2
+
3
+ API_URL = 'http://ws.audioscrobbler.com/'
4
+ API_VERSION = '2.0'
5
+
6
+ class Base
7
+ class << self
8
+ def connection
9
+ @connection ||= REST::Connection.new(API_URL + API_VERSION + "/")
10
+ end
11
+
12
+ def fetch_and_parse(resource, params = {}, sign_request = false)
13
+ Hpricot::XML(connection.get(resource, sign_request, params))
14
+ end
15
+
16
+ def get_instance(api_method, instance_name, element, params, sign_request = false)
17
+ rockstar_class = "rockstar/#{element.to_s}".camelize.constantize
18
+ doc = self.fetch_and_parse(api_method, params, sign_request)
19
+ (doc/element).inject([]) { |elements, el| elements << rockstar_class.new_from_xml(el, doc); elements }
20
+ end
21
+ end
22
+
23
+ private
24
+ # in order for subclass to use, it must have api_path method
25
+ def get_instance(api_method, instance_name, element, params, force = false, sign_request = false)
26
+ rockstar_class = "rockstar/#{element.to_s}".camelize.constantize
27
+
28
+ if instance_variable_get("@#{instance_name}").nil? || force
29
+ doc = self.class.fetch_and_parse(api_method, params, sign_request)
30
+ elements = (doc/element).inject([]) { |elements, el| elements << rockstar_class.new_from_xml(el, doc); elements }
31
+ instance_variable_set("@#{instance_name}", elements)
32
+ end
33
+ instance_variable_get("@#{instance_name}")
34
+ end
35
+
36
+ def self.fix_url(url)
37
+ if (!url.blank? && !url.match("^http://"))
38
+ url = "http://#{url}"
39
+ end
40
+ url
41
+ end
42
+
43
+ def self.parse_time(time_str)
44
+ return nil if time_str.blank?
45
+ Time.parse(time_str)
46
+ end
47
+ end
48
+ end