Class: Drum::MusicService
- Includes:
- Log
- Defined in:
- lib/drum/service/music.rb
Overview
A service that uses AppleScript to interact with the local Apple Music (Music.app) library.
Useful resources:
Instance Method Summary collapse
- 
  
    
      #download(ref)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Service. 
- #get_library_proxy ⇒ Object
- #name ⇒ Object
- 
  
    
      #parse_ref(raw_ref)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Ref parsing. 
- #require_rb_scpt ⇒ Object
- 
  
    
      #to_track_proxy(library_proxy, playlist, track)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Upload helpers. 
- #upload(ref, playlists) ⇒ Object
- #upload_playlist(library_proxy, playlist) ⇒ Object
Methods included from Log
Methods inherited from Service
Instance Method Details
#download(ref) ⇒ Object
Service
| 101 102 103 | # File 'lib/drum/service/music.rb', line 101 def download(ref) raise 'Downloading is not implemented yet' end | 
#get_library_proxy ⇒ Object
| 34 35 36 37 38 39 40 41 42 | # File 'lib/drum/service/music.rb', line 34 def get_library_proxy self.require_rb_scpt music = Appscript.app('Music') source = music.sources[1] unless source.kind.get == :library raise 'Could not get music library source' end return source end | 
#name ⇒ Object
| 22 23 24 | # File 'lib/drum/service/music.rb', line 22 def name 'music' end | 
#parse_ref(raw_ref) ⇒ Object
Ref parsing
| 46 47 48 49 50 51 52 53 54 55 56 | # File 'lib/drum/service/music.rb', line 46 def parse_ref(raw_ref) if raw_ref.is_token location = case raw_ref.text when "#{self.name}/playlists" then :playlists else return nil end Ref.new(self.name, :special, location) else nil end end | 
#require_rb_scpt ⇒ Object
| 26 27 28 29 30 31 32 | # File 'lib/drum/service/music.rb', line 26 def require_rb_scpt begin require 'rb-scpt' rescue LoadError raise "Using the local Apple Music importer requires the 'rb-scpt' gem (which requires macOS)" end end | 
#to_track_proxy(library_proxy, playlist, track) ⇒ Object
Upload helpers
| 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | # File 'lib/drum/service/music.rb', line 60 def to_track_proxy(library_proxy, playlist, track) # Get track metadata name = track.name artists = track.artist_ids.map { |id| playlist.artists[id].name } # Match the track with a track in the local library # TODO: Don't require exact 100% matches name_query = Appscript.its.name.eq(name) artists_query = artists .map { |a| Appscript.its.artist.contains(a) } .reduce { |q1, q2| q1.or(q2) } query = name_query.and(artists_query) # Find a matching track in the track # TODO: Instead of choosing the first, prefer iTunes-matched/higher bitrate ones etc. track_proxy = library_proxy.tracks[query].get.first if track_proxy.nil? log.warn "No match found for '#{track.name}' by '#{artists.first}'" else log.info "Matched '#{track.name}' with '#{track_proxy.name.get}' by '#{track_proxy.artist.get}'" end track_proxy end | 
#upload(ref, playlists) ⇒ Object
| 105 106 107 108 109 110 111 112 113 114 115 | # File 'lib/drum/service/music.rb', line 105 def upload(ref, playlists) library_proxy = self.get_library_proxy unless ref.resource_type == :special && ref.resource_location == :playlists raise "Cannot upload to anything other than @#{self.name}/playlists yet!" end playlists.each do |playlist| self.upload_playlist(library_proxy, playlist) end end | 
#upload_playlist(library_proxy, playlist) ⇒ Object
| 85 86 87 88 89 90 91 92 93 94 95 96 97 | # File 'lib/drum/service/music.rb', line 85 def upload_playlist(library_proxy, playlist) playlist_proxy = library_proxy.make(new: :playlist, with_properties: { name: playlist.name, description: playlist.description, }.compact) playlist.tracks.each do |track| track_proxy = self.to_track_proxy(library_proxy, playlist, track) unless track_proxy.nil? track_proxy.duplicate(to: playlist_proxy) end end end |