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

Compare commits

..

No commits in common. "00253815a043faf81487a5a53a672f64335dc5fe" and "146ef71b6cc54c9a01cc32cc980fdc4093ace8f4" have entirely different histories.

14 changed files with 51 additions and 121 deletions

View File

@ -53,7 +53,6 @@
E450ADA12229E7C90091BED3 /* PMKFoundation.framework.dSYM in Resources */ = {isa = PBXBuildFile; fileRef = E450AD9F2229E7C90091BED3 /* PMKFoundation.framework.dSYM */; }; E450ADA12229E7C90091BED3 /* PMKFoundation.framework.dSYM in Resources */ = {isa = PBXBuildFile; fileRef = E450AD9F2229E7C90091BED3 /* PMKFoundation.framework.dSYM */; };
E450ADA32229E7E00091BED3 /* PMKFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E450ADA02229E7C90091BED3 /* PMKFoundation.framework */; }; E450ADA32229E7E00091BED3 /* PMKFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E450ADA02229E7C90091BED3 /* PMKFoundation.framework */; };
E450ADA42229E7E00091BED3 /* PMKFoundation.framework in Embed Libraries */ = {isa = PBXBuildFile; fileRef = E450ADA02229E7C90091BED3 /* PMKFoundation.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; E450ADA42229E7E00091BED3 /* PMKFoundation.framework in Embed Libraries */ = {isa = PBXBuildFile; fileRef = E450ADA02229E7C90091BED3 /* PMKFoundation.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
E45962C62241A78500FC1A1E /* Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = E45962C52241A78500FC1A1E /* Command.swift */; };
E465049A21E94DF500A70F4C /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E465049921E94DF500A70F4C /* WindowController.swift */; }; E465049A21E94DF500A70F4C /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E465049921E94DF500A70F4C /* WindowController.swift */; };
E47E2FCC2220573500F747E6 /* MediaKeyTap.framework.dSYM in Resources */ = {isa = PBXBuildFile; fileRef = E47E2FCB2220573500F747E6 /* MediaKeyTap.framework.dSYM */; }; E47E2FCC2220573500F747E6 /* MediaKeyTap.framework.dSYM in Resources */ = {isa = PBXBuildFile; fileRef = E47E2FCB2220573500F747E6 /* MediaKeyTap.framework.dSYM */; };
E47E2FD122205C4600F747E6 /* MainSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47E2FD022205C4600F747E6 /* MainSplitViewController.swift */; }; E47E2FD122205C4600F747E6 /* MainSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47E2FD022205C4600F747E6 /* MainSplitViewController.swift */; };
@ -211,7 +210,6 @@
E450AD9E2229B9BC0091BED3 /* PersephoneBridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PersephoneBridgingHeader.h; sourceTree = "<group>"; }; E450AD9E2229B9BC0091BED3 /* PersephoneBridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PersephoneBridgingHeader.h; sourceTree = "<group>"; };
E450AD9F2229E7C90091BED3 /* PMKFoundation.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = PMKFoundation.framework.dSYM; path = Carthage/Build/Mac/PMKFoundation.framework.dSYM; sourceTree = "<group>"; }; E450AD9F2229E7C90091BED3 /* PMKFoundation.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = PMKFoundation.framework.dSYM; path = Carthage/Build/Mac/PMKFoundation.framework.dSYM; sourceTree = "<group>"; };
E450ADA02229E7C90091BED3 /* PMKFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PMKFoundation.framework; path = Carthage/Build/Mac/PMKFoundation.framework; sourceTree = "<group>"; }; E450ADA02229E7C90091BED3 /* PMKFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PMKFoundation.framework; path = Carthage/Build/Mac/PMKFoundation.framework; sourceTree = "<group>"; };
E45962C52241A78500FC1A1E /* Command.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Command.swift; sourceTree = "<group>"; };
E465049921E94DF500A70F4C /* WindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = "<group>"; }; E465049921E94DF500A70F4C /* WindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = "<group>"; };
E47E2FCB2220573500F747E6 /* MediaKeyTap.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = MediaKeyTap.framework.dSYM; path = Carthage/Build/Mac/MediaKeyTap.framework.dSYM; sourceTree = "<group>"; }; E47E2FCB2220573500F747E6 /* MediaKeyTap.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = MediaKeyTap.framework.dSYM; path = Carthage/Build/Mac/MediaKeyTap.framework.dSYM; sourceTree = "<group>"; };
E47E2FD022205C4600F747E6 /* MainSplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainSplitViewController.swift; sourceTree = "<group>"; }; E47E2FD022205C4600F747E6 /* MainSplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainSplitViewController.swift; sourceTree = "<group>"; };
@ -514,7 +512,6 @@
E4EB2378220F10B8008C70C0 /* Pair.swift */, E4EB2378220F10B8008C70C0 /* Pair.swift */,
E4EB237A220F7CF1008C70C0 /* Album.swift */, E4EB237A220F7CF1008C70C0 /* Album.swift */,
E4C8B53D22349002009A20F3 /* Idle.swift */, E4C8B53D22349002009A20F3 /* Idle.swift */,
E45962C52241A78500FC1A1E /* Command.swift */,
); );
path = Models; path = Models;
sourceTree = "<group>"; sourceTree = "<group>";
@ -735,7 +732,6 @@
E450AD7E222620A10091BED3 /* AlbumItem.swift in Sources */, E450AD7E222620A10091BED3 /* AlbumItem.swift in Sources */,
E4E8CC942206097F0024217A /* NotificationsController.swift in Sources */, E4E8CC942206097F0024217A /* NotificationsController.swift in Sources */,
E408D3B6220DD8970006D9BE /* Notification.swift in Sources */, E408D3B6220DD8970006D9BE /* Notification.swift in Sources */,
E45962C62241A78500FC1A1E /* Command.swift in Sources */,
E408D3B9220DE98F0006D9BE /* NSUserInterfaceItemIdentifier.swift in Sources */, E408D3B9220DE98F0006D9BE /* NSUserInterfaceItemIdentifier.swift in Sources */,
E4EB2379220F10B8008C70C0 /* Pair.swift in Sources */, E4EB2379220F10B8008C70C0 /* Pair.swift in Sources */,
E4F6B463221E125900ACF42A /* SongItem.swift in Sources */, E4F6B463221E125900ACF42A /* SongItem.swift in Sources */,

View File

@ -11,15 +11,15 @@ import mpdclient
extension MPDClient { extension MPDClient {
func fetchAllAlbums() { func fetchAllAlbums() {
enqueueCommand(command: .fetchAllAlbums) queueCommand(command: .fetchAllAlbums)
} }
func playAlbum(_ album: Album) { func playAlbum(_ album: Album) {
enqueueCommand(command: .playAlbum, userData: ["album": album]) queueCommand(command: .playAlbum, userData: ["album": album])
} }
func getAlbumURI(for album: Album, callback: @escaping (String?) -> Void) { func getAlbumURI(for album: Album, callback: @escaping (String?) -> Void) {
enqueueCommand( queueCommand(
command: .getAlbumURI, command: .getAlbumURI,
priority: .low, priority: .low,
userData: ["album": album, "callback": callback] userData: ["album": album, "callback": callback]

View File

@ -54,22 +54,4 @@ extension MPDClient {
albumURI(for: album, callback: callback) albumURI(for: album, callback: callback)
} }
} }
func enqueueCommand(
command: Command,
priority: BlockOperation.QueuePriority = .normal,
userData: Dictionary<String, Any> = [:]
) {
guard isConnected else { return }
noIdle()
let commandOperation = BlockOperation() { [unowned self] in
self.sendCommand(command: command, userData: userData)
self.idle()
}
commandOperation.queuePriority = priority
commandQueue.addOperation(commandOperation)
}
} }

View File

@ -18,7 +18,7 @@ extension MPDClient {
} }
func idle() { func idle() {
if !self.isIdle && self.commandQueue.operationCount == 1 { if !self.isIdle && self.commandsQueued == 0 {
mpd_send_idle(self.connection) mpd_send_idle(self.connection)
self.isIdle = true self.isIdle = true

View File

@ -15,7 +15,7 @@ extension MPDClient {
} }
func playTrack(at queuePos: Int) { func playTrack(at queuePos: Int) {
enqueueCommand(command: .playTrack, userData: ["queuePos": queuePos]) queueCommand(command: .playTrack, userData: ["queuePos": queuePos])
} }
func sendPlayTrack(at queuePos: Int) { func sendPlayTrack(at queuePos: Int) {

View File

@ -11,23 +11,23 @@ import mpdclient
extension MPDClient { extension MPDClient {
func playPause() { func playPause() {
enqueueCommand(command: .playPause) queueCommand(command: .playPause)
} }
func stop() { func stop() {
enqueueCommand(command: .stop) queueCommand(command: .stop)
} }
func prevTrack() { func prevTrack() {
enqueueCommand(command: .prevTrack) queueCommand(command: .prevTrack)
} }
func nextTrack() { func nextTrack() {
enqueueCommand(command: .nextTrack) queueCommand(command: .nextTrack)
} }
func seekCurrentSong(timeInSeconds: Float) { func seekCurrentSong(timeInSeconds: Float) {
enqueueCommand( queueCommand(
command: .seekCurrentSong, command: .seekCurrentSong,
userData: ["timeInSeconds": timeInSeconds] userData: ["timeInSeconds": timeInSeconds]
) )

View File

@ -19,9 +19,36 @@ class MPDClient {
var queue: [Song] = [] var queue: [Song] = []
let commandQueue = OperationQueue() let commandQueue = OperationQueue()
var commandsQueued: UInt = 0
enum Command {
case prevTrack, nextTrack, playPause, stop, seekCurrentSong,
fetchStatus, fetchQueue, playTrack, fetchAllAlbums,
playAlbum, getAlbumURI
}
init(withDelegate delegate: MPDClientDelegate?) { init(withDelegate delegate: MPDClientDelegate?) {
commandQueue.maxConcurrentOperationCount = 1 commandQueue.maxConcurrentOperationCount = 1
self.delegate = delegate self.delegate = delegate
} }
func queueCommand(
command: Command,
priority: BlockOperation.QueuePriority = .normal,
userData: Dictionary<String, Any> = [:]
) {
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)
}
} }

View File

@ -1,32 +0,0 @@
//
// Command.swift
// Persephone
//
// Created by Daniel Barber on 2019/3/19.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import Foundation
extension MPDClient {
enum Command {
// Transport commands
case prevTrack
case nextTrack
case playPause
case stop
case seekCurrentSong
// Status commands
case fetchStatus
// Queue commands
case fetchQueue
case playTrack
// Album commands
case fetchAllAlbums
case playAlbum
case getAlbumURI
}
}

View File

@ -62,15 +62,6 @@ struct Preferences {
return NSString(string: mpdLibraryDirOrDefault).expandingTildeInPath return NSString(string: mpdLibraryDirOrDefault).expandingTildeInPath
} }
var fetchMissingArtworkFromInternet: Bool {
get {
return preferences.bool(forKey: "fetchMissingArtworkFromInternet")
}
set {
preferences.set(newValue, forKey: "fetchMissingArtworkFromInternet")
}
}
func addObserver(_ observer: NSObject, forKeyPath keyPath: String) { func addObserver(_ observer: NSObject, forKeyPath keyPath: String) {
preferences.addObserver(observer, forKeyPath: keyPath, options: .new, context: nil) preferences.addObserver(observer, forKeyPath: keyPath, options: .new, context: nil)
} }

View File

@ -18,12 +18,6 @@ class AlbumArtPrefsController: NSViewController {
mpdLibraryDirField.stringValue = mpdLibraryDir mpdLibraryDirField.stringValue = mpdLibraryDir
} }
if preferences.fetchMissingArtworkFromInternet {
fetchMissingArtworkFromInternet.state = .on
} else {
fetchMissingArtworkFromInternet.state = .off
}
preferredContentSize = NSMakeSize(view.frame.size.width, view.frame.size.height) preferredContentSize = NSMakeSize(view.frame.size.width, view.frame.size.height)
} }
@ -40,14 +34,4 @@ class AlbumArtPrefsController: NSViewController {
} }
@IBOutlet var mpdLibraryDirField: NSTextField! @IBOutlet var mpdLibraryDirField: NSTextField!
@IBAction func updateFetchMissingArtworkFromInternet(_ sender: NSButton) {
if sender.state == .on {
preferences.fetchMissingArtworkFromInternet = true
} else {
preferences.fetchMissingArtworkFromInternet = false
}
}
@IBOutlet var fetchMissingArtworkFromInternet: NSButton!
} }

View File

@ -326,9 +326,6 @@
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/> <behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
</buttonCell> </buttonCell>
<connections>
<action selector="updateFetchMissingArtworkFromInternet:" target="3C9-vU-zjZ" id="I7x-9V-xJr"/>
</connections>
</button> </button>
</subviews> </subviews>
<constraints> <constraints>
@ -342,7 +339,6 @@
</constraints> </constraints>
</view> </view>
<connections> <connections>
<outlet property="fetchMissingArtworkFromInternet" destination="pRL-MG-1Be" id="Xcp-sb-iZm"/>
<outlet property="mpdLibraryDirField" destination="gDk-ca-eOa" id="myi-BQ-0NS"/> <outlet property="mpdLibraryDirField" destination="gDk-ca-eOa" id="myi-BQ-0NS"/>
</connections> </connections>
</viewController> </viewController>

View File

@ -9,12 +9,11 @@
import Cocoa import Cocoa
class AlbumArtService: NSObject { class AlbumArtService: NSObject {
var preferences = Preferences()
let cachedArtworkSize = 180 let cachedArtworkSize = 180
let cachedArtworkQuality: CGFloat = 0.5 let cachedArtworkQuality: CGFloat = 0.5
static var shared = AlbumArtService() static var shared = AlbumArtService()
var preferences = Preferences()
var session = URLSession(configuration: .default) var session = URLSession(configuration: .default)
let cacheQueue = DispatchQueue(label: "albumArtCacheQueue", attributes: .concurrent) let cacheQueue = DispatchQueue(label: "albumArtCacheQueue", attributes: .concurrent)

View File

@ -12,9 +12,7 @@ extension AlbumArtService {
func getArtworkFromFilesystem( func getArtworkFromFilesystem(
for album: AlbumItem, for album: AlbumItem,
callback: @escaping (_ image: NSImage) -> Void callback: @escaping (_ image: NSImage) -> Void
) { ) {
var tryImage: NSImage?
let coverArtFilenames = [ let coverArtFilenames = [
"folder.jpg", "folder.jpg",
"cover.jpg", "cover.jpg",
@ -31,9 +29,7 @@ extension AlbumArtService {
for coverArtFilename in coverArtFilenames { for coverArtFilename in coverArtFilenames {
let coverArtURI = "\(fullAlbumURI)/\(coverArtFilename)" let coverArtURI = "\(fullAlbumURI)/\(coverArtFilename)"
tryImage = self.tryImage(coverArtURI) if let image = self.tryImage(coverArtURI) {
if let image = tryImage {
self.cacheArtwork( self.cacheArtwork(
for: album, for: album,
data: image.jpegData(compressionQuality: self.cachedArtworkQuality) data: image.jpegData(compressionQuality: self.cachedArtworkQuality)
@ -42,10 +38,6 @@ extension AlbumArtService {
break break
} }
} }
if tryImage == nil && self.preferences.fetchMissingArtworkFromInternet {
self.getRemoteArtwork(for: album, callback: callback)
}
} }
AppDelegate.mpdClient.getAlbumURI( AppDelegate.mpdClient.getAlbumURI(
@ -55,15 +47,17 @@ extension AlbumArtService {
} }
func tryImage(_ filePath: String) -> NSImage? { func tryImage(_ filePath: String) -> NSImage? {
guard FileManager.default.fileExists(atPath: filePath), if FileManager.default.fileExists(atPath: filePath),
let data = FileManager.default.contents(atPath: filePath), let data = FileManager.default.contents(atPath: filePath),
let image = NSImage(data: data) let image = NSImage(data: data) {
else { return nil }
let imageThumb = image.toFitBox( let imageThumb = image.toFitBox(
size: NSSize(width: self.cachedArtworkSize, height: self.cachedArtworkSize) size: NSSize(width: self.cachedArtworkSize, height: self.cachedArtworkSize)
) )
return imageThumb return imageThumb
} else {
return nil
}
} }
} }

View File

@ -40,15 +40,8 @@ extension AlbumArtService {
let url = urlComponents!.url let url = urlComponents!.url
return URLSession.shared.dataTask(.promise, with: url!).validate() return URLSession.shared.dataTask(.promise, with: url!).validate()
}.compactMap { }.compactMap {
NSImage(data: $0.data)?.toFitBox( self.cacheArtwork(for: album, data: $0.data)
size: NSSize(width: self.cachedArtworkSize, height: self.cachedArtworkSize) return NSImage(data: $0.data)
)
}.compactMap {
self.cacheArtwork(
for: album,
data: $0.jpegData(compressionQuality: self.cachedArtworkQuality)
)
return $0
}.done { }.done {
callback($0) callback($0)
}.catch { }.catch {