napster 0.0.0 → 0.1.0
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 +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
|