1- #process checker
1+ #Process Monitor
2+ # Created by @Gitago for TouchPortal
3+ # Jan, 2023
24
35
46## BUGS
57## when checking for a process if its NOT loaded, then no states are made or mention that its not running.. but if its runing then you close it updates as expected
6-
8+ # when stopping a monitor it doesnt seem to clear the length of total?
79
810import TouchPortalAPI as TP
911from argparse import ArgumentParser
1517import sys
1618import webbrowser
1719import time
20+ import requests
21+ import base64
22+ import time
1823
1924PLUGIN_NAME = "Process Monitor"
2025PLUGIN_ID = "tp.plugin.process_monitor"
2126GITHUB_URL = "process-monitor-touchportal-plugin"
2227# DEFAULT_CONFIG_SAVE_PATH = path.join(path.dirname(path.realpath(__file__)), "color_config.json")
2328
24- def handleSettings (settings , on_connect = False ):
25- ## Setting the Color Naming Convention based on user input
26- print ("Settings: " + str (settings ))
27- # the_colors.color_name_setting = settings[0]['Color Names - Can be changed via plugin actions']
28- # TPClient.stateUpdate(stateId=PLUGIN_ID + ".state.current_text_name_style", stateValue=the_colors.color_name_setting)
29-
30-
3129
3230
3331
34-
35-
36- import time
32+ process_monitor_choiceList = []
33+ process_monitor_dict = {}
3734
3835class ProcessChecker :
3936 def __init__ (self , process_name ):
4037 self .process_name = process_name
4138 self .should_continue = True
42-
39+ # self.process_monitor_choiceList = []
4340
4441
4542 def time_completion (self , data , the_process ):
@@ -50,31 +47,36 @@ def time_completion(self, data, the_process):
5047 print ("Task completed in: " , completion_time , " seconds" )
5148
5249
53- def the_task (self , data , the_process ):
50+ def the_task (self , process_name , the_process ):
5451 process_checked = self .is_running ()
5552
53+ global process_monitor_choiceList
54+
55+ # print("This is process checked the is_running stuff", process_checked)
5656
5757 if process_checked == False :
5858 for x in ['pid' , 'username' , 'cpu_percent' , 'memory_percent' , 'cmdline' , 'create_time' ]:
5959 TPClient .createState (stateId = PLUGIN_ID + f".state.{ self .process_name } .process_info.{ x } " , description = f"PM | { self .process_name } - { x } " , value = "" , parentGroup = str (self .process_name ))
6060
61- process_monitor_dict [data ] = the_process
62- TPClient .stateUpdate (stateId = PLUGIN_ID + ".state.process_monitor.count" , stateValue = str (len (process_monitor_dict .keys ())))
63-
61+ # Updating Status to "Closed" since the process appears to not be running
6462 TPClient .createState (stateId = PLUGIN_ID + f".state.{ self .process_name } .process_info.status" , description = f"PM | { self .process_name } - status" , value = "Closed" , parentGroup = str (self .process_name ))
6563
66-
6764 if process_checked :
68- process_monitor_dict [data ] = the_process
65+ process_monitor_dict [process_name ] = the_process
6966 the_list = list (process_monitor_dict .keys ())
7067 the_list .append ("ALL" )
7168
72- TPClient .choiceUpdate (choiceId = PLUGIN_ID + ".act.process_name.stop" , values = the_list )
69+ # Checking to see if the Process monitor Choice List is the same, if so we dont update it
70+ if process_monitor_choiceList != the_list :
71+ ## submitted a PR for this to be added to the API by default
72+ TPClient .choiceUpdate (choiceId = PLUGIN_ID + ".act.process_name.stop" , values = the_list )
73+
74+ process_monitor_choiceList = the_list
7375
7476 ## update a state showing how many values are in the list minus the "ALL" value
7577 TPClient .stateUpdate (stateId = PLUGIN_ID + ".state.process_monitor.count" , stateValue = str (len (the_list ) - 1 ))
7678
77- print (f"{ the_process .process_name } is running" )
79+ # print(f"{the_process.process_name} is running")
7880
7981 for x in process_checked :
8082 if x == 'memory_percent' :
@@ -90,47 +92,38 @@ def the_task(self, data, the_process):
9092
9193 ## use a thread to create sttes as fast as possible
9294 TPClient .createState (stateId = PLUGIN_ID + f".state.{ the_process .process_name } .process_info.{ x } " , description = f"PM | { the_process .process_name } - { x } " , value = str (process_checked .get (x , "None" )), parentGroup = str (the_process .process_name ))
93-
94-
95-
95+
96+
9697 def is_running (self ):
9798
9899 for process in psutil .process_iter ():
99- if process .name () == self .process_name :
100+ if process .name (). lower () == self .process_name . lower () :
100101 process_Info = process .as_dict (attrs = ['pid' , 'name' , 'username' , 'cpu_percent' , 'memory_percent' , 'cmdline' , 'create_time' , 'status' ])
102+ # print("Before joiing the cmdline: ", process_checked)
103+ process_Info ["cmdline" ] = ' ' .join (process_Info ["cmdline" ])
104+
105+ # print("After joiing the cmdline: ", process_checked)
106+ # memory_info = process.memory_info().rss
107+ # memory_mb = memory_info / 1048576
108+ # process_Info['memory_MB'] = memory_mb
101109 return process_Info
102110
103111 return False
104112
105113
106- def check_continuously (self , interval , data , the_process ):
114+ def check_continuously (self , interval , process_name , the_process ):
107115 while self .should_continue :
108116 g_log .debug ("Checking if " + self .process_name + " is running" )
109117 # print("Checking if ", self.process_name, " is running")
110- self .the_task (data , the_process = the_process )
118+
119+ self .the_task (process_name = process_name , the_process = the_process )
111120 time .sleep (interval )
112121
113122 return False
114123
115124
116-
117125 def stop (self ):
118126 self .should_continue = False
119-
120-
121-
122-
123- # ## STARTING THE THING
124- # pc = ProcessChecker("WizLight_Plugisn.exe")
125- #
126- # is_running = pc.is_running()
127- #
128- # check_always = pc.check_continuously(10)
129-
130-
131-
132-
133-
134127
135128
136129
@@ -148,14 +141,11 @@ def stop(self):
148141 sys .exit (f"Could not create TP Client, exiting. Error was:\n { repr (e )} " )
149142
150143
151-
152144# Crate the global logger
153145g_log = getLogger ()
154146
155147
156148
157-
158-
159149@TPClient .on (TP .TYPES .onNotificationOptionClicked )
160150def check_noti (data ):
161151 if data ['optionId' ] == PLUGIN_ID + '.update.download' :
@@ -165,27 +155,26 @@ def check_noti(data):
165155
166156
167157
168-
169158@TPClient .on (TP .TYPES .onConnect )
170159def onConnect (data ):
171160 g_log .info (f"Connected to TP v{ data .get ('tpVersionString' , '?' )} , plugin v{ data .get ('pluginVersion' , '?' )} ." )
172161 g_log .debug (f"Connection: { data } " )
173162 if settings := data .get ('settings' ):
174163 handleSettings (settings , True )
175164
165+ plugin_update_check (data )
176166 TPClient .stateUpdate (stateId = PLUGIN_ID + ".state.process_monitor.count" , stateValue = "0" )
177167
178168
179169
180-
181170@TPClient .on (TP .TYPES .onSettingUpdate )
182171def onSettingUpdate (data ):
183172 g_log .debug (f"Settings: { data } " )
184173 if (settings := data .get ('values' )):
185174 handleSettings (settings , False )
186175
187176
188- process_monitor_dict = {}
177+
189178
190179@TPClient .on (TP .TYPES .onAction )
191180def onAction (data ):
@@ -196,14 +185,14 @@ def onAction(data):
196185
197186 if not (action_data := data .get ('data' )) or not (aid := data .get ('actionId' )):
198187 return
199-
188+
200189 ## Get Color from Mouse
201190 if data ['actionId' ] == PLUGIN_ID + ".act.check_process" :
202191
203192 if data ['data' ][1 ]['value' ]:
204193 if data ['data' ][1 ]['value' ] == "0" :
205- the_process = ProcessChecker (data ['data' ][0 ]['value' ])
206- the_process .the_task (data = data , the_process = the_process )
194+ the_process = ProcessChecker (data ['data' ][0 ]['value' ])
195+ the_process .the_task (process_name = data [ 'data' ][ 0 ][ 'value' ] , the_process = the_process )
207196 else :
208197 print (f"Checking every { str (data ['data' ][1 ]['value' ])} seconds for { data ['data' ][0 ]['value' ]} " )
209198 the_process = ProcessChecker (data ['data' ][0 ]['value' ])
@@ -215,8 +204,8 @@ def onAction(data):
215204
216205
217206 # process_checked = the_process.check_continuously(int(data['data'][1]['value']), data=data['data'][0]['value'], the_process=the_process)
218-
219-
207+
208+
220209 if data ['actionId' ] == PLUGIN_ID + ".act.stop_process.Monitor" :
221210 the_process = data ['data' ][0 ]['value' ]
222211 try :
@@ -243,6 +232,43 @@ def onAction(data):
243232
244233
245234
235+
236+ def handleSettings (settings , on_connect = False ):
237+ #print("Settings: " + str(settings))
238+ pass
239+
240+
241+
242+ def plugin_update_check (data ):
243+ """
244+ Checks Github for the latest version of the plugin
245+ - Returns patchnotes on notification if there is a new version
246+ """
247+
248+ try :
249+ github_check = TP .Tools .updateCheck ("GitagoGaming" , GITHUB_URL ).replace ('v' ,'' ).replace ("." ,"" )
250+ plugin_version = str (data ['pluginVersion' ])
251+
252+ ## Checking to see if current version is different from github version
253+ if github_check != plugin_version :
254+ # Pulling Patch Notes for Notification
255+ r = requests .get (f"https://api.github.com/repos/GitagoGaming/{ GITHUB_URL } /contents/recent_patchnotes.txt" )
256+ message = base64 .b64decode (r .json ()['content' ]).decode ('ascii' )
257+
258+ TPClient .showNotification (
259+ notificationId = PLUGIN_ID + ".update.check" ,
260+ title = f"{ PLUGIN_NAME } Plugin { github_check } is available" ,
261+ msg = f"A new version of { PLUGIN_NAME } is available and ready to Download. This may include Bug Fixes and or New Features\n \n Patch Notes\n { message } " ,
262+ options = [{
263+ "id" :PLUGIN_ID + ".update.download" ,
264+ "title" :"Click to Update!"
265+ }])
266+ except Exception as e :
267+ g_log .error ("[UPDATE CHECK] Something went wrong checking update" , e )
268+
269+
270+
271+
246272# Shutdown handler
247273@TPClient .on (TP .TYPES .onShutdown )
248274def onShutdown (data ):
@@ -258,6 +284,14 @@ def onShutdown(data):
258284
259285
260286
287+
288+
289+
290+
291+
292+
293+
294+
261295## The Main + Logging System
262296def main ():
263297 global TPClient , g_log
@@ -329,9 +363,3 @@ def main():
329363
330364if __name__ == "__main__" :
331365 sys .exit (main ())
332-
333-
334-
335-
336- ## stop it
337- #pc.stop()
0 commit comments