From 9af7722d8bc104ddbea73fa3469706aec0c1a135 Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Sat, 14 Sep 2024 16:06:28 +0200 Subject: [PATCH 1/2] Detect language from GitHub repo --- .../Extensions/AXUIElementExtension.swift | 4 +- WakaTime/Helpers/MonitoringManager.swift | 77 +++++++++++++++++-- WakaTime/WakaTime.swift | 13 +++- 3 files changed, 81 insertions(+), 13 deletions(-) diff --git a/WakaTime/Extensions/AXUIElementExtension.swift b/WakaTime/Extensions/AXUIElementExtension.swift index fe00ae2..44b41bd 100644 --- a/WakaTime/Extensions/AXUIElementExtension.swift +++ b/WakaTime/Extensions/AXUIElementExtension.swift @@ -119,7 +119,7 @@ extension AXUIElement { return nil } - // Traverses the element's subtree (breadth-first) until visitor() returns false or traversal is completed + // Traverses the element's children (breadth-first) until visitor() returns false or traversal is completed func traverseDown(visitor: (AXUIElement) -> Bool) { var queue: [AXUIElement] = [self] while !queue.isEmpty { @@ -144,7 +144,7 @@ extension AXUIElement { } } - // Traverses the element's subtree (breadth-first) until visitor() returns false or traversal is completed + // Traverses the element's parents until visitor() returns false or traversal is completed func traverseUp(visitor: (AXUIElement) -> Bool, element: AXUIElement? = nil) { let element = element ?? self if let parent = element.parent { diff --git a/WakaTime/Helpers/MonitoringManager.swift b/WakaTime/Helpers/MonitoringManager.swift index 0a427c9..6af8ec7 100644 --- a/WakaTime/Helpers/MonitoringManager.swift +++ b/WakaTime/Helpers/MonitoringManager.swift @@ -52,13 +52,20 @@ class MonitoringManager { let entityUnwrapped = entity.0 else { return nil } - return HeartbeatData( + let project = project(for: app, activeWindow) + var language = language(for: app, activeWindow) + if project != nil && language == nil { + language = "<>" + } + + let heartbeat = HeartbeatData( entity: entityUnwrapped, entityType: entity.1, - project: project(for: app, activeWindow), - language: language(for: app), - category: category(for: app) + project: project, + language: language, + category: category(for: app, activeWindow) ) + return heartbeat } static var isMonitoringBrowsing: Bool { @@ -251,8 +258,11 @@ class MonitoringManager { } } - static func category(for app: NSRunningApplication) -> Category? { - guard let monitoredApp = app.monitoredApp else { return .coding } + static func category(for app: NSRunningApplication, _ element: AXUIElement) -> Category { + guard let monitoredApp = app.monitoredApp else { + guard let url = currentBrowserUrl(for: app, element) else { return .coding } + return category(from: url) + } switch monitoredApp { case .adobeaftereffect: @@ -325,6 +335,29 @@ class MonitoringManager { } // swiftlint:enable cyclomatic_complexity + static func category(from url: String) -> Category { + let patterns = [ + "github.com/[^/]+/[^/]+/pull/.*$", + "gitlab.com/[^/]+/[^/]+/[^/]+/merge_requests/.*$", + "bitbucket.org/[^/]+/[^/]+/pull-requests/.*$", + ] + + for pattern in patterns { + do { + let regex = try NSRegularExpression(pattern: pattern) + let nsrange = NSRange(url.startIndex.. String? { guard let monitoredApp = app.monitoredApp else { guard let url = currentBrowserUrl(for: app, element) else { return nil } @@ -346,6 +379,7 @@ class MonitoringManager { static func project(from url: String) -> String? { let patterns = [ "github.com/([^/]+/[^/]+)/?.*$", + "gitlab.com/([^/]+/[^/]+)/?.*$", "bitbucket.org/([^/]+/[^/]+)/?.*$", "app.circleci.com/.*/?(github|bitbucket|gitlab)/([^/]+/[^/]+)/?.*$", "app.travis-ci.com/(github|bitbucket|gitlab)/([^/]+/[^/]+)/?.*$", @@ -376,12 +410,41 @@ class MonitoringManager { return nil } - static func language(for app: NSRunningApplication) -> String? { + static func language(for app: NSRunningApplication, _ element: AXUIElement) -> String? { guard let monitoredApp = app.monitoredApp else { return nil } switch monitoredApp { case .canva: return "Image (svg)" + case .chrome: + do { + guard let url = currentBrowserUrl(for: app, element) else { return nil } + + let regex = try NSRegularExpression(pattern: "github.com/[^/]+/[^/]+/?$") + let nsrange = NSRange(url.startIndex..>", ] - if let project { + if let project = project { args.append("--project") args.append(project) - } - if isWrite { - args.append("--write") + } else { + args.append("--alternate-project") + args.append("<>") } if let language = language { args.append("--language") args.append(language) } + if isWrite { + args.append("--write") + } Logging.default.log("Sending heartbeat with: \(args)") From 5e162cf45d70b658eaf181f0f879f15d42643ee4 Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Sat, 14 Sep 2024 16:18:50 +0200 Subject: [PATCH 2/2] fix unmonitoring apps --- WakaTime/Helpers/MonitoringManager.swift | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/WakaTime/Helpers/MonitoringManager.swift b/WakaTime/Helpers/MonitoringManager.swift index 6af8ec7..ad74380 100644 --- a/WakaTime/Helpers/MonitoringManager.swift +++ b/WakaTime/Helpers/MonitoringManager.swift @@ -102,9 +102,11 @@ class MonitoringManager { } static func set(monitoringState: MonitoringState, for bundleId: String) { - let allApps = allMonitoredApps - if !allApps.contains(bundleId) { - UserDefaults.standard.set(allApps + [bundleId], forKey: monitoringKey) + if monitoringState == .on { + UserDefaults.standard.set(Array(Set(allMonitoredApps + [bundleId])), forKey: monitoringKey) + } else { + let apps = allMonitoredApps.filter { $0 != bundleId } + UserDefaults.standard.set(apps, forKey: monitoringKey) } UserDefaults.standard.synchronize() }