apple_music_library 0.3.0 → 0.6.0

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
  SHA256:
3
- metadata.gz: 840cb609f61bcb54a260d57acc3e6f5ff4ac72acbaf582bba56aeb1cc1b4bcd7
4
- data.tar.gz: 9987bdbcf17275cdddc99ec4fa81f815932ffe394eb1e9d48b98bfd68016c1c2
3
+ metadata.gz: 63c39fb0820781890a73912185de50cd207af719b59d25a022626374f1ab8eac
4
+ data.tar.gz: 99d363ef519977c4b2786684e539289a58cf76503e397c34c7060f42a02c52aa
5
5
  SHA512:
6
- metadata.gz: aa00cf271b73e5465a5c383a85002071211f615bbd6244977f2480bff5e3c44f783d46fcd050db5702958b84e24a27c3195b8e2987062213a065ec21a962365f
7
- data.tar.gz: 6d1f93fc11f8dc2e7a64e0a94c073b5aac70e5e5ee3389e17b7ca3d02b86b329069f3c507bbca9d93c9ba1576cf1394809e0913918f9e59e56d8b29d4aec3482
6
+ metadata.gz: e8f45294602867c1de2a10ad3dbe1d88ad02508dc6060712c0cdb436e032c93ea5eb35f69eb0a9e9f1c5dae98089666d8928919f140b668d1c8980b11a7ec517
7
+ data.tar.gz: d0724a89d0d22c4be3a65550253284e176102e3c2c2f085ace60418516ba333ed7ebbdc25fda382ee18303d47bf29eeef256b533b231c733813f473c3c28a3a5
data/CHANGELOG.md ADDED
@@ -0,0 +1,28 @@
1
+ # Changelog
2
+
3
+ ## [Unreleased]
4
+ - Ability to print out playlist folder hierarchy
5
+
6
+ ## 0.6.0 - 2022-03-11
7
+ ### Added
8
+ - Ability to sort list top artists by play count
9
+
10
+ ## 0.5.0 - 2022-03-11
11
+ ### Added
12
+ - Basic functionality for track ratings via the #rating, #star_rating, and #loved
13
+
14
+ ## 0.4.0 - 2022-03-11
15
+ ### Added
16
+ - Basic functionality for Playlist Folders
17
+ ### Fixed
18
+ - The #find_by_name methods for Playlists and PlaylistFolders now return a single object when only a single exact match is found (the most common case) but continue to return an array of objects when there are multiple matches.
19
+
20
+ ## 0.3.0 - 2022-03-10
21
+
22
+ ### Fixed
23
+ - Fixed handling of albums, genres, and playlists as accessed via methods on artists/tracks.
24
+
25
+ ## 0.2.0 - 2022-03-10
26
+ ### Added
27
+ - Basic functionality to parse a library plist into Track, Album, Artist, Genre, and Playlist objects.
28
+
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- apple_music_library (0.3.0)
4
+ apple_music_library (0.6.0)
5
5
  facets (~> 3.1)
6
6
  plist (~> 3.6)
7
7
 
data/README.md CHANGED
@@ -28,6 +28,12 @@ library = AppleMusicLibrary.new('path/to/Library.xml')
28
28
  # Count albums
29
29
  puts library.albums.count
30
30
 
31
+ # Show playlist inside playlist folder
32
+ playlist_folder = library.playlist_folder('Folder for Testing')
33
+ playlist_folder.playlists.each do |playlist|
34
+ puts playlist.name
35
+ end
36
+
31
37
  # Show tracks in a specific playlist
32
38
  playlist = library.playlist('XTC Favorites')
33
39
  playlist.tracks.each do |track|
@@ -38,6 +44,14 @@ end
38
44
  artist = library.artist('XTC')
39
45
  puts artist.tracks.count
40
46
 
47
+ # Get favorite tracks by this artist
48
+ favorite_tracks = artist.tracks.select{|t| t.loved? || t.star_rating > 3}
49
+
50
+ # List out the most played artists
51
+ library.artists(:most_played).each do |artist|
52
+ puts "#{artist.play_count} :: #{artist.name}"
53
+ end
54
+
41
55
  # Display track counts per genre
42
56
  library.genres.each do |genre|
43
57
  puts "#{genre.tracks.count} #{genre.name}"
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Todd Gehman"]
9
9
  spec.email = ["github@pugetive.com"]
10
10
 
11
- spec.summary = "Provides a ruby OO interface to the information stored in an Apple Music (formerly iTunes) Library xml file."
11
+ spec.summary = "Provides a Ruby interface to the information stored in an Apple Music (formerly iTunes) Library xml file."
12
12
  # spec.description = "TODO: Write a longer description or delete this line."
13
13
  spec.homepage = "https://github.com/pugetive/apple_music_library"
14
14
  spec.license = "MIT"
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
 
19
19
  spec.metadata["homepage_uri"] = spec.homepage
20
20
  spec.metadata["source_code_uri"] = "https://github.com/pugetive/apple_music_library"
21
- # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
21
+ spec.metadata["changelog_uri"] = "https://github.com/pugetive/apple_music_library/blob/main/CHANGELOG.md"
22
22
 
23
23
  # Specify which files should be added to the gem when it is released.
24
24
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -15,6 +15,14 @@ module AppleMusicLibrary
15
15
  @@artists.values
16
16
  end
17
17
 
18
+ def self.most_played(limit = 20)
19
+ if limit.nil?
20
+ self.all.sort_by(&:play_count).reverse
21
+ else
22
+ self.all.sort_by(&:play_count).reverse.take(limit)
23
+ end
24
+ end
25
+
18
26
  def self.find_or_create(name)
19
27
  if @@artists[name]
20
28
  return @@artists[name]
@@ -49,5 +57,9 @@ module AppleMusicLibrary
49
57
  @tracks
50
58
  end
51
59
 
60
+ def play_count
61
+ tracks.map(&:play_count).sum
62
+ end
63
+
52
64
  end
53
65
  end
@@ -2,6 +2,7 @@ require_relative 'album'
2
2
  require_relative 'artist'
3
3
  require_relative 'genre'
4
4
  require_relative 'playlist'
5
+ require_relative 'playlist_folder'
5
6
  require_relative 'track'
6
7
  require_relative "utils"
7
8
  require 'plist'
@@ -43,8 +44,8 @@ module AppleMusicLibrary
43
44
  @albums ||= Album.all
44
45
  end
45
46
 
46
- def artists
47
- @artists ||= Artist.all
47
+ def artists(filter = nil, limit = nil)
48
+ filter.present? ? Artist.send(filter, limit) : Artist.all
48
49
  end
49
50
 
50
51
  def artist(artist_name)
@@ -67,8 +68,16 @@ module AppleMusicLibrary
67
68
  Playlist.find_by_name(playlist_name)
68
69
  end
69
70
 
70
- def tracks
71
- @tracks ||= Track.all
71
+ def playlist_folders
72
+ @playlist_folders ||= PlaylistFolder.all
73
+ end
74
+
75
+ def playlist_folder(playlist_folder_name)
76
+ PlaylistFolder.find_by_name(playlist_folder_name)
77
+ end
78
+
79
+ def tracks(filter = nil)
80
+ filter.present? ? Track.send(filter) : Track.all
72
81
  end
73
82
 
74
83
  def track(track_id)
@@ -108,89 +117,12 @@ module AppleMusicLibrary
108
117
 
109
118
  def extract_playlists_from_plist
110
119
  plist['Playlists'].each do |playlist_info|
111
- Playlist.new(playlist_info, self)
120
+ # The distinction between playlists and playlist folders
121
+ # is made inside the Playlist instantiation
122
+ Playlist.new(playlist_info)
112
123
  end
113
124
  end
114
125
 
115
-
116
-
117
-
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
193
-
194
126
  end
195
127
 
196
128
  end
@@ -1,17 +1,3 @@
1
- # <key>Name</key><string>Non-XTC</string>
2
- # <key>Description</key><string></string>
3
- # <key>Playlist ID</key><integer>79359</integer>
4
- # <key>Playlist Persistent ID</key><string>59C95825DF1F0DCC</string>
5
- # <key>All Items</key><true/>
6
- # <key>Smart Info</key>
7
- # <data>
8
- # AQEAAwAAAAIAAAAZAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
9
- # AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
10
- # AAAAAA==
11
- # </data>
12
- # <key>Smart Criteria</key>
13
- # <data>
14
-
15
1
  require 'facets'
16
2
 
17
3
  module AppleMusicLibrary
@@ -25,18 +11,20 @@ module AppleMusicLibrary
25
11
  'Description',
26
12
  'Playlist ID',
27
13
  'Playlist Persistent ID',
14
+ 'Parent Persistent ID',
28
15
  'All Items',
29
16
  'Smart Info',
30
17
  'Smart Criteria',
31
18
  'Playlist Items',
32
19
  'Folder']
33
20
 
34
- def initialize(info, library)
21
+ def initialize(info)
35
22
  @info = info
36
23
 
37
- return nil if folder?
24
+ if folder?
25
+ return PlaylistFolder.new(info)
26
+ end
38
27
 
39
- @library = library
40
28
  @tracks = []
41
29
 
42
30
  load_tracks
@@ -49,11 +37,15 @@ module AppleMusicLibrary
49
37
  end
50
38
 
51
39
  def self.find_by_name(playlist_name)
52
- @@playlists.values.select{|p| p.name == playlist_name}
40
+ results = @@playlists.values.select{|p| p.name == playlist_name}
41
+ if results.size == 1
42
+ return results.first
43
+ end
44
+ results
53
45
  end
54
46
 
55
47
  def id
56
- playlist_id
48
+ playlist_persistent_id
57
49
  end
58
50
 
59
51
  ATTRIBUTES.each do |attribute|
@@ -72,7 +64,7 @@ module AppleMusicLibrary
72
64
  if playlist_items and playlist_items.any?
73
65
  playlist_items.each do |playlist_item|
74
66
  track_id = playlist_item['Track ID']
75
- track = @library.track(track_id)
67
+ track = Track.find(track_id)
76
68
  @tracks << track
77
69
  end
78
70
  end
@@ -81,3 +73,18 @@ module AppleMusicLibrary
81
73
 
82
74
  end
83
75
  end
76
+
77
+ # <key>Name</key><string>Non-XTC</string>
78
+ # <key>Description</key><string></string>
79
+ # <key>Playlist ID</key><integer>79359</integer>
80
+ # <key>Playlist Persistent ID</key><string>59C95825DF1F0DCC</string>
81
+ # <key>All Items</key><true/>
82
+ # <key>Smart Info</key>
83
+ # <data>
84
+ # AQEAAwAAAAIAAAAZAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
85
+ # AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
86
+ # AAAAAA==
87
+ # </data>
88
+ # <key>Smart Criteria</key>
89
+ # <data>
90
+
@@ -0,0 +1,55 @@
1
+ require 'facets'
2
+
3
+ module AppleMusicLibrary
4
+ class PlaylistFolder
5
+
6
+ attr_reader :info
7
+
8
+ @@playlist_folders = {}
9
+
10
+ def initialize(info)
11
+ @info = info
12
+
13
+ @@playlist_folders[id] = self
14
+ end
15
+
16
+ def self.all
17
+ @@playlist_folders.values
18
+ end
19
+
20
+ def self.find_by_name(playlist_folder_name)
21
+ results = @@playlist_folders.values.select{|pf| pf.name == playlist_folder_name}
22
+ if results.size == 1
23
+ return results.first
24
+ end
25
+ results
26
+ end
27
+
28
+ def id
29
+ playlist_persistent_id
30
+ end
31
+
32
+ def children
33
+ playlist_folders.concat(playlists)
34
+ end
35
+
36
+ def playlist_folders
37
+ @@playlist_folders.values.select{|pf| pf.parent_persistent_id == id}
38
+ end
39
+
40
+ def playlists
41
+ Playlist.all.select{|p| p.parent_persistent_id == id}
42
+ end
43
+
44
+ Playlist::ATTRIBUTES.each do |attribute|
45
+ define_method(attribute.to_s.snakecase) do
46
+ info[attribute]
47
+ end
48
+ end
49
+
50
+
51
+ private
52
+
53
+
54
+ end
55
+ end
@@ -24,6 +24,7 @@ module AppleMusicLibrary
24
24
  'Rating',
25
25
  'Album Rating',
26
26
  'Album Rating Computed',
27
+ 'Loved',
27
28
  'Normalization',
28
29
  'Persistent ID',
29
30
  'Track Type',
@@ -55,6 +56,10 @@ module AppleMusicLibrary
55
56
  @@tracks.values
56
57
  end
57
58
 
59
+ def self.loved
60
+ @loved ||= self.all.select{|t| t.loved?}
61
+ end
62
+
58
63
  def id
59
64
  track_id
60
65
  end
@@ -71,6 +76,14 @@ module AppleMusicLibrary
71
76
  @info['Genre']
72
77
  end
73
78
 
79
+ def star_rating
80
+ rating / 20
81
+ end
82
+
83
+ def loved?
84
+ loved
85
+ end
86
+
74
87
  ATTRIBUTES.each do |track_attribute|
75
88
  define_method(track_attribute.to_s.snakecase) do
76
89
  @info[track_attribute]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AppleMusicLibrary
4
- VERSION = "0.3.0"
4
+ VERSION = "0.6.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apple_music_library
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Todd Gehman
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-10 00:00:00.000000000 Z
11
+ date: 2022-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: awesome_print
@@ -116,6 +116,7 @@ extensions: []
116
116
  extra_rdoc_files: []
117
117
  files:
118
118
  - ".rspec"
119
+ - CHANGELOG.md
119
120
  - Gemfile
120
121
  - Gemfile.lock
121
122
  - LICENSE.txt
@@ -128,6 +129,7 @@ files:
128
129
  - lib/apple_music_library/genre.rb
129
130
  - lib/apple_music_library/library.rb
130
131
  - lib/apple_music_library/playlist.rb
132
+ - lib/apple_music_library/playlist_folder.rb
131
133
  - lib/apple_music_library/track.rb
132
134
  - lib/apple_music_library/utils.rb
133
135
  - lib/apple_music_library/version.rb
@@ -138,6 +140,7 @@ licenses:
138
140
  metadata:
139
141
  homepage_uri: https://github.com/pugetive/apple_music_library
140
142
  source_code_uri: https://github.com/pugetive/apple_music_library
143
+ changelog_uri: https://github.com/pugetive/apple_music_library/blob/main/CHANGELOG.md
141
144
  post_install_message:
142
145
  rdoc_options: []
143
146
  require_paths:
@@ -156,6 +159,6 @@ requirements: []
156
159
  rubygems_version: 3.3.3
157
160
  signing_key:
158
161
  specification_version: 4
159
- summary: Provides a ruby OO interface to the information stored in an Apple Music
160
- (formerly iTunes) Library xml file.
162
+ summary: Provides a Ruby interface to the information stored in an Apple Music (formerly
163
+ iTunes) Library xml file.
161
164
  test_files: []