grooveshark 0.2.11 → 0.2.12

Sign up to get free protection for your applications and to get access to all the features.
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