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 +4 -4
- data/.gitignore +4 -1
- data/.rspec +2 -2
- data/.rubocop.yml +6 -0
- data/.travis.yml +11 -0
- data/Gemfile +2 -1
- data/README.md +5 -3
- data/Rakefile +11 -4
- data/grooveshark.gemspec +24 -17
- data/lib/grooveshark/broadcast.rb +5 -3
- data/lib/grooveshark/client.rb +67 -46
- data/lib/grooveshark/errors.rb +11 -4
- data/lib/grooveshark/playlist.rb +24 -20
- data/lib/grooveshark/song.rb +17 -15
- data/lib/grooveshark/user.rb +43 -27
- data/lib/grooveshark/utils.rb +14 -12
- data/lib/grooveshark/version.rb +2 -1
- data/spec/grooveshark/broadcast_spec.rb +41 -0
- data/spec/grooveshark/client_spec.rb +80 -0
- data/spec/grooveshark/errors_spec.rb +15 -0
- data/spec/grooveshark/playlist_spec.rb +98 -0
- data/spec/grooveshark/song_spec.rb +43 -0
- data/spec/grooveshark/user_spec.rb +233 -0
- data/spec/grooveshark/utils_spec.rb +38 -0
- data/spec/helper.rb +7 -2
- metadata +105 -39
- data/spec/broadcast_spec.rb +0 -39
- data/spec/client_spec.rb +0 -85
- data/spec/utils_spec.rb +0 -35
data/lib/grooveshark/song.rb
CHANGED
@@ -1,25 +1,27 @@
|
|
1
|
+
# Grooveshark module
|
1
2
|
module Grooveshark
|
3
|
+
# Song class
|
2
4
|
class Song
|
3
5
|
attr_reader :data
|
4
6
|
attr_reader :id, :artist_id, :album_id
|
5
7
|
attr_reader :name, :artist, :album, :track, :year
|
6
8
|
attr_reader :duration, :artwork, :playcount
|
7
9
|
|
8
|
-
def initialize(data=nil)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
10
|
+
def initialize(data = nil)
|
11
|
+
return if data.nil?
|
12
|
+
|
13
|
+
@data = data
|
14
|
+
@id = data['song_id']
|
15
|
+
@name = data['song_name'] || data['name']
|
16
|
+
@artist = data['artist_name']
|
17
|
+
@artist_id = data['artist_id']
|
18
|
+
@album = data['album_name']
|
19
|
+
@album_id = data['album_id']
|
20
|
+
@track = data['track_num']
|
21
|
+
@duration = data['estimate_duration']
|
22
|
+
@artwork = data['cover_art_filename']
|
23
|
+
@playcount = data['song_plays']
|
24
|
+
@year = data['year']
|
23
25
|
end
|
24
26
|
|
25
27
|
# Presentable format
|
data/lib/grooveshark/user.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
+
# Grooveshark module
|
1
2
|
module Grooveshark
|
3
|
+
# User class
|
2
4
|
class User
|
3
|
-
attr_reader :id, :
|
5
|
+
attr_reader :id, :name, :email, :premium, :data
|
4
6
|
attr_reader :city, :country, :sex
|
5
7
|
attr_reader :playlists, :favorites
|
6
8
|
|
7
9
|
# Init user account object
|
8
|
-
def initialize(client, data=nil)
|
10
|
+
def initialize(client, data = nil)
|
9
11
|
if data
|
10
12
|
@data = data
|
11
13
|
@id = data['user_id']
|
12
|
-
@
|
14
|
+
@name = data['f_name']
|
13
15
|
@premium = data['is_premium']
|
14
16
|
@email = data['email']
|
15
17
|
@city = data['city']
|
@@ -25,9 +27,11 @@ module Grooveshark
|
|
25
27
|
end
|
26
28
|
|
27
29
|
# Get user activity for the date (COMES AS RAW RESPONSE)
|
28
|
-
def feed(date=nil)
|
30
|
+
def feed(date = nil)
|
29
31
|
date = Time.now if date.nil?
|
30
|
-
@client.request('getProcessedUserFeedData',
|
32
|
+
@client.request('getProcessedUserFeedData',
|
33
|
+
userID: @id,
|
34
|
+
day: date.strftime('%Y%m%d'))
|
31
35
|
end
|
32
36
|
|
33
37
|
# --------------------------------------------------------------------------
|
@@ -35,26 +39,35 @@ module Grooveshark
|
|
35
39
|
# --------------------------------------------------------------------------
|
36
40
|
|
37
41
|
# Fetch songs from library
|
38
|
-
def library(page=0)
|
39
|
-
|
40
|
-
resp
|
42
|
+
def library(page = 0)
|
43
|
+
songs = []
|
44
|
+
resp = @client.request('userGetSongsInLibrary',
|
45
|
+
userID: @id,
|
46
|
+
page: page.to_s)
|
47
|
+
songs = resp['songs'].map do |song|
|
48
|
+
Song.new song
|
49
|
+
end if resp.key?('songs')
|
50
|
+
songs
|
41
51
|
end
|
42
52
|
|
43
53
|
# Add songs to user's library
|
44
|
-
def library_add(songs=[])
|
45
|
-
@client.request('userAddSongsToLibrary',
|
54
|
+
def library_add(songs = [])
|
55
|
+
@client.request('userAddSongsToLibrary', songs: songs.map(&:to_hash))
|
46
56
|
end
|
47
57
|
|
48
58
|
# Remove song from user library
|
49
59
|
def library_remove(song)
|
50
|
-
|
51
|
-
req = {:
|
60
|
+
fail ArgumentError, 'Song object required' unless song.is_a?(Song)
|
61
|
+
req = { userID: @id,
|
62
|
+
songID: song.id,
|
63
|
+
albumID: song.album_id,
|
64
|
+
artistID: song.artist_id }
|
52
65
|
@client.request('userRemoveSongFromLibrary', req)
|
53
66
|
end
|
54
67
|
|
55
68
|
# Get library modification time
|
56
69
|
def library_ts_modified
|
57
|
-
@client.request('userGetLibraryTSModified',
|
70
|
+
@client.request('userGetLibraryTSModified', userID: @id)
|
58
71
|
end
|
59
72
|
|
60
73
|
# --------------------------------------------------------------------------
|
@@ -64,8 +77,10 @@ module Grooveshark
|
|
64
77
|
# Fetch user playlists
|
65
78
|
def playlists
|
66
79
|
return @playlists if @playlists
|
67
|
-
results = @client.request('userGetPlaylists', :
|
68
|
-
@playlists = results['playlists'].map
|
80
|
+
results = @client.request('userGetPlaylists', userID: @id)
|
81
|
+
@playlists = results['playlists'].map do |list|
|
82
|
+
Playlist.new(@client, list, @id)
|
83
|
+
end
|
69
84
|
end
|
70
85
|
|
71
86
|
# Get playlist by ID
|
@@ -74,15 +89,16 @@ module Grooveshark
|
|
74
89
|
result.nil? ? nil : result.first
|
75
90
|
end
|
76
91
|
|
77
|
-
|
92
|
+
alias_method :playlist, :get_playlist
|
78
93
|
|
79
94
|
# Create new user playlist
|
80
|
-
def create_playlist(name, description='', songs=[])
|
81
|
-
@client.request('createPlaylist',
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
95
|
+
def create_playlist(name, description = '', songs = [])
|
96
|
+
@client.request('createPlaylist',
|
97
|
+
'playlistName' => name,
|
98
|
+
'playlistAbout' => description,
|
99
|
+
'songIDs' => songs.map do |s|
|
100
|
+
s.is_a?(Song) ? s.id : s.to_s
|
101
|
+
end)
|
86
102
|
end
|
87
103
|
|
88
104
|
# --------------------------------------------------------------------------
|
@@ -92,20 +108,20 @@ module Grooveshark
|
|
92
108
|
# Get user favorites
|
93
109
|
def favorites
|
94
110
|
return @favorites if @favorites
|
95
|
-
resp = @client.request('getFavorites', :
|
111
|
+
resp = @client.request('getFavorites', ofWhat: 'Songs', userID: @id)
|
96
112
|
@favorites = resp.map { |s| Song.new(s) }
|
97
113
|
end
|
98
114
|
|
99
115
|
# Add song to favorites
|
100
116
|
def add_favorite(song)
|
101
|
-
song_id = song.
|
102
|
-
@client.request('favorite',
|
117
|
+
song_id = song.is_a?(Song) ? song.id : song
|
118
|
+
@client.request('favorite', what: 'Song', ID: song_id)
|
103
119
|
end
|
104
120
|
|
105
121
|
# Remove song from favorites
|
106
122
|
def remove_favorite(song)
|
107
|
-
song_id = song.
|
108
|
-
@client.request('unfavorite',
|
123
|
+
song_id = song.is_a?(Song) ? song.id : song
|
124
|
+
@client.request('unfavorite', what: 'Song', ID: song_id)
|
109
125
|
end
|
110
126
|
end
|
111
127
|
end
|
data/lib/grooveshark/utils.rb
CHANGED
@@ -1,26 +1,28 @@
|
|
1
|
+
# String class
|
1
2
|
class String
|
2
3
|
def normalize_attribute
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
gsub(/^.*::/, '')
|
5
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
6
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
7
|
+
.downcase
|
7
8
|
end
|
8
9
|
end
|
9
10
|
|
11
|
+
# Hash class
|
10
12
|
class Hash
|
11
13
|
def normalize
|
12
14
|
h = {}
|
13
|
-
|
15
|
+
each_pair do |k, v|
|
14
16
|
attr = k.to_s.normalize_attribute
|
15
17
|
case v
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
when Hash
|
19
|
+
h[attr] = v.normalize
|
20
|
+
when Array
|
21
|
+
h[attr] = v.map { |o| o.is_a?(Hash) ? o.normalize : o }
|
22
|
+
else
|
23
|
+
h[attr] = v
|
22
24
|
end
|
23
25
|
end
|
24
26
|
h
|
25
27
|
end
|
26
|
-
end
|
28
|
+
end
|
data/lib/grooveshark/version.rb
CHANGED
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
|
3
|
+
require 'grooveshark'
|
4
|
+
|
5
|
+
describe Grooveshark::Broadcast do
|
6
|
+
let(:client) { Grooveshark::Client.new }
|
7
|
+
|
8
|
+
describe 'search' do
|
9
|
+
let(:result) { client.top_broadcasts(10) }
|
10
|
+
|
11
|
+
it 'returns an array' do
|
12
|
+
expect(result).to be_an Array
|
13
|
+
expect(result.size).to eq 10
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'includes brodcasts' do
|
17
|
+
all = result.all? { |item| item.is_a?(Grooveshark::Broadcast) }
|
18
|
+
expect(all).to be_truthy
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'broadcast' do
|
23
|
+
let(:broadcast) { client.top_broadcasts.first }
|
24
|
+
|
25
|
+
it 'has a valid id' do
|
26
|
+
expect(broadcast.id).to match(/^[abcdef\d]{24}$/i)
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#active_song' do
|
30
|
+
it 'is a song instance' do
|
31
|
+
expect(broadcast.active_song).to be_a Grooveshark::Song
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#next_song' do
|
36
|
+
it 'is a song instance' do
|
37
|
+
expect(broadcast.active_song).to be_a Grooveshark::Song
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
|
3
|
+
require 'grooveshark'
|
4
|
+
|
5
|
+
describe 'Client' do
|
6
|
+
context 'initialization' do
|
7
|
+
it 'should have a valid session' do
|
8
|
+
@gs = Grooveshark::Client.new
|
9
|
+
expect(@gs.session).to_not be_nil
|
10
|
+
expect(@gs.session).to match(/^[abcdef\d]{32}$/i)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should have a valid country' do
|
14
|
+
gs = Grooveshark::Client.new
|
15
|
+
expect(gs.country).to be_a Hash
|
16
|
+
expect(gs.country.size).to eq(11)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should have a valid token' do
|
20
|
+
@gs = Grooveshark::Client.new
|
21
|
+
expect(@gs.comm_token).to_not be_nil
|
22
|
+
expect(@gs.comm_token).to match(/^[abcdef\d]{40}$/i)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'authentication' do
|
27
|
+
it 'should raise InvalidAuthentication error for invalid credentials' do
|
28
|
+
@gs = Grooveshark::Client.new
|
29
|
+
expect { @gs.login('invlid_user_name', 'invalid_password') }
|
30
|
+
.to raise_error Grooveshark::InvalidAuthentication
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should obtain a new communication token on TTL expiration' do
|
34
|
+
@gs = Grooveshark::Client.new(ttl: 1)
|
35
|
+
@tokens = []
|
36
|
+
|
37
|
+
3.times do
|
38
|
+
@gs.search_songs('Muse')
|
39
|
+
@tokens << @gs.comm_token
|
40
|
+
sleep 3
|
41
|
+
end
|
42
|
+
|
43
|
+
@tokens.uniq!
|
44
|
+
expect(@tokens.size).to eq(3)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'search' do
|
49
|
+
before(:all) do
|
50
|
+
@gs = Grooveshark::Client.new
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should return empty songs collection' do
|
54
|
+
songs = @gs.search_songs('@@@@@%%%%%%%@%@%%@')
|
55
|
+
expect(songs).to be_a Array
|
56
|
+
expect(songs.size).to eq(0)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should return songs collection' do
|
60
|
+
songs = @gs.search_songs('Nirvana')
|
61
|
+
expect(songs).to be_a Array
|
62
|
+
expect(songs.first).to be_a(Grooveshark::Song)
|
63
|
+
expect(songs.size).to_not eq(0)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should return playlist' do
|
67
|
+
playlists = @gs.search('Playlists', 'CruciAGoT')
|
68
|
+
expect(playlists).to be_a(Array)
|
69
|
+
expect(playlists.first).to be_a(Grooveshark::Playlist)
|
70
|
+
expect(playlists.size).to_not eq(0)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should return result' do
|
74
|
+
artists = @gs.search('Artists', 'Nirvana')
|
75
|
+
expect(artists).to be_a(Array)
|
76
|
+
expect(artists.first).to be_a(Hash)
|
77
|
+
expect(artists.size).to_not eq(0)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
|
3
|
+
require 'grooveshark'
|
4
|
+
|
5
|
+
describe 'Errors' do
|
6
|
+
it 'should test ApiError' do
|
7
|
+
fault = {
|
8
|
+
'code' => '25',
|
9
|
+
'message' => 'Something went wrong'
|
10
|
+
}
|
11
|
+
|
12
|
+
error = Grooveshark::ApiError.new(fault)
|
13
|
+
expect(error.to_s).to eq('25 - Something went wrong')
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
|
3
|
+
require 'grooveshark'
|
4
|
+
|
5
|
+
describe 'Playlist' do
|
6
|
+
it 'should initialize without data' do
|
7
|
+
expect(Grooveshark::Playlist.new(double).id).to be_nil
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should initialize with data' do
|
11
|
+
playlist = Grooveshark::Playlist
|
12
|
+
.new(double,
|
13
|
+
'playlist_id' => '1',
|
14
|
+
'name' => 'something',
|
15
|
+
'about' => 'me',
|
16
|
+
'picture' => 'ruby.jpg',
|
17
|
+
'user_id' => '2',
|
18
|
+
'user_name' => 'PierreRambaud')
|
19
|
+
expect(playlist.id).to eq('1')
|
20
|
+
expect(playlist.name).to eq('something')
|
21
|
+
expect(playlist.about).to eq('me')
|
22
|
+
expect(playlist.picture).to eq('ruby.jpg')
|
23
|
+
expect(playlist.user_id).to eq('2')
|
24
|
+
expect(playlist.username).to eq('PierreRambaud')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should initiliaze without data and user_id' do
|
28
|
+
playlist = Grooveshark::Playlist.new(double, nil, '2')
|
29
|
+
expect(playlist.id).to be_nil
|
30
|
+
expect(playlist.user_id).to be_nil
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should initiliaze with data and user_id' do
|
34
|
+
playlist = Grooveshark::Playlist
|
35
|
+
.new(double, { 'playlist_id' => '1' }, '2')
|
36
|
+
expect(playlist.id).to eq('1')
|
37
|
+
expect(playlist.user_id).to eq('2')
|
38
|
+
end
|
39
|
+
|
40
|
+
it "shouldn't load songs if playlist isn't found" do
|
41
|
+
client = double
|
42
|
+
allow(client).to receive(:request)
|
43
|
+
.with('getPlaylistByID', playlistID: nil).and_return({})
|
44
|
+
expect(Grooveshark::Playlist.new(client).load_songs).to eq([])
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should load songs if playlist is found' do
|
48
|
+
client = double
|
49
|
+
allow(client).to receive(:request)
|
50
|
+
.with('getPlaylistByID', playlistID: nil)
|
51
|
+
.and_return('songs' => ['song_id' => '42',
|
52
|
+
'name' => 'End of days',
|
53
|
+
'artist_name' => 'Vinnie Paz'])
|
54
|
+
songs = Grooveshark::Playlist.new(client).load_songs
|
55
|
+
expect(songs.first).to be_a(Grooveshark::Song)
|
56
|
+
expect(songs.first.to_s).to eq('42 - End of days - Vinnie Paz')
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should rename playlist' do
|
60
|
+
client = double
|
61
|
+
allow(client).to receive(:request)
|
62
|
+
.with('renamePlaylist', playlistID: '2', playlistName: 'GoT')
|
63
|
+
.and_return(true)
|
64
|
+
|
65
|
+
allow(client).to receive(:request)
|
66
|
+
.with('setPlaylistAbout', playlistID: '2', about: 'Description')
|
67
|
+
.and_return(true)
|
68
|
+
|
69
|
+
playlist = Grooveshark::Playlist.new(client, 'playlist_id' => '2')
|
70
|
+
expect(playlist.rename('GoT', 'Description')).to eq(true)
|
71
|
+
expect(playlist.name).to eq('GoT')
|
72
|
+
expect(playlist.about).to eq('Description')
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should return false when rename playlist failed' do
|
76
|
+
client = double
|
77
|
+
allow(client).to receive(:request)
|
78
|
+
.with('renamePlaylist', playlistID: '2', playlistName: 'GoT')
|
79
|
+
.and_raise(ArgumentError)
|
80
|
+
|
81
|
+
playlist = Grooveshark::Playlist.new(client, 'playlist_id' => '2')
|
82
|
+
expect(playlist.rename('GoT', 'Description')).to eq(false)
|
83
|
+
expect(playlist.name).to be_nil
|
84
|
+
expect(playlist.about).to be_nil
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should delete playlist' do
|
88
|
+
client = double
|
89
|
+
allow(client).to receive(:request)
|
90
|
+
.with('deletePlaylist', playlistID: '2', name: 'GoT')
|
91
|
+
.and_return(true)
|
92
|
+
|
93
|
+
playlist = Grooveshark::Playlist.new(client,
|
94
|
+
'playlist_id' => '2',
|
95
|
+
'name' => 'GoT')
|
96
|
+
expect(playlist.delete).to eq(true)
|
97
|
+
end
|
98
|
+
end
|