apple_music_library 0.2.0 → 0.3.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/Gemfile.lock +1 -1
- data/lib/apple_music_library/album.rb +15 -1
- data/lib/apple_music_library/artist.rb +29 -3
- data/lib/apple_music_library/genre.rb +17 -0
- data/lib/apple_music_library/library.rb +101 -81
- data/lib/apple_music_library/playlist.rb +15 -0
- data/lib/apple_music_library/track.rb +29 -12
- data/lib/apple_music_library/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 840cb609f61bcb54a260d57acc3e6f5ff4ac72acbaf582bba56aeb1cc1b4bcd7
|
4
|
+
data.tar.gz: 9987bdbcf17275cdddc99ec4fa81f815932ffe394eb1e9d48b98bfd68016c1c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa00cf271b73e5465a5c383a85002071211f615bbd6244977f2480bff5e3c44f783d46fcd050db5702958b84e24a27c3195b8e2987062213a065ec21a962365f
|
7
|
+
data.tar.gz: 6d1f93fc11f8dc2e7a64e0a94c073b5aac70e5e5ee3389e17b7ca3d02b86b329069f3c507bbca9d93c9ba1576cf1394809e0913918f9e59e56d8b29d4aec3482
|
data/Gemfile.lock
CHANGED
@@ -5,12 +5,26 @@ module AppleMusicLibrary
|
|
5
5
|
|
6
6
|
attr_reader :artist, :album_name, :tracks
|
7
7
|
|
8
|
+
@@albums = {}
|
9
|
+
|
8
10
|
def initialize(artist, album_name)
|
9
11
|
@artist = artist
|
10
12
|
@album_name = album_name
|
11
13
|
@tracks = []
|
12
14
|
end
|
13
15
|
|
16
|
+
def self.all
|
17
|
+
@@albums.values
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.find_or_create(artist, album_name)
|
21
|
+
key = "#{artist.name}-#{album_name}"
|
22
|
+
if @@albums[key]
|
23
|
+
return @@albums[key]
|
24
|
+
end
|
25
|
+
@@albums[key] = self.new(artist, album_name)
|
26
|
+
end
|
27
|
+
|
14
28
|
def id
|
15
29
|
"#{artist.name}-#{album_name}"
|
16
30
|
end
|
@@ -20,7 +34,7 @@ module AppleMusicLibrary
|
|
20
34
|
end
|
21
35
|
|
22
36
|
def year
|
23
|
-
@year ||= tracks.
|
37
|
+
@year ||= @tracks.sort_by(&:year).last.year
|
24
38
|
end
|
25
39
|
|
26
40
|
end
|
@@ -3,24 +3,50 @@ module AppleMusicLibrary
|
|
3
3
|
|
4
4
|
attr_reader :name
|
5
5
|
|
6
|
+
@@artists = {}
|
7
|
+
|
6
8
|
def initialize(name)
|
7
9
|
@name = name
|
8
10
|
@albums = []
|
11
|
+
@tracks = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.all
|
15
|
+
@@artists.values
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.find_or_create(name)
|
19
|
+
if @@artists[name]
|
20
|
+
return @@artists[name]
|
21
|
+
end
|
22
|
+
@@artists[name] = self.new(name)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.find_by_name(artist_name)
|
26
|
+
if @@artists[artist_name]
|
27
|
+
return @@artists[artist_name]
|
28
|
+
end
|
29
|
+
nil
|
9
30
|
end
|
10
31
|
|
11
32
|
def add_album(album)
|
12
|
-
unless albums.include?(album)
|
33
|
+
unless @albums.include?(album)
|
13
34
|
@albums << album
|
14
35
|
end
|
15
36
|
end
|
16
37
|
|
38
|
+
def add_track(track)
|
39
|
+
unless @tracks.include?(track)
|
40
|
+
@tracks << track
|
41
|
+
end
|
42
|
+
end
|
17
43
|
|
18
44
|
def albums
|
19
|
-
@albums.
|
45
|
+
@albums.sort_by(&:year)
|
20
46
|
end
|
21
47
|
|
22
48
|
def tracks
|
23
|
-
@tracks
|
49
|
+
@tracks
|
24
50
|
end
|
25
51
|
|
26
52
|
end
|
@@ -3,11 +3,28 @@ module AppleMusicLibrary
|
|
3
3
|
|
4
4
|
attr_reader :name, :tracks
|
5
5
|
|
6
|
+
@@genres = {}
|
7
|
+
|
6
8
|
def initialize(name)
|
7
9
|
@name = name
|
8
10
|
@tracks = []
|
9
11
|
end
|
10
12
|
|
13
|
+
def self.all
|
14
|
+
@@genres.values
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.find_or_create(name)
|
18
|
+
if @@genres[name]
|
19
|
+
return @@genres[name]
|
20
|
+
end
|
21
|
+
@@genres[name] = self.new(name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.find_by_name(name)
|
25
|
+
@@genres[name]
|
26
|
+
end
|
27
|
+
|
11
28
|
def add_track(track)
|
12
29
|
unless tracks.include?(track)
|
13
30
|
@tracks << track
|
@@ -36,53 +36,43 @@ module AppleMusicLibrary
|
|
36
36
|
raise Error, "Failed to parse library xml file [#{e.message}]"
|
37
37
|
end
|
38
38
|
|
39
|
-
@artists_hash = {}
|
40
|
-
@tracks_hash = {}
|
41
|
-
@playlists_hash = {}
|
42
|
-
@albums_hash = {}
|
43
|
-
@genres_hash = {}
|
44
|
-
|
45
|
-
@locations_hash = {}
|
46
|
-
@slugs_hash = {}
|
47
|
-
|
48
39
|
extract_plist_info
|
49
40
|
end
|
50
41
|
|
51
|
-
def
|
52
|
-
@
|
42
|
+
def albums
|
43
|
+
@albums ||= Album.all
|
53
44
|
end
|
54
45
|
|
55
46
|
def artists
|
56
|
-
@
|
47
|
+
@artists ||= Artist.all
|
57
48
|
end
|
58
49
|
|
59
50
|
def artist(artist_name)
|
60
|
-
|
51
|
+
Artist.find_by_name(artist_name)
|
61
52
|
end
|
62
53
|
|
63
|
-
def
|
64
|
-
@
|
54
|
+
def genres
|
55
|
+
@genres ||= Genre.all
|
65
56
|
end
|
66
57
|
|
67
|
-
def
|
68
|
-
|
58
|
+
def genre(genre_name)
|
59
|
+
Genre.find_by_name(genre_name)
|
69
60
|
end
|
70
61
|
|
71
|
-
def
|
72
|
-
playlists
|
62
|
+
def playlists
|
63
|
+
@playlists ||= Playlist.all
|
73
64
|
end
|
74
65
|
|
75
|
-
|
76
|
-
|
77
|
-
@albums_hash.values
|
66
|
+
def playlist(playlist_name)
|
67
|
+
Playlist.find_by_name(playlist_name)
|
78
68
|
end
|
79
69
|
|
80
|
-
def
|
81
|
-
@
|
70
|
+
def tracks
|
71
|
+
@tracks ||= Track.all
|
82
72
|
end
|
83
73
|
|
84
|
-
def
|
85
|
-
|
74
|
+
def track(track_id)
|
75
|
+
Track.find(track_id)
|
86
76
|
end
|
87
77
|
|
88
78
|
def valid?
|
@@ -93,83 +83,113 @@ module AppleMusicLibrary
|
|
93
83
|
tracks.any?
|
94
84
|
end
|
95
85
|
|
96
|
-
def track(track_id)
|
97
|
-
track = @tracks_hash[track_id.to_i]
|
98
|
-
if track.nil?
|
99
|
-
message("Cound not find track with ID [#{track_id}]")
|
100
|
-
message("Searched tracks: [#{@tracks_hash.keys.sort.join(', ')}]")
|
101
|
-
end
|
102
|
-
track
|
103
|
-
end
|
104
|
-
|
105
86
|
private
|
106
87
|
|
107
88
|
def extract_plist_info
|
89
|
+
extract_tracks_from_plist
|
90
|
+
extract_playlists_from_plist
|
91
|
+
end
|
92
|
+
|
93
|
+
def extract_tracks_from_plist
|
108
94
|
non_music_formats = {}
|
109
95
|
plist['Tracks'].each do |track|
|
110
96
|
if MUSIC_FORMATS.include?(track[1]['Kind'])
|
111
|
-
|
112
|
-
# next if track.artist.name == 'NPR'
|
113
|
-
@tracks_hash[track.id] = track
|
114
|
-
# @locations_hash[track.location] = track
|
115
|
-
|
116
|
-
artist = add_artist(track.artist)
|
117
|
-
album = add_track_to_album(track, track.album)
|
118
|
-
artist.add_album(album)
|
119
|
-
|
120
|
-
if track.genre_name.present?
|
121
|
-
genre = add_track_to_genre(track)
|
122
|
-
end
|
97
|
+
Track.new(track[1])
|
123
98
|
else
|
124
99
|
non_music_formats[track[1]['Kind']] = true
|
125
100
|
end
|
126
101
|
end
|
127
102
|
|
128
|
-
plist['Playlists'].each do |playlist_info|
|
129
|
-
playlist = Playlist.new(playlist_info, self)
|
130
|
-
next if playlist.folder?
|
131
|
-
@playlists_hash[playlist.id] = playlist
|
132
|
-
end
|
133
|
-
|
134
103
|
if non_music_formats.any?
|
135
104
|
message("Skipped the following non-music formats:\n#{non_music_formats.keys.join(', ')}")
|
136
105
|
end
|
137
|
-
end
|
138
106
|
|
107
|
+
end
|
139
108
|
|
140
|
-
def
|
141
|
-
|
142
|
-
|
109
|
+
def extract_playlists_from_plist
|
110
|
+
plist['Playlists'].each do |playlist_info|
|
111
|
+
Playlist.new(playlist_info, self)
|
143
112
|
end
|
144
|
-
artist
|
145
113
|
end
|
146
114
|
|
147
|
-
def add_track_to_album(track, album)
|
148
|
-
return if @albums_hash[album.id]
|
149
|
-
# message("Creating new artist #{artist.name}")
|
150
|
-
@albums_hash[album.id] = album
|
151
|
-
album.add_track(track)
|
152
|
-
album
|
153
|
-
end
|
154
115
|
|
155
|
-
def find_or_create_album(album)
|
156
|
-
unless @albums_hash[album.id]
|
157
|
-
@albums_hash[album.id] = album
|
158
|
-
end
|
159
|
-
album.artist.add_album(album)
|
160
|
-
end
|
161
116
|
|
162
117
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
118
|
+
|
119
|
+
# def track(track_id)
|
120
|
+
# track = @tracks_hash[track_id.to_i]
|
121
|
+
# if track.nil?
|
122
|
+
# message("Cound not find track with ID [#{track_id}]")
|
123
|
+
# message("Searched tracks: [#{@tracks_hash.keys.sort.join(', ')}]")
|
124
|
+
# end
|
125
|
+
# track
|
126
|
+
# end
|
127
|
+
|
128
|
+
# private
|
129
|
+
|
130
|
+
# def extract_plist_info
|
131
|
+
# non_music_formats = {}
|
132
|
+
# plist['Tracks'].each do |track|
|
133
|
+
# if MUSIC_FORMATS.include?(track[1]['Kind'])
|
134
|
+
# track = Track.new(track[1])
|
135
|
+
# # next if track.artist.name == 'NPR'
|
136
|
+
# @tracks_hash[track.id] = track
|
137
|
+
# # @locations_hash[track.location] = track
|
138
|
+
|
139
|
+
# artist = Artist.find_or_create(track.artist_name)
|
140
|
+
# album = add_track_to_album(track, track.album)
|
141
|
+
# artist.add_album(album)
|
142
|
+
|
143
|
+
# if track.genre_name.present?
|
144
|
+
# genre = add_track_to_genre(track)
|
145
|
+
# end
|
146
|
+
# else
|
147
|
+
# non_music_formats[track[1]['Kind']] = true
|
148
|
+
# end
|
149
|
+
# end
|
150
|
+
|
151
|
+
# plist['Playlists'].each do |playlist_info|
|
152
|
+
# playlist = Playlist.new(playlist_info, self)
|
153
|
+
# next if playlist.folder?
|
154
|
+
# @playlists_hash[playlist.id] = playlist
|
155
|
+
# end
|
156
|
+
|
157
|
+
# if non_music_formats.any?
|
158
|
+
# message("Skipped the following non-music formats:\n#{non_music_formats.keys.join(', ')}")
|
159
|
+
# end
|
160
|
+
# end
|
161
|
+
|
162
|
+
|
163
|
+
# def add_artist(artist)
|
164
|
+
# Artist.find_or_create(artist_name)
|
165
|
+
# end
|
166
|
+
|
167
|
+
# def add_track_to_album(track, album)
|
168
|
+
# unless album = @albums_hash[album.id]
|
169
|
+
# @albums_hash[album.id] = album
|
170
|
+
# end
|
171
|
+
# album.add_track(track)
|
172
|
+
# album
|
173
|
+
# end
|
174
|
+
|
175
|
+
# def find_or_create_album(album)
|
176
|
+
# unless @albums_hash[album.id]
|
177
|
+
# @albums_hash[album.id] = album
|
178
|
+
# end
|
179
|
+
# album.artist.add_album(album)
|
180
|
+
# end
|
181
|
+
|
182
|
+
|
183
|
+
# def add_track_to_genre(track)
|
184
|
+
# if @genres_hash[track.genre_name]
|
185
|
+
# return @genres_hash[track.genre_name]
|
186
|
+
# end
|
187
|
+
# # message("Creating new artist #{artist.name}")
|
188
|
+
# genre = AppleMusicLibrary::Genre.new(track.genre_name)
|
189
|
+
# @genres_hash[track.genre_name] = genre
|
190
|
+
# genre.add_track(track)
|
191
|
+
# genre
|
192
|
+
# end
|
173
193
|
|
174
194
|
end
|
175
195
|
|
@@ -19,6 +19,8 @@ module AppleMusicLibrary
|
|
19
19
|
|
20
20
|
attr_reader :info, :tracks
|
21
21
|
|
22
|
+
@@playlists = {}
|
23
|
+
|
22
24
|
ATTRIBUTES = ['Name',
|
23
25
|
'Description',
|
24
26
|
'Playlist ID',
|
@@ -31,10 +33,23 @@ module AppleMusicLibrary
|
|
31
33
|
|
32
34
|
def initialize(info, library)
|
33
35
|
@info = info
|
36
|
+
|
37
|
+
return nil if folder?
|
38
|
+
|
34
39
|
@library = library
|
35
40
|
@tracks = []
|
36
41
|
|
37
42
|
load_tracks
|
43
|
+
|
44
|
+
@@playlists[id] = self
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.all
|
48
|
+
@@playlists.values
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.find_by_name(playlist_name)
|
52
|
+
@@playlists.values.select{|p| p.name == playlist_name}
|
38
53
|
end
|
39
54
|
|
40
55
|
def id
|
@@ -2,13 +2,13 @@ require 'facets'
|
|
2
2
|
|
3
3
|
module AppleMusicLibrary
|
4
4
|
class Track
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :artist, :album, :genre
|
6
6
|
|
7
|
-
ATTRIBUTES = ['Track ID',
|
8
|
-
'Name',
|
9
7
|
# 'Artist', The #artist, #album, and #genre methods return objects rather than strings and have methods like #artist_name to retrieve the strings.
|
10
8
|
# 'Album',
|
11
9
|
# 'Genre',
|
10
|
+
ATTRIBUTES = ['Track ID',
|
11
|
+
'Name',
|
12
12
|
'Kind',
|
13
13
|
'Size',
|
14
14
|
'Total Time',
|
@@ -31,10 +31,28 @@ module AppleMusicLibrary
|
|
31
31
|
'File Folder Count',
|
32
32
|
'Library Folder Count']
|
33
33
|
|
34
|
+
@@tracks = {}
|
35
|
+
|
34
36
|
def initialize(info)
|
35
37
|
@info = info
|
36
|
-
@artist = Artist.
|
37
|
-
@album = Album.
|
38
|
+
@artist = Artist.find_or_create(artist_name)
|
39
|
+
@album = Album.find_or_create(@artist, album_name)
|
40
|
+
@genre = Genre.find_or_create(genre_name)
|
41
|
+
|
42
|
+
@artist.add_track(self)
|
43
|
+
@artist.add_album(@album)
|
44
|
+
@album.add_track(self)
|
45
|
+
@genre.add_track(self)
|
46
|
+
@@tracks[id] = self
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
def self.find(track_id)
|
51
|
+
@@tracks[track_id]
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.all
|
55
|
+
@@tracks.values
|
38
56
|
end
|
39
57
|
|
40
58
|
def id
|
@@ -42,22 +60,21 @@ module AppleMusicLibrary
|
|
42
60
|
end
|
43
61
|
|
44
62
|
def artist_name
|
45
|
-
info['Artist']
|
63
|
+
@info['Artist']
|
46
64
|
end
|
47
65
|
|
48
66
|
def album_name
|
49
|
-
info['Album']
|
67
|
+
@info['Album']
|
50
68
|
end
|
51
69
|
|
52
70
|
def genre_name
|
53
|
-
info['Genre']
|
71
|
+
@info['Genre']
|
54
72
|
end
|
55
73
|
|
56
|
-
ATTRIBUTES.each do |
|
57
|
-
define_method(
|
58
|
-
info[
|
74
|
+
ATTRIBUTES.each do |track_attribute|
|
75
|
+
define_method(track_attribute.to_s.snakecase) do
|
76
|
+
@info[track_attribute]
|
59
77
|
end
|
60
|
-
|
61
78
|
end
|
62
79
|
|
63
80
|
# def slug
|