-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp-tracker.ahk
135 lines (116 loc) · 4.06 KB
/
app-tracker.ahk
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
; App tracker AHK script, to detect window/process running and secretly send email alert
#SingleInstance Force
#Requires AutoHotkey v2.0
#include lib/SendEmail.ahk
#include lib/MergeObjects.ahk
#include lib/FetchGoogleSpreadsheet.ahk
#include lib/UseBase64TrayIcon.ahk
#include lib/RemoveTrayTooltip.ahk
#include lib/Jsons.ahk
SetTitleMatchMode "RegEx"
global config := {
localConfig: "./config.json", ; remoteConfig > localConfig > config
remoteConfig: "", ; googleDocId or url, see https://docs.google.com/spreadsheets/d/13uh9TW2axb28s9i2lOH9ShnHjEdAqKyGZayvVwDs1CA
apps: ["test"], ; array of apps to detect, e.g. substring of window title ("roblox") or full process name ("photoshop.exe") (string with comma as separator)
checkPeriodSeconds: 20, ; (20 seconds) interval between scans for apps running
alertLimitSeconds: 60 * 60 * 3, ; (3 hours) minimum interval between two alerts, to prevent spamming
alertOnUserExit: false, ; if true, send special email on user to close app tracker
trayIcon: "transparent", ; one of "bell", "eye", "shield", "transparent" or path to local file ("./ico/radar.ico")
smtp: { ; smtp account to send email alert
username: "[email protected]",
password: "" ; create app password https://security.google.com/settings/security/apppasswords
},
email: { ; alert' email settings
from: "App Spy <[email protected]>", ; address must be the same as smtp.username
to: "Tester <[email protected]>, [email protected]",
subj: "email.subj",
bodyPrefix: "email.body.prefix<br/>", ; html is acceptable
bodySuffix: "email.body.suffix<br/>"
},
debug: false
}
config := MergeObjects(config, ReadJson(config.localConfig)) ; local config to take pecedence
if (config.HasOwnProp("remoteConfig")) {
config := MergeObjects(config, FetchGoogleSpreadsheet(config.remoteConfig,,,config.debug)) ; remote config to take pecedence
}
global s := {} ; global storage of script' state
s.appsFound := ""
s.secondsSinceAlert := config.alertLimitSeconds + 1 ; init as if limit has been passed
RunAppTracker() ; main routine
RunAppTracker() {
if (config.debug)
MsgBox "config + localConfig + remoteConfig: `r`n" Jsons.Dump(config, 4)
SetTimer CheckAppsRunning, 1000 * config.checkPeriodSeconds ; main routine
RemoveTrayTooltip()
SetTrayIcon(config.trayIcon)
OnExit HandleExit
}
CheckAppsRunning() {
s.secondsSinceAlert += config.checkPeriodSeconds
apps := config.apps
if !(apps is Array)
apps := StringToArray(config.apps)
if apps.Length < 1
return
; lookup for running apps
for appSubstring in apps {
rexp := "i).*" appSubstring ".*"
count := WinGetCount(rexp)
if (count == 0 and ProcessExist(appSubstring)) {
count := 1
}
if (count != 0) {
if (s.appsFound == "") {
s.appsFound := appSubstring " (" count ")"
} else {
s.appsFound .= ", " appSubstring " (" count ")"
}
}
}
if (s.appsFound != "") {
if (s.secondsSinceAlert > config.alertLimitSeconds)
AlertEmail()
s.appsFound := "" ; cleanup
}
}
AlertEmail() {
_email := config.email.Clone()
_email.subj := config.email.subj . " " . FormatTime(, "(HH:mm, dddd)")
_email.body := config.email.bodyPrefix . s.appsFound . "<br/>" . config.email.bodySuffix
SendEmail(config.smtp, _email, config.debug)
s.secondsSinceAlert := 0 ; cleanup
}
ReadJson(path, fileReadOptions := "UTF-8") {
if !FileExist(path) {
if (config.debug)
MsgBox('json file not found: ' path)
return {}
}
text := FileRead(path, fileReadOptions)
obj := Jsons.Load(&text)
return MergeObjects({}, obj)
}
HandleExit(ExitReason, ExitCode) {
if !(ExitReason ~= "^(?i:Logoff|Shutdown)$") {
if (config.alertOnUserExit) {
_email := config.email.Clone()
_email.subj := "App tracker closed! (" . A_ComputerName . ", " . FormatTime(, "HH:mm, dddd)")
_email.body := "User explicitly closed app tracker.<br/><br/>" . config.email.bodySuffix
SendEmail(config.smtp, _email, config.debug)
}
}
}
SetTrayIcon(nameOrPath) {
if (InStr(nameOrPath, ".")) {
if FileExist(nameOrPath)
TraySetIcon(nameOrPath)
} else {
UseBase64TrayIcon(config.trayIcon)
}
}
StringToArray(v) {
if !(v is String) {
return []
}
return StrSplit(v, ",")
}