From 0306f9e9b50070da861c292fafc00441389139ef Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Sat, 16 Mar 2019 19:53:37 -0400 Subject: [PATCH] Now gets artwork from filesystem! --- .../Extensions/MPDClient+Album.swift | 23 ++++++---- .../Extensions/MPDClient+Command.swift | 6 ++- .../MPDClient/Extensions/MPDClient+Idle.swift | 14 +++--- Persephone/MPDClient/MPDClient.swift | 4 +- Persephone/Models/Preferences.swift | 4 ++ Persephone/Services/AlbumArtService.swift | 43 +++++++++++++++---- 6 files changed, 64 insertions(+), 30 deletions(-) diff --git a/Persephone/MPDClient/Extensions/MPDClient+Album.swift b/Persephone/MPDClient/Extensions/MPDClient+Album.swift index 12240bf..4c5a719 100644 --- a/Persephone/MPDClient/Extensions/MPDClient+Album.swift +++ b/Persephone/MPDClient/Extensions/MPDClient+Album.swift @@ -18,8 +18,12 @@ extension MPDClient { queueCommand(command: .playAlbum, userData: ["album": album]) } - func getAlbumURI(for album: Album) { - queueCommand(command: .getAlbumURI, userData: ["album": album]) + func getAlbumURI(for album: Album, callback: @escaping (String?) -> Void) { + queueCommand( + command: .getAlbumURI, + priority: .low, + userData: ["album": album, "callback": callback] + ) } func sendPlayAlbum(_ album: Album) { @@ -65,30 +69,31 @@ extension MPDClient { self.delegate?.didLoadAlbums(mpdClient: self, albums: albums) } - func albumURI(for album: Album) -> String? { + func albumURI(for album: Album, callback: (String?) -> Void) { var songURI: String? - guard isConnected else { return nil } + guard isConnected else { return } - print("Getting URI") mpd_search_db_songs(self.connection, true) mpd_search_add_tag_constraint(self.connection, MPD_OPERATOR_DEFAULT, MPD_TAG_ALBUM, album.title) mpd_search_add_tag_constraint(self.connection, MPD_OPERATOR_DEFAULT, MPD_TAG_ALBUM_ARTIST, album.artist) mpd_search_add_tag_constraint(self.connection, MPD_OPERATOR_DEFAULT, MPD_TAG_TRACK, "1") mpd_search_commit(self.connection) - print("Performed search") while let mpdSong = mpd_recv_song(self.connection) { let song = Song(mpdSong) - print(song) if songURI == nil { songURI = song.uriString } } - print("Got URI") - return songURI + callback( + songURI? + .split(separator: "/") + .dropLast() + .joined(separator: "/") + ) } } diff --git a/Persephone/MPDClient/Extensions/MPDClient+Command.swift b/Persephone/MPDClient/Extensions/MPDClient+Command.swift index 8a857ef..2fdbb49 100644 --- a/Persephone/MPDClient/Extensions/MPDClient+Command.swift +++ b/Persephone/MPDClient/Extensions/MPDClient+Command.swift @@ -38,8 +38,10 @@ extension MPDClient { guard let album = userData["album"] as? Album else { return } sendPlayAlbum(album) case .getAlbumURI: - guard let album = userData["album"] as? Album else { return } - _ = getAlbumURI(for: album) + guard let album = userData["album"] as? Album, + let callback = userData["callback"] as? (String?) -> Void + else { return } + albumURI(for: album, callback: callback) } } } diff --git a/Persephone/MPDClient/Extensions/MPDClient+Idle.swift b/Persephone/MPDClient/Extensions/MPDClient+Idle.swift index 60e6df5..4ad127a 100644 --- a/Persephone/MPDClient/Extensions/MPDClient+Idle.swift +++ b/Persephone/MPDClient/Extensions/MPDClient+Idle.swift @@ -18,17 +18,13 @@ extension MPDClient { } func idle() { - let idleOperation = BlockOperation { - if !self.isIdle && self.commandsQueued == 0 { - mpd_send_idle(self.connection) - self.isIdle = true + if !self.isIdle && self.commandsQueued == 0 { + mpd_send_idle(self.connection) + self.isIdle = true - let result = mpd_recv_idle(self.connection, true) - self.handleIdleResult(result) - } + let result = mpd_recv_idle(self.connection, true) + self.handleIdleResult(result) } - idleOperation.queuePriority = .veryLow - commandQueue.addOperation(idleOperation) } func handleIdleResult(_ result: mpd_idle) { diff --git a/Persephone/MPDClient/MPDClient.swift b/Persephone/MPDClient/MPDClient.swift index 5eb7309..611dab8 100644 --- a/Persephone/MPDClient/MPDClient.swift +++ b/Persephone/MPDClient/MPDClient.swift @@ -40,13 +40,15 @@ class MPDClient { guard isConnected else { return } noIdle() + let commandOperation = BlockOperation() { [unowned self] in self.commandsQueued -= 1 self.sendCommand(command: command, userData: userData) + + self.idle() } commandOperation.queuePriority = priority commandsQueued += 1 commandQueue.addOperation(commandOperation) - idle() } } diff --git a/Persephone/Models/Preferences.swift b/Persephone/Models/Preferences.swift index 1ab491f..94926c9 100644 --- a/Persephone/Models/Preferences.swift +++ b/Persephone/Models/Preferences.swift @@ -58,6 +58,10 @@ struct Preferences { return mpdLibraryDir ?? mpdLibraryDirDefault } + var expandedMpdLibraryDir: String { + return NSString(string: mpdLibraryDirOrDefault).expandingTildeInPath + } + func addObserver(_ observer: NSObject, forKeyPath keyPath: String) { preferences.addObserver(observer, forKeyPath: keyPath, options: .new, context: nil) } diff --git a/Persephone/Services/AlbumArtService.swift b/Persephone/Services/AlbumArtService.swift index b40eadf..62c91f1 100644 --- a/Persephone/Services/AlbumArtService.swift +++ b/Persephone/Services/AlbumArtService.swift @@ -13,18 +13,16 @@ import PMKFoundation class AlbumArtService: NSObject { static var shared = AlbumArtService() + var preferences = Preferences() var session = URLSession(configuration: .default) let cacheQueue = DispatchQueue(label: "albumArtCacheQueue", attributes: .concurrent) - let filesystemQueue = DispatchQueue(label: "albumArtFilesystemQueue", attributes: .concurrent) func fetchAlbumArt(for album: AlbumItem, callback: @escaping (_ image: NSImage) -> Void) { cacheQueue.async { [unowned self] in //print("Trying cache") if !self.getCachedArtwork(for: album, callback: callback) { -// self.filesystemQueue.async { -// _ = self.getArtworkFromFilesystem(for: album, callback: callback) -// } + self.getArtworkFromFilesystem(for: album, callback: callback) // if !self.getArtworkFromFilesystem(for: album, callback: callback) { // // self.getRemoteArtwork(for: album, callback: callback) // } @@ -53,11 +51,38 @@ class AlbumArtService: NSObject { } } - func getArtworkFromFilesystem(for album: AlbumItem, callback: @escaping (_ image: NSImage) -> Void) -> Bool { - print("No cache trying filesystem") - let uri = AppDelegate.mpdClient.getAlbumURI(for: album.album) - print(uri) - return false + func getArtworkFromFilesystem( + for album: AlbumItem, + callback: @escaping (_ image: NSImage) -> Void + ) { + let coverArtFilenames = [ + "folder.jpg", + "cover.jpg", + "\(album.artist) - \(album.title).jpg" + ] + + AppDelegate.mpdClient.getAlbumURI( + for: album.album, + callback: { (_ albumURI: String?) in + guard let albumURI = albumURI + else { return } + + let musicDir = self.preferences.expandedMpdLibraryDir + let fullAlbumURI = "\(musicDir)/\(albumURI)" + + for coverArtFilename in coverArtFilenames { + let coverArtURI = "\(fullAlbumURI)/\(coverArtFilename)" + + if FileManager.default.fileExists(atPath: coverArtURI), + let data = FileManager.default.contents(atPath: coverArtURI), + let image = NSImage(data: data) { + self.cacheArtwork(for: album, data: data) + callback(image) + break + } + } + } + ) } func cacheArtwork(for album: AlbumItem, data: Data) {