-
Notifications
You must be signed in to change notification settings - Fork 2k
/
Copy pathAppDelegate.swift
152 lines (121 loc) · 4.64 KB
/
AppDelegate.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
static let serverStartedNotification = NSNotification.Name("serverStarted")
private var serverProcess: Process?
private weak var whatsnewWindow: NSWindow?
var isServerStarted: Bool {
get { return serverProcess != nil }
}
var serverPort = 8088
var sessionToken: String = ""
func applicationDidFinishLaunching(_ aNotification: Notification) {
copyResources()
startServer()
showWhatsNewDialogIfNeeded()
NotificationCenter.default.post(name: AppDelegate.serverStartedNotification, object: nil)
}
func applicationWillTerminate(_ aNotification: Notification) {
stopServer()
}
@IBAction func openNewWindow(_ sender: Any?) {
let mainStoryBoard = NSStoryboard(name: "Main", bundle: nil)
let tabViewController = mainStoryBoard.instantiateController(withIdentifier: "ViewController") as? ViewController
let windowController = mainStoryBoard.instantiateController(withIdentifier: "WindowController") as! NSWindowController
windowController.showWindow(self)
windowController.contentViewController = tabViewController
}
private func showWhatsNewDialogIfNeeded() {
if Globals.currentWhatsNewVersion < Globals.WhatsNewVersion {
Globals.currentWhatsNewVersion = Globals.WhatsNewVersion
showWhatsNew(self)
}
}
@IBAction func showWhatsNew(_: AnyObject) {
if let whatsnewWindow = self.whatsnewWindow {
whatsnewWindow.close()
self.whatsnewWindow = nil
}
let controller: WhatsNewViewController = NSStoryboard.main!.instantiateController(withIdentifier: "WhatsNewViewController") as! WhatsNewViewController
let window = NSWindow(contentViewController: controller)
self.whatsnewWindow = window
window.makeKeyAndOrderFront(self)
let vc = NSWindowController(window: window)
vc.showWindow(self)
}
private func webFolder() -> URL {
let url = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
return url.appendingPathComponent("Focalboard").appendingPathComponent("server")
}
private func copyResources() {
let destBaseUrl = webFolder()
do {
try FileManager.default.createDirectory(atPath: destBaseUrl.path, withIntermediateDirectories: true, attributes: nil)
} catch {
NSLog("copyResources createDirectory ERROR")
}
copyResource(destBaseUrl: destBaseUrl, resourceRelativePath: "pack")
copyResource(destBaseUrl: destBaseUrl, resourceRelativePath: "config.json")
NSLog("copyResources OK")
}
private func copyResource(destBaseUrl: URL, resourceRelativePath: String, fileExtension: String = "") {
let srcUrl = Bundle.main.url(forResource: "resources/" + resourceRelativePath, withExtension: fileExtension)!
let destUrl = destBaseUrl.appendingPathComponent(resourceRelativePath)
let fileManager = FileManager.default
if fileManager.fileExists(atPath: destUrl.path) {
do {
try fileManager.removeItem(at: destUrl)
} catch {
NSLog("copyResource removeItem ERROR")
}
}
do {
try fileManager.copyItem(at: srcUrl, to: destUrl)
} catch {
NSLog("copyResource copyItem ERROR")
return
}
}
private func generateSessionToken() -> String {
let bytesCount = 16
var randomNumber = ""
var randomBytes = [UInt8](repeating: 0, count: bytesCount)
let status = SecRandomCopyBytes(kSecRandomDefault, bytesCount, &randomBytes)
if status != errSecSuccess {
fatalError("SecRandomCopyBytes ERROR: \(status)")
}
randomNumber = randomBytes.map({String(format: "%02hhx", $0)}).joined(separator: "")
return "su-" + randomNumber
}
private func getFreePort() {
if PortUtils.isPortFree(in_port_t(serverPort)) {
return
}
serverPort = Int(PortUtils.getFreePort())
}
private func startServer() {
getFreePort()
sessionToken = generateSessionToken()
let cwdUrl = webFolder()
let executablePath = Bundle.main.path(forResource: "resources/bin/focalboard-server", ofType: "")
let pid = ProcessInfo.processInfo.processIdentifier
NSLog("pid: \(pid)")
let serverProcess = Process()
serverProcess.currentDirectoryPath = cwdUrl.path
serverProcess.arguments = ["-monitorpid", "\(pid)", "-port", "\(serverPort)", "-single-user"]
serverProcess.environment = ["FOCALBOARD_SINGLE_USER_TOKEN": sessionToken]
serverProcess.launchPath = executablePath
serverProcess.launch()
self.serverProcess = serverProcess
NSLog("startServer OK")
NSLog("cwd: \(cwdUrl)")
}
private func stopServer() {
guard let serverProcess = self.serverProcess else { return }
serverProcess.terminate()
self.serverProcess = nil
NSLog("stopServer OK")
}
}