forked from I2P_Developers/i2p.i2p
Mac OS X Launcher:
* In general bugfixes * Introduced event manager for better control flow * Splitted RouterStatusView to own file * Added shell script to setup and produce dmg file
This commit is contained in:
@ -43,6 +43,9 @@
|
|||||||
BFBDCB0021505BEE0014EB07 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFBDCAFF21505BED0014EB07 /* AppKit.framework */; };
|
BFBDCB0021505BEE0014EB07 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFBDCAFF21505BED0014EB07 /* AppKit.framework */; };
|
||||||
BFBDCB02215060190014EB07 /* DetectJava.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFBDCB01215060190014EB07 /* DetectJava.swift */; };
|
BFBDCB02215060190014EB07 /* DetectJava.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFBDCB01215060190014EB07 /* DetectJava.swift */; };
|
||||||
BFBDCB04215060970014EB07 /* StatusBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFBDCB03215060970014EB07 /* StatusBarController.swift */; };
|
BFBDCB04215060970014EB07 /* StatusBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFBDCB03215060970014EB07 /* StatusBarController.swift */; };
|
||||||
|
BFDD81DA2156B3E30014EB07 /* RouterManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFDD81D92156B3E30014EB07 /* RouterManager.swift */; };
|
||||||
|
BFE16BF82156C61E0014EB07 /* RouterStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE16BF72156C61E0014EB07 /* RouterStatusView.swift */; };
|
||||||
|
BFE16BFA2156DAED0014EB07 /* EventManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE16BF92156DAED0014EB07 /* EventManager.swift */; };
|
||||||
BFE1CBAD2151908F0014EB07 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFE1CBAC2151908F0014EB07 /* CoreFoundation.framework */; };
|
BFE1CBAD2151908F0014EB07 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BFE1CBAC2151908F0014EB07 /* CoreFoundation.framework */; };
|
||||||
BFF4581C213C48EA0014EB07 /* EventMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF4581B213C48EA0014EB07 /* EventMonitor.swift */; };
|
BFF4581C213C48EA0014EB07 /* EventMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF4581B213C48EA0014EB07 /* EventMonitor.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
@ -94,6 +97,10 @@
|
|||||||
BFBDCAFF21505BED0014EB07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
BFBDCAFF21505BED0014EB07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||||
BFBDCB01215060190014EB07 /* DetectJava.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetectJava.swift; sourceTree = "<group>"; };
|
BFBDCB01215060190014EB07 /* DetectJava.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetectJava.swift; sourceTree = "<group>"; };
|
||||||
BFBDCB03215060970014EB07 /* StatusBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarController.swift; sourceTree = "<group>"; };
|
BFBDCB03215060970014EB07 /* StatusBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusBarController.swift; sourceTree = "<group>"; };
|
||||||
|
BFDD81D92156B3E30014EB07 /* RouterManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouterManager.swift; sourceTree = "<group>"; };
|
||||||
|
BFE16BF72156C61E0014EB07 /* RouterStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouterStatusView.swift; sourceTree = "<group>"; };
|
||||||
|
BFE16BF92156DAED0014EB07 /* EventManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventManager.swift; sourceTree = "<group>"; };
|
||||||
|
BFE16BFB2156E94E0014EB07 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = ../../../Sparkle/build/Release/Sparkle.framework; sourceTree = "<group>"; };
|
||||||
BFE1CBAC2151908F0014EB07 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
|
BFE1CBAC2151908F0014EB07 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
|
||||||
BFF45818213C428E0014EB07 /* I2PLauncher-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "I2PLauncher-Bridging-Header.h"; sourceTree = "<group>"; };
|
BFF45818213C428E0014EB07 /* I2PLauncher-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "I2PLauncher-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
BFF4581B213C48EA0014EB07 /* EventMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventMonitor.swift; sourceTree = "<group>"; };
|
BFF4581B213C48EA0014EB07 /* EventMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventMonitor.swift; sourceTree = "<group>"; };
|
||||||
@ -134,6 +141,7 @@
|
|||||||
BF07789C21506D2B0014EB07 /* PopoverViewController.swift */,
|
BF07789C21506D2B0014EB07 /* PopoverViewController.swift */,
|
||||||
BFBDCB03215060970014EB07 /* StatusBarController.swift */,
|
BFBDCB03215060970014EB07 /* StatusBarController.swift */,
|
||||||
BF531514215105B40014EB07 /* LogViewController.swift */,
|
BF531514215105B40014EB07 /* LogViewController.swift */,
|
||||||
|
BFE16BF72156C61E0014EB07 /* RouterStatusView.swift */,
|
||||||
);
|
);
|
||||||
path = userinterface;
|
path = userinterface;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -191,6 +199,7 @@
|
|||||||
BF5061922113C6ED0014EB07 /* Frameworks */ = {
|
BF5061922113C6ED0014EB07 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
BFE16BFB2156E94E0014EB07 /* Sparkle.framework */,
|
||||||
BFE1CBAC2151908F0014EB07 /* CoreFoundation.framework */,
|
BFE1CBAC2151908F0014EB07 /* CoreFoundation.framework */,
|
||||||
BF865416215182820014EB07 /* Foundation.framework */,
|
BF865416215182820014EB07 /* Foundation.framework */,
|
||||||
BF865414215180F60014EB07 /* libswiftDarwin.tbd */,
|
BF865414215180F60014EB07 /* libswiftDarwin.tbd */,
|
||||||
@ -209,6 +218,7 @@
|
|||||||
BF5315062150C55B0014EB07 /* RouterRunner.swift */,
|
BF5315062150C55B0014EB07 /* RouterRunner.swift */,
|
||||||
BF5315082150C6760014EB07 /* RouterDeployer.swift */,
|
BF5315082150C6760014EB07 /* RouterDeployer.swift */,
|
||||||
BF53150A2150C6E80014EB07 /* I2PSubprocess.swift */,
|
BF53150A2150C6E80014EB07 /* I2PSubprocess.swift */,
|
||||||
|
BFDD81D92156B3E30014EB07 /* RouterManager.swift */,
|
||||||
);
|
);
|
||||||
path = routermgmt;
|
path = routermgmt;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -221,6 +231,7 @@
|
|||||||
BFBDCAF52150428D0014EB07 /* StringExtensions.swift */,
|
BFBDCAF52150428D0014EB07 /* StringExtensions.swift */,
|
||||||
BFBDCAF7215047FE0014EB07 /* ArrayExtensions.swift */,
|
BFBDCAF7215047FE0014EB07 /* ArrayExtensions.swift */,
|
||||||
BF53150C2150CE310014EB07 /* DateTimeUtils.swift */,
|
BF53150C2150CE310014EB07 /* DateTimeUtils.swift */,
|
||||||
|
BFE16BF92156DAED0014EB07 /* EventManager.swift */,
|
||||||
);
|
);
|
||||||
path = Utils;
|
path = Utils;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -334,8 +345,10 @@
|
|||||||
BFBDCB04215060970014EB07 /* StatusBarController.swift in Sources */,
|
BFBDCB04215060970014EB07 /* StatusBarController.swift in Sources */,
|
||||||
BFBDCAF8215047FE0014EB07 /* ArrayExtensions.swift in Sources */,
|
BFBDCAF8215047FE0014EB07 /* ArrayExtensions.swift in Sources */,
|
||||||
BF5315072150C55B0014EB07 /* RouterRunner.swift in Sources */,
|
BF5315072150C55B0014EB07 /* RouterRunner.swift in Sources */,
|
||||||
|
BFE16BFA2156DAED0014EB07 /* EventManager.swift in Sources */,
|
||||||
BFBDCAF12150420C0014EB07 /* ExecutionResult.swift in Sources */,
|
BFBDCAF12150420C0014EB07 /* ExecutionResult.swift in Sources */,
|
||||||
BF5315092150C6760014EB07 /* RouterDeployer.swift in Sources */,
|
BF5315092150C6760014EB07 /* RouterDeployer.swift in Sources */,
|
||||||
|
BFE16BF82156C61E0014EB07 /* RouterStatusView.swift in Sources */,
|
||||||
BFBDCAEF215041E30014EB07 /* Error.swift in Sources */,
|
BFBDCAEF215041E30014EB07 /* Error.swift in Sources */,
|
||||||
BF1EFA41215141110014EB07 /* RouterTask.mm in Sources */,
|
BF1EFA41215141110014EB07 /* RouterTask.mm in Sources */,
|
||||||
BF7506CB21509CFD0014EB07 /* RouterProcessStatus.swift in Sources */,
|
BF7506CB21509CFD0014EB07 /* RouterProcessStatus.swift in Sources */,
|
||||||
@ -350,6 +363,7 @@
|
|||||||
BF531515215105B40014EB07 /* LogViewController.swift in Sources */,
|
BF531515215105B40014EB07 /* LogViewController.swift in Sources */,
|
||||||
BF5315132150EB510014EB07 /* RouterProcessStatus+ObjectiveC.swift in Sources */,
|
BF5315132150EB510014EB07 /* RouterProcessStatus+ObjectiveC.swift in Sources */,
|
||||||
BFBDCAFE2150567D0014EB07 /* SwiftMainDelegate.swift in Sources */,
|
BFBDCAFE2150567D0014EB07 /* SwiftMainDelegate.swift in Sources */,
|
||||||
|
BFDD81DA2156B3E30014EB07 /* RouterManager.swift in Sources */,
|
||||||
BF53150B2150C6E80014EB07 /* I2PSubprocess.swift in Sources */,
|
BF53150B2150C6E80014EB07 /* I2PSubprocess.swift in Sources */,
|
||||||
BFF4581C213C48EA0014EB07 /* EventMonitor.swift in Sources */,
|
BFF4581C213C48EA0014EB07 /* EventMonitor.swift in Sources */,
|
||||||
BF1EFA3A215140E60014EB07 /* SBridge.mm in Sources */,
|
BF1EFA3A215140E60014EB07 /* SBridge.mm in Sources */,
|
||||||
|
@ -11,10 +11,9 @@ import Cocoa
|
|||||||
|
|
||||||
@objc class SwiftMainDelegate : NSObject {
|
@objc class SwiftMainDelegate : NSObject {
|
||||||
|
|
||||||
//let statusItem = NSStatusBar.system().statusItem(withLength: NSSquareStatusItemLength )
|
|
||||||
let statusBarController = StatusBarController()
|
let statusBarController = StatusBarController()
|
||||||
|
let sharedRouterMgmr = RouterManager.shared()
|
||||||
static let javaDetector = DetectJava()
|
static let javaDetector = DetectJava()
|
||||||
static let objCBridge = SBridge()
|
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
super.init()
|
super.init()
|
||||||
@ -37,10 +36,7 @@ import Cocoa
|
|||||||
} else {
|
} else {
|
||||||
RouterProcessStatus.isRouterRunning = false
|
RouterProcessStatus.isRouterRunning = false
|
||||||
print("I2P Router seems to NOT be running")
|
print("I2P Router seems to NOT be running")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // End of init()
|
} // End of init()
|
||||||
|
|
||||||
@objc func findInstalledI2PVersion() {
|
@objc func findInstalledI2PVersion() {
|
||||||
@ -63,13 +59,12 @@ import Cocoa
|
|||||||
let sub:Subprocess = Subprocess.init(executablePath: "/bin/sh", arguments: cmdArgs)
|
let sub:Subprocess = Subprocess.init(executablePath: "/bin/sh", arguments: cmdArgs)
|
||||||
let results:ExecutionResult = sub.execute(captureOutput: true)!
|
let results:ExecutionResult = sub.execute(captureOutput: true)!
|
||||||
if (results.didCaptureOutput) {
|
if (results.didCaptureOutput) {
|
||||||
print("captured output")
|
|
||||||
let i2pVersion = results.outputLines.first?.replace(target: "I2P Core version: ", withString: "")
|
let i2pVersion = results.outputLines.first?.replace(target: "I2P Core version: ", withString: "")
|
||||||
NSLog("I2P version detected: %@",i2pVersion ?? "Unknown")
|
NSLog("I2P version detected: %@",i2pVersion ?? "Unknown")
|
||||||
RouterProcessStatus.routerVersion = i2pVersion
|
RouterProcessStatus.routerVersion = i2pVersion
|
||||||
|
RouterManager.shared().eventManager.trigger(eventName: "router_version", information: i2pVersion)
|
||||||
} else {
|
} else {
|
||||||
print("did NOT captured output")
|
print("Warning: Version Detection did NOT captured output")
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,21 +73,11 @@ import Cocoa
|
|||||||
var i2pPath = NSHomeDirectory()
|
var i2pPath = NSHomeDirectory()
|
||||||
i2pPath += "/Library/I2P"
|
i2pPath += "/Library/I2P"
|
||||||
|
|
||||||
let fileManager = FileManager()
|
|
||||||
var ok = ObjCBool(true)
|
|
||||||
let doesI2PDirExists = fileManager.fileExists(atPath: i2pPath, isDirectory: &ok)
|
|
||||||
|
|
||||||
if (!doesI2PDirExists) {
|
|
||||||
// Deploy
|
|
||||||
}
|
|
||||||
|
|
||||||
//let i2pJarPath = i2pPath + "/lib/i2p.jar"
|
|
||||||
|
|
||||||
findInstalledI2PVersion()
|
findInstalledI2PVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc static func openLink(url: String) {
|
@objc static func openLink(url: String) {
|
||||||
objCBridge.openUrl(url)
|
SBridge.sharedInstance().openUrl(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func applicationWillTerminate() {
|
@objc func applicationWillTerminate() {
|
||||||
|
83
launchers/macosx/I2PLauncher/Utils/EventManager.swift
Normal file
83
launchers/macosx/I2PLauncher/Utils/EventManager.swift
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
//
|
||||||
|
// EventManager.swift
|
||||||
|
// I2PLauncher
|
||||||
|
//
|
||||||
|
// Created by Mikal Villa on 22/09/2018.
|
||||||
|
// Copyright © 2018 The I2P Project. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class EventManager {
|
||||||
|
var listeners = Dictionary<String, NSMutableArray>();
|
||||||
|
|
||||||
|
// Create a new event listener, not expecting information from the trigger
|
||||||
|
// @param eventName: Matching trigger eventNames will cause this listener to fire
|
||||||
|
// @param action: The function/lambda you want executed when the event triggers
|
||||||
|
func listenTo(eventName:String, action: @escaping (()->())) {
|
||||||
|
let newListener = EventListenerAction(callback: action)
|
||||||
|
addListener(eventName: eventName, newEventListener: newListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new event listener, expecting information from the trigger
|
||||||
|
// @param eventName: Matching trigger eventNames will cause this listener to fire
|
||||||
|
// @param action: The function/lambda you want executed when the event triggers
|
||||||
|
func listenTo(eventName:String, action: @escaping ((Any?)->())) {
|
||||||
|
let newListener = EventListenerAction(callback: action)
|
||||||
|
addListener(eventName: eventName, newEventListener: newListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal func addListener(eventName:String, newEventListener:EventListenerAction) {
|
||||||
|
if let listenerArray = self.listeners[eventName] {
|
||||||
|
listenerArray.add(newEventListener)
|
||||||
|
} else {
|
||||||
|
self.listeners[eventName] = [newEventListener] as NSMutableArray
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes all listeners by default, or specific listeners through paramters
|
||||||
|
// @param eventName: If an event name is passed, only listeners for that event will be removed
|
||||||
|
func removeListeners(eventNameToRemoveOrNil:String?) {
|
||||||
|
if let eventNameToRemove = eventNameToRemoveOrNil {
|
||||||
|
if let actionArray = self.listeners[eventNameToRemove] {
|
||||||
|
actionArray.removeAllObjects()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.listeners.removeAll(keepingCapacity: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Triggers an event
|
||||||
|
// @param eventName: Matching listener eventNames will fire when this is called
|
||||||
|
// @param information: pass values to your listeners
|
||||||
|
func trigger(eventName:String, information:Any? = nil) {
|
||||||
|
if let actionObjects = self.listeners[eventName] {
|
||||||
|
for actionObject in actionObjects {
|
||||||
|
if let actionToPerform = actionObject as? EventListenerAction {
|
||||||
|
if let methodToCall = actionToPerform.actionExpectsInfo {
|
||||||
|
methodToCall(information)
|
||||||
|
}
|
||||||
|
else if let methodToCall = actionToPerform.action {
|
||||||
|
methodToCall()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Class to hold actions to live in NSMutableArray
|
||||||
|
class EventListenerAction {
|
||||||
|
let action:(() -> ())?
|
||||||
|
let actionExpectsInfo:((Any?) -> ())?
|
||||||
|
|
||||||
|
init(callback: @escaping (() -> ()) ) {
|
||||||
|
self.action = callback
|
||||||
|
self.actionExpectsInfo = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
init(callback: @escaping ((Any?) -> ()) ) {
|
||||||
|
self.actionExpectsInfo = callback
|
||||||
|
self.action = nil
|
||||||
|
}
|
||||||
|
}
|
99
launchers/macosx/I2PLauncher/routermgmt/RouterManager.swift
Normal file
99
launchers/macosx/I2PLauncher/routermgmt/RouterManager.swift
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
//
|
||||||
|
// RouterManager.swift
|
||||||
|
// I2PLauncher
|
||||||
|
//
|
||||||
|
// Created by Mikal Villa on 22/09/2018.
|
||||||
|
// Copyright © 2018 The I2P Project. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class RouterManager : NSObject {
|
||||||
|
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
static let packedVersion : String = "0.9.36"
|
||||||
|
|
||||||
|
let eventManager = EventManager()
|
||||||
|
|
||||||
|
var logViewStorage: NSTextStorage?
|
||||||
|
|
||||||
|
private static func handleRouterStart(information:Any?) {
|
||||||
|
NSLog("event! - handle router start")
|
||||||
|
RouterProcessStatus.routerStartedAt = Date()
|
||||||
|
RouterProcessStatus.isRouterChildProcess = true
|
||||||
|
RouterProcessStatus.isRouterRunning = true
|
||||||
|
}
|
||||||
|
private static func handleRouterStop(information:Any?) {
|
||||||
|
NSLog("event! - handle router stop")
|
||||||
|
RouterProcessStatus.routerStartedAt = nil
|
||||||
|
RouterProcessStatus.isRouterChildProcess = false
|
||||||
|
RouterProcessStatus.isRouterRunning = false
|
||||||
|
}
|
||||||
|
private static func handleRouterPid(information:Any?) {
|
||||||
|
Swift.print("event! - handle router pid: %s", information ?? "")
|
||||||
|
}
|
||||||
|
private static func handleRouterVersion(information:Any?) {
|
||||||
|
Swift.print("event! - handle router version: %s", information ?? "")
|
||||||
|
let currentVersion : String = information as! String
|
||||||
|
if (packedVersion.compare(currentVersion, options: .numeric) == .orderedDescending) {
|
||||||
|
Swift.print("event! - router version: Packed version is newer, gonna re-deploy")
|
||||||
|
} else {
|
||||||
|
Swift.print("event! - router version: No update needed")
|
||||||
|
RouterManager.shared().eventManager.trigger(eventName: "router_can_start", information: "all ok")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static var sharedRouterManager: RouterManager = {
|
||||||
|
let inst = DetectJava()
|
||||||
|
let routerManager = RouterManager(detectJavaInstance: inst)
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
// ...
|
||||||
|
routerManager.updateState()
|
||||||
|
|
||||||
|
routerManager.eventManager.listenTo(eventName: "router_start", action: handleRouterStart)
|
||||||
|
routerManager.eventManager.listenTo(eventName: "router_stop", action: handleRouterStop)
|
||||||
|
routerManager.eventManager.listenTo(eventName: "router_pid", action: handleRouterPid)
|
||||||
|
routerManager.eventManager.listenTo(eventName: "router_version", action: handleRouterVersion)
|
||||||
|
return routerManager
|
||||||
|
}()
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
let detectJava: DetectJava
|
||||||
|
private var routerInstance: I2PRouterTask?{
|
||||||
|
//Called after the change
|
||||||
|
didSet{
|
||||||
|
print("RouterManager.routerInstance did change to ", self.routerInstance ?? "null")
|
||||||
|
if (self.routerInstance != nil) {
|
||||||
|
RouterProcessStatus.isRouterRunning = (self.routerInstance?.isRouterRunning)!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialization
|
||||||
|
|
||||||
|
private init(detectJavaInstance: DetectJava) {
|
||||||
|
self.detectJava = detectJavaInstance
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Accessors
|
||||||
|
|
||||||
|
class func shared() -> RouterManager {
|
||||||
|
return sharedRouterManager
|
||||||
|
}
|
||||||
|
|
||||||
|
func setRouterTask(router: I2PRouterTask) {
|
||||||
|
self.routerInstance = router
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRouterTask() -> I2PRouterTask? {
|
||||||
|
return self.routerInstance
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateState() {
|
||||||
|
self.routerInstance = SBridge.sharedInstance()?.currentRouterInstance
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -9,10 +9,15 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension RouterProcessStatus {
|
extension RouterProcessStatus {
|
||||||
|
|
||||||
static func createNewRouterProcess(i2pPath: String, javaBinPath: String) {
|
static func createNewRouterProcess(i2pPath: String, javaBinPath: String) {
|
||||||
let bridge = SBridge()
|
|
||||||
let timeWhenStarted = Date()
|
let timeWhenStarted = Date()
|
||||||
RouterProcessStatus.routerStartedAt = timeWhenStarted
|
RouterProcessStatus.routerStartedAt = timeWhenStarted
|
||||||
bridge.startupI2PRouter(i2pPath, javaBinPath: javaBinPath)
|
SBridge.sharedInstance().startupI2PRouter(i2pPath, javaBinPath: javaBinPath)
|
||||||
|
RouterManager.shared().updateState()
|
||||||
|
}
|
||||||
|
static func shutdownRouterChildProcess() {
|
||||||
|
RouterManager.shared().getRouterTask()?.requestShutdown()
|
||||||
|
RouterManager.shared().updateState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,10 @@ import AppKit
|
|||||||
@objc func getJavaHome() -> String {
|
@objc func getJavaHome() -> String {
|
||||||
return RouterProcessStatus.knownJavaBinPath!
|
return RouterProcessStatus.knownJavaBinPath!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func triggerEvent(en: String, details: String? = nil) {
|
||||||
|
RouterManager.shared().eventManager.trigger(eventName: en, information: details)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension RouterProcessStatus {
|
extension RouterProcessStatus {
|
||||||
|
@ -14,11 +14,43 @@ class LogViewerViewController : NSTabViewItem {
|
|||||||
@IBOutlet var scrollView: NSScrollView?
|
@IBOutlet var scrollView: NSScrollView?
|
||||||
@IBOutlet var textFieldView: NSTextView?
|
@IBOutlet var textFieldView: NSTextView?
|
||||||
|
|
||||||
|
private var outputPipe : Pipe?
|
||||||
|
|
||||||
|
override init(identifier: Any?) {
|
||||||
|
super.init(identifier: identifier)
|
||||||
|
self.captureStandardOutputAndRouteToTextView()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder aDecoder: NSCoder) {
|
||||||
|
super.init(coder: aDecoder)
|
||||||
|
self.captureStandardOutputAndRouteToTextView()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func captureStandardOutputAndRouteToTextView() {
|
||||||
|
outputPipe = RouterManager.shared().getRouterTask()?.processPipe
|
||||||
|
outputPipe?.fileHandleForReading.waitForDataInBackgroundAndNotify()
|
||||||
|
|
||||||
|
NotificationCenter.default.addObserver(forName: NSNotification.Name.NSFileHandleDataAvailable, object: outputPipe?.fileHandleForReading , queue: nil) {
|
||||||
|
notification in
|
||||||
|
|
||||||
|
let output = self.outputPipe?.fileHandleForReading.availableData
|
||||||
|
let outputString = String(data: output!, encoding: String.Encoding.utf8) ?? ""
|
||||||
|
|
||||||
|
DispatchQueue.main.async(execute: {
|
||||||
|
let previousOutput = self.textFieldView?.string ?? ""
|
||||||
|
let nextOutput = previousOutput + "\n" + outputString
|
||||||
|
self.textFieldView?.string = nextOutput
|
||||||
|
|
||||||
|
let range = NSRange(location:nextOutput.characters.count,length:0)
|
||||||
|
self.textFieldView?.scrollRangeToVisible(range)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
self.outputPipe?.fileHandleForReading.waitForDataInBackgroundAndNotify()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LogViewController {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -12,9 +12,6 @@ class PopoverViewController: NSViewController {
|
|||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
super.init(coder: coder)
|
super.init(coder: coder)
|
||||||
//super.init(nibName: "UserInterfaces", bundle: Bundle.main)!
|
|
||||||
//let nib = NSNib(nibNamed: "UserInterfaces", bundle: Bundle.main)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -22,83 +19,6 @@ class PopoverViewController: NSViewController {
|
|||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
// Do view setup here.
|
// Do view setup here.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc class RouterStatusView : NSView {
|
|
||||||
static var instance: RouterStatusView?
|
|
||||||
|
|
||||||
static func getInstance() -> RouterStatusView? {
|
|
||||||
if (self.instance != Optional.none) {
|
|
||||||
return RouterStatusView.instance
|
|
||||||
}
|
|
||||||
return Optional.none
|
|
||||||
}
|
|
||||||
|
|
||||||
@IBOutlet var routerStatusLabel: NSTextField?
|
|
||||||
@IBOutlet var routerVersionLabel: NSTextField?
|
|
||||||
@IBOutlet var routerStartedByLabel: NSTextField?
|
|
||||||
@IBOutlet var routerUptimeLabel: NSTextField?
|
|
||||||
|
|
||||||
@IBOutlet var quickControlView: NSView?
|
|
||||||
@IBOutlet var routerStartStopButton: NSButton?
|
|
||||||
|
|
||||||
|
|
||||||
@objc func actionBtnStartRouter(_ sender: Any?) {
|
|
||||||
NSLog("START ROUTER")
|
|
||||||
(sender as! NSButton).cell?.stringValue = "Stop Router"
|
|
||||||
let timeWhenStarted = Date()
|
|
||||||
RouterProcessStatus.routerStartedAt = timeWhenStarted
|
|
||||||
SwiftMainDelegate.objCBridge.startupI2PRouter(RouterProcessStatus.i2pDirectoryPath, javaBinPath: RouterProcessStatus.knownJavaBinPath!)
|
|
||||||
}
|
|
||||||
@objc func actionBtnStopRouter(_ sender: Any?) {
|
|
||||||
NSLog("STOP ROUTER")
|
|
||||||
}
|
|
||||||
@objc func actionBtnRestartRouter(sender: Any?) {}
|
|
||||||
|
|
||||||
override func viewWillDraw() {
|
|
||||||
super.viewWillDraw()
|
|
||||||
if (RouterStatusView.instance != nil) {
|
|
||||||
RouterStatusView.instance = self
|
|
||||||
}
|
|
||||||
self.setRouterStatusLabelText()
|
|
||||||
}
|
|
||||||
|
|
||||||
func setRouterStatusLabelText() {
|
|
||||||
if (RouterProcessStatus.isRouterRunning) {
|
|
||||||
routerStatusLabel?.cell?.stringValue = "Router status: Running"
|
|
||||||
routerStartStopButton?.action = #selector(self.actionBtnStopRouter(_:))
|
|
||||||
} else {
|
|
||||||
routerStatusLabel?.cell?.stringValue = "Router status: Not running"
|
|
||||||
routerStartStopButton?.action = #selector(self.actionBtnStartRouter(_:))
|
|
||||||
}
|
|
||||||
routerStartStopButton?.needsDisplay = true
|
|
||||||
routerStartStopButton?.target = self
|
|
||||||
quickControlView?.needsDisplay = true
|
|
||||||
|
|
||||||
if let version = RouterProcessStatus.routerVersion {
|
|
||||||
routerVersionLabel?.cell?.stringValue = "Router version: " + version
|
|
||||||
} else {
|
|
||||||
routerVersionLabel?.cell?.stringValue = "Router version: Still unknown"
|
|
||||||
}
|
|
||||||
if let routerStartTime = RouterProcessStatus.routerStartedAt {
|
|
||||||
routerUptimeLabel?.cell?.stringValue = "Router has runned for " + DateTimeUtils.timeAgoSinceDate(date: NSDate(date: routerStartTime), numericDates: false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
let c = NSCoder()
|
|
||||||
super.init(coder: c)!
|
|
||||||
self.setRouterStatusLabelText()
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder decoder: NSCoder) {
|
|
||||||
super.init(coder: decoder)
|
|
||||||
self.setRouterStatusLabelText()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,113 @@
|
|||||||
|
//
|
||||||
|
// RouterStatusView.swift
|
||||||
|
// I2PLauncher
|
||||||
|
//
|
||||||
|
// Created by Mikal Villa on 22/09/2018.
|
||||||
|
// Copyright © 2018 The I2P Project. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
|
||||||
|
@objc class RouterStatusView : NSView {
|
||||||
|
static var instance: RouterStatusView?
|
||||||
|
|
||||||
|
static func getInstance() -> RouterStatusView? {
|
||||||
|
if (self.instance != Optional.none) {
|
||||||
|
return RouterStatusView.instance
|
||||||
|
}
|
||||||
|
return Optional.none
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBOutlet var routerStatusLabel: NSTextField?
|
||||||
|
@IBOutlet var routerVersionLabel: NSTextField?
|
||||||
|
@IBOutlet var routerStartedByLabel: NSTextField?
|
||||||
|
@IBOutlet var routerUptimeLabel: NSTextField?
|
||||||
|
|
||||||
|
@IBOutlet var quickControlView: NSView?
|
||||||
|
@IBOutlet var routerStartStopButton: NSButton?
|
||||||
|
|
||||||
|
@objc func actionBtnStartRouter(_ sender: Any?) {
|
||||||
|
NSLog("START ROUTER")
|
||||||
|
if (!(RouterManager.shared().getRouterTask()?.isRunning())!) {
|
||||||
|
SBridge.sharedInstance().startupI2PRouter(RouterProcessStatus.i2pDirectoryPath, javaBinPath: RouterProcessStatus.knownJavaBinPath!)
|
||||||
|
}
|
||||||
|
RouterManager.shared().updateState()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func actionBtnStopRouter(_ sender: Any?) {
|
||||||
|
NSLog("STOP ROUTER")
|
||||||
|
if ((RouterManager.shared().getRouterTask()?.isRunning())!) {
|
||||||
|
NSLog("Found running router")
|
||||||
|
RouterManager.shared().getRouterTask()?.requestShutdown()
|
||||||
|
RouterManager.shared().updateState()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func actionBtnRestartRouter(sender: Any?) {
|
||||||
|
if ((RouterManager.shared().getRouterTask()?.isRunning())!) {
|
||||||
|
RouterManager.shared().getRouterTask()?.requestRestart()
|
||||||
|
} else {
|
||||||
|
NSLog("Can't restart a non running router, start it however...")
|
||||||
|
SBridge.sharedInstance().startupI2PRouter(RouterProcessStatus.i2pDirectoryPath, javaBinPath: RouterProcessStatus.knownJavaBinPath!)
|
||||||
|
}
|
||||||
|
RouterManager.shared().updateState()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
override func viewWillDraw() {
|
||||||
|
super.viewWillDraw()
|
||||||
|
if (RouterStatusView.instance != nil) {
|
||||||
|
RouterStatusView.instance = self
|
||||||
|
}
|
||||||
|
self.setRouterStatusLabelText()
|
||||||
|
}
|
||||||
|
|
||||||
|
func setRouterStatusLabelText() {
|
||||||
|
if (RouterProcessStatus.isRouterRunning) {
|
||||||
|
routerStatusLabel?.cell?.stringValue = "Router status: Running"
|
||||||
|
routerStartStopButton?.title = "Stop Router"
|
||||||
|
routerStartStopButton?.action = #selector(self.actionBtnStopRouter(_:))
|
||||||
|
} else {
|
||||||
|
routerStatusLabel?.cell?.stringValue = "Router status: Not running"
|
||||||
|
routerStartStopButton?.title = "Start Router"
|
||||||
|
routerStartStopButton?.action = #selector(self.actionBtnStartRouter(_:))
|
||||||
|
}
|
||||||
|
routerStartStopButton?.needsDisplay = true
|
||||||
|
routerStartStopButton?.target = self
|
||||||
|
quickControlView?.needsDisplay = true
|
||||||
|
|
||||||
|
let staticStartedByLabelText = "Router started by launcher?"
|
||||||
|
if RouterProcessStatus.isRouterChildProcess {
|
||||||
|
routerStartedByLabel?.cell?.stringValue = staticStartedByLabelText+" Yes"
|
||||||
|
} else {
|
||||||
|
routerStartedByLabel?.cell?.stringValue = staticStartedByLabelText+" No"
|
||||||
|
}
|
||||||
|
routerStartedByLabel?.needsDisplay = true
|
||||||
|
|
||||||
|
if let version = RouterProcessStatus.routerVersion {
|
||||||
|
routerVersionLabel?.cell?.stringValue = "Router version: " + version
|
||||||
|
} else {
|
||||||
|
routerVersionLabel?.cell?.stringValue = "Router version: Still unknown"
|
||||||
|
}
|
||||||
|
if let routerStartTime = RouterProcessStatus.routerStartedAt {
|
||||||
|
routerUptimeLabel?.cell?.stringValue = "Uptime: Router started " + DateTimeUtils.timeAgoSinceDate(date: NSDate(date: routerStartTime), numericDates: false)
|
||||||
|
} else {
|
||||||
|
routerUptimeLabel?.cell?.stringValue = "Uptime: Router isn't running"
|
||||||
|
}
|
||||||
|
routerUptimeLabel?.needsDisplay = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
init() {
|
||||||
|
let c = NSCoder()
|
||||||
|
super.init(coder: c)!
|
||||||
|
self.setRouterStatusLabelText()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder decoder: NSCoder) {
|
||||||
|
super.init(coder: decoder)
|
||||||
|
self.setRouterStatusLabelText()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -22,7 +22,6 @@ import Cocoa
|
|||||||
|
|
||||||
@objc func constructMenu() -> NSMenu {
|
@objc func constructMenu() -> NSMenu {
|
||||||
let menu = NSMenu()
|
let menu = NSMenu()
|
||||||
//let sb = SwiftMainDelegate.objCBridge
|
|
||||||
|
|
||||||
menu.addItem(NSMenuItem(title: "Open I2P Console", action: #selector(self.handleOpenConsole(_:)), keyEquivalent: "O"))
|
menu.addItem(NSMenuItem(title: "Open I2P Console", action: #selector(self.handleOpenConsole(_:)), keyEquivalent: "O"))
|
||||||
menu.addItem(NSMenuItem.separator())
|
menu.addItem(NSMenuItem.separator())
|
||||||
@ -33,17 +32,12 @@ import Cocoa
|
|||||||
|
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
super.init()//(xib: "UserInterface", bundle: nil)
|
super.init()
|
||||||
popover.contentViewController = PopoverViewController.freshController()
|
popover.contentViewController = PopoverViewController.freshController()
|
||||||
|
|
||||||
if let button = statusItem.button {
|
if let button = statusItem.button {
|
||||||
button.image = NSImage(named:"StatusBarButtonImage")
|
button.image = NSImage(named:"StatusBarButtonImage")
|
||||||
//button.title = "I2P"
|
|
||||||
button.toolTip = "I2P Launch Manager"
|
button.toolTip = "I2P Launch Manager"
|
||||||
//button.isVisible = true
|
|
||||||
//button.action = #selector(self.statusBarButtonClicked)
|
|
||||||
//button.sendAction(on: [.leftMouseUp, .rightMouseUp])
|
|
||||||
//button.doubleAction = #selector(self.systemBarIconDoubleClick)
|
|
||||||
button.target = self
|
button.target = self
|
||||||
button.action = #selector(self.statusBarButtonClicked(sender:))
|
button.action = #selector(self.statusBarButtonClicked(sender:))
|
||||||
button.sendAction(on: [.leftMouseUp, .rightMouseUp])
|
button.sendAction(on: [.leftMouseUp, .rightMouseUp])
|
||||||
@ -97,6 +91,7 @@ import Cocoa
|
|||||||
if popover.isShown {
|
if popover.isShown {
|
||||||
closePopover(sender: sender)
|
closePopover(sender: sender)
|
||||||
} else {
|
} else {
|
||||||
|
RouterManager.shared().updateState()
|
||||||
showPopover(sender: sender)
|
showPopover(sender: sender)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,11 +39,16 @@ const std::vector<std::string> defaultFlagsForExtractorJob {
|
|||||||
@class I2PRouterTask;
|
@class I2PRouterTask;
|
||||||
@interface I2PRouterTask : NSObject
|
@interface I2PRouterTask : NSObject
|
||||||
@property (strong) NSTask* routerTask;
|
@property (strong) NSTask* routerTask;
|
||||||
|
|
||||||
|
// TODO: Not in use, remove?
|
||||||
|
/*
|
||||||
@property (strong) NSUserDefaults *userPreferences;
|
@property (strong) NSUserDefaults *userPreferences;
|
||||||
@property (strong) NSFileHandle *readLogHandle;
|
@property (strong) NSFileHandle *readLogHandle;
|
||||||
@property (strong) NSMutableData *totalLogData;
|
@property (strong) NSMutableData *totalLogData;
|
||||||
@property (strong) NSPipe *processPipe;
|
|
||||||
@property (strong) NSFileHandle *input;
|
@property (strong) NSFileHandle *input;
|
||||||
|
*/
|
||||||
|
|
||||||
|
@property (strong) NSPipe *processPipe;
|
||||||
@property (atomic) BOOL isRouterRunning;
|
@property (atomic) BOOL isRouterRunning;
|
||||||
@property (atomic) BOOL userRequestedRestart;
|
@property (atomic) BOOL userRequestedRestart;
|
||||||
- (instancetype) initWithOptions : (RTaskOptions*) options;
|
- (instancetype) initWithOptions : (RTaskOptions*) options;
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
{
|
{
|
||||||
self.userRequestedRestart = NO;
|
self.userRequestedRestart = NO;
|
||||||
self.isRouterRunning = NO;
|
self.isRouterRunning = NO;
|
||||||
self.input = [NSFileHandle fileHandleWithStandardInput];
|
//self.input = [NSFileHandle fileHandleWithStandardInput];
|
||||||
self.routerTask = [NSTask new];
|
self.routerTask = [NSTask new];
|
||||||
self.processPipe = [NSPipe new];
|
self.processPipe = [NSPipe new];
|
||||||
[self.routerTask setLaunchPath:options.binPath];
|
[self.routerTask setLaunchPath:options.binPath];
|
||||||
@ -44,13 +44,41 @@
|
|||||||
[self.routerTask setStandardOutput:self.processPipe];
|
[self.routerTask setStandardOutput:self.processPipe];
|
||||||
[self.routerTask setStandardError:self.processPipe];
|
[self.routerTask setStandardError:self.processPipe];
|
||||||
|
|
||||||
NSFileHandle *stdoutFileHandle = [self.processPipe fileHandleForReading];
|
/*
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
NSFileHandle *stdoutFileHandle = [self.processPipe fileHandleForReading];
|
||||||
selector:@selector(routerStdoutData:)
|
dup2([[self.processPipe fileHandleForWriting] fileDescriptor], fileno(stdout));
|
||||||
name:NSFileHandleDataAvailableNotification
|
auto source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, [stdoutFileHandle fileDescriptor], 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
|
||||||
object:stdoutFileHandle];
|
dispatch_source_set_event_handler(source, ^{
|
||||||
|
void* data = malloc(4096);
|
||||||
|
ssize_t readResult = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
readResult = read([stdoutFileHandle fileDescriptor], data, 4096);
|
||||||
|
} while (readResult == -1 && errno == EINTR);
|
||||||
|
if (readResult > 0)
|
||||||
|
{
|
||||||
|
//AppKit UI should only be updated from the main thread
|
||||||
|
dispatch_async(dispatch_get_main_queue(),^{
|
||||||
|
NSString* stdOutString = [[NSString alloc] initWithBytesNoCopy:data length:readResult encoding:NSUTF8StringEncoding freeWhenDone:YES];
|
||||||
|
NSAttributedString* stdOutAttributedString = [[NSAttributedString alloc] initWithString:stdOutString];
|
||||||
|
NSLog(@"Router stdout: %@", stdOutString);
|
||||||
|
//auto logForwarder = new LogForwarder();
|
||||||
|
//[logForwarder appendLogViewWithLogLine:stdOutAttributedString];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else{free(data);}
|
||||||
|
});
|
||||||
|
dispatch_resume(source);
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
|
selector:@selector(routerStdoutData:)
|
||||||
|
name:NSFileHandleDataAvailableNotification
|
||||||
|
object:stdoutFileHandle];
|
||||||
|
|
||||||
[stdoutFileHandle waitForDataInBackgroundAndNotify];
|
[stdoutFileHandle waitForDataInBackgroundAndNotify];
|
||||||
|
*/
|
||||||
|
|
||||||
[self.routerTask setTerminationHandler:^(NSTask* task) {
|
[self.routerTask setTerminationHandler:^(NSTask* task) {
|
||||||
// Cleanup
|
// Cleanup
|
||||||
@ -58,6 +86,8 @@
|
|||||||
auto swiftRouterStatus = [[RouterProcessStatus alloc] init];
|
auto swiftRouterStatus = [[RouterProcessStatus alloc] init];
|
||||||
[swiftRouterStatus setRouterStatus: false];
|
[swiftRouterStatus setRouterStatus: false];
|
||||||
[swiftRouterStatus setRouterRanByUs: false];
|
[swiftRouterStatus setRouterRanByUs: false];
|
||||||
|
[swiftRouterStatus triggerEventWithEn:@"router_stop" details:@"normal shutdown"];
|
||||||
|
[[SBridge sharedInstance] setCurrentRouterInstance:nil];
|
||||||
sendUserNotification(APP_IDSTR, @"I2P Router has stopped");
|
sendUserNotification(APP_IDSTR, @"I2P Router has stopped");
|
||||||
}];
|
}];
|
||||||
return self;
|
return self;
|
||||||
@ -82,8 +112,9 @@
|
|||||||
- (int) execute
|
- (int) execute
|
||||||
{
|
{
|
||||||
@try {
|
@try {
|
||||||
|
auto swiftRouterStatus = [[RouterProcessStatus alloc] init];
|
||||||
|
[swiftRouterStatus triggerEventWithEn:@"router_start" details:@"normal start"];
|
||||||
[self.routerTask launch];
|
[self.routerTask launch];
|
||||||
watchPid([self.routerTask processIdentifier]);
|
|
||||||
self.isRouterRunning = YES;
|
self.isRouterRunning = YES;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -91,8 +122,11 @@
|
|||||||
{
|
{
|
||||||
NSLog(@"Expection occurred %@", [e reason]);
|
NSLog(@"Expection occurred %@", [e reason]);
|
||||||
auto swiftRouterStatus = [[RouterProcessStatus alloc] init];
|
auto swiftRouterStatus = [[RouterProcessStatus alloc] init];
|
||||||
|
self.isRouterRunning = NO;
|
||||||
[swiftRouterStatus setRouterStatus: false];
|
[swiftRouterStatus setRouterStatus: false];
|
||||||
[swiftRouterStatus setRouterRanByUs: false];
|
[swiftRouterStatus setRouterRanByUs: false];
|
||||||
|
[swiftRouterStatus triggerEventWithEn:@"router_stop" details:@"error shutdown"];
|
||||||
|
[[SBridge sharedInstance] setCurrentRouterInstance:nil];
|
||||||
sendUserNotification(@"An error occured, can't start the I2P Router", [e reason]);
|
sendUserNotification(@"An error occured, can't start the I2P Router", [e reason]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
#import "RouterTask.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <future>
|
#include <future>
|
||||||
@ -54,7 +56,9 @@ inline std::string buildClassPathForObjC(std::string basePath)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
@interface SBridge : NSObject
|
@interface SBridge : NSObject
|
||||||
|
@property (nonatomic, assign) I2PRouterTask* currentRouterInstance;
|
||||||
- (NSString*) buildClassPath:(NSString*)i2pPath;
|
- (NSString*) buildClassPath:(NSString*)i2pPath;
|
||||||
- (void) startupI2PRouter:(NSString*)i2pRootPath javaBinPath:(NSString*)javaBinPath;
|
- (void) startupI2PRouter:(NSString*)i2pRootPath javaBinPath:(NSString*)javaBinPath;
|
||||||
- (void) openUrl:(NSString*)url;
|
- (void) openUrl:(NSString*)url;
|
||||||
|
+ (instancetype)sharedInstance; // this makes it a singleton
|
||||||
@end
|
@end
|
||||||
|
@ -33,9 +33,16 @@ std::future<int> startupRouter(NSString* javaBin, NSArray<NSString*>* arguments,
|
|||||||
options.arguments = arguments;
|
options.arguments = arguments;
|
||||||
options.i2pBaseDir = i2pBaseDir;
|
options.i2pBaseDir = i2pBaseDir;
|
||||||
auto instance = [[I2PRouterTask alloc] initWithOptions: options];
|
auto instance = [[I2PRouterTask alloc] initWithOptions: options];
|
||||||
|
|
||||||
|
[[SBridge sharedInstance] setCurrentRouterInstance:instance];
|
||||||
[instance execute];
|
[instance execute];
|
||||||
sendUserNotification(APP_IDSTR, @"The I2P router is starting up.");
|
sendUserNotification(APP_IDSTR, @"The I2P router is starting up.");
|
||||||
auto pid = [instance getPID];
|
auto pid = [instance getPID];
|
||||||
|
NSLog(@"Got pid: %d", pid);
|
||||||
|
|
||||||
|
auto swiftRouterStatus = [[RouterProcessStatus alloc] init];
|
||||||
|
[swiftRouterStatus triggerEventWithEn:@"router_pid" details:[NSString stringWithFormat:@"%d", pid]];
|
||||||
|
|
||||||
return std::async(std::launch::async, [&pid]{
|
return std::async(std::launch::async, [&pid]{
|
||||||
return pid;
|
return pid;
|
||||||
});
|
});
|
||||||
@ -45,6 +52,13 @@ std::future<int> startupRouter(NSString* javaBin, NSArray<NSString*>* arguments,
|
|||||||
auto errStr = [NSString stringWithFormat:@"Expection occurred %@",[e reason]];
|
auto errStr = [NSString stringWithFormat:@"Expection occurred %@",[e reason]];
|
||||||
NSLog(@"%@", errStr);
|
NSLog(@"%@", errStr);
|
||||||
sendUserNotification(APP_IDSTR, errStr);
|
sendUserNotification(APP_IDSTR, errStr);
|
||||||
|
[[SBridge sharedInstance] setCurrentRouterInstance:nil];
|
||||||
|
|
||||||
|
auto swiftRouterStatus = [[RouterProcessStatus alloc] init];
|
||||||
|
[swiftRouterStatus setRouterStatus: false];
|
||||||
|
[swiftRouterStatus setRouterRanByUs: false];
|
||||||
|
[swiftRouterStatus triggerEventWithEn:@"router_exception" details:errStr];
|
||||||
|
|
||||||
return std::async(std::launch::async, [&]{
|
return std::async(std::launch::async, [&]{
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
@ -55,6 +69,16 @@ std::future<int> startupRouter(NSString* javaBin, NSArray<NSString*>* arguments,
|
|||||||
|
|
||||||
@implementation SBridge
|
@implementation SBridge
|
||||||
|
|
||||||
|
// this makes it a singleton
|
||||||
|
+ (instancetype)sharedInstance {
|
||||||
|
static SBridge *sharedInstance = nil;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
sharedInstance = [[SBridge alloc] init];
|
||||||
|
});
|
||||||
|
return sharedInstance;
|
||||||
|
}
|
||||||
|
|
||||||
- (void) openUrl:(NSString*)url
|
- (void) openUrl:(NSString*)url
|
||||||
{
|
{
|
||||||
@ -125,6 +149,7 @@ std::future<int> startupRouter(NSString* javaBin, NSArray<NSString*>* arguments,
|
|||||||
sendUserNotification(APP_IDSTR, [NSString stringWithFormat:@"Error: %@", errMsg]);
|
sendUserNotification(APP_IDSTR, [NSString stringWithFormat:@"Error: %@", errMsg]);
|
||||||
[routerStatus setRouterStatus: false];
|
[routerStatus setRouterStatus: false];
|
||||||
[routerStatus setRouterRanByUs: false];
|
[routerStatus setRouterRanByUs: false];
|
||||||
|
[routerStatus triggerEventWithEn:@"router_exception" details:[NSString stringWithFormat:@"Error: %@", errMsg]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
@ -204,7 +204,6 @@ using namespace subprocess;
|
|||||||
|
|
||||||
|
|
||||||
NSBundle *launcherBundle = [NSBundle mainBundle];
|
NSBundle *launcherBundle = [NSBundle mainBundle];
|
||||||
auto sBridge = [[SBridge alloc] init];
|
|
||||||
|
|
||||||
// Helper object to hold statefull path information
|
// Helper object to hold statefull path information
|
||||||
self.metaInfo = [[ExtractMetaInfo alloc] init];
|
self.metaInfo = [[ExtractMetaInfo alloc] init];
|
||||||
@ -237,7 +236,7 @@ using namespace subprocess;
|
|||||||
NSLog(@"Time to detect I2P version in install directory");
|
NSLog(@"Time to detect I2P version in install directory");
|
||||||
[self.swiftRuntime findInstalledI2PVersion];
|
[self.swiftRuntime findInstalledI2PVersion];
|
||||||
if (shouldAutoStartRouter) {
|
if (shouldAutoStartRouter) {
|
||||||
[sBridge startupI2PRouter:self.metaInfo.i2pBase javaBinPath:self.metaInfo.javaBinary];
|
[[SBridge sharedInstance] startupI2PRouter:self.metaInfo.i2pBase javaBinPath:self.metaInfo.javaBinary];
|
||||||
[routerStatus setRouterRanByUs: true];
|
[routerStatus setRouterRanByUs: true];
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
@ -248,7 +247,7 @@ using namespace subprocess;
|
|||||||
[self.swiftRuntime findInstalledI2PVersion];
|
[self.swiftRuntime findInstalledI2PVersion];
|
||||||
|
|
||||||
if (shouldAutoStartRouter) {
|
if (shouldAutoStartRouter) {
|
||||||
[sBridge startupI2PRouter:self.metaInfo.i2pBase javaBinPath:self.metaInfo.javaBinary];
|
[[SBridge sharedInstance] startupI2PRouter:self.metaInfo.i2pBase javaBinPath:self.metaInfo.javaBinary];
|
||||||
[routerStatus setRouterRanByUs: true];
|
[routerStatus setRouterRanByUs: true];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
107
launchers/macosx/osx_create_dmg.sh
Executable file
107
launchers/macosx/osx_create_dmg.sh
Executable file
@ -0,0 +1,107 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
APP_NAME="I2PLauncher"
|
||||||
|
VERSION="0.9.36"
|
||||||
|
DMG_BACKGROUND_IMG="Background.png"
|
||||||
|
|
||||||
|
APP_EXE="${APP_NAME}.app/Contents/MacOS/${APP_NAME}"
|
||||||
|
VOL_NAME="${APP_NAME} ${VERSION}"
|
||||||
|
DMG_TMP="${VOL_NAME}-temp.dmg"
|
||||||
|
DMG_FINAL="${VOL_NAME}.dmg"
|
||||||
|
STAGING_DIR="/tmp/mkdmg$$"
|
||||||
|
|
||||||
|
# Check the background image DPI and convert it if it isn't 72x72
|
||||||
|
_BACKGROUND_IMAGE_DPI_H=`sips -g dpiHeight ${DMG_BACKGROUND_IMG} | grep -Eo '[0-9]+\.[0-9]+'`
|
||||||
|
_BACKGROUND_IMAGE_DPI_W=`sips -g dpiWidth ${DMG_BACKGROUND_IMG} | grep -Eo '[0-9]+\.[0-9]+'`
|
||||||
|
|
||||||
|
if [ $(echo " $_BACKGROUND_IMAGE_DPI_H != 72.0 " | bc) -eq 1 -o $(echo " $_BACKGROUND_IMAGE_DPI_W != 72.0 " | bc) -eq 1 ]; then
|
||||||
|
echo "WARNING: The background image's DPI is not 72. This will result in distorted backgrounds on Mac OS X 10.7+."
|
||||||
|
echo " I will convert it to 72 DPI for you."
|
||||||
|
|
||||||
|
_DMG_BACKGROUND_TMP="${DMG_BACKGROUND_IMG%.*}"_dpifix."${DMG_BACKGROUND_IMG##*.}"
|
||||||
|
|
||||||
|
sips -s dpiWidth 72 -s dpiHeight 72 ${DMG_BACKGROUND_IMG} --out ${_DMG_BACKGROUND_TMP}
|
||||||
|
|
||||||
|
DMG_BACKGROUND_IMG="${_DMG_BACKGROUND_TMP}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# clear out any old data
|
||||||
|
rm -rf "${STAGING_DIR}" "${DMG_TMP}" "${DMG_FINAL}"
|
||||||
|
|
||||||
|
# copy over the stuff we want in the final disk image to our staging dir
|
||||||
|
mkdir -p "${STAGING_DIR}"
|
||||||
|
cp -rpf "${APP_NAME}.app" "${STAGING_DIR}"
|
||||||
|
# ... cp anything else you want in the DMG - documentation, etc.
|
||||||
|
|
||||||
|
# figure out how big our DMG needs to be
|
||||||
|
# assumes our contents are at least 1M!
|
||||||
|
SIZE=`du -sh "${STAGING_DIR}" | sed 's/\([0-9\.]*\)M\(.*\)/\1/'`
|
||||||
|
SIZE=`echo "${SIZE} + 1.0" | bc | awk '{print int($1+0.5)}'`
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Cannot compute size of staging dir"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
# create the temp DMG file
|
||||||
|
hdiutil create -srcfolder "${STAGING_DIR}" -volname "${VOL_NAME}" -fs HFS+ \
|
||||||
|
-fsargs "-c c=64,a=16,e=16" -format UDRW -size ${SIZE}M "${DMG_TMP}"
|
||||||
|
|
||||||
|
echo "Created DMG: ${DMG_TMP}"
|
||||||
|
|
||||||
|
# mount it and save the device
|
||||||
|
DEVICE=$(hdiutil attach -readwrite -noverify "${DMG_TMP}" | \
|
||||||
|
egrep '^/dev/' | sed 1q | awk '{print $1}')
|
||||||
|
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
# add a link to the Applications dir
|
||||||
|
echo "Add link to /Applications"
|
||||||
|
pushd /Volumes/"${VOL_NAME}"
|
||||||
|
ln -s /Applications
|
||||||
|
popd
|
||||||
|
|
||||||
|
# add a background image
|
||||||
|
mkdir /Volumes/"${VOL_NAME}"/.background
|
||||||
|
cp "${DMG_BACKGROUND_IMG}" /Volumes/"${VOL_NAME}"/.background/
|
||||||
|
|
||||||
|
# tell the Finder to resize the window, set the background,
|
||||||
|
# change the icon size, place the icons in the right position, etc.
|
||||||
|
echo '
|
||||||
|
tell application "Finder"
|
||||||
|
tell disk "'${VOL_NAME}'"
|
||||||
|
open
|
||||||
|
set current view of container window to icon view
|
||||||
|
set toolbar visible of container window to false
|
||||||
|
set statusbar visible of container window to false
|
||||||
|
set the bounds of container window to {400, 100, 920, 440}
|
||||||
|
set viewOptions to the icon view options of container window
|
||||||
|
set arrangement of viewOptions to not arranged
|
||||||
|
set icon size of viewOptions to 72
|
||||||
|
set background picture of viewOptions to file ".background:'${DMG_BACKGROUND_IMG}'"
|
||||||
|
set position of item "'${APP_NAME}'.app" of container window to {160, 205}
|
||||||
|
set position of item "Applications" of container window to {360, 205}
|
||||||
|
close
|
||||||
|
open
|
||||||
|
update without registering applications
|
||||||
|
delay 2
|
||||||
|
end tell
|
||||||
|
end tell
|
||||||
|
' | osascript
|
||||||
|
|
||||||
|
sync
|
||||||
|
|
||||||
|
# unmount it
|
||||||
|
hdiutil detach "${DEVICE}"
|
||||||
|
|
||||||
|
# now make the final image a compressed disk image
|
||||||
|
echo "Creating compressed image"
|
||||||
|
hdiutil convert "${DMG_TMP}" -format UDZO -imagekey zlib-level=9 -o "${DMG_FINAL}"
|
||||||
|
|
||||||
|
# clean up
|
||||||
|
rm -rf "${DMG_TMP}"
|
||||||
|
rm -rf "${STAGING_DIR}"
|
||||||
|
|
||||||
|
echo 'Done.'
|
||||||
|
|
||||||
|
exit
|
Reference in New Issue
Block a user