Skip to content

Commit

Permalink
Many more fixes for 0.5
Browse files Browse the repository at this point in the history
  • Loading branch information
glouel committed Aug 10, 2020
1 parent fff3cd1 commit 811433c
Show file tree
Hide file tree
Showing 16 changed files with 381 additions and 172 deletions.
8 changes: 4 additions & 4 deletions AerialUpdater.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
03592ABC24CC821500C1AE52 /* Update.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03592ABB24CC821500C1AE52 /* Update.swift */; };
03592ABE24CC86E900C1AE52 /* CachedManifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03592ABD24CC86E900C1AE52 /* CachedManifest.swift */; };
035F6F1C24CC8D97002E4EEE /* ErrorLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035F6F1B24CC8D97002E4EEE /* ErrorLog.swift */; };
03ADA8EC24E034A40093D0A2 /* LaunchAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03ADA8EB24E034A40093D0A2 /* LaunchAgent.swift */; };
03CE4F5924CB0CA700494D32 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CE4F5824CB0CA700494D32 /* AppDelegate.swift */; };
03CE4F5B24CB0CA700494D32 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CE4F5A24CB0CA700494D32 /* ViewController.swift */; };
03CE4F5D24CB0CA900494D32 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 03CE4F5C24CB0CA900494D32 /* Assets.xcassets */; };
03CE4F6024CB0CA900494D32 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 03CE4F5E24CB0CA900494D32 /* Main.storyboard */; };
03CE4F7E24CB43FE00494D32 /* Manifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CE4F7D24CB43FE00494D32 /* Manifest.swift */; };
Expand All @@ -51,9 +51,9 @@
03592ABB24CC821500C1AE52 /* Update.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Update.swift; sourceTree = "<group>"; };
03592ABD24CC86E900C1AE52 /* CachedManifest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CachedManifest.swift; sourceTree = "<group>"; };
035F6F1B24CC8D97002E4EEE /* ErrorLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorLog.swift; sourceTree = "<group>"; };
03ADA8EB24E034A40093D0A2 /* LaunchAgent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchAgent.swift; sourceTree = "<group>"; };
03CE4F5524CB0CA700494D32 /* AerialUpdater.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AerialUpdater.app; sourceTree = BUILT_PRODUCTS_DIR; };
03CE4F5824CB0CA700494D32 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
03CE4F5A24CB0CA700494D32 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
03CE4F5C24CB0CA900494D32 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
03CE4F5F24CB0CA900494D32 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
03CE4F6124CB0CA900494D32 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -107,6 +107,7 @@
0333115A24D85D4600E4622D /* UpdaterVersion.swift */,
03592ABB24CC821500C1AE52 /* Update.swift */,
0319460524CDBD2600F37B35 /* BackgroundCheck.swift */,
03ADA8EB24E034A40093D0A2 /* LaunchAgent.swift */,
);
path = Model;
sourceTree = "<group>";
Expand Down Expand Up @@ -156,7 +157,6 @@
03CE4F5E24CB0CA900494D32 /* Main.storyboard */,
03CE4F6124CB0CA900494D32 /* Info.plist */,
03CE4F6224CB0CA900494D32 /* AerialUpdater.entitlements */,
03CE4F5A24CB0CA700494D32 /* ViewController.swift */,
03592AB624CC80A600C1AE52 /* Model */,
031A3A6924D835B90011E738 /* New Group */,
);
Expand Down Expand Up @@ -245,13 +245,13 @@
0333115924D85CCA00E4622D /* String+version.swift in Sources */,
03592AB524CC809F00C1AE52 /* LocalVersion.swift in Sources */,
03592ABE24CC86E900C1AE52 /* CachedManifest.swift in Sources */,
03CE4F5B24CB0CA700494D32 /* ViewController.swift in Sources */,
03592ABC24CC821500C1AE52 /* Update.swift in Sources */,
0333115624D8448E00E4622D /* MenuViewController.swift in Sources */,
03592AB824CC80FD00C1AE52 /* Helpers.swift in Sources */,
0333115E24D8796F00E4622D /* UpdateCheckWindowController.swift in Sources */,
03592AB224CC765500C1AE52 /* Preferences.swift in Sources */,
03CE4F5924CB0CA700494D32 /* AppDelegate.swift in Sources */,
03ADA8EC24E034A40093D0A2 /* LaunchAgent.swift in Sources */,
03CE4F8024CB4CFB00494D32 /* FileDownloader.swift in Sources */,
035F6F1C24CC8D97002E4EEE /* ErrorLog.swift in Sources */,
);
Expand Down
74 changes: 61 additions & 13 deletions AerialUpdater/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,68 @@ class AppDelegate: NSObject, NSApplicationDelegate {

// MARK: - Lifecycle
func applicationDidFinishLaunching(_ aNotification: Notification) {
debugLog("Version \(Helpers.version) launched")
debugLog("Version \(Helpers.version) launched on \(ProcessInfo.processInfo.operatingSystemVersionString)")

// TODO detect launch params
let arguments = ProcessInfo.processInfo.arguments

// This is imperative, breaks everything
ensureNotInstalledForAllUsers()

if arguments.contains("--silent") {
debugLog("Background mode")

// Returns true if we need to stay around
if !silentModeCheck() {
return
}
// We're staying then !
debugLog("Falling back to menu for a notification")
}

// Menu mode, we may fall down here from silent mode too in notify mode,
// or if we must update

// Set the icon
setIcon(mode: .normal)

createMenu()
}

// This returns true if we should stay around, and false if we can safely return
func silentModeCheck() -> Bool {
Update.instance.commandLine = true

// Force a cache update
CachedManifest.instance.updateNow()

// Make sure we don't need to update, or redirect you there
if UpdaterVersion.needsUpdating() {
return true // Then stay around !
}

// Ensure we don't have something in /Library/Screen Savers/
let (stringVersion, shouldInstall) = Update.instance.check()

if shouldInstall {
debugLog(stringVersion)
if Preferences.updateMode == .automatic {
Update.instance.unattendedPerform()
return false // We are done
} else {
return true // Stay around !
}
} else {
// We need to stay around for a bit, because if not
// launchd will think we are crashing...
debugLog("No new version, quitting in 20sec.")
RunLoop.main.run(until: Date() + 0x14)
NSApplication.shared.terminate(self)

return false
}
}

// Ensure we don't have something in /Library/Screen Savers/
func ensureNotInstalledForAllUsers() {
if LocalVersion.isInstalledForAllUsers() {
NSApp.activate(ignoringOtherApps: true)
// Open finder with the file selected
Expand All @@ -39,14 +95,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
}
}

// Menu mode

// Set the icon
setIcon(mode: .normal)

createMenu()

}

func applicationWillTerminate(_ aNotification: Notification) {
Expand All @@ -56,14 +104,14 @@ class AppDelegate: NSObject, NSApplicationDelegate {
// Change the icon based on status
func setIcon(mode: IconMode) {
DispatchQueue.main.async {
print("setIcon")
print("setIcon \(mode)")
switch mode {
case .normal:
self.statusItem.image = NSImage(named: "Status48")
case .updating:
self.statusItem.image = NSImage(named: "StatusTransp48")
case .notification:
self.statusItem.image = NSImage(named: "StatusGreen48")
self.statusItem.image = NSImage(named: "Status48Attention")
}

self.statusItem.image?.size.width = 22
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions AerialUpdater/Model/BackgroundCheck.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,14 @@ class BackgroundCheck {
}
}

func getTimer() -> Int {
switch Preferences.checkEvery {
case .hour:
return hourSeconds
case .day:
return daySeconds
case .week:
return weekSeconds
}
}
}
7 changes: 4 additions & 3 deletions AerialUpdater/Model/Helpers/ErrorLog.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func Log(level: ErrorLevel, message: String) {
}

func logToDisk(_ message: String) {
DispatchQueue.main.async {
//DispatchQueue.main.async {
// Prefix message with date
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS"
Expand All @@ -67,9 +67,10 @@ func logToDisk(_ message: String) {
let fileHandle = try FileHandle(forWritingTo: cacheFileUrl)
fileHandle.seekToEndOfFile()
fileHandle.write(data)
fileHandle.synchronizeFile()
fileHandle.closeFile()
} catch {
NSLog("AerialUpdater: Can't open handle for Log.txt")
NSLog("AerialUpdater: Can't open handle for Log.txt \(error.localizedDescription)")
}
} else {
// Create new log
Expand All @@ -79,7 +80,7 @@ func logToDisk(_ message: String) {
NSLog("AerialUpdater: Can't write to Log.txt")
}
}
}
//}
}

func debugLog(_ message: String) {
Expand Down
10 changes: 10 additions & 0 deletions AerialUpdater/Model/Helpers/Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@
import Cocoa

struct Helpers {
static func showErrorAlert(question: String, text: String, button: String = "OK") {
let alert = NSAlert()
alert.messageText = question
alert.informativeText = text
alert.alertStyle = .critical
alert.icon = NSImage(named: NSImage.cautionName)
alert.addButton(withTitle: button)
alert.runModal()
}

static func showAlert(question: String, text: String, button1: String = "OK", button2: String = "Cancel") -> Bool {
let alert = NSAlert()
alert.messageText = question
Expand Down
155 changes: 155 additions & 0 deletions AerialUpdater/Model/LaunchAgent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
//
// LaunchAgent.swift
// AerialUpdater
//
// Created by Guillaume Louel on 09/08/2020.
//

import Cocoa

struct LaunchAgent {
// com.glouel.AerialUpdaterAgent.plist
static let agentPath: String = {
let path = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true)[0] as String
let url = NSURL(fileURLWithPath: path)
if let pathComponent = url.appendingPathComponent("LaunchAgents/com.glouel.AerialUpdaterAgent.plist") {
return pathComponent.path
} else {
return ""
}
}()

/// Update the Launch Agent to the current settings
///
/// It will remove the Launch Agent first if any exists then install the correct one depending on the mode. In manual mode, nothing is installed.
static public func update() {
// Let's start by cleaning up
removeAgent()

// If we need to set something, do it
if Preferences.launchMode != .manual {
installAgent()
}
}

static private func removeAgent() {
if FileManager.default.fileExists(atPath: agentPath) {
do {
debugLog("Removing LaunchAgent")
try FileManager().removeItem(atPath: agentPath)
} catch {
// ERROR
errorLog("Cannot remove LaunchAgent")
Helpers.showErrorAlert(question: "Cannot remove launch agent", text: "Please report !")
return
}
}
}

static private func installAgent() {
var agent: String = ""
switch Preferences.launchMode {
case .manual:
errorLog("Calling installAgent in manual mode, please report")
return
case .startup:
agent = getStartupAgent()
case .background:
agent = getBackgroundAgent()
}

do {
try agent.write(toFile: agentPath, atomically: true, encoding: .utf8)
debugLog("LaunchAgent installed")
} catch {
Helpers.showErrorAlert(question: "Can't install LaunchAgent", text: "Please report the issue")
}

restart()
if Preferences.launchMode == .background {
debugLog("Quitting after installing background mode")
NSApplication.shared.terminate(nil)
}
}

// Restarts our agent via launchctl
// This may not work on very old macOS versions?
static private func restart() {
debugLog("Restarting LaunchAgent")
let out1 = Helpers.shell(launchPath: "/bin/launchctl", arguments: ["unload", agentPath])
debugLog(out1 ?? "(no output)")
let out2 = Helpers.shell(launchPath: "/bin/launchctl", arguments: ["load", agentPath])
debugLog(out2 ?? "(no output)")
}

static private func getStartupAgent() -> String {
let top =
"""
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.glouel.AerialUpdater</string>
<key>LimitLoadToSessionType</key>
<string>Aqua</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/open</string>
"""

let bundleLine = "<string>" + Bundle.main.bundlePath + "</string>"

let bottom =
"""
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
"""
return top + bundleLine + bottom
}


static private func getBackgroundAgent() -> String {
let top =
"""
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.glouel.AerialUpdater</string>
<key>LimitLoadToSessionType</key>
<string>Aqua</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/open</string>
"""

let bundleLine = "<string>" + Bundle.main.bundlePath + "</string>"

let bottom =
"""
<string>--args</string>
<string>--silent</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartInterval</key>
<integer>
"""
let bottom2 =
"""
</integer>
</dict>
</plist>
"""
return top + bundleLine + bottom + String(BackgroundCheck.instance.getTimer()) + bottom2
}

}

Loading

0 comments on commit 811433c

Please sign in to comment.