Skip to content

Commit

Permalink
Provide network port selection
Browse files Browse the repository at this point in the history
  • Loading branch information
gao-sun committed Jun 14, 2021
1 parent 262c89f commit bb76a71
Show file tree
Hide file tree
Showing 25 changed files with 120 additions and 14 deletions.
2 changes: 2 additions & 0 deletions Resource/ar.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "داخل";
"network.out" = "خارج";
"network.no_activity" = "لا يوجد نشاط";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "Summary";
Expand Down
2 changes: 2 additions & 0 deletions Resource/cs.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "In";
"network.out" = "Out";
"network.no_activity" = "Žádná aktivita";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "Souhrn";
Expand Down
2 changes: 2 additions & 0 deletions Resource/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "Empfangen";
"network.out" = "Gesendet";
"network.no_activity" = "Keine Aktivität";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "Zusammenfassung";
Expand Down
2 changes: 2 additions & 0 deletions Resource/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "In";
"network.out" = "Out";
"network.no_activity" = "No activity";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "Summary";
Expand Down
2 changes: 2 additions & 0 deletions Resource/es.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "Entrada";
"network.out" = "Salida";
"network.no_activity" = "Sin actividad";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "Resumen";
Expand Down
2 changes: 2 additions & 0 deletions Resource/fr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "Entrée";
"network.out" = "Sortie";
"network.no_activity" = "Aucune activité";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "Sommaire";
Expand Down
2 changes: 2 additions & 0 deletions Resource/hu.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "Be";
"network.out" = "Ki";
"network.no_activity" = "Tétlen";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "Összefoglaló";
Expand Down
2 changes: 2 additions & 0 deletions Resource/it.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
"network.in" = "Download";
"network.out" = "Upload";
"network.no_activity" = "Inattiva";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "Sommario";
Expand Down
2 changes: 2 additions & 0 deletions Resource/ja.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "受信";
"network.out" = "送信";
"network.no_activity" = "アクティビティなし";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "サマリー";
Expand Down
2 changes: 2 additions & 0 deletions Resource/ko.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ battery.timeRemaining = "Time Rem.";
"network.in" = "수신된 바이트";
"network.out" = "송신된 바이트";
"network.no_activity" = "활동 없음";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "요약";
Expand Down
2 changes: 2 additions & 0 deletions Resource/mn.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "Оролт";
"network.out" = "Гаралт";
"network.no_activity" = "Идэвхигүй";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "Summary";
Expand Down
2 changes: 2 additions & 0 deletions Resource/my.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "ဝင်";
"network.out" = "ထွက်";
"network.no_activity" = "Activity မရှိပါ";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "အကျဉ်းချုပ်";
Expand Down
2 changes: 2 additions & 0 deletions Resource/pt.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "Recebido";
"network.out" = "Enviado";
"network.no_activity" = "Sem atividade";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "Sumário";
Expand Down
2 changes: 2 additions & 0 deletions Resource/ru.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "Входящ.";
"network.out" = "Исходящ.";
"network.no_activity" = "Нет активности";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "Суммарно";
Expand Down
2 changes: 2 additions & 0 deletions Resource/th.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "ได้รับ";
"network.out" = "ส่ง";
"network.no_activity" = "ไม่มีกิจกรรม";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "สรุป";
Expand Down
2 changes: 2 additions & 0 deletions Resource/uk.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "Отримано/c";
"network.out" = "Відправлено/c";
"network.no_activity" = "Немає активності";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "Підсумок";
Expand Down
2 changes: 2 additions & 0 deletions Resource/zh-Hans.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "下载";
"network.out" = "上传";
"network.no_activity" = "无活动";
"network.port.auto" = "自动检测";
"network.port.select" = "选择端口";

// MARK: Menu
"menu.summary" = "概览";
Expand Down
2 changes: 2 additions & 0 deletions Resource/zh-Hant.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"network.in" = "下載";
"network.out" = "上傳";
"network.no_activity" = "無活動";
"network.port.auto" = "Auto-detect";
"network.port.select" = "Port";

// MARK: Menu
"menu.summary" = "概覽";
Expand Down
4 changes: 4 additions & 0 deletions SharedLibrary/Extension/String.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ public extension String {
filter("0123456789.".contains)
}

var nilIfEmpty: String? {
trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ? nil : self
}

func firstMatch(_ pattern: String) -> NSTextCheckingResult? {
let range = NSRange(location: 0, length: utf16.count)
guard let regex = try? NSRegularExpression(pattern: pattern) else {
Expand Down
8 changes: 4 additions & 4 deletions eul.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1656,7 +1656,7 @@
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 6;
CURRENT_PROJECT_VERSION = 7;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = M8G2RFZVFV;
DYLIB_COMPATIBILITY_VERSION = 1;
Expand All @@ -1670,7 +1670,7 @@
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 1.0.5;
MARKETING_VERSION = 1.0.6;
PRODUCT_BUNDLE_IDENTIFIER = com.gaosun.eul.SharedLibrary;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
Expand All @@ -1687,7 +1687,7 @@
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 6;
CURRENT_PROJECT_VERSION = 7;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = M8G2RFZVFV;
DYLIB_COMPATIBILITY_VERSION = 1;
Expand All @@ -1701,7 +1701,7 @@
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 10.15;
MARKETING_VERSION = 1.0.5;
MARKETING_VERSION = 1.0.6;
PRODUCT_BUNDLE_IDENTIFIER = com.gaosun.eul.SharedLibrary;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
Expand Down
4 changes: 4 additions & 0 deletions eul/Schema/EulComponent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ enum EulComponent: String, CaseIterable, Identifiable, Codable, JSONCodabble, Lo
self == .Disk
}

var isNetworkInterfaceSelectionAvailable: Bool {
self == .Network
}

func getView() -> AnyView {
switch self {
case .Battery:
Expand Down
6 changes: 6 additions & 0 deletions eul/Schema/EulComponentConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ struct EulComponentConfig: Codable {
var showIcon: Bool = true
var showGraph: Bool = false
var diskSelection: String = ""
var networkPortSelection: String = ""

var json: JSON {
JSON([
"component": component.rawValue,
"showIcon": showIcon,
"showGraph": showGraph,
"diskSelection": diskSelection,
"networkPortSelection": networkPortSelection,
])
}
}
Expand All @@ -44,5 +46,9 @@ extension EulComponentConfig {
if let string = json["diskSelection"].string {
diskSelection = string
}

if let string = json["networkPortSelection"].string {
networkPortSelection = string
}
}
}
18 changes: 17 additions & 1 deletion eul/Store/NetworkStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ class NetworkStore: ObservableObject, Refreshable {
private var lastTimestamp: TimeInterval

@Published var networkUsage = Info.NetworkUsage(inBytes: 0, outBytes: 0)
@Published var ports = [Info.NetworkPort]()
@Published var currentActivePort: Info.NetworkPort?

@Published var inSpeedInByte: Double = 0
@Published var outSpeedInByte: Double = 0

var config: EulComponentConfig {
SharedStore.componentConfig[EulComponent.Network]
}

var inSpeed: String {
ByteUnit(inSpeedInByte).readable + "/s"
}
Expand All @@ -27,14 +33,22 @@ class NetworkStore: ObservableObject, Refreshable {
ByteUnit(outSpeedInByte).readable + "/s"
}

var autoPortDesscription: String {
guard let currentActivePort = currentActivePort else {
return "network.port.auto".localized()
}

return "\("network.port.auto".localized()) (\(currentActivePort.device))"
}

@objc func refresh() {
guard networkUsageHasBeenSet else {
return
}

networkUsageHasBeenSet = false

Info.getNetworkUsage { [self] current in
Info.getNetworkUsage(forDevice: config.networkPortSelection.nilIfEmpty) { [self] current, ports, currentActivePort in
let time = Date().timeIntervalSince1970

if networkUsage.inBytes > 0, current.inBytes >= networkUsage.inBytes {
Expand All @@ -51,6 +65,8 @@ class NetworkStore: ObservableObject, Refreshable {

lastTimestamp = time
networkUsage = current
self.ports = ports
self.currentActivePort = currentActivePort
writeToContainer()
networkUsageHasBeenSet = true
}
Expand Down
40 changes: 31 additions & 9 deletions eul/Utilities/Info.swift
Original file line number Diff line number Diff line change
Expand Up @@ -104,23 +104,45 @@ enum Info {
var outBytes: UInt64
}

struct NetworkPort: Identifiable {
var port: String?
var device: String

var id: String {
device
}

var description: String {
guard let port = port else {
return device
}
return "\(port) (\(device))"
}
}

struct InterfaceStatus {
var name: String
var status: String?
}

static func findPort(_ string: String) -> String? {
static func findPort(_ string: String) -> NetworkPort? {
guard string.hasPrefix("("), string.hasSuffix(")") else {
return nil
}

let trimmed = String(string.dropFirst().dropLast())

guard let matched = trimmed.firstMatch("Device: ([^,]+)")?.range(at: 1), let range = Range(matched, in: trimmed) else {
guard let matched = trimmed.firstMatch("Device: ([^,]+)")?.range(at: 1), let deviceRange = Range(matched, in: trimmed) else {
return nil
}

return String(trimmed[range])
var port: String?
let device = String(trimmed[deviceRange])
if let matched = trimmed.firstMatch("Port: ([^,]+)")?.range(at: 1), let portRange = Range(matched, in: trimmed) {
port = String(trimmed[portRange])
}

return NetworkPort(port: port, device: device)
}

static func getActiveInterfaces() -> [String] {
Expand All @@ -145,24 +167,24 @@ enum Info {
} ?? []
}

static func getNetworkUsage(_ onData: @escaping (NetworkUsage) -> Void) {
static func getNetworkUsage(forDevice: String?, _ onData: @escaping (NetworkUsage, [NetworkPort], NetworkPort?) -> Void) {
// TO-DO: use Combine
shellAsync("networksetup -listnetworkserviceorder") {
let services = $0?.split(separator: "\n").map(String.init).compactMap(Info.findPort) ?? []
let activeInterfaces = Info.getActiveInterfaces()
let currentActiveInterface = services.first(where: activeInterfaces.contains)
let currentActivePort = services.first(where: { activeInterfaces.contains($0.device) })

Print("network services order", services)
Print("network active interfaces", activeInterfaces)
Print("network current active interfaces", currentActiveInterface ?? "N/A")
Print("network current active interfaces", currentActivePort ?? "N/A")

var inBytes: UInt64?
var outBytes: UInt64?

let interface = currentActiveInterface ?? "en0"
let device = forDevice ?? currentActivePort?.device ?? "en0"

if
let rows = shell("netstat -bI \(interface)")?.split(separator: "\n").map({ String($0) }),
let rows = shell("netstat -bI \(device)")?.split(separator: "\n").map({ String($0) }),
rows.count > 1
{
let headers = rows[0].splittedByWhitespace
Expand All @@ -178,7 +200,7 @@ enum Info {
}

DispatchQueue.main.async {
onData(NetworkUsage(inBytes: inBytes ?? 0, outBytes: outBytes ?? 0))
onData(NetworkUsage(inBytes: inBytes ?? 0, outBytes: outBytes ?? 0), services, currentActivePort)
}
}
}
Expand Down
Loading

0 comments on commit bb76a71

Please sign in to comment.