From 2ad58efa4fbc636a748b7ea8a0dcd9c5f3bd8ee3 Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Wed, 19 Jan 2022 09:50:41 +0300 Subject: [PATCH] Fix Web Def Helper (save last params in dict) Test Process add Mute utility to save the process interactions # next todo: form of schedule - has until but not has 'from' # next todo: create def to check safe signal termination --- .../Orchestrator/Managers/Process.py | 77 +++++++++++++++++-- Sources/pyOpenRPA/Orchestrator/Web/Index.js | 27 ++++--- 2 files changed, 88 insertions(+), 16 deletions(-) diff --git a/Sources/pyOpenRPA/Orchestrator/Managers/Process.py b/Sources/pyOpenRPA/Orchestrator/Managers/Process.py index c224a1b1..190858b3 100644 --- a/Sources/pyOpenRPA/Orchestrator/Managers/Process.py +++ b/Sources/pyOpenRPA/Orchestrator/Managers/Process.py @@ -41,6 +41,19 @@ class Process(): mMSTdNInt = None mMSTStartTimeList = [] + mAgentMuteBool = False # Mute any sends to agent while some action is perfomed + + def MuteWait(self): + """ + Internal def. Wait when class is apply to send new activities to the agent + + :return: + """ + lIntervalSecFloat = 0.3 + while self.mAgentMuteBool == True: + time.sleep(lIntervalSecFloat) + return None + def __init__(self, inAgentHostNameStr, inAgentUserNameStr, inProcessNameWOExeStr, inStartPathStr=None, inStartCMDStr = None, inStopSafeTimeoutSecFloat=120): self.mAgentHostNameStr = inAgentHostNameStr self.mAgentUserNameStr = inAgentUserNameStr @@ -83,9 +96,21 @@ class Process(): if ldTSecFloat < self.mMSTdTSecFloat: lMSTStartTimeList.append(lTimeItemSecFloat) self.mMSTStartTimeList = lMSTStartTimeList # Set new list # Check count in list - if len(lMSTStartTimeList) > self.mMSTdNInt: self.mStatusStr = "1_STOPPED_MANUAL" + if len(lMSTStartTimeList) > self.mMSTdNInt: + self.mStatusStr = "1_STOPPED_MANUAL" + # Log info about process + lL = __Orchestrator__.OrchestratorLoggerGet() + lL.info(f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): ManualStopTrigger is activated. {self.mMSTdNInt} start tries in {self.mMSTdTSecFloat} sec.") return self.mStatusStr + def ManualStopListClear(self) -> None: + """ + Clear the last start tries list. + + :return: None + """ + self.mMSTStartTimeList=[] + def Manual2Auto(self) -> str: """ Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self): @@ -108,17 +133,18 @@ class Process(): :param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL """ + if inIsManualBool == False: self.ManualStopTriggerNewStart() # Set the time if (self.mStatusStr == "1_STOPPED_MANUAL" or "STOP_SAFE" in self.mStatusStr) and inIsManualBool == False: lStr = f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Process will not start because of stopped manual or stop safe is now." __Orchestrator__.OrchestratorLoggerGet().warning(lStr) return self.mStatusStr - if inIsManualBool == False: self.ManualStopTriggerNewStart() # Set the time - # Send activity item to agent - wait result if self.mStartPathStr is not None: lCMDStr = f"start {os.path.abspath(self.mStartPathStr)}" elif self.mStartCMDStr is not None: lCMDStr = f"start {self.mStartCMDStr}" #import pdb #pdb.set_trace() + self.MuteWait() + self.mAgentMuteBool=True lActivityItemStart = __Orchestrator__.ProcessorActivityItemCreate(inDef="OSCMD", inArgDict={"inCMDStr":lCMDStr,"inSendOutputToOrchestratorLogsBool":False}, inArgGSettingsStr="inGSettings") @@ -132,6 +158,7 @@ class Process(): self.mStatusStr = "4_STARTED" # Log info about process self.StatusChangeLog() + self.mAgentMuteBool = False return self.mStatusStr def StartCheck(self) -> str: @@ -140,6 +167,7 @@ class Process(): :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL """ + self.MuteWait() if self.mStatusStr == "0_STOPPED": self.Start(inIsManualBool=False) return self.mStatusStr @@ -152,7 +180,8 @@ class Process(): :param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL """ - + self.MuteWait() + self.mAgentMuteBool=True # Send activity item to agent - wait result lCMDStr = f'taskkill /im "{self.mProcessNameWOExeStr}.exe" /fi "username eq %USERNAME%"' lActivityItemStart = __Orchestrator__.ProcessorActivityItemCreate( @@ -180,6 +209,7 @@ class Process(): self.StopForce(inIsManualBool=inIsManualBool) # Log info about process self.StatusChangeLog() + self.mAgentMuteBool=False return self.mStatusStr def StopSafeCheck(self) -> str: @@ -188,6 +218,7 @@ class Process(): :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL """ + self.MuteWait() if self.mStatusStr == "4_STARTED": self.StopSafe(inIsManualBool=False) return self.mStatusStr @@ -200,6 +231,8 @@ class Process(): :param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL """ + self.MuteWait() + self.mAgentMuteBool=True # Send activity item to agent - wait result lCMDStr = f'taskkill /F /im "{self.mProcessNameWOExeStr}.exe" /fi "username eq %USERNAME%"' lActivityItemStart = __Orchestrator__.ProcessorActivityItemCreate( @@ -214,6 +247,7 @@ class Process(): self.mStatusStr = "0_STOPPED" # Log info about process self.StatusChangeLog() + self.mAgentMuteBool=False return self.mStatusStr def StopForceCheck(self) -> str: @@ -222,6 +256,7 @@ class Process(): :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL """ + self.MuteWait() if self.mStatusStr == "4_STARTED": self.StopForce(inIsManualBool=False) return self.mStatusStr @@ -268,6 +303,8 @@ class Process(): # Send activity item to agent - wait result lLogBool = False lActivityItemUserProcessList = __Orchestrator__.ProcessorActivityItemCreate(inDef="ProcessWOExeUpperUserListGet") + self.MuteWait() + self.mAgentMuteBool=True lGUIDStr = __Orchestrator__.AgentActivityItemAdd(inHostNameStr=self.mAgentHostNameStr,inUserStr=self.mAgentUserNameStr,inActivityItemDict=lActivityItemUserProcessList) lUserProcessList = __Orchestrator__.AgentActivityItemReturnGet(inGUIDStr=lGUIDStr) if self.mProcessNameWOExeStr.upper() in lUserProcessList: @@ -282,6 +319,7 @@ class Process(): if self.mStatusStr is None: self.mStatusStr = "0_STOPPED"; lLogBool=True # Log info about process if lLogBool == True: self.StatusChangeLog() + self.mAgentMuteBool = False return self.mStatusStr def StatusCheckStart(self): """ @@ -464,4 +502,33 @@ def ProcessManual2Auto(inAgentHostNameStr: str, inAgentUserNameStr: str, inProce """ lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr, inProcessNameWOExeStr=inProcessNameWOExeStr) - if lProcess is not None: return lProcess.Manual2Auto() \ No newline at end of file + if lProcess is not None: return lProcess.Manual2Auto() + +def ProcessManualStopTriggerSet(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inMSTdTSecFloat: float, inMSTdNInt: int) -> None: + """ + Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self): + + :param inAgentHostNameStr: Agent hostname in any case. Required to identify Process + :param inAgentUserNameStr: Agent user name in any case. Required to identify Process + :param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case + :param inMSTdTSecFloat: Time periods in seconds + :param inMSTdNInt: Counts of the start tries + :return: None + """ + lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr, + inProcessNameWOExeStr=inProcessNameWOExeStr) + if lProcess is not None: lProcess.ManualStopTriggerSet(inMSTdTSecFloat = inMSTdTSecFloat, inMSTdNInt = inMSTdNInt) + + +def ProcessManualStopListClear(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str) -> None: + """ + Clear the last start tries list. + + :param inAgentHostNameStr: Agent hostname in any case. Required to identify Process + :param inAgentUserNameStr: Agent user name in any case. Required to identify Process + :param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case + :return: None + """ + lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr, + inProcessNameWOExeStr=inProcessNameWOExeStr) + if lProcess is not None: lProcess.ManualStopListClear() \ No newline at end of file diff --git a/Sources/pyOpenRPA/Orchestrator/Web/Index.js b/Sources/pyOpenRPA/Orchestrator/Web/Index.js index d53c7e86..7c78a4c4 100644 --- a/Sources/pyOpenRPA/Orchestrator/Web/Index.js +++ b/Sources/pyOpenRPA/Orchestrator/Web/Index.js @@ -898,18 +898,11 @@ $(document).ready(function() { //////////////////////////////////////////// // 1.2.7 Debugging /// Execute ActivityItem - // 1.2.7 Debugging toolbox init - $('.ui.dropdown.mGlobal-pyOpenRPA-Debugging-Def-Dropdown') - .dropdown({ - apiSettings: { - // this url parses query server side and returns filtered results - url: '/pyOpenRPA/Debugging/HelperDefList/{query}' - }, - }) - ; + // Debugging onchange def autofill init - $('.ui.dropdown.mGlobal-pyOpenRPA-Debugging-Def-Dropdown')[0].onchange=function(inEvent){ - lValueStr = inEvent.target.value + var lDropdownOnChange = function(inEvent){ + //lValueStr = inEvent.target.value + lValueStr = inEvent $.ajax({ type: "GET", url: '/pyOpenRPA/Debugging/HelperDefAutofill/'+lValueStr, @@ -937,6 +930,8 @@ $(document).ready(function() { dataType: "text" }); } + //$('.ui.dropdown.mGlobal-pyOpenRPA-Debugging-Def-Dropdown')[0].onchange=lDropdownOnChange + mGlobal.pyOpenRPA.DebuggingExecute=function() { @@ -985,4 +980,14 @@ $(document).ready(function() { } return inTargetDict } + // 1.2.7 Debugging toolbox init + $('.ui.dropdown.mGlobal-pyOpenRPA-Debugging-Def-Dropdown') + .dropdown({ + apiSettings: { + // this url parses query server side and returns filtered results + url: '/pyOpenRPA/Debugging/HelperDefList/{query}' + }, + onChange: lDropdownOnChange + }) + ; }); \ No newline at end of file