grooveshark 0.2.11 → 0.2.12

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8b22e2adb61445f3b5c0253a93cd2a8e012a6c8b
4
- data.tar.gz: f93bd8afcc2b20b0de542127067226228b5a1014
3
+ metadata.gz: 265e469716c245b3c4421d9b1f4a97e9808c3371
4
+ data.tar.gz: 4e1d82a8c9b0c9e3c12f40d200052ad4d7398c43
5
5
  SHA512:
6
- metadata.gz: c0538198b0cf8a836731ca3c467a9ad455d68d7a3c61368fd768c6cd5080d0b6490e79156ba4341b7027c1a132c82e0e28fc6596393eb24e393b615b2129358b
7
- data.tar.gz: b1fecfb1371885c65b9bb0a09c641b1a6e1fc217074de4f44a5fa88f7c14b973c9a322dd84996acc82506ab4303111baabd6de0cfdf6241456a5ccb841436f12
6
+ metadata.gz: 8a9732cce0fdaf0edafd248efae89676f7003c1b4c6fa02fabbaadcb19d78cde55bb2fc69ab488abe124f5a3417f66cbec617b531782ca4177f8ce730b3a0a9f
7
+ data.tar.gz: b7d86f7a0ae7cc1170b3e62ad4bbadbaad2014472eca7c054abbcc56e5cb3db9f181e7e9d8b27ce1c9c66b230cf83243e96802ec2edf69b38bd44cf8e47f5448
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
+ .ruby-version
2
+ .ruby-gemset
1
3
  !.gitignore
2
4
  *.gem
3
5
  *.rbc
@@ -13,6 +15,7 @@
13
15
  .bundle
14
16
  .config
15
17
  .directory
18
+ .project
16
19
  .elc
17
20
  .redcar
18
21
  .yardoc
@@ -38,4 +41,4 @@ test/tmp
38
41
  test/version_tmp
39
42
  tmp
40
43
  tmtags
41
- tramp
44
+ tramp
data/.rspec CHANGED
@@ -1,3 +1,3 @@
1
1
  --color
2
- --format=nested
3
- --backtrace
2
+ --format=documentation
3
+ --backtrace
@@ -0,0 +1,6 @@
1
+ Metrics/MethodLength:
2
+ Enabled: false
3
+ Metrics/ClassLength:
4
+ Enabled: false
5
+ Metrics/AbcSize:
6
+ Enabled: false
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - 2.0
7
+ - 2.1
8
+
9
+ script:
10
+ - bundle exec rake spec
11
+ - sh -c "if [ \"$TRAVIS_RUBY_VERSION\" != '1.9.2' ]; then bundle exec rake rubocop; fi"
data/Gemfile CHANGED
@@ -1,2 +1,3 @@
1
1
  source 'https://rubygems.org'
2
- gemspec
2
+
3
+ gemspec
data/README.md CHANGED
@@ -1,9 +1,11 @@
1
- # Grooveshark API
1
+ # Grooveshark API [![Build Status](https://travis-ci.org/sosedoff/grooveshark.svg?branch=master)](https://travis-ci.org/sosedoff/grooveshark)
2
2
 
3
3
  Unofficial grooveshark API ruby library gives your ability to search and stream songs,
4
4
  manage playlists, media library and favorites.
5
5
  API was discovered using http proxy and does not pretend to be always valid due to website API changes.
6
6
 
7
+ **Looking for maintainer. Submit a new issue if interested.**
8
+
7
9
  ## Installation
8
10
 
9
11
  Install gem from rubygems:
@@ -242,14 +244,14 @@ user.feed
242
244
  Run test suite:
243
245
 
244
246
  ```
245
- rake test
247
+ bundle exec rake
246
248
  ```
247
249
 
248
250
  ## Contact
249
251
 
250
252
  - Dan Sosedoff
251
253
  - dan.sosedoff@gmail.com
252
- - http://twitter.com/dan_sosedoff
254
+ - http://twitter.com/sosedoff
253
255
 
254
256
  ## License
255
257
 
data/Rakefile CHANGED
@@ -1,10 +1,17 @@
1
1
  require 'bundler'
2
2
  require 'bundler/gem_tasks'
3
- require "rspec/core/rake_task"
3
+ require 'rspec/core/rake_task'
4
4
 
5
- RSpec::Core::RakeTask.new(:test) do |t|
6
- t.pattern = 'spec/*_spec.rb'
5
+ begin
6
+ require 'rubocop/rake_task'
7
+
8
+ RuboCop::RakeTask.new(:rubocop)
9
+ rescue LoadError
10
+ puts 'Rubocop is needed to run this task.'
11
+ end
12
+
13
+ RSpec::Core::RakeTask.new(:spec) do |t|
7
14
  t.verbose = false
8
15
  end
9
16
 
10
- task :default => :test
17
+ task default: [:rubocop, :spec]
@@ -1,25 +1,32 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path("../lib/grooveshark/version", __FILE__)
2
+ require File.expand_path('../lib/grooveshark/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
- s.name = "grooveshark"
5
+ s.name = 'grooveshark'
6
6
  s.version = Grooveshark::VERSION
7
- s.description = "Unofficial ruby library for consuming the Grooveshark API."
8
- s.summary = "Grooveshark API"
9
- s.authors = ["Dan Sosedoff"]
10
- s.email = "dan.sosedoff@gmail.com"
11
- s.homepage = "http://github.com/sosedoff/grooveshark"
12
- s.license = "MIT"
7
+ s.description = 'Unofficial ruby library for consuming the Grooveshark API.'
8
+ s.summary = 'Grooveshark API'
9
+ s.authors = ['Dan Sosedoff']
10
+ s.email = 'dan.sosedoff@gmail.com'
11
+ s.homepage = 'http://github.com/sosedoff/grooveshark'
12
+ s.license = 'MIT'
13
13
 
14
14
  s.files = `git ls-files`.split("\n")
15
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
- s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
17
- s.require_paths = ["lib"]
18
-
19
- s.add_development_dependency "rspec", "~> 2.12"
20
- s.add_development_dependency "rake", "~> 10.0"
21
-
22
- s.add_runtime_dependency "json", ">= 1.4.6"
23
- s.add_runtime_dependency "rest-client", ">= 1.5.1"
24
- s.add_runtime_dependency "uuid", "~> 2.0"
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map do |f|
17
+ File.basename(f)
18
+ end
19
+ s.require_paths = ['lib']
20
+
21
+ s.add_runtime_dependency 'json', '>= 1.4.6'
22
+ s.add_runtime_dependency 'rest-client', '>= 1.5.1'
23
+ s.add_runtime_dependency 'uuid', '~> 2.0'
24
+
25
+ s.add_development_dependency 'rake', '~>10.0'
26
+ s.add_development_dependency 'rack-test', '~>0.6'
27
+ s.add_development_dependency 'rspec', '~>3.0'
28
+ s.add_development_dependency 'simplecov', '~>0.9'
29
+ s.add_development_dependency 'fakefs', '~>0.5'
30
+
31
+ s.add_development_dependency 'rubocop', '~>0.25' if RUBY_VERSION != '1.9.2'
25
32
  end
@@ -1,16 +1,18 @@
1
+ # Grooveshark module
1
2
  module Grooveshark
3
+ # Broadcast class
2
4
  class Broadcast
3
5
  attr_reader :id, :user_ids
4
6
  attr_reader :is_active, :is_playing
5
7
  attr_reader :name, :usernames
6
8
  attr_reader :active_song, :next_song
7
9
 
8
- def initialize(client, broadcast_id=nil, data=nil)
10
+ def initialize(client, broadcast_id = nil, data = nil)
9
11
  @client = client
10
12
 
11
13
  if broadcast_id
12
14
  @id = broadcast_id
13
- reload_status()
15
+ reload_status
14
16
  elsif data
15
17
  @id = data['broadcast_id'] || broadcast_id
16
18
  @name = data['name']
@@ -28,7 +30,7 @@ module Grooveshark
28
30
  def reload_status
29
31
  initialize(
30
32
  @client, nil,
31
- @client.request('broadcastStatusPoll', {:broadcastID => id})
33
+ @client.request('broadcastStatusPoll', broadcastID: @id)
32
34
  )
33
35
  true
34
36
  rescue
@@ -1,4 +1,6 @@
1
+ # Grooveshark module
1
2
  module Grooveshark
3
+ # Client class
2
4
  class Client
3
5
  attr_accessor :session, :comm_token
4
6
  attr_reader :user, :comm_token_ttl, :country
@@ -6,60 +8,71 @@ module Grooveshark
6
8
  def initialize(params = {})
7
9
  @ttl = params[:ttl] || 120 # 2 minutes
8
10
  @uuid = UUID.new.generate.upcase
9
- get_token_data
11
+ token_data
10
12
  end
11
13
 
12
14
  # Authenticate user
13
15
  def login(user, password)
14
- data = request('authenticateUser', {:username => user, :password => password}, true)
16
+ data = request('authenticateUser',
17
+ { username: user, password: password },
18
+ true)
15
19
  @user = User.new(self, data)
16
- raise InvalidAuthentication, 'Wrong username or password!' if @user.id == 0
17
- return @user
20
+ fail InvalidAuthentication, 'Wrong username or password!' if @user.id == 0
21
+
22
+ @user
18
23
  end
19
24
 
20
25
  # Find user by ID
21
26
  def get_user_by_id(id)
22
- resp = request('getUserByID', {:userID => id})['user']
23
- resp['username'].empty? ? nil : User.new(self, resp)
27
+ resp = request('getUserByID', userID: id)['user']
28
+ resp['user_id'].nil? ? nil : User.new(self, resp)
24
29
  end
25
30
 
26
31
  # Find user by username
27
32
  def get_user_by_username(name)
28
- resp = request('getUserByUsername', {:username => name})['user']
29
- resp['username'].empty? ? nil : User.new(self, resp)
33
+ resp = request('getUserByUsername', username: name)['user']
34
+ resp['user_id'].nil? ? nil : User.new(self, resp)
30
35
  end
31
36
 
32
37
  # Get recently active users
33
38
  def recent_users
34
- request('getRecentlyActiveUsers', {})['users'].map { |u| User.new(self, u) }
39
+ request('getRecentlyActiveUsers', {})['users']
40
+ .map do |u|
41
+ User.new(self, u)
42
+ end
35
43
  end
36
44
 
37
45
  # Get popular songs
38
46
  # type => daily, monthly
39
- def popular_songs(type='daily')
40
- raise ArgumentError, 'Invalid type' unless ['daily', 'monthly'].include?(type)
41
- request('popularGetSongs', {:type => type})['songs'].map { |s| Song.new(s) }
47
+ def popular_songs(type = 'daily')
48
+ fail ArgumentError, 'Invalid type' unless %w(daily monthly).include?(type)
49
+ request('popularGetSongs', type: type)['songs'].map { |s| Song.new(s) }
42
50
  end
43
51
 
44
52
  # Get top broadcasts
45
53
  # count => specifies how many broadcasts to get
46
- def top_broadcasts(count=10)
54
+ def top_broadcasts(count = 10)
47
55
  top_broadcasts = []
48
- request('getTopBroadcastsCombined').each do |key,val|
56
+ request('getTopBroadcastsCombined').each do |key, _val|
49
57
  broadcast_id = key.split(':')[1]
50
58
  top_broadcasts.push(Broadcast.new(self, broadcast_id))
51
59
  count -= 1
52
- if count == 0
53
- break
54
- end
60
+ break if count == 0
55
61
  end
56
- return top_broadcasts
62
+
63
+ top_broadcasts
57
64
  end
58
65
 
59
66
  # Perform search request for query
60
67
  def search(type, query)
61
- results = request('getResultsFromSearch', {:type => type, :query => query})['result']
62
- results.map { |song| Song.new song }
68
+ results = []
69
+ search = request('getResultsFromSearch', type: type, query: query)
70
+ results = search['result'].map do |data|
71
+ next Song.new data if type == 'Songs'
72
+ next Playlist.new data if type == 'Playlists'
73
+ data
74
+ end if search.key?('result')
75
+ results
63
76
  end
64
77
 
65
78
  # Perform songs search request for query
@@ -69,20 +82,20 @@ module Grooveshark
69
82
 
70
83
  # Return raw response for songs search request
71
84
  def search_songs_pure(query)
72
- request('getSearchResultsEx', {:type => 'Songs', :query => query})
85
+ request('getSearchResultsEx', type: 'Songs', query: query)
73
86
  end
74
87
 
75
88
  # Get stream authentication by song ID
76
89
  def get_stream_auth_by_songid(song_id)
77
- result = request('getStreamKeyFromSongIDEx', {
78
- 'type' => 0,
79
- 'prefetch' => false,
80
- 'songID' => song_id,
81
- 'country' => @country,
82
- 'mobile' => false,
83
- })
84
- if result == [] then
85
- raise GeneralError, "No data for this song. Maybe Grooveshark banned your IP."
90
+ result = request('getStreamKeyFromSongIDEx',
91
+ 'type' => 0,
92
+ 'prefetch' => false,
93
+ 'songID' => song_id,
94
+ 'country' => @country,
95
+ 'mobile' => false)
96
+ if result == []
97
+ fail GeneralError, 'No data for this song. ' \
98
+ 'Maybe Grooveshark banned your IP.'
86
99
  end
87
100
  result
88
101
  end
@@ -103,16 +116,18 @@ module Grooveshark
103
116
  get_song_url_by_id(song.id)
104
117
  end
105
118
 
106
- def get_token_data
119
+ def token_data
107
120
  response = RestClient.get('http://grooveshark.com')
108
121
 
109
- preload_regex = /gsPreloadAjax\(\{url: '\/preload.php\?(.*)&hash=' \+ clientPage\}\)/
122
+ preload_regex = /gsPreloadAjax\(\{url: '\/preload.php\?(.*)&hash=' \+ clientPage\}\)/ # rubocop:disable Metrics/LineLength
110
123
  preload_id = response.to_s.scan(preload_regex).flatten.first
111
- preload_url = "http://grooveshark.com/preload.php?#{preload_id}&getCommunicationToken=1&hash=%2F"
124
+ preload_url = "http://grooveshark.com/preload.php?#{preload_id}" \
125
+ '&getCommunicationToken=1&hash=%2F'
112
126
  preload_response = RestClient.get(preload_url)
113
127
 
114
- token_data_json = preload_response.to_s.scan(/window.tokenData = (.*);/).flatten.first
115
- raise GeneralError, "token data not found" if not token_data_json
128
+ token_data_json = preload_response.to_s
129
+ .scan(/window.tokenData = (.*);/).flatten.first
130
+ fail GeneralError, 'token data not found' unless token_data_json
116
131
  token_data = JSON.parse(token_data_json)
117
132
  @comm_token = token_data['getCommunicationToken']
118
133
  @comm_token_ttl = Time.now.to_i
@@ -124,7 +139,7 @@ module Grooveshark
124
139
  # Sign method
125
140
  def create_token(method)
126
141
  rnd = get_random_hex_chars(6)
127
- salt = "gooeyFlubber"
142
+ salt = 'gooeyFlubber'
128
143
  plain = [method, @comm_token, salt, rnd].join(':')
129
144
  hash = Digest::SHA1.hexdigest(plain)
130
145
  "#{rnd}#{hash}"
@@ -135,11 +150,7 @@ module Grooveshark
135
150
  (0...length).map { chars[rand(chars.length)] }.join
136
151
  end
137
152
 
138
- # Perform API request
139
- def request(method, params={}, secure=false)
140
- refresh_token if @comm_token
141
-
142
- url = "#{secure ? 'https' : 'http'}://grooveshark.com/more.php?#{method}"
153
+ def body(method, params)
143
154
  body = {
144
155
  'header' => {
145
156
  'client' => 'mobileshark',
@@ -153,17 +164,27 @@ module Grooveshark
153
164
  'parameters' => params
154
165
  }
155
166
  body['header']['token'] = create_token(method) if @comm_token
167
+ body
168
+ end
169
+
170
+ # Perform API request
171
+ def request(method, params = {}, secure = false)
172
+ refresh_token if @comm_token
173
+
174
+ url = "#{secure ? 'https' : 'http'}://grooveshark.com/more.php?#{method}"
156
175
  begin
157
- data = RestClient.post(url, body.to_json, {'Content-Type' => 'application/json'})
158
- rescue Exception => ex
176
+ data = RestClient.post(url,
177
+ body(method, params).to_json,
178
+ 'Content-Type' => 'application/json')
179
+ rescue StandardError => ex
159
180
  raise GeneralError, ex.message
160
181
  end
161
182
 
162
183
  data = JSON.parse(data)
163
- data = data.normalize if data.kind_of?(Hash)
184
+ data = data.normalize if data.is_a?(Hash)
164
185
 
165
186
  if data.key?('fault')
166
- raise ApiError.new(data['fault'])
187
+ fail ApiError, data['fault']
167
188
  else
168
189
  data['result']
169
190
  end
@@ -171,7 +192,7 @@ module Grooveshark
171
192
 
172
193
  # Refresh communications token on ttl
173
194
  def refresh_token
174
- get_token_data if Time.now.to_i - @comm_token_ttl > @ttl
195
+ token_data if Time.now.to_i - @comm_token_ttl > @ttl
175
196
  end
176
197
  end
177
198
  end
@@ -1,8 +1,15 @@
1
+ # Grooveshark module
1
2
  module Grooveshark
2
- class InvalidAuthentication < Exception ; end
3
- class ReadOnlyAccess < Exception ; end
4
- class GeneralError < Exception ; end
3
+ class InvalidAuthentication < Exception
4
+ end
5
+
6
+ class ReadOnlyAccess < Exception
7
+ end
8
+
9
+ class GeneralError < Exception
10
+ end
5
11
 
12
+ # Api error
6
13
  class ApiError < Exception
7
14
  attr_reader :code
8
15
 
@@ -15,4 +22,4 @@ module Grooveshark
15
22
  "#{@code} - #{@message}"
16
23
  end
17
24
  end
18
- end
25
+ end
@@ -1,44 +1,48 @@
1
+ # Grooveshark module
1
2
  module Grooveshark
3
+ # Playlist class
2
4
  class Playlist
3
5
  attr_reader :id, :user_id
4
6
  attr_reader :name, :about, :picture, :username
5
7
  attr_reader :songs
6
8
 
7
- def initialize(client, data=nil, user_id=nil)
9
+ def initialize(client, data = nil, user_id = nil)
8
10
  @client = client
9
11
  @songs = []
10
12
 
11
- if data
12
- @id = data['playlist_id']
13
- @name = data['name']
14
- @about = data['about']
15
- @picture = data['picture']
16
- @user_id = data['user_id'] || user_id
17
- @username = data['user_name']
18
- end
13
+ return if data.nil?
14
+ @id = data['playlist_id']
15
+ @name = data['name']
16
+ @about = data['about']
17
+ @picture = data['picture']
18
+ @user_id = data['user_id'] || user_id
19
+ @username = data['user_name']
19
20
  end
20
21
 
21
22
  # Fetch playlist songs
22
23
  def load_songs
23
- @songs = @client.request('getPlaylistByID', :playlistID => @id)['songs']
24
- @songs.map! { |s| Song.new(s) }
24
+ @songs = []
25
+ playlist = @client.request('getPlaylistByID', playlistID: @id)
26
+ @songs = playlist['songs'].map! do |s|
27
+ Song.new(s)
28
+ end if playlist.key?('songs')
29
+ @songs
25
30
  end
26
31
 
27
32
  # Rename playlist
28
33
  def rename(name, description)
29
- begin
30
- @client.request('renamePlaylist', :playlistID => @id, :playlistName => name)
31
- @client.request('setPlaylistAbout', :playlistID => @id, :about => description)
32
- @name = name ; @about = description
33
- return true
34
- rescue
35
- return false
36
- end
34
+ @client.request('renamePlaylist', playlistID: @id, playlistName: name)
35
+ @client.request('setPlaylistAbout', playlistID: @id, about: description)
36
+ @name = name
37
+ @about = description
38
+ true
39
+ rescue
40
+ false
37
41
  end
38
42
 
39
43
  # Delete existing playlist
40
44
  def delete
41
- @client.request('deletePlaylist', {:playlistID => @id, :name => @name})
45
+ @client.request('deletePlaylist', playlistID: @id, name: @name)
42
46
  end
43
47
  end
44
48
  end