apple_music_library 0.3.0 → 0.6.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 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: []