From c923087acbc80a6acefd680fd1caaae406b8d350 Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Sat, 1 Feb 2020 13:21:05 +0300 Subject: [PATCH] #HotFixes: OrchestratorProcessorStartStop, OrchestratorStartNotRunExplorerWhenRun, UIdesktopFixes, Orchestrator add ProcessStartIfNotStarted --- .../Settings/SettingsOrchestratorExample.py | 18 +++--- Sources/pyOpenRPA/Orchestrator/Processor.py | 57 +++++++++++++++++-- Sources/pyOpenRPA/Orchestrator/Server.py | 2 - Sources/pyOpenRPA/Robot/UIDesktop.py | 4 +- Utils/RobotDB/SettingsExample.py | 2 +- Utils/ToolScreenScrapRecognize/Main.py | 8 ++- 6 files changed, 70 insertions(+), 21 deletions(-) diff --git a/Orchestrator/Settings/SettingsOrchestratorExample.py b/Orchestrator/Settings/SettingsOrchestratorExample.py index febbaa2e..b2fe880c 100644 --- a/Orchestrator/Settings/SettingsOrchestratorExample.py +++ b/Orchestrator/Settings/SettingsOrchestratorExample.py @@ -154,15 +154,15 @@ def Settings(): } }, { - "TimeHH:MMStart": "19:20", #Time [HH:MM] to trigger activity - "TimeHH:MMStop": "19:20", - "ActivityIntervalSeconds": 5, - "WeekdayList": [1, 2, 3], #List of the weekday index when activity is applicable, Default [1,2,3,4,5,6,7] + "TimeHH:MMStart": "12:40", #Time [HH:MM] to trigger activity + "TimeHH:MMStop": "12:40", + "ActivityIntervalSeconds": 2, + "WeekdayList": [1, 2, 3, 4, 5, 6, 7], #List of the weekday index when activity is applicable, Default [1,2,3,4,5,6,7] "Activity":{ - "Type": "PythonStart", #Activity type - "ModuleName": "CheckActivity", #Python function module name - "FunctionName": "test_activity", #Python function name - "ArgList": ["TestArg1", "TestArg2"] #Input python function args + "Type": "ProcessStartIfTurnedOff", #Activity type + "CheckTaskName": "notepad.exe", #Python function module name + "Path": "notepad", #Python function name + "ArgList": [] #Input python function args } } ], @@ -218,7 +218,7 @@ def Settings(): #lFunction to call in subfiles lSubmoduleFunctionName = "SettingsUpdate" #lSettingsPath = os.path.join(inSettingsFolderPath, "Settings") - lSettingsPath = "\\".join(__file__.split("\\")[:-1]) + lSettingsPath = "\\".join(os.path.join(os.getcwd(),__file__).split("\\")[:-1]) #lSettingsPath = os.path.join(os.getcwd(), "Settings") #Lambda function to get files .py from settings folder except Settings.py lFileList = [f for f in os.listdir(lSettingsPath) if os.path.isfile(os.path.join(lSettingsPath, f)) and f.split(".")[-1] == "py" and os.path.join(lSettingsPath, f) != __file__] diff --git a/Sources/pyOpenRPA/Orchestrator/Processor.py b/Sources/pyOpenRPA/Orchestrator/Processor.py index 6089a62c..7c10775e 100644 --- a/Sources/pyOpenRPA/Orchestrator/Processor.py +++ b/Sources/pyOpenRPA/Orchestrator/Processor.py @@ -7,6 +7,7 @@ import sys import subprocess import copy import importlib +import psutil #Input arg # [ # { @@ -38,6 +39,13 @@ import importlib # # }, # { +# "Type":"ProcessStartIfTurnedOff", +# "CheckTaskName":"", #Check if current task name is not active (then start process), +# "Path":"", +# "ArgList":[] +# +# }, +# { # "Type":"ProcessStop", # "Name":"", # "FlagForce":True, @@ -71,6 +79,7 @@ def Activity(inActivity): inActivity["DateTimeUTCStringStart"] = datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%dT%H:%M:%S.%f") #Alias (compatibility) lItem = inActivity + lCurrentDateTime = datetime.datetime.now() ########################################################### #Обработка запроса на отправку команды на удаленную машину ########################################################### @@ -138,11 +147,33 @@ def Activity(inActivity): #Вид активности - запуск процесса #Запись в массив отработанных активностей #Лог - mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processPath"], "activityStartDateTime":str(lCurrentDateTime)}) + mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Path"], "activityStartDateTime":str(lCurrentDateTime)}) #Запустить процесс - lItemArgs=[lItem["processPath"]] - lItemArgs.extend(lItem["processArgs"]) + lItemArgs=[lItem["Path"]] + lItemArgs.extend(lItem["ArgList"]) subprocess.Popen(lItemArgs,shell=True) + ##################################### + #ProcessStartIfTurnedOff + ##################################### + if lItem["Type"]=="ProcessStartIfTurnedOff": + #Check if process running + #remove .exe from Taskname if exists + lCheckTaskName = lItem["CheckTaskName"] + if len(lCheckTaskName)>4: + if lCheckTaskName[-4:].upper() != ".EXE": + lCheckTaskName = lCheckTaskName+".exe" + else: + lCheckTaskName = lCheckTaskName+".exe" + #Check if process exist + if not CheckIfProcessRunning(lCheckTaskName): + #Вид активности - запуск процесса + #Запись в массив отработанных активностей + #Лог + mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Path"], "activityStartDateTime":str(lCurrentDateTime)}) + #Запустить процесс + lItemArgs=[lItem["Path"]] + lItemArgs.extend(lItem["ArgList"]) + subprocess.Popen(lItemArgs,shell=True) ################################# #ProcessStop ################################# @@ -150,7 +181,7 @@ def Activity(inActivity): #Вид активности - остановка процесса #часовой пояс пока не учитываем #Сформировать команду на завершение - lActivityCloseCommand='taskkill /im '+lItem["processName"] + lActivityCloseCommand='taskkill /im '+lItem["Name"] #TODO Сделать безопасную обработку,если параметра нет в конфигурации if lItem.get('FlagForce',False): lActivityCloseCommand+=" /F" @@ -158,7 +189,7 @@ def Activity(inActivity): if lItem.get('User',"")!="": lActivityCloseCommand+=f' /fi "username eq {lItem["User"]}"' #Лог - mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processName"], "activityStartDateTime":str(lCurrentDateTime)}) + mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Name"], "activityStartDateTime":str(lCurrentDateTime)}) #Завершить процесс os.system(lActivityCloseCommand) ################################# @@ -213,4 +244,18 @@ def ActivityListOrDict(inActivityListOrDict): return lResult if type(inActivityListOrDict)==dict: #Dict activity - return Activity(inActivityListOrDict) \ No newline at end of file + return Activity(inActivityListOrDict) + +def CheckIfProcessRunning(processName): + ''' + Check if there is any running process that contains the given name processName. + ''' + #Iterate over the all the running process + for proc in psutil.process_iter(): + try: + # Check if process name contains the given name string. + if processName.lower() in proc.name().lower(): + return True + except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): + pass + return False; \ No newline at end of file diff --git a/Sources/pyOpenRPA/Orchestrator/Server.py b/Sources/pyOpenRPA/Orchestrator/Server.py index e5d54b87..d82eaf3a 100644 --- a/Sources/pyOpenRPA/Orchestrator/Server.py +++ b/Sources/pyOpenRPA/Orchestrator/Server.py @@ -425,8 +425,6 @@ class RobotDaemonServer(Thread): #httpd = HTTPServer(server_address, testHTTPServer_RequestHandler) # Logging mGlobalDict["Logger"].info(f"Server init. Listen URL: {inServerAddress}, Listen port: {inPort}") - # Запуск адреса в браузере - os.system("explorer http://127.0.0.1:8081") #httpd.serve_forever() httpd = ThreadedHTTPServer(server_address, testHTTPServer_RequestHandler) #print('Starting server, use to stop') diff --git a/Sources/pyOpenRPA/Robot/UIDesktop.py b/Sources/pyOpenRPA/Robot/UIDesktop.py index d18da2c6..3a003c5d 100644 --- a/Sources/pyOpenRPA/Robot/UIDesktop.py +++ b/Sources/pyOpenRPA/Robot/UIDesktop.py @@ -1208,7 +1208,7 @@ def UIOSelector_Highlight(inUIOSelector): UIO_Highlight(UIOSelector_Get_UIO(inUIOSelector)) else: # Run function from other process with help of PIPE - lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Exist_Bool", + lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Highlight", "ArgumentList": [inUIOSelector], "ArgumentDict": {}} # Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами @@ -1233,7 +1233,7 @@ def UIOSelector_FocusHighlight(inUIOSelector): UIO_FocusHighlight(UIOSelector_Get_UIO(inUIOSelector)) else: # Run function from other process with help of PIPE - lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_Exist_Bool", + lPIPEResuestDict = {"ModuleName": "UIDesktop", "ActivityName": "UIOSelector_FocusHighlight", "ArgumentList": [inUIOSelector], "ArgumentDict": {}} # Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами diff --git a/Utils/RobotDB/SettingsExample.py b/Utils/RobotDB/SettingsExample.py index 3a97df1b..bc9b38a6 100644 --- a/Utils/RobotDB/SettingsExample.py +++ b/Utils/RobotDB/SettingsExample.py @@ -90,7 +90,7 @@ def Settings(): #lFunction to call in subfiles lSubmoduleFunctionName = "SettingsUpdate" #lSettingsPath = os.path.join(inSettingsFolderPath, "Settings") - lSettingsPath = "\\".join(__file__.split("\\")[:-1]) + lSettingsPath = "\\".join(os.path.join(os.getcwd(),__file__).split("\\")[:-1]) #lSettingsPath = os.path.join(os.getcwd(), "Settings") #Lambda function to get files .py from settings folder except Settings.py lFileList = [f for f in os.listdir(lSettingsPath) if os.path.isfile(os.path.join(lSettingsPath, f)) and f.split(".")[-1] == "py" and os.path.join(lSettingsPath, f) != __file__] diff --git a/Utils/ToolScreenScrapRecognize/Main.py b/Utils/ToolScreenScrapRecognize/Main.py index a2699cf0..8be4ceff 100644 --- a/Utils/ToolScreenScrapRecognize/Main.py +++ b/Utils/ToolScreenScrapRecognize/Main.py @@ -78,7 +78,13 @@ class App(tk.Frame): self.rectx1, self.recty1) print('Rectangle ended') print('##################Recognition result###########################') - print(pytesseract.image_to_string(Image.open('screencapture_256_256.png'), lang='rus')) + print(pytesseract.image_to_string(Image.open('screencapture_256_256.png'), lang='rus+eng')) + # Get verbose data including boxes, confidences, line and page numbers + print('##Get verbose data including boxes, confidences, line and page numbers##') + print(pytesseract.image_to_data(Image.open('screencapture_256_256.png'), lang='rus+eng')) + print('##Get information about orientation and script detection##') + # Get information about orientation and script detection + print(pytesseract.image_to_osd(Image.open('screencapture_256_256.png'), lang='rus+eng')) if __name__ == "__main__": root = tk.Tk()