-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwtlogger.py
More file actions
197 lines (151 loc) · 6.56 KB
/
Copy pathwtlogger.py
File metadata and controls
197 lines (151 loc) · 6.56 KB
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
import time
import datetime
import atexit
import sys
import os
import webbrowser
from PIL import Image
import pystray
from tkinter.messagebox import showinfo, showerror
import modules.process_info as procinfo
import modules.ui as ui
import modules.configfile as configfile
script_dir = os.path.dirname(os.path.realpath(__file__))
def file_append_line(path, string):
with open(path, "a", encoding="utf-8") as file:
file.write(string)
def log_message(path, string):
try:
print(string)
file_append_line(path, string+"\n")
except PermissionError:
print(f"ERROR: Permission denied for file {path}. Make sure the program has the correct permissions. Try running as admin.")
showerror("Error", f"Permission denied for file {path}. Make sure the program has the correct permissions. Try running as admin.")
sys.exit(1)
class App:
def main(self):
self.stop_flag = False
self.log_started = False
self.proc_name = ""
if len(sys.argv) == 1:
#self.proc_name = input("Process name to log: ")
self.ui = ui.ProcessSelectGUI(
log_loop_func=self.log_loop_from_ui,
logs_folder_func=self.open_logs_dir,
script_dir=script_dir
)
self.ui.mainloop()
else:
self.proc_name = sys.argv[1]
print("Process to log: ",self.proc_name)
self.log_loop(self.proc_name)
def log_loop_from_ui(self, proc_name):
self.ui.destroy()
self.proc_name = proc_name
self.log_loop(proc_name)
#Bucle de logeo
def log_loop(self, proc_name):
#Carga la configuracion
config = configfile.load_config(script_dir+"/config.json")
ui.send_toast(
f"Started logging {proc_name}",
f"Window Title Logger started logging the process {proc_name} into the file {proc_name}.log. You can access the logger from the system tray.",
script_dir+'/strayico.ico'
)
if not os.path.isdir(script_dir + "/logs/"):
os.mkdir(script_dir + "/logs/")
log_file_path = script_dir + "/logs/" + proc_name+".log"
last_title = ""
#Crea el icono
self.sticon = SystemTrayIcon(
cancel_func = self.cancel_logging,
open_log_func = self.open_log,
process_logging = self.proc_name
)
self.sticon.setup_system_tray()
atexit.register(self.exit_handler)
#Espera a que el programa arranque
print("Waiting for the process to start...")
seconds = 30
while seconds > 0:
proc_handle = procinfo.get_proc_handle(proc_name)
t = procinfo.get_window_title_by_handle(proc_handle)
if proc_handle != None and t != None:
break
#Si lo cancelan deja de esperar al proceso
if self.stop_flag:
seconds = -1
break
time.sleep(config["wait_time_interval"])
seconds -= config["wait_time_interval"]
#Si seconds es 0 quiere decir timeout, no encontro el programa y sale sin esperar.
if seconds <= 0:
print("Timeout. Exiting...")
return
self.log_started = True
log_message(log_file_path, f"--- Log started for process {proc_name}, at {datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")} ---")
#Bucle principal donde registra los titulos
while True:
# Flag para cancelar el logger desde el systray
if self.stop_flag:
break
proc_handle = procinfo.get_proc_handle(proc_name)
#Si es none quiere decir que el proceso logueado se termino de ejecutar. Entonces cierra el bucle
if proc_handle == None:
break
proc_title = procinfo.get_window_title_by_handle(proc_handle)
if last_title != proc_title:
log_message(log_file_path, f"[{datetime.datetime.now().strftime("%d/%m/%Y %I:%M%p")}] "+proc_title)
last_title = proc_title
#TODO: Crear un menu de configuracion donde se ajuste el tiempo de espera a nuevo escaneo.
time.sleep(config["log_time_interval"])
#Fin del programa.
log_message(log_file_path,f"--- Process {proc_name} finished, at {datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")} ---")
#Para el icono del system tray
self.sticon.stop_system_tray()
ui.send_toast(
f"Stopped logging {proc_name}",
f"Window Title Logger finished logging the process {proc_name}.",
script_dir+'/strayico.ico'
)
#Manejador de cerrar el programa
def exit_handler(self):
#Fin del programa.
if self.log_started:
log_message(script_dir + "/logs/" + self.proc_name+".log", f"--- Logger terminated, at {datetime.datetime.now().strftime("%I:%M%p on %B %d, %Y")} ---")
self.sticon.stop_system_tray()
#Cancela el loggeo poniendo el flag de parar como True;
#Este se chequea en cada iteracion del bucle principal; Si es True se interrumpe.
def cancel_logging(self):
self.stop_flag = True
#Abre el archivo de log
def open_log(self):
log_path = script_dir+"/logs/"+self.proc_name+".log"
print(f"Opening file: {log_path}")
if os.path.exists(log_path):
webbrowser.open(log_path)
def open_logs_dir(self):
webbrowser.open(script_dir+"/logs/")
class SystemTrayIcon():
def __init__(self, cancel_func = None, open_log_func = None, process_logging = "PROCESS LOGGING"):
self.icon = None
self.cancel_func = cancel_func
self.open_log_func = open_log_func
self.process_logging = process_logging
def setup_system_tray(self):
image = Image.open(script_dir+"/strayico.ico")
menu = (pystray.MenuItem(f' - Process logging: {self.process_logging} - ', None),
pystray.MenuItem('Open log file', self.open_log_func),
pystray.MenuItem('End logging',self.cancel_logging))
self.icon = pystray.Icon("Window Title Logger", image, "Window Title Logger", menu)
self.icon.run_detached(setup=self.icon_loop)
def stop_system_tray(self):
self.icon.stop()
def cancel_logging(self):
self.icon.stop()
self.cancel_func()
def icon_loop(self, icon):
icon.visible = True
if __name__ == '__main__':
app = App()
app.main()