1
1
mirror of https://github.com/danbee/persephone synced 2025-03-04 08:39:11 +00:00

Refactor the album art code to use promises

This commit is contained in:
Daniel Barber 2019-03-03 17:27:12 -05:00
parent 4ff0ff6e9b
commit 38431702d2
Signed by: danbarber
GPG Key ID: 931D8112E0103DD8

View File

@ -14,10 +14,10 @@ import PMKFoundation
class AlbumArtService: NSObject { class AlbumArtService: NSObject {
static var shared = AlbumArtService() static var shared = AlbumArtService()
var session = URLSession(configuration: .default) var session = URLSession(configuration: .default)
let cacheQueue = DispatchQueue(label: "albumArtCacheQueue", attributes: .concurrent) let albumArtQueue = DispatchQueue(label: "albumArtCacheQueue", attributes: .concurrent)
func fetchAlbumArt(for album: AlbumItem, callback: @escaping (_ image: NSImage) -> Void) { func fetchAlbumArt(for album: AlbumItem, callback: @escaping (_ image: NSImage) -> Void) {
cacheQueue.async { albumArtQueue.async {
if !self.getCachedArtwork(for: album, callback: callback) { if !self.getCachedArtwork(for: album, callback: callback) {
self.getRemoteArtwork(for: album, callback: callback) self.getRemoteArtwork(for: album, callback: callback)
} }
@ -35,7 +35,7 @@ class AlbumArtService: NSObject {
if FileManager.default.fileExists(atPath: cacheFilePath) { if FileManager.default.fileExists(atPath: cacheFilePath) {
guard let data = FileManager.default.contents(atPath: cacheFilePath), guard let data = FileManager.default.contents(atPath: cacheFilePath),
let image = NSImage(data: data) let image = NSImage(data: data)
else { return false } else { return true }
callback(image) callback(image)
@ -65,50 +65,32 @@ class AlbumArtService: NSObject {
} }
func getArtworkFromMusicBrainz(for album: AlbumItem, callback: @escaping (_ image: NSImage) -> Void) { func getArtworkFromMusicBrainz(for album: AlbumItem, callback: @escaping (_ image: NSImage) -> Void) {
if var urlComponents = URLComponents(string: "https://musicbrainz.org/ws/2/release/") { guard var urlComponents = URLComponents(string: "https://musicbrainz.org/ws/2/release/")
urlComponents.query = "query=artist:\(album.artist) AND release:\(album.title) AND country:US&limit=1&fmt=json" else { return }
guard let searchURL = urlComponents.url urlComponents.query = "query=artist:\(album.artist) AND release:\(album.title) AND country:US&limit=1&fmt=json"
else { return }
let releaseTask = session.dataTask(with: searchURL) { data, response, error in guard let searchURL = urlComponents.url
if let _ = error { else { return }
return
}
guard let httpResponse = response as? HTTPURLResponse, firstly {
(200...299).contains(httpResponse.statusCode) else { URLSession.shared.dataTask(.promise, with: searchURL).validate()
return }.compactMap {
} JSON($0.data)
}.compactMap {
if let mimeType = httpResponse.mimeType, mimeType == "application/json", $0["releases"][0]["id"].string
let data = data, }.compactMap {
let json = try? JSON(data: data) { URLComponents(string: "https://coverartarchive.org/release/\($0)/front-500")
}.then { (urlComponents: URLComponents?) -> Promise<(data: Data, response: URLResponse)> in
let releaseId = json["releases"][0]["id"] let url = urlComponents!.url
return URLSession.shared.dataTask(.promise, with: url!).validate()
let coverURL = URLComponents(string: "https://coverartarchive.org/release/\(releaseId)/front-500") }.compactMap {
self.cacheArtwork(for: album, data: $0.data)
let coverArtTask = self.session.dataTask(with: coverURL!.url!) { data, response, error in return NSImage(data: $0.data)
}.done {
guard let httpResponse = response as? HTTPURLResponse, callback($0)
(200...299).contains(httpResponse.statusCode) else { }.catch { (error: Error) in
return self.cacheArtwork(for: album, data: Data())
}
if let mimeType = httpResponse.mimeType, mimeType == "image/jpeg",
let data = data,
let coverImage = NSImage(data: data) {
self.cacheArtwork(for: album, data: data)
callback(coverImage)
}
}
coverArtTask.resume()
}
}
releaseTask.resume()
} }
} }
} }