Просмотр исходного кода

refactored to simpler formatter and cleanup autosens

Marc R Kellerman 1 год назад
Родитель
Сommit
85bf02a575
1 измененных файлов с 84 добавлено и 61 удалено
  1. 84 61
      FreeAPS/Sources/APS/OpenAPS/JavaScriptWorker.swift

+ 84 - 61
FreeAPS/Sources/APS/OpenAPS/JavaScriptWorker.swift

@@ -4,28 +4,13 @@ import JavaScriptCore
 private let contextLock = NSRecursiveLock()
 
 extension String {
-    func replacingRegex(
-        matching pattern: String,
-        findingOptions: NSRegularExpression.Options = .caseInsensitive,
-        replacingOptions: NSRegularExpression.MatchingOptions = [],
-        with template: String
-    ) throws -> String {
-        let regex = try NSRegularExpression(pattern: pattern, options: findingOptions)
-        let range = NSRange(startIndex..., in: self)
-        return regex.stringByReplacingMatches(in: self, options: replacingOptions, range: range, withTemplate: template)
-    }
-}
-
-extension String {
     var lowercasingFirst: String { prefix(1).lowercased() + dropFirst() }
     var uppercasingFirst: String { prefix(1).uppercased() + dropFirst() }
-
     var camelCased: String {
         guard !isEmpty else { return "" }
         let parts = components(separatedBy: .alphanumerics.inverted)
         let first = parts.first!.lowercasingFirst
         let rest = parts.dropFirst().map(\.uppercasingFirst)
-
         return ([first] + rest).joined()
     }
 
@@ -34,7 +19,6 @@ extension String {
         let parts = components(separatedBy: .alphanumerics.inverted)
         let first = parts.first!.uppercasingFirst
         let rest = parts.dropFirst().map(\.uppercasingFirst)
-
         return ([first] + rest).joined()
     }
 }
@@ -43,7 +27,8 @@ final class JavaScriptWorker {
     private let processQueue = DispatchQueue(label: "DispatchQueue.JavaScriptWorker")
     private let virtualMachine: JSVirtualMachine
     @SyncAccess(lock: contextLock) private var commonContext: JSContext? = nil
-    private var aggregatedLogs: [String] = [] // Step 1: Property to store log messages
+    private var aggregatedLogs: [String] = []
+    private var logFormatting: String = ""
 
     init() {
         virtualMachine = processQueue.sync { JSVirtualMachine()! }
@@ -57,39 +42,11 @@ final class JavaScriptWorker {
             }
         }
         let consoleLog: @convention(block) (String) -> Void = { message in
-
-            // Step 1: Format/Leandup the log entry using RegEx
-            var parsedMessage = message.trimmingCharacters(in: .whitespacesAndNewlines)
-            parsedMessage = try! parsedMessage.replacingRegex(matching: ";", with: ", ")
-            parsedMessage = try! parsedMessage.replacingRegex(matching: "\\s?:\\s?,?", with: ": ")
-            parsedMessage = try! parsedMessage.replacingRegex(matching: "(\\w+: \\d+(?= [^,:\\s]+:))", with: "$1,")
-            parsedMessage = try! parsedMessage.replacingRegex(matching: "^[^\\w]*", with: "")
-            parsedMessage = try! parsedMessage.replacingRegex(matching: "(\\sset)?\\sto:?\\s+", with: ": ")
-            parsedMessage = try! parsedMessage.replacingRegex(matching: "(\\w+) is (\\w+)\\!?", with: "$1: $2")
-            parsedMessage = try! parsedMessage.replacingRegex(matching: "NaN \\(\\. (.+)\\)", with: "$1, ")
-            parsedMessage = try! parsedMessage.replacingRegex(matching: "Setting (.+) of (.*)", with: "$1: $2 ")
-            parsedMessage = try! parsedMessage.replacingRegex(matching: "(Using\\s|\\sused)", with: "")
-            parsedMessage = try! parsedMessage.replacingRegex(
-                matching: " instead of past 24 h \\((" + "(-?\\d+(\\.\\d+)?)" + " U)\\)",
-                with: "weighted TDD average past 24h: $1"
-            )
-            parsedMessage = try! parsedMessage.replacingRegex(matching: "^(.+) \\((.+)\\)$", with: "$1: $2")
-            parsedMessage = try! parsedMessage.replacingRegex(matching: "\\s?,\\s?$", with: "")
-
-            // Step 2: Split parsedMessage by ',' and, then split by ':' to get the key-value pair
-            var keyPairResults = "    "
-            parsedMessage.split(separator: ",").forEach { property in
-                let keyPair = property.split(separator: ":")
-                if keyPair.count != 2 {
-                    keyPairResults += "\"unknown\": \"\(property)\", "
-                } else {
-                    // Step 3: Convert the key to a PascalCased string
-                    let key = keyPair[0].trimmingCharacters(in: .whitespacesAndNewlines).pascalCased
-                    let value = keyPair[1].trimmingCharacters(in: .whitespacesAndNewlines)
-                    keyPairResults += "\"\(key)\": \"\(value)\", "
-                }
+            let trimmedMessage = message.trimmingCharacters(in: .whitespacesAndNewlines)
+            if !trimmedMessage.isEmpty {
+//                debug(.openAPS, "JavaScript log: \(trimmedMessage)")
+                self.aggregatedLogs.append("\(trimmedMessage)")
             }
-            self.aggregatedLogs.append("\(keyPairResults)")
         }
         context.setObject(
             consoleLog,
@@ -100,26 +57,92 @@ final class JavaScriptWorker {
 
     // New method to flush aggregated logs
     private func aggregateLogs() {
-        let combinedLogs = aggregatedLogs.joined(separator: "\n")
+        let combinedLogs = aggregatedLogs.joined(separator: "\n").trimmingCharacters(in: .whitespacesAndNewlines)
         aggregatedLogs.removeAll()
 
-        if !combinedLogs.isEmpty {
-            // Check if combinedLogs is a valid JSON string. If so, print it as JSON, if not, print it as a string
-            if let jsonData = "{\(combinedLogs)}".data(using: .utf8) {
-                do {
-                    let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: [])
-                    _ = try JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted)
-                    debug(.openAPS, "JavaScript log [JSON]: \n{\n\(combinedLogs)\n}")
-                } catch {
-                    debug(.openAPS, "JavaScript log: \(combinedLogs)")
+        if combinedLogs.isEmpty { return }
+
+        var logOutput = ""
+        var jsonOutput = ""
+        if logFormatting == "Middleware" {
+            jsonOutput += "{\n"
+            combinedLogs.replacingOccurrences(of: ";", with: ",")
+                .replacingOccurrences(of: "\\s?:\\s?,?", with: ": ", options: .regularExpression)
+                .replacingOccurrences(of: "(\\w+: \\d+(?= [^,:\\s]+:))", with: "$1,", options: .regularExpression)
+                .replacingOccurrences(of: "^[^\\w]*", with: "", options: .regularExpression)
+                .replacingOccurrences(of: "(\\sset)?\\sto:?\\s+", with: ": ", options: .regularExpression)
+                .replacingOccurrences(of: "(\\w+) is (\\w+)\\!?", with: "$1: $2", options: .regularExpression)
+                .replacingOccurrences(of: "NaN \\(\\. (.+)\\)", with: "$1, ", options: .regularExpression)
+                .replacingOccurrences(of: "Setting (.+) of (.*)", with: "$1: $2 ", options: .regularExpression)
+                .replacingOccurrences(of: "(Using\\s|\\sused)", with: "", options: .regularExpression)
+                .replacingOccurrences(
+                    of: " instead of past 24 h \\((" + "(-?\\d+(\\.\\d+)?)" + " U)\\)",
+                    with: "weighted TDD average past 24h: $1",
+                    options: .regularExpression
+                )
+                .replacingOccurrences(of: "^(.+) \\((.+)\\)$", with: "$1: $2", options: .regularExpression)
+                .replacingOccurrences(of: "\\s?,\\s?$", with: "", options: .regularExpression)
+                .split(separator: "\n").forEach { logLine in
+                    jsonOutput += "    "
+                    logLine.split(separator: ",").forEach { logItem in
+                        let keyPair = logItem.split(separator: ":")
+                        if keyPair.count != 2 {
+                            jsonOutput += "\"unknown\": \"\(logItem)\", "
+                        } else {
+                            let key = keyPair[0].trimmingCharacters(in: .whitespacesAndNewlines).pascalCased
+                            let value = keyPair[1].trimmingCharacters(in: .whitespacesAndNewlines)
+                            jsonOutput += "\"\(key)\": \"\(value)\", "
+                        }
+                    }
+                    jsonOutput += "\n"
                 }
-            } else {
-                debug(.openAPS, "JavaScript log: \(combinedLogs)")
+            jsonOutput += "}"
+        }
+
+        if logFormatting == "prepare/autosens.js" {
+            logOutput += combinedLogs.replacingOccurrences(
+                of: "((?:[\\=\\+\\-]\\n)+)?\\d+h\\n((?:[\\=\\+\\-]\\n)+)?",
+                with: "",
+                options: .regularExpression
+            )
+        }
+
+        if logFormatting == "prepare/autotune-prep.js" {
+            // print(combinedLogs)
+        }
+
+        if logFormatting == "prepare/autotune-core.js" {
+            // print(combinedLogs)
+        }
+
+        debug(.openAPS, "JavaScript Format: \(logFormatting)")
+
+        // Check if combinedLogs is a valid JSON string. If so, print it as JSON, if not, print it as a string
+        if let jsonData = "\(jsonOutput)".data(using: .utf8) {
+            do {
+                let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: [])
+                _ = try JSONSerialization.data(withJSONObject: jsonObject, options: .prettyPrinted)
+                debug(.openAPS, "JavaScript log: \(jsonOutput)")
+                return
+            } catch {
+                // debug(.openAPS, "JavaScript log: \(combinedLogs)")
+            }
+        }
+
+        if !logOutput.isEmpty {
+            logOutput.split(separator: "\n").forEach { logLine in
+                debug(.openAPS, "JavaScript log: \(logLine)")
             }
+            return
+        }
+
+        combinedLogs.split(separator: "\n").forEach { logLine in
+            debug(.openAPS, "JavaScript log: \(logLine)")
         }
     }
 
     @discardableResult func evaluate(script: Script) -> JSValue! {
+        logFormatting = script.name
         let result = evaluate(string: script.body)
         aggregateLogs()
         return result