napster 0.0.0 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +39 -5
- data/.rubocop.yml +4 -0
- data/README.md +336 -8
- data/Rakefile +3 -3
- data/bin/console +3 -3
- data/lib/napster.rb +27 -4
- data/lib/napster/client.rb +276 -0
- data/lib/napster/me.rb +58 -0
- data/lib/napster/models/album.rb +97 -0
- data/lib/napster/models/artist.rb +93 -0
- data/lib/napster/models/chart.rb +34 -0
- data/lib/napster/models/content.rb +28 -0
- data/lib/napster/models/favorite.rb +130 -0
- data/lib/napster/models/favorite_status.rb +34 -0
- data/lib/napster/models/follower.rb +39 -0
- data/lib/napster/models/following.rb +62 -0
- data/lib/napster/models/library.rb +136 -0
- data/lib/napster/models/library_date_time.rb +33 -0
- data/lib/napster/models/member.rb +124 -0
- data/lib/napster/models/playlist.rb +279 -0
- data/lib/napster/models/profile.rb +75 -0
- data/lib/napster/models/tag.rb +74 -0
- data/lib/napster/models/track.rb +72 -0
- data/lib/napster/models/uploaded_image.rb +36 -0
- data/lib/napster/moniker.rb +29 -0
- data/lib/napster/request.rb +24 -0
- data/lib/napster/response_error.rb +14 -0
- data/lib/napster/version.rb +1 -1
- data/lib/string_helper.rb +10 -0
- data/napster.gemspec +30 -17
- metadata +132 -11
@@ -0,0 +1,93 @@
|
|
1
|
+
using StringHelper
|
2
|
+
|
3
|
+
module Napster
|
4
|
+
module Models
|
5
|
+
# Artist model
|
6
|
+
class Artist
|
7
|
+
ATTRIBUTES = [:type,
|
8
|
+
:id,
|
9
|
+
:href,
|
10
|
+
:name,
|
11
|
+
:shortcut,
|
12
|
+
:blurbs,
|
13
|
+
:bios,
|
14
|
+
:album_groups,
|
15
|
+
:links].freeze
|
16
|
+
|
17
|
+
ATTRIBUTES.each do |attribute|
|
18
|
+
attr_accessor attribute
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_accessor :client
|
22
|
+
|
23
|
+
def initialize(arg)
|
24
|
+
@client = arg[:client] if arg[:client]
|
25
|
+
return unless arg[:data]
|
26
|
+
|
27
|
+
ATTRIBUTES.each do |attribute|
|
28
|
+
send("#{attribute}=", arg[:data][attribute.to_s.camel_case_lower])
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.collection(arg)
|
33
|
+
arg[:data].map do |artist|
|
34
|
+
Artist.new(data: artist, client: arg[:client])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Top level methods
|
39
|
+
|
40
|
+
def top(params)
|
41
|
+
response = @client.get('/artists/top', params: params)
|
42
|
+
Artist.collection(data: response['artists'], client: @client)
|
43
|
+
end
|
44
|
+
|
45
|
+
def find(arg)
|
46
|
+
return find_by_id(arg) if Napster::Moniker.check(arg, :artist)
|
47
|
+
find_by_name(arg)
|
48
|
+
end
|
49
|
+
|
50
|
+
def find_by_id(id)
|
51
|
+
response = @client.get("/artists/#{id}")
|
52
|
+
Artist.new(data: response['artists'].first, client: @client)
|
53
|
+
end
|
54
|
+
|
55
|
+
def find_all_by_name(name)
|
56
|
+
options = {
|
57
|
+
params: {
|
58
|
+
q: name,
|
59
|
+
type: 'artist'
|
60
|
+
}
|
61
|
+
}
|
62
|
+
response = @client.get('/search', options)
|
63
|
+
Artist.collection(data: response['data'], client: @client)
|
64
|
+
end
|
65
|
+
|
66
|
+
def find_by_name(name)
|
67
|
+
find_all_by_name(name).first
|
68
|
+
end
|
69
|
+
|
70
|
+
# Instance methods
|
71
|
+
|
72
|
+
def albums(params)
|
73
|
+
response = @client.get("/artists/#{@id}/albums", params: params)
|
74
|
+
Album.collection(data: response['albums'], client: @client)
|
75
|
+
end
|
76
|
+
|
77
|
+
def new_albums(params)
|
78
|
+
response = @client.get("/artists/#{@id}/albums/new", params: params)
|
79
|
+
Album.collection(data: response['albums'], client: @client)
|
80
|
+
end
|
81
|
+
|
82
|
+
def tracks(params)
|
83
|
+
response = @client.get("/artists/#{@id}/tracks", params: params)
|
84
|
+
Track.collection(data: response['tracks'], client: @client)
|
85
|
+
end
|
86
|
+
|
87
|
+
def top_tracks(params)
|
88
|
+
response = @client.get("/artists/#{@id}/tracks/top", params: params)
|
89
|
+
Track.collection(data: response['tracks'], client: @client)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
using StringHelper
|
2
|
+
|
3
|
+
module Napster
|
4
|
+
module Models
|
5
|
+
# Chart model
|
6
|
+
class Chart
|
7
|
+
ATTRIBUTES = [:id,
|
8
|
+
:play_count,
|
9
|
+
:type,
|
10
|
+
:links].freeze
|
11
|
+
|
12
|
+
ATTRIBUTES.each do |attribute|
|
13
|
+
attr_accessor attribute
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_accessor :client
|
17
|
+
|
18
|
+
def initialize(arg)
|
19
|
+
@client = arg[:client] if arg[:client]
|
20
|
+
return unless arg[:data]
|
21
|
+
|
22
|
+
ATTRIBUTES.each do |attribute|
|
23
|
+
send("#{attribute}=", arg[:data][attribute.to_s.camel_case_lower])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.collection(arg)
|
28
|
+
arg[:data].map do |chart|
|
29
|
+
Chart.new(data: chart, client: @client)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
using StringHelper
|
2
|
+
|
3
|
+
module Napster
|
4
|
+
module Models
|
5
|
+
# Contet model
|
6
|
+
# This model is used for
|
7
|
+
class Content
|
8
|
+
attr_accessor :client
|
9
|
+
|
10
|
+
def self.collection(arg)
|
11
|
+
arg[:data].map do |content|
|
12
|
+
case content['type']
|
13
|
+
when 'album'
|
14
|
+
Album.new(data: content, client: @client)
|
15
|
+
when 'artist'
|
16
|
+
Artist.new(data: content, client: @client)
|
17
|
+
when 'genre'
|
18
|
+
Genre.new(data: content, client: @client)
|
19
|
+
when 'playlist'
|
20
|
+
Playlist.new(data: content, client: @client)
|
21
|
+
when 'track'
|
22
|
+
Track.new(data: content, client: @client)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
using StringHelper
|
2
|
+
|
3
|
+
module Napster
|
4
|
+
module Models
|
5
|
+
# Favorite model
|
6
|
+
class Favorite
|
7
|
+
ATTRIBUTES = [:type,
|
8
|
+
:id,
|
9
|
+
:name,
|
10
|
+
:modified,
|
11
|
+
:href,
|
12
|
+
:privacy,
|
13
|
+
:images,
|
14
|
+
:description,
|
15
|
+
:favorite_count,
|
16
|
+
:free_play_compliant].freeze
|
17
|
+
|
18
|
+
ATTRIBUTES.each do |attribute|
|
19
|
+
attr_accessor attribute
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_accessor :client
|
23
|
+
|
24
|
+
def initialize(arg)
|
25
|
+
@client = arg[:client] if arg[:client]
|
26
|
+
return unless arg[:data]
|
27
|
+
|
28
|
+
ATTRIBUTES.each do |attribute|
|
29
|
+
send("#{attribute}=", arg[:data][attribute.to_s.camel_case_lower])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.collection(arg)
|
34
|
+
arg[:data].map do |favorite|
|
35
|
+
Favorite.new(data: favorite, client: @client)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Top level methods
|
40
|
+
|
41
|
+
def members_who_favorited_albums(id)
|
42
|
+
e = 'Invalid playlist id'
|
43
|
+
raise ArgumentError, e unless Napster::Moniker.check(id, :album)
|
44
|
+
response = @client.get("/albums/#{id}/favorited/members")
|
45
|
+
Member.collection(data: response['members'], client: @client)
|
46
|
+
end
|
47
|
+
|
48
|
+
def members_who_favorited_artists(id)
|
49
|
+
e = 'Invalid playlist id'
|
50
|
+
raise ArgumentError, e unless Napster::Moniker.check(id, :artist)
|
51
|
+
response = @client.get("/artists/#{id}/favorited/members")
|
52
|
+
Member.collection(data: response['members'], client: @client)
|
53
|
+
end
|
54
|
+
|
55
|
+
def member_favorites_for(id)
|
56
|
+
request_member_favorites(id)
|
57
|
+
end
|
58
|
+
|
59
|
+
# /me
|
60
|
+
|
61
|
+
def get(params)
|
62
|
+
get_options = {
|
63
|
+
params: params,
|
64
|
+
headers: {
|
65
|
+
Authorization: 'Bearer ' + @client.access_token,
|
66
|
+
'Content-Type' => 'application/json',
|
67
|
+
'Accept-Version' => '2.0.0'
|
68
|
+
}
|
69
|
+
}
|
70
|
+
response = @client.get('/me/favorites', get_options)
|
71
|
+
Favorite.collection(data: response['favorites'], client: @client)
|
72
|
+
end
|
73
|
+
|
74
|
+
def status(ids)
|
75
|
+
get_options = {
|
76
|
+
params: {
|
77
|
+
ids: ids
|
78
|
+
},
|
79
|
+
headers: {
|
80
|
+
Authorization: 'Bearer ' + @client.access_token,
|
81
|
+
'Content-Type' => 'application/json',
|
82
|
+
'Accept-Version' => '2.0.0'
|
83
|
+
}
|
84
|
+
}
|
85
|
+
response = @client.get('/me/favorites/status', get_options)
|
86
|
+
FavoriteStatus.collection(data: response['status'], client: @client)
|
87
|
+
end
|
88
|
+
|
89
|
+
def add(ids)
|
90
|
+
post_options = {
|
91
|
+
headers: {
|
92
|
+
Authorization: 'Bearer ' + @client.access_token,
|
93
|
+
'Content-Type' => 'application/json',
|
94
|
+
'Accept-Version' => '2.0.0'
|
95
|
+
}
|
96
|
+
}
|
97
|
+
body = prepare_add_favorites_body(ids)
|
98
|
+
@client.post('/me/favorites', Oj.dump(body), post_options)
|
99
|
+
status(ids)
|
100
|
+
end
|
101
|
+
|
102
|
+
def remove(id)
|
103
|
+
delete_options = {
|
104
|
+
headers: {
|
105
|
+
Authorization: 'Bearer ' + @client.access_token,
|
106
|
+
'Content-Type' => 'application/json',
|
107
|
+
'Accept-Version' => '2.0.0'
|
108
|
+
}
|
109
|
+
}
|
110
|
+
@client.delete("/me/favorites/#{id}", delete_options)
|
111
|
+
status([id])
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def request_member_favorites(id)
|
117
|
+
response = @client.get("/favorites/#{id}/members")
|
118
|
+
Member.collection(data: response['members'], client: @client)
|
119
|
+
end
|
120
|
+
|
121
|
+
def prepare_add_favorites_body(ids)
|
122
|
+
favorites_body = []
|
123
|
+
ids.each do |id|
|
124
|
+
favorites_body << { id: id }
|
125
|
+
end
|
126
|
+
{ 'favorites' => favorites_body }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
using StringHelper
|
2
|
+
|
3
|
+
module Napster
|
4
|
+
module Models
|
5
|
+
# FavoriteStatus model
|
6
|
+
class FavoriteStatus
|
7
|
+
ATTRIBUTES = [:total,
|
8
|
+
:id,
|
9
|
+
:tags,
|
10
|
+
:favorite].freeze
|
11
|
+
|
12
|
+
ATTRIBUTES.each do |attribute|
|
13
|
+
attr_accessor attribute
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_accessor :client
|
17
|
+
|
18
|
+
def initialize(arg)
|
19
|
+
@client = arg[:client] if arg[:client]
|
20
|
+
return unless arg[:data]
|
21
|
+
|
22
|
+
ATTRIBUTES.each do |attribute|
|
23
|
+
send("#{attribute}=", arg[:data][attribute.to_s.camel_case_lower])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.collection(arg)
|
28
|
+
arg[:data].map do |favorite_status|
|
29
|
+
FavoriteStatus.new(data: favorite_status, client: @client)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
using StringHelper
|
2
|
+
|
3
|
+
module Napster
|
4
|
+
module Models
|
5
|
+
# Followers model
|
6
|
+
class Follower
|
7
|
+
attr_accessor :client
|
8
|
+
|
9
|
+
def initialize(arg)
|
10
|
+
@client = arg[:client] if arg[:client]
|
11
|
+
end
|
12
|
+
|
13
|
+
def members(params)
|
14
|
+
options = {
|
15
|
+
params: params,
|
16
|
+
headers: {
|
17
|
+
Authorization: 'Bearer ' + @client.access_token,
|
18
|
+
'Content-Type' => 'application/json',
|
19
|
+
'Accept-Version' => '2.0.0'
|
20
|
+
}
|
21
|
+
}
|
22
|
+
response = @client.get('/me/followers', options)
|
23
|
+
Member.collection(data: response['members'], client: @client)
|
24
|
+
end
|
25
|
+
|
26
|
+
def by?(guids)
|
27
|
+
path = "/me/followers/#{guids.join(',')}"
|
28
|
+
options = {
|
29
|
+
headers: {
|
30
|
+
Authorization: 'Bearer ' + @client.access_token,
|
31
|
+
'Content-Type' => 'application/json',
|
32
|
+
'Accept-Version' => '2.0.0'
|
33
|
+
}
|
34
|
+
}
|
35
|
+
@client.get(path, options)['members']
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
using StringHelper
|
2
|
+
|
3
|
+
module Napster
|
4
|
+
module Models
|
5
|
+
# Following model
|
6
|
+
class Following
|
7
|
+
attr_accessor :client
|
8
|
+
|
9
|
+
def initialize(arg)
|
10
|
+
@client = arg[:client] if arg[:client]
|
11
|
+
end
|
12
|
+
|
13
|
+
def members(params)
|
14
|
+
options = {
|
15
|
+
params: params,
|
16
|
+
headers: {
|
17
|
+
Authorization: 'Bearer ' + @client.access_token,
|
18
|
+
'Content-Type' => 'application/json',
|
19
|
+
'Accept-Version' => '2.0.0'
|
20
|
+
}
|
21
|
+
}
|
22
|
+
response = @client.get('/me/following', options)
|
23
|
+
Member.collection(data: response['members'], client: @client)
|
24
|
+
end
|
25
|
+
|
26
|
+
def by?(guids)
|
27
|
+
path = "/me/following/#{guids.join(',')}"
|
28
|
+
options = {
|
29
|
+
headers: {
|
30
|
+
Authorization: 'Bearer ' + @client.access_token,
|
31
|
+
'Content-Type' => 'application/json',
|
32
|
+
'Accept-Version' => '2.0.0'
|
33
|
+
}
|
34
|
+
}
|
35
|
+
@client.get(path, options)['members']
|
36
|
+
end
|
37
|
+
|
38
|
+
def follow(array)
|
39
|
+
body = Oj.dump('members' => array)
|
40
|
+
options = {
|
41
|
+
headers: {
|
42
|
+
Authorization: 'Bearer ' + @client.access_token,
|
43
|
+
'Content-Type' => 'application/json',
|
44
|
+
'Accept-Version' => '2.0.0'
|
45
|
+
}
|
46
|
+
}
|
47
|
+
@client.post('/me/following', body, options)
|
48
|
+
end
|
49
|
+
|
50
|
+
def unfollow(array)
|
51
|
+
options = {
|
52
|
+
headers: {
|
53
|
+
Authorization: 'Bearer ' + @client.access_token,
|
54
|
+
'Content-Type' => 'application/json',
|
55
|
+
'Accept-Version' => '2.0.0'
|
56
|
+
}
|
57
|
+
}
|
58
|
+
@client.delete("/me/following/#{array.join(',')}", options)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
using StringHelper
|
2
|
+
|
3
|
+
module Napster
|
4
|
+
module Models
|
5
|
+
# Library model
|
6
|
+
class Library
|
7
|
+
attr_accessor :client
|
8
|
+
|
9
|
+
def initialize(arg)
|
10
|
+
@client = arg[:client] if arg[:client]
|
11
|
+
end
|
12
|
+
|
13
|
+
def artists(params)
|
14
|
+
get_options = {
|
15
|
+
params: params,
|
16
|
+
headers: {
|
17
|
+
Authorization: 'Bearer ' + @client.access_token,
|
18
|
+
'Content-Type' => 'application/json',
|
19
|
+
'Accept-Version' => '2.0.0'
|
20
|
+
}
|
21
|
+
}
|
22
|
+
response = @client.get('/me/library/artists', get_options)
|
23
|
+
Artist.collection(data: response['artists'], client: @client)
|
24
|
+
end
|
25
|
+
|
26
|
+
def artist_albums(artist_id, params)
|
27
|
+
path = "/me/library/artists/#{artist_id}/albums"
|
28
|
+
get_options = {
|
29
|
+
params: params,
|
30
|
+
headers: {
|
31
|
+
Authorization: 'Bearer ' + @client.access_token,
|
32
|
+
'Content-Type' => 'application/json',
|
33
|
+
'Accept-Version' => '2.0.0'
|
34
|
+
}
|
35
|
+
}
|
36
|
+
response = @client.get(path, get_options)
|
37
|
+
Album.collection(data: response['albums'], client: @client)
|
38
|
+
end
|
39
|
+
|
40
|
+
def artist_tracks(artist_id, params)
|
41
|
+
path = "/me/library/artists/#{artist_id}/tracks"
|
42
|
+
get_options = {
|
43
|
+
params: params,
|
44
|
+
headers: {
|
45
|
+
Authorization: 'Bearer ' + @client.access_token,
|
46
|
+
'Content-Type' => 'application/json',
|
47
|
+
'Accept-Version' => '2.0.0'
|
48
|
+
}
|
49
|
+
}
|
50
|
+
response = @client.get(path, get_options)
|
51
|
+
Track.collection(data: response['tracks'], client: @client)
|
52
|
+
end
|
53
|
+
|
54
|
+
def albums(params)
|
55
|
+
get_options = {
|
56
|
+
params: params,
|
57
|
+
headers: {
|
58
|
+
Authorization: 'Bearer ' + @client.access_token,
|
59
|
+
'Content-Type' => 'application/json',
|
60
|
+
'Accept-Version' => '2.0.0'
|
61
|
+
}
|
62
|
+
}
|
63
|
+
response = @client.get('/me/library/albums', get_options)
|
64
|
+
Album.collection(data: response['albums'], client: @client)
|
65
|
+
end
|
66
|
+
|
67
|
+
def album_tracks(album_id, params)
|
68
|
+
path = "/me/library/albums/#{album_id}/tracks"
|
69
|
+
get_options = {
|
70
|
+
params: params,
|
71
|
+
headers: {
|
72
|
+
Authorization: 'Bearer ' + @client.access_token,
|
73
|
+
'Content-Type' => 'application/json',
|
74
|
+
'Accept-Version' => '2.0.0'
|
75
|
+
}
|
76
|
+
}
|
77
|
+
response = @client.get(path, get_options)
|
78
|
+
Track.collection(data: response['tracks'], client: @client)
|
79
|
+
end
|
80
|
+
|
81
|
+
def tracks(params)
|
82
|
+
get_options = {
|
83
|
+
params: params,
|
84
|
+
headers: {
|
85
|
+
Authorization: 'Bearer ' + @client.access_token,
|
86
|
+
'Content-Type' => 'application/json',
|
87
|
+
'Accept-Version' => '2.0.0'
|
88
|
+
}
|
89
|
+
}
|
90
|
+
response = @client.get('/me/library/tracks', get_options)
|
91
|
+
Track.collection(data: response['tracks'], client: @client)
|
92
|
+
end
|
93
|
+
|
94
|
+
def add_track(tracks)
|
95
|
+
e = 'tracks argument should be an array.'
|
96
|
+
raise ArgumentError, e unless tracks.class == Array
|
97
|
+
|
98
|
+
tracks = tracks.join(',')
|
99
|
+
options = {
|
100
|
+
params: { id: tracks },
|
101
|
+
headers: {
|
102
|
+
Authorization: 'Bearer ' + @client.access_token,
|
103
|
+
'Content-Type' => 'application/json',
|
104
|
+
'Accept-Version' => '2.0.0'
|
105
|
+
}
|
106
|
+
}
|
107
|
+
@client.post('/me/library/tracks', '{}', options)
|
108
|
+
end
|
109
|
+
|
110
|
+
def remove_track(track_id)
|
111
|
+
path = "/me/library/tracks/#{track_id}"
|
112
|
+
options = {
|
113
|
+
headers: {
|
114
|
+
Authorization: 'Bearer ' + @client.access_token,
|
115
|
+
'Content-Type' => 'application/json',
|
116
|
+
'Accept-Version' => '2.0.0'
|
117
|
+
}
|
118
|
+
}
|
119
|
+
@client.delete(path, options)
|
120
|
+
end
|
121
|
+
|
122
|
+
def last_updated_date
|
123
|
+
path = '/me/library/updated'
|
124
|
+
options = {
|
125
|
+
headers: {
|
126
|
+
Authorization: 'Bearer ' + @client.access_token,
|
127
|
+
'Content-Type' => 'application/json',
|
128
|
+
'Accept-Version' => '2.0.0'
|
129
|
+
}
|
130
|
+
}
|
131
|
+
response = @client.get(path, options)
|
132
|
+
LibraryDateTime.new(data: response['lastUpdateDate'], client: @client)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|