From 090754443f43edf2e5745161e516a378b5163989 Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Sun, 11 Oct 2020 20:18:17 +0300 Subject: [PATCH] # Updated all old defs in new Orchestrator. --- .../Orchestrator/BackwardCompatibility.py | 151 ++++++++++------- .../pyOpenRPA/Orchestrator/Orchestrator.py | 156 +++++++++++++++++- Sources/pyOpenRPA/Orchestrator/Processor.py | 14 +- .../pyOpenRPA/Orchestrator/ProcessorOld.py | 11 ++ .../Orchestrator/SettingsTemplate.py | 1 + Sources/pyOpenRPA/Orchestrator/__main__.py | 2 +- changelog.md | 16 +- 7 files changed, 286 insertions(+), 65 deletions(-) diff --git a/Sources/pyOpenRPA/Orchestrator/BackwardCompatibility.py b/Sources/pyOpenRPA/Orchestrator/BackwardCompatibility.py index 9dc39663..cd89d5d0 100644 --- a/Sources/pyOpenRPA/Orchestrator/BackwardCompatibility.py +++ b/Sources/pyOpenRPA/Orchestrator/BackwardCompatibility.py @@ -2,80 +2,117 @@ # !!! ATTENTION: Backward compatibility has been started from v1.1.13 !!! # So you can use config of the orchestrator 1.1.13 in new Orchestrator versions and all will be ok :) (hope it's true) import win32security - +from . import Orchestrator # For user defs # v1.2.0 Def for old procesor to new processor # Return new activity for the new processor def v1_2_0_ProcessorOld2NewActivityDict(inActivityOld): - - # # # # # # # # # # # # # # # # # # # # # # # # # # # # - # Technical defs for support old operations in old processor - # # # # # # # # # # # # # # # # # # # # # # # # # # # # - # { - # "Type":"WindowsLogon", - # "Domain":"", - # "User":"", - # "Password":"" - # # Return "Result": True - user is logged on, False - user is not logged on - # } - def WindowLogon(inUserStr, inPasswordStr, inDomainStr=""): - ################################# - # Windows logon - ################################# - try: - hUser = win32security.LogonUser( - inUserStr, - inDomainStr, - inPasswordStr, - win32security.LOGON32_LOGON_NETWORK, - win32security.LOGON32_PROVIDER_DEFAULT - ) - except win32security.error: - return False - else: - return True - ################################### - # { - # "Type": "GlobalDictKeyListValueGet", - # "KeyList": ["key1","key2",...] - # }, - def GlobalDictKeyListValueGet(inGSettings, inKeyList=[]): - ########################################################### - # Обработка команды GlobalDictKeyListValueGet - ########################################################### - lResult = None - lDict = inGSettings - for lItem2 in inKeyList[:-1]: - # Check if key - value exists - if lItem2 in lDict: - pass - else: - lDict[lItem2] = {} - lDict = lDict[lItem2] - # Return value - lResult = lDict.get(inKeyList[-1], None) - return lResult - - # # # # # # # # # # # # # # # # # # # # # # # # # # # # - # # # # # # # # # # # # # # # # # # # # # # # # # # # # - if inActivityOld["Type"] == "WindowsLogon": lResult = { - "Def": WindowLogon, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "Def": Orchestrator.OSCredentialsVerify, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) "ArgList":[], # Args list "ArgDict":{"inUserStr": inActivityOld["User"],"inPasswordStr":inActivityOld["Password"],"inDomainStr":inActivityOld["Domain"]}, # Args dictionary - "ArgGSettings": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgGSettings": None, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) } elif inActivityOld["Type"] == "GlobalDictKeyListValueGet": lResult = { - "Def": GlobalDictKeyListValueGet, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "Def": Orchestrator.GSettingsKeyListValueGet, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) "ArgList":[], # Args list "ArgDict":{"inKeyList": inActivityOld["KeyList"]}, # Args dictionary - "ArgGSettings": "inGSettings" # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgGSettings": "inGSettings", # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + } + elif inActivityOld["Type"] == "CMDStart": + lResult = { + "Def": Orchestrator.OSCMD, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "ArgList": [], # Args list + "ArgDict": {"inCMDStr": inActivityOld["Command"]}, # Args dictionary + "ArgGSettings": None, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + } + elif inActivityOld["Type"] == "OrchestratorRestart": + lResult = { + "Def": Orchestrator.OrchestratorRestart, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "ArgList": [], # Args list + "ArgDict": {}, # Args dictionary + "ArgGSettings": "inGSettings", # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + } + elif inActivityOld["Type"] == "OrchestratorSessionSave": + lResult = { + "Def": Orchestrator.OrchestratorSessionSave, + # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "ArgList": [], # Args list + "ArgDict": {}, # Args dictionary + "ArgGSettings": "inGSettings", # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + } + elif inActivityOld["Type"] == "GlobalDictKeyListValueSet": + lResult = { + "Def": Orchestrator.GSettingsKeyListValueSet, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "ArgList": [], # Args list + "ArgDict": {"inKeyList": inActivityOld["KeyList"], "inValue": inActivityOld["Value"]}, # Args dictionary + "ArgGSettings": "inGSettings", # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + } + elif inActivityOld["Type"] == "GlobalDictKeyListValueAppend": + lResult = { + "Def": Orchestrator.GSettingsKeyListValueAppend, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "ArgList": [], # Args list + "ArgDict": {"inKeyList": inActivityOld["KeyList"], "inValue": inActivityOld["Value"]}, # Args dictionary + "ArgGSettings": "inGSettings", # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + } + elif inActivityOld["Type"] == "GlobalDictKeyListValueOperator+": + lResult = { + "Def": Orchestrator.GSettingsKeyListValueOperatorPlus, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "ArgList": [], # Args list + "ArgDict": {"inKeyList": inActivityOld["KeyList"], "inValue": inActivityOld["Value"]}, # Args dictionary + "ArgGSettings": None, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + } + elif inActivityOld["Type"] == "ProcessStart": + lResult = { + "Def": Orchestrator.ProcessStart, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "ArgList": [], # Args list + "ArgDict": {"inPathStr": inActivityOld["Path"], "inArgList": inActivityOld["ArgList"]}, # Args dictionary + "ArgGSettings": None, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + } + elif inActivityOld["Type"] == "ProcessStartIfTurnedOff": + lResult = { + "Def": Orchestrator.ProcessStart, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "ArgList": [], # Args list + "ArgDict": {"inPathStr": inActivityOld["Path"], "inArgList": inActivityOld["ArgList"], "inStopProcessNameWOExeStr": inActivityOld["CheckTaskName"]}, # Args dictionary + "ArgGSettings": None, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + } + elif inActivityOld["Type"] == "ProcessStop": + lResult = { + "Def": Orchestrator.ProcessStop, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "ArgList": [], # Args list + "ArgDict": {"inProcessNameWOExeStr": inActivityOld["Name"], "inCloseForceBool": inActivityOld["FlagForce"], "inUserNameStr": inActivityOld["User"]}, # Args dictionary + "ArgGSettings": None, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + } + elif inActivityOld["Type"] == "PythonStart": + lResult = { + "Def": Orchestrator.PythonStart, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "ArgList": [], # Args list + "ArgDict": {"inModulePathStr": inActivityOld["ModuleName"], "inDefNameStr": inActivityOld["FunctionName"], "inArgList": inActivityOld["ArgList"], + "inArgDict": inActivityOld["ArgDict"] }, # Args dictionary + "ArgGSettings": None, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": "inLogger" # Name of GSettings attribute: str (ArgDict) or index (for ArgList) } else: raise Exception(f"BackwardCompatibility up to v1.2.0, old processor: No type {inActivityOld['Type']} has been found in old processor.") return lResult # return the result +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # HERE IS THE MAIN DEF WHICH IS LAUNCHES WHEN START # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # def Update(inGSettings): lL = inGSettings["Logger"] # Alias for logger # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # diff --git a/Sources/pyOpenRPA/Orchestrator/Orchestrator.py b/Sources/pyOpenRPA/Orchestrator/Orchestrator.py index 63117108..7281efe5 100644 --- a/Sources/pyOpenRPA/Orchestrator/Orchestrator.py +++ b/Sources/pyOpenRPA/Orchestrator/Orchestrator.py @@ -1,9 +1,8 @@ -import subprocess -import json +import subprocess, json, psutil import datetime import time import codecs -import os +import os, win32security import signal import sys #Get input argument import pdb @@ -24,6 +23,155 @@ import datetime # datetime #Единый глобальный словарь (За основу взять из Settings.py) global gSettingsDict +# Defs to use in orchestrator +def OSCredentialsVerify(inUserStr, inPasswordStr, inDomainStr=""): ## Verify credentials in windows + try: + hUser = win32security.LogonUser( + inUserStr,inDomainStr, inPasswordStr, + win32security.LOGON32_LOGON_NETWORK, win32security.LOGON32_PROVIDER_DEFAULT + ) + except win32security.error: + return False + else: + return True + +def OSCMD(inCMDStr): ## OS send command in shell locally + lCMDCode = "cmd /c " + inCMDStr + subprocess.Popen(lCMDCode) + lResultCMDRun = 1 # os.system(lCMDCode) + return lResultCMDRun + +def OrchestratorRestart(inGSettings=None): ## Orchestrator restart + OrchestratorSessionSave(inGSettings=inGSettings) # Dump RDP List in file json + if inGSettings is not None: + lL = inGSettings["Logger"] + if lL: lL.info(f"Do restart") + # Restart session + os.execl(sys.executable, os.path.abspath(__file__), *sys.argv) + sys.exit(0) + +def OrchestratorSessionSave(inGSettings=None): ## Orchestrator session save + # Dump RDP List in file json + lFile = open("_SessionLast_RDPList.json", "w", encoding="utf-8") + lFile.write(json.dumps(gSettingsDict["RobotRDPActive"]["RDPList"])) # dump json to file + lFile.close() # Close the file + if inGSettings is not None: + lL = inGSettings["Logger"] + if lL: lL.info( + f"Orchestrator has dump the RDP list before the restart. The RDP List is {inGSettings['RobotRDPActive']['RDPList']}") + return True + +## GSettings defs +def GSettingsKeyListValueSet(inGSettings, inValue, inKeyList=[]): # Set value in GSettings by the key list + lDict = inGSettings + for lItem2 in inKeyList[:-1]: + #Check if key - value exists + if lItem2 in lDict: + pass + else: + lDict[lItem2]={} + lDict=lDict[lItem2] + lDict[inKeyList[-1]] = inValue #Set value + return True + +def GSettingsKeyListValueGet(inGSettings, inKeyList=[]): # Get the value from the GSettings by the key list + lDict = inGSettings + for lItem2 in inKeyList[:-1]: + #Check if key - value exists + if lItem2 in lDict: + pass + else: + lDict[lItem2]={} + lDict=lDict[lItem2] + return lDict.get(inKeyList[-1],None) + +def GSettingsKeyListValueAppend(inGSettings, inValue, inKeyList=[]): # Append value in GSettings by the key list + lDict = inGSettings + for lItem2 in inKeyList[:-1]: + #Check if key - value exists + if lItem2 in lDict: + pass + else: + lDict[lItem2]={} + lDict=lDict[lItem2] + lDict[inKeyList[-1]].append(inValue) #Set value + return True + +def GSettingsKeyListValueOperatorPlus(inGSettings, inValue, inKeyList=[]): # Operator plus value in GSettings by the key list + lDict = inGSettings + for lItem2 in inKeyList[:-1]: + #Check if key - value exists + if lItem2 in lDict: + pass + else: + lDict[lItem2]={} + lDict=lDict[lItem2] + lDict[inKeyList[-1]] += inValue #Set value + return True + +## Process defs +def ProcessIsStarted(inProcessNameWOExeStr): # Check if process is started + ''' + 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 inProcessNameWOExeStr.lower() in proc.name().lower(): + return True + except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): + pass + return False; + +def ProcessStart(inPathStr, inArgList, inStopProcessNameWOExeStr=None): # Start process locally [optional: if task name is not started] + lStartProcessBool = True + if inStopProcessNameWOExeStr is not None: #Check if process running + lCheckTaskName = inStopProcessNameWOExeStr + if len(lCheckTaskName)>4: + if lCheckTaskName[-4:].upper() != ".EXE": + lCheckTaskName = lCheckTaskName+".exe" + else: + lCheckTaskName = lCheckTaskName+".exe" + #Check if process exist + if not ProcessIsStarted(inProcessNameWOExeStr=lCheckTaskName): lStartProcessBool=True + + if lStartProcessBool == True: # Start if flag is true + lItemArgs=[inPathStr] + lItemArgs.extend(inArgList) + subprocess.Popen(lItemArgs,shell=True) + +def ProcessStop(inProcessNameWOExeStr, inCloseForceBool, inUserNameStr = "%username%"): # Stop process + # Support input arg if with .exe + lProcessNameWExeStr = inProcessNameWOExeStr + if len(lProcessNameWExeStr) > 4: + if lProcessNameWExeStr[-4:].upper() != ".EXE": + lProcessNameWExeStr = lProcessNameWExeStr + ".exe" + else: + lProcessNameWExeStr = lProcessNameWExeStr + ".exe" + # Flag Force + lActivityCloseCommand = 'taskkill /im ' + lProcessNameWExeStr + if inCloseForceBool == True: + lActivityCloseCommand += " /F" + # None - all users, %username% - current user, another str - another user + if inUserNameStr is not None: + lActivityCloseCommand += f' /fi "username eq {inUserNameStr}"' + # Kill process + os.system(lActivityCloseCommand) + +# Python def - start module function +def PythonStart(inModulePathStr, inDefNameStr, inArgList=[], inArgDict={}, inLogger = None): # Python import module and start def + try: + lModule=importlib.import_module(inModulePathStr) #Подключить модуль для вызова + lFunction=getattr(lModule,inDefNameStr) #Найти функцию + return lFunction(*inArgList,**inArgDict) + except Exception as e: + if inLogger: inLogger.exception("Loop activity error: module/function not founded") + +# # # # # # # # # # # # # # # # # # # # # # # +# # # # # Start orchestrator +# # # # # # # # # # # # # # # # # # # # # # # + # Interval gsettings auto cleaner def GSettingsAutocleaner(inGSettings): while True: @@ -195,7 +343,7 @@ def Orchestrator(inGSettings): time.sleep(lDaemonLoopSeconds) # Backward compatibility below to 1.2.0 -def __deprecated_run__(): +def __deprecated_orchestrator_start__(): #Call Settings function from argv[1] file ################################################ lSubmoduleFunctionName = "Settings" diff --git a/Sources/pyOpenRPA/Orchestrator/Processor.py b/Sources/pyOpenRPA/Orchestrator/Processor.py index 2abadb1d..b465c9b1 100644 --- a/Sources/pyOpenRPA/Orchestrator/Processor.py +++ b/Sources/pyOpenRPA/Orchestrator/Processor.py @@ -10,6 +10,7 @@ def ProcessorRunSync(inGSettings): # "ArgList":[1,2,3], # Args list # "ArgDict":{"ttt":1,"222":2,"dsd":3}, # Args dictionary # "ArgGSettings": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + # "ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) # }, ], "AliasDefDict": {}, # Storage for def with Str alias. To use it see pyOpenRPA.Orchestrator.ControlPanel @@ -33,14 +34,23 @@ def ActivityListExecute(inGSettings, inActivityList): lDef = lActivityItem["Def"] # Get the def else: # Is not callable - check alias lDef = inGSettings["ProcessorDict"]["AliasDefDict"].pop(lActivityItem["Def"], None) # get def if def key in Alias def storage - # + #gSettings lGSettingsDictKey = lActivityItem.pop("ArgGSettings",None) - # # Prepare arg dict + # # Prepare arg dict - gSettings if type(lGSettingsDictKey) is str: # check if gSetting key is in ArgDict lActivityItem["ArgDict"][lGSettingsDictKey] = inGSettings # Set the gSettings in dict # # Prepare arg list elif type(lGSettingsDictKey) is int: # check if gSetting key is in ArgDict lActivityItem["ArgList"].insert(lGSettingsDictKey,inGSettings)# Set the gSettings in list by the index + #Logger + lLoggerDictKey = lActivityItem.pop("ArgLogger",None) + # # Prepare arg dict - gSettings + if type(lLoggerDictKey) is str: # check if gSetting key is in ArgDict + lActivityItem["ArgDict"][lLoggerDictKey] = lL # Set the lLogger in dict + # # Prepare arg list + elif type(lLoggerDictKey) is int: # check if gSetting key is in ArgDict + lActivityItem["ArgList"].insert(lLoggerDictKey,lL)# Set the lLogger in list by the index + try: # try to run function from Processor.py lActivityItemResult = lDef(*lActivityItem["ArgList"], **lActivityItem["ArgDict"]) lResultList.append(lActivityItemResult) # return the result diff --git a/Sources/pyOpenRPA/Orchestrator/ProcessorOld.py b/Sources/pyOpenRPA/Orchestrator/ProcessorOld.py index aa2eb97c..bafc630e 100644 --- a/Sources/pyOpenRPA/Orchestrator/ProcessorOld.py +++ b/Sources/pyOpenRPA/Orchestrator/ProcessorOld.py @@ -17,26 +17,32 @@ import copy # port: , # bodyObject: # }, +# -----BELOW IS UPDATED---------------- # { # "Type": "CMDStart", # "Command": "" # }, +# -----BELOW IS UPDATED---------------- # { # "Type": "OrchestratorRestart" # }, +# -----BELOW IS UPDATED---------------- # { # "Type": "OrchestratorSessionSave" # }, +# -----BELOW IS UPDATED---------------- # { # "Type": "GlobalDictKeyListValueSet", # "KeyList": ["key1","key2",...], # "Value": # }, +# -----BELOW IS UPDATED---------------- # { # "Type": "GlobalDictKeyListValueAppend", # "KeyList": ["key1","key2",...], # "Value": # }, +# -----BELOW IS UPDATED---------------- # { # "Type": "GlobalDictKeyListValueOperator+", # "KeyList": ["key1","key2",...], @@ -47,23 +53,27 @@ import copy # "Type": "GlobalDictKeyListValueGet", # "KeyList": ["key1","key2",...] # }, +# -----BELOW IS UPDATED---------------- # { # "Type":"ProcessStart", # "Path":"", # "ArgList":[] # }, +# -----BELOW IS UPDATED---------------- # { # "Type":"ProcessStartIfTurnedOff", # "CheckTaskName":"", #Check if current task name is not active (then start process), # "Path":"", # "ArgList":[] # }, +# -----BELOW IS UPDATED---------------- # { # "Type":"ProcessStop", # "Name":"", # "FlagForce":True, # "User":"" #Empty - all users, user or %username% # }, +# -----BELOW IS UPDATED---------------- # { # "Type":"PythonStart", # "ModuleName":"", @@ -71,6 +81,7 @@ import copy # "ArgList":[], # "ArgDict":{} # }, +# -----BELOW IS UPDATED---------------- # { # "Type":"WindowsLogon", # "Domain":"", diff --git a/Sources/pyOpenRPA/Orchestrator/SettingsTemplate.py b/Sources/pyOpenRPA/Orchestrator/SettingsTemplate.py index 25585b1c..f17cd3cd 100644 --- a/Sources/pyOpenRPA/Orchestrator/SettingsTemplate.py +++ b/Sources/pyOpenRPA/Orchestrator/SettingsTemplate.py @@ -199,6 +199,7 @@ def __Create__(): # "ArgList":[1,2,3], # Args list # "ArgDict":{"ttt":1,"222":2,"dsd":3} # Args dictionary # "ArgGSettings": # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + # "ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList) # }, ], "AliasDefDict": {}, # Storage for def with Str alias. To use it see pyOpenRPA.Orchestrator.ControlPanel diff --git a/Sources/pyOpenRPA/Orchestrator/__main__.py b/Sources/pyOpenRPA/Orchestrator/__main__.py index c63c1826..4554f715 100644 --- a/Sources/pyOpenRPA/Orchestrator/__main__.py +++ b/Sources/pyOpenRPA/Orchestrator/__main__.py @@ -2,4 +2,4 @@ import sys lFolderPath = "\\".join(__file__.split("\\")[:-3]) sys.path.insert(0, lFolderPath) from pyOpenRPA.Orchestrator import Orchestrator -Orchestrator.__deprecated_run__() # Backward compatibility below the v1.2.0. Will be deprecated in 1.3.0 \ No newline at end of file +Orchestrator.__deprecated_orchestrator_start__() # Backward compatibility below the v1.2.0. Will be deprecated in 1.3.0 \ No newline at end of file diff --git a/changelog.md b/changelog.md index f8210cd1..fd994eca 100644 --- a/changelog.md +++ b/changelog.md @@ -6,9 +6,23 @@ - - Support scheduler - - Support old items - Backward compatibility from 1.1.13 +- Add ArgLogger key in Processor struct item +- Old function will be tranformated in Orchestrator defs (from pyOpenRPA.Orchestrator import Orchestrator): +- - def OSCredentialsVerify(inUserStr, inPasswordStr, inDomainStr=""): ## Verify credentials in windows +- - def OSCMD(inCMDStr): ## OS send command in shell locally +- - def OrchestratorRestart(inGSettings=None): ## Orchestrator restart +- - def OrchestratorSessionSave(inGSettings=None): ## Orchestrator session save +- - def GSettingsKeyListValueSet(inGSettings, inValue, inKeyList=[]): # Set value in GSettings by the key list +- - def GSettingsKeyListValueAppend(inGSettings, inValue, inKeyList=[]): # Append value in GSettings by the key list +- - def GSettingsKeyListValueOperatorPlus(inGSettings, inValue, inKeyList=[]): # Operator plus value in GSettings by the key list +- - def GSettingsKeyListValueGet(inGSettings, inKeyList=[]): # Get the value from the GSettings by the key list +- - def ProcessIsStarted(inProcessNameWOExeStr): # Check if process is started +- - def ProcessStart(inPathStr, inArgList, inStopProcessNameWOExeStr=None): # Start process locally [optional: if task name is not started] +- - def ProcessStop(inProcessNameWOExeStr, inCloseForceBool, inUserNameStr = "%username%"): # Stop process +- - def PythonStart(inModulePathStr, inDefNameStr, inArgList=[], inArgDict={}, inLogger = None): # Python import module and start def [1.1.0] After 2 month test prefinal with new improovements (+RobotRDPActive in Orchestrator + Easy ControlPanelTemplate) -Beta before 1.1.0 (new way of OpenRPA with improovments. Sorry, but no backward compatibility)/ Backward compatibility will start from 1.0.1 +Beta before 1.1.0 (new way of OpenRPA with improvements. Sorry, but no backward compatibility)/ Backward compatibility will start from 1.0.1 [1.0.37] Minor fix in RobotRDPActive [1.0.33]