diff --git a/Orchestrator/ControlPanel_RobotRDPActive_Template.py b/Orchestrator/ControlPanel_RobotRDPActive_Template.py deleted file mode 100644 index 0bb59f4f..00000000 --- a/Orchestrator/ControlPanel_RobotRDPActive_Template.py +++ /dev/null @@ -1,207 +0,0 @@ -import psutil, datetime, logging, os, json -# # # # # # # ORCHESTRATOR CONTROL PANEL # # # # # # # -# Init parameters -gProcessNameWOEXE = "OpenRPA_RobotRDPActive_" -gRDPOrchestratorStorageKey = "" -gRDPStartFilePath = os.path.abspath(os.path.join(os.getcwd(), gRDPOrchestratorStorageKey+r"\pyOpenRPA.Tools.RobotRDPActive_x64.cmd")) # cwd is orchestrator working directory -gOrchestratorToRobotKeyList = ["Storage",gRDPOrchestratorStorageKey,"OrchestratorToRobotStorage"] -gOrchestratorToRobotResetKeyList = ["Storage",gRDPOrchestratorStorageKey,"OrchestratorToRobotResetStorage"] -gRobotToOrchestratorKeyList = ["Storage",gRDPOrchestratorStorageKey,"RobotToOrchestratorStorage"] -gRobotRDPActiveDefsFolderPath = "" -gRobotProcessNameWOEXE = "" -gRobotProcessFilePath = r"path\to\start\link" -# Function, which is generate Dict for front-endswith -def ControlPanelRenderDict(inGSettings): - """result={ - "HeaderLeftText":"", - "HeaderRightText":"
", - "DataStorageKey":"Robot_Name", #Use key for set current dict in mGlobal.DataStorage["DataStorageKey"] on client side - "SubheaderText": "State: Turned on", - "BodyKeyValueList":[ - {"Key":"Session list","Value":""}, - {"Key":"Session list","Value":""} - ], - "FooterText":"Last update: 9:38:00 09.10.2019", - "FooterButtonX2List":[ - {"Text":"Turn on", "Color":"green", "Link":"", "OnClick": lOnClickRunButton.replace("\\","\\\\")}, - ], - "FooterButtonX1List":[ - {"Text":"Kill", "Color":"red", "Link":"", "OnClick": lOnClickForceCloseButton.replace("\\","\\\\")} - ] - }""" - # START :: Create activities :: START # - ## RDP Start - lActivityRDPStartEscaped = (f"mGlobal.Controller.CMDRunText('start cmd /K {gRDPStartFilePath}');").replace("\\","\\\\").replace("\"","\'") # Need escape because this is render on client side and after that it goes to server side :( - ## RDP Safe turn off - lActivityRDPSafeOffEscaped = (f"mGlobal.Processor.ServerValueSet({json.dumps(gOrchestratorToRobotKeyList+['SafeTurnOff'])},true);").replace("\\","\\\\").replace("\"","\'") - ## RDP Kill - lActivityRDPKillEscaped = (f"mGlobal.Controller.CMDRunText('taskkill /F /im {gProcessNameWOEXE}.exe');").replace("\\","\\\\").replace("\"","\'") - ## Robot start - lActivityROBOTStartList = [ - { - "ModulePath": f"{os.path.abspath(os.path.join(gRobotRDPActiveDefsFolderPath,'Defs_SessionIndex.py'))}", # "RobotRDPActive\\SessionDefs.py" - "DefName":"ProcessStartIfNotRunning", # Function name - "ArgList":[], # Args list - "ArgDict":{"inSessionIndex": 0, "inProcessName": f"{gRobotProcessNameWOEXE}.exe", "inFilePath": gRobotProcessFilePath} # Args dictionary - } - ] - lActivityROBOTStartEscaped = f"mGlobal.Processor.ServerValueSet({json.dumps(gOrchestratorToRobotResetKeyList+['ActivityList'])},{json.dumps(lActivityROBOTStartList)});".replace("\"","\'") - ## ROBOT r3 stop - lActivityROBOTStopList = [ - { - "ModulePath": f"{os.path.abspath(os.path.join(gRobotRDPActiveDefsFolderPath,'Defs_SessionIndex.py'))}", # "Session\\SessionDefs.py" - "DefName":"ProcessStop", # Function name - "ArgList":[], # Args list - "ArgDict":{"inSessionIndex": 0, "inProcessName": f"{gRobotProcessNameWOEXE}.exe", "inFlagForceClose":True} # Args dictionary - } - ] - lActivityROBOTStopEscaped = f"mGlobal.Processor.ServerValueSet({json.dumps(gOrchestratorToRobotResetKeyList+['ActivityList'])},{json.dumps(lActivityROBOTStopList)});".replace("\"","\'") - ## ROBOT r3 restart - lActivityROBOTRestartList = lActivityROBOTStartList + lActivityROBOTStopList - lActivityROBOTRestartEscaped = f"mGlobal.Processor.ServerValueSet({json.dumps(gOrchestratorToRobotResetKeyList+['ActivityList'])},{json.dumps(lActivityROBOTRestartList)});".replace("\"","\'") - # END :: Create activities :: END # - # START :: Init result dict template :: START # - lBodyKeyValue_r3_start=f'Start' - lBodyKeyValue_r3_stop=f'Stop' - lBodyKeyValue_r3_restart=f'restart' - lResultDict={ - "HeaderLeftText":"ROBOT r4", - "HeaderRightText":"r4", - "DataStorageKey":gRDPOrchestratorStorageKey, #Use key for set current dict in mGlobal.DataStorage["DataStorageKey"] on client side - "SubheaderText":"", - "BodyKeyValueList":[ - {"Key":"ROBOT robots (r1-r5) list","Value":""}, - {"Key":"r4","Value":f"{lBodyKeyValue_r3_start}, {lBodyKeyValue_r3_stop}, {lBodyKeyValue_r3_restart}"}, - {"Key":"Session list","Value":""} - ], - "FooterText":"Last update: 9:38:00 09.10.2019", - "FooterButtonX2List":[ - {"Text":"Turn on", "Color":"green", "Link":"", "OnClick": lActivityRDPStartEscaped}, - {"Text":"Safe turn off", "Color":"orange", "Link":"", "OnClick": lActivityRDPSafeOffEscaped} - ], - "FooterButtonX1List":[ - {"Text":"Kill", "Color":"red", "Link":"", "OnClick": lActivityRDPKillEscaped} - ], - "GlobalStorage": inGSettings.get("Storage",{}) # UNCOMMENT FOR DEBUG PURPOSE TO WATCH inGSettings on client side - } - # END :: Init result dict template :: END # - # START :: Fill BodyKeyValueList :: START # - ## Read RDPList - lRDPList = TechDictKeyList_ItemGet(inDict=inGSettings, inKeyList=gRobotToOrchestratorKeyList+["RDPList"], inDefault=[]) - lFullScreenSessionIndex = TechDictKeyList_ItemGet(inDict=inGSettings, inKeyList=gRobotToOrchestratorKeyList+["FullScreenSessionIndex"], inDefault=None) - lRDPListIndex = 0 - for lItem in lRDPList: - ### Lable that session has fullscreen - lLabelSessionFullScreen = "" - lLabelIsIgnored = "" - ### Link set full screen - lOnClickSetFullScreen = f"mGlobal.Processor.ServerValueSet(['Storage','{gRDPOrchestratorStorageKey}','OrchestratorToRobotStorage','FullScreenSessionIndex'],{lRDPListIndex});" - lSetFullScreenA = f'Set fullscreen' - if lRDPListIndex == lFullScreenSessionIndex: - lLabelSessionFullScreen = '[Fullscreen]' - lOnClickSetFullScreen = f"mGlobal.Processor.ServerValueSet(['Storage','{gRDPOrchestratorStorageKey}','OrchestratorToRobotStorage','FullScreenSessionIndex'],null);" - lSetFullScreenA = f'Set minimized' - lIgnoreIndexListOnClick = "$.ajax({type: 'POST', url: '{gRDPOrchestratorStorageKey}/IgnoreIndexListAppend', data: '"+str(lRDPListIndex)+"', success: function(lData,l2,l3){}, dataType: 'text'});" - lIgnoreIndexListLink = f'Ignore' - ### Check if in ignore - if lRDPListIndex in inGSettings.get("Storage",{}).get(gRDPOrchestratorStorageKey,{}).get("OrchestratorToRobotStorage",{}).get("IgnoreIndexList",[]): - lLabelIsIgnored = '[Ignored]' - lIgnoreIndexListOnClick = "$.ajax({type: 'POST', url: '"+gRDPOrchestratorStorageKey+"/IgnoreIndexListRemove', data: '"+str(lRDPListIndex)+"', success: function(lData,l2,l3){}, dataType: 'text'});" - lIgnoreIndexListLink = f'Unignore' - ### Session state - lItemSessionState='Disconnected' - if lItem.get("SessionIsWindowResponsibleBool",False): - lItemSessionState='Connected' - lResultDict["BodyKeyValueList"].append({"Key":f"[{str(lRDPListIndex)}]{lLabelSessionFullScreen}{lLabelIsIgnored}{lItem.get('Host','localhost')}:{lItem.get('Port','--')}","Value":f"{lItem.get('Login','--')}, {lItem.get('SessionHex','--')}, State {lItemSessionState}, {lSetFullScreenA}, {lIgnoreIndexListLink}"}) - lRDPListIndex = lRDPListIndex + 1 - # END :: Fill BodyKeyValueList :: END # - # START :: Fill SubheaderText :: START # - ## Variants - lSubheaderRunTrueText="State: Turned on" - lSubheaderRunFalseText="State: Turned off" - if CheckIfProcessRunning(gProcessNameWOEXE): - lResultDict["SubheaderText"]=lSubheaderRunTrueText - else: - lResultDict["SubheaderText"]=lSubheaderRunFalseText - # END :: Fill SubheaderText :: END # - # Fill FooterText - lResultDict["FooterText"]=f'Last update: {datetime.datetime.now().strftime("%H:%M:%S %d.%m.%Y")}' - return lResultDict -# Check in control panel, that process is runnning -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 -#Add to ignore list - AJAX request from client side -def IgnoreIndexListAppend(inRequest,inConfiguration): - lIgnoreList = TechDictKeyList_ItemGet(inDict=inConfiguration, inKeyList=gOrchestratorToRobotKeyList+["IgnoreIndexList"], inDefault=[]) - lIgnoreIndex={} - if inRequest.headers.get('Content-Length') is not None: - lInputByteArrayLength = int(inRequest.headers.get('Content-Length')) - lInputByteArray=inRequest.rfile.read(lInputByteArrayLength) - #Превращение массива байт в объект - lIgnoreIndex=int(lInputByteArray.decode('utf8')) - #check if index not in list - if lIgnoreIndex not in lIgnoreList: - #append to list - lIgnoreList.append(lIgnoreIndex) -#remove from Ignore list - AJAX request from client side -def IgnoreIndexListRemove(inRequest,inConfiguration): - lIgnoreList = TechDictKeyList_ItemGet(inDict=inConfiguration, inKeyList=gOrchestratorToRobotKeyList+["IgnoreIndexList"], inDefault=[]) - lIgnoreIndex={} - if inRequest.headers.get('Content-Length') is not None: - lInputByteArrayLength = int(inRequest.headers.get('Content-Length')) - lInputByteArray=inRequest.rfile.read(lInputByteArrayLength) - #Превращение массива байт в объект - lIgnoreIndex=int(lInputByteArray.decode('utf8')) - #check if index not in list - if lIgnoreIndex in lIgnoreList: - #append to list - lIgnoreList.remove(lIgnoreIndex) #Remove delete the element lIgnoreIndex -# Technical def - Get item by the list of keys -def TechDictKeyList_ItemGet(inDict, inKeyList, inDefault={}): - lResult=inDict - for lItem in inKeyList: - if lResult: - lResult = lResult.get(lItem,None) - if lResult is None: - lResult=inDefault - return lResult -# # # # # # # # # # # # # # # # # # # # # # # # -#Orchestrator settings -def SettingsUpdate(inGSettings): - #Add RobotRDPActive in control panel - inGSettings["ControlPanelDict"]["RobotList"].append({"RenderFunction": ControlPanelRenderDict}) - #Default structure - inGSettings["Storage"][gRDPOrchestratorStorageKey]={ - "OrchestratorToRobotResetStorage":{"SafeTurnOff":False, "ActivityList":[]}, - "OrchestratorToRobotStorage":{ - "FullScreenSessionIndex":None, - "IgnoreIndexList": [] - } - } - #Add methods - inGSettings["Server"]["URLList"].append( - { - "Method":"POST", - "URL": f"/{gRDPOrchestratorStorageKey}/IgnoreIndexListAppend", #URL of the request - "MatchType": "Equal", #"BeginWith|Contains|Equal|EqualCase", - "ResponseDefRequestGlobal": IgnoreIndexListAppend #Function with str result - } - ) - inGSettings["Server"]["URLList"].append( - { - "Method":"POST", - "URL": f"/{gRDPOrchestratorStorageKey}/IgnoreIndexListRemove", #URL of the request - "MatchType": "Equal", #"BeginWith|Contains|Equal|EqualCase", - "ResponseDefRequestGlobal": IgnoreIndexListRemove #Function with str result - } - ) - return inGSettings \ No newline at end of file diff --git a/Orchestrator/ControlPanel_Template.py b/Orchestrator/ControlPanel_Template.py new file mode 100644 index 00000000..0b4bcd11 --- /dev/null +++ b/Orchestrator/ControlPanel_Template.py @@ -0,0 +1,124 @@ +import psutil, datetime, logging, os, json +# # # # # # # ORCHESTRATOR CONTROL PANEL # # # # # # # +# Init parameters +gRobotStartFilePathStr = r"path\to\start\file" # path\to\start\file +gRobotProcessNameWOEXEStr = "process name" # RobotProcessName +gRobotADLoginStr = "Login" # Login of the robot session +gRobotADPasswordStr = "Password" # Password for session +gRobotKeyStr = "Robot_Template" +gRDPSessionKeyStr = "RDP_Template" +gRDPSessionHostStr = "localhost" # Rdp session host +gRDPSessionPortStr = "3389" # Default 3389 +gControlPanelKeyStr = "ControlPanel_Template" +gControlPanelCheckRobotProcessFromOrchestratorUserBool = True # Check process activity from orchestrator GUI session (with help of task manager, when users on the same machine) +# !! ATTENTION !! SCHEDULE TIME START STOP FILL BELOW IN ACTIVITY SECTION +gRobotToOrchestratorKeyList = ["Storage",gRobotKeyStr,"RobotToOrchestrator"] +gOrchestratorToRobotResetKeyList = ["Storage",gRobotKeyStr,"OrchestratorToRobotReset"] +gOrchestratorToRobotResetSafeStopKeyList = gOrchestratorToRobotResetKeyList+["SafeTurnOffBool"] + +# Function, which is generate Dict for front-endswith +def ControlPanelRenderDict(inGSettings): + """result={ + "HeaderLeftText":"", + "HeaderRightText":"
", + "DataStorageKey":"Robot_Name", #Use key for set current dict in mGlobal.DataStorage["DataStorageKey"] on client side + "SubheaderText": "State: Turned on", + "BodyKeyValueList":[ + {"Key":"Session list","Value":""}, + {"Key":"Session list","Value":""} + ], + "FooterText":"Last update: 9:38:00 09.10.2019", + "FooterButtonX2List":[ + {"Text":"Turn on", "Color":"green", "Link":"", "OnClick": lOnClickRunButton.replace("\\","\\\\")}, + ], + "FooterButtonX1List":[ + {"Text":"Kill", "Color":"red", "Link":"", "OnClick": lOnClickForceCloseButton.replace("\\","\\\\")} + ] + }""" + # START :: Create activities :: START # + ## Robot START (create RDP session, send CMD to start process) + lActivityROBOTStartList = [ + { # Start RDP Session + "DefNameStr":"RDPSessionConnect", # Function name in RobotRDPActive.Processor + "ArgList":[], # Args list + "ArgDict":{"inRDPSessionKeyStr": gRDPSessionKeyStr, "inHostStr": gRDPSessionHostStr, "inPortStr": gRDPSessionPortStr, "inLoginStr": gRobotADLoginStr, "inPasswordStr": gRobotADPasswordStr} # Args dictionary + }, + { # Run robot file in RDP session + "DefNameStr":"RDPSessionProcessStartIfNotRunning", # Function name in RobotRDPActive.Processor + "ArgList":[], # Args list + "ArgDict":{"inRDPSessionKeyStr": gRDPSessionKeyStr, "inProcessNameWEXEStr": f"{gRobotProcessNameWOEXEStr}.exe", "inFilePathStr": gRobotStartFilePathStr, "inFlagGetAbsPathBool": False} # Args dictionary + } + ] + lActivityROBOTStartEscaped = f"mGlobal.Processor.ServerValueSet({json.dumps(['RobotRDPActive','ActivityList'])},{json.dumps(lActivityROBOTStartList)});".replace("\"","\'") + ## Robot SAFE STOP (SAFE STOP COMMAND (FROM ROBOT RULES), Logoff must do robot when safe turn off) + lActivityROBOTSafeStopEscaped = f"mGlobal.Processor.ServerValueSet({json.dumps(gOrchestratorToRobotResetSafeStopKeyList)},true);".replace("\"","\'") + ## Robot FORCE STOP (create RDP session, send CMD to start process) + lActivityROBOTStopList = [ + { # Kill process + "DefNameStr":"RDPSessionProcessStop", # Function name in RobotRDPActive.Processor + "ArgList":[], # Args list + "ArgDict":{"inRDPSessionKeyStr": gRDPSessionKeyStr, "inProcessNameWEXEStr":f"{gRobotProcessNameWOEXEStr}.exe","inFlagForceCloseBool": True} # Args dictionary + }, + { # Logoff RDP Session + "DefNameStr":"RDPSessionLogoff", # Function name in RobotRDPActive.Processor + "ArgList":[], # Args list + "ArgDict":{"inRDPSessionKeyStr": gRDPSessionKeyStr} # Args dictionary + } + ] + lActivityROBOTStopEscaped = f"mGlobal.Processor.ServerValueSet({json.dumps(['RobotRDPActive','ActivityList'])},{json.dumps(lActivityROBOTStopList)});".replace("\"","\'") + # END :: Create activities :: END # + # START :: Init result dict template :: START # + # lBodyKeyValue_r3_start=f'Start' + lResultDict={ + "HeaderLeftText":"ROBOT KEYWORD", + "HeaderRightText":"ROBOT NAME", + "DataStorageKey":gControlPanelKeyStr, # CLIENT SIDE:: Use key for set current dict in mGlobal.DataStorage["DataStorageKey"] on client side + "SubheaderText":"", + "BodyKeyValueList":[ + {"Key":"Info","Value":"1"}, + {"Key":"Info","Value":"2"}, + {"Key":"Info","Value":"3"}, + {"Key":"Statistic","Value":""} + ], + "FooterText":"Last update: 9:38:00 09.10.2019", + "FooterButtonX2List":[ + {"Text":"Turn on", "Color":"green", "Link":"", "OnClick": lActivityROBOTStartEscaped}, + {"Text":"Safe turn off", "Color":"orange", "Link":"", "OnClick": lActivityROBOTSafeStopEscaped} + ], + "FooterButtonX1List":[ + {"Text":"Kill", "Color":"red", "Link":"", "OnClick": lActivityROBOTStopEscaped} + ], + # "GlobalStorage": inGSettings.get("Storage",{}) # UNCOMMENT FOR DEBUG PURPOSE TO WATCH inGSettings on client side + } + # END :: Init result dict template :: END # + # START :: Fill BodyKeyValueList :: START # + + # END :: Fill BodyKeyValueList :: END # + # START :: Fill SubheaderText :: START # + ## FILL Robot state by the check the RDP session state + lSubheaderRunTrueText="State: Turned on" + lSubheaderRunFalseText="State: Turned off" + if gControlPanelCheckRobotProcessFromOrchestratorUserBool and gRDPSessionKeyStr in inGSettings["RobotRDPActive"]["RDPList"]: + lResultDict["SubheaderText"]=lSubheaderRunTrueText + else: + lResultDict["SubheaderText"]=lSubheaderRunFalseText + # END :: Fill SubheaderText :: END # + # Fill FooterText + lResultDict["FooterText"]=f'Last update: {datetime.datetime.now().strftime("%H:%M:%S %d.%m.%Y")}' + return lResultDict + +# Technical def - Get item by the list of keys +def TechDictKeyList_ItemGet(inDict, inKeyList, inDefault={}): + lResult=inDict + for lItem in inKeyList: + if lResult: + lResult = lResult.get(lItem,None) + if lResult is None: + lResult=inDefault + return lResult +# # # # # # # # # # # # # # # # # # # # # # # # +#Orchestrator settings update +def SettingsUpdate(inGSettings): + #Add RobotRDPActive in control panel + inGSettings["ControlPanelDict"]["RobotList"].append({"RenderFunction": ControlPanelRenderDict, "KeyStr": gControlPanelKeyStr}) + return inGSettings \ No newline at end of file diff --git a/Orchestrator/Settings/AccessUser_ND.py b/Orchestrator/Settings/AccessUser_ND.py index 3321c779..183a8ff1 100644 --- a/Orchestrator/Settings/AccessUser_ND.py +++ b/Orchestrator/Settings/AccessUser_ND.py @@ -18,7 +18,8 @@ def SettingsUpdate(inDict): #"FlagAccessDefRequestGlobalAuthenticate": TestDef "FlagAccess": True } - ] + ], + "ControlPanelKeyAllowedList": ["TestControlPanel", "RobotRDPActive","RobotScreenActive", "ControlPanel_Template"] # If empty - all is allowed } } #Append to global list diff --git a/Orchestrator/Settings/ControlPanel_RobotRDPActive.py b/Orchestrator/Settings/ControlPanel_RobotRDPActive.py deleted file mode 100644 index dd018264..00000000 --- a/Orchestrator/Settings/ControlPanel_RobotRDPActive.py +++ /dev/null @@ -1,155 +0,0 @@ -import psutil -import datetime -import logging -import os -import json -lProcessName = "OpenRPA_RobotRDPActive.exe" -lStartFilePath = os.path.join(os.getcwd(), "..\\Utils\\RobotRDPActive\\pyOpenRPA.Tools.RobotRDPActive_x64.cmd") -def RenderRobotRDPActive(inGlobalConfiguration): - #Subheader Variants - lSubheaderRunTrueText="State: Turned on" - lSubheaderRunFalseText="State: Turned off" - #Run button - #Такое большое количество слэшей связано с тем, что этот текст отправляется сначала в браузер, рендерится там, а потом отправляется на процессор оркестратора - lRobotRDPActivePath = f"start cmd /K {lStartFilePath}" - lOnClickRunButton=f"mGlobal.Controller.CMDRunText('{lRobotRDPActivePath}');" - #Safe turn off - lOnClickSafeTurnOff = "mGlobal.Processor.ServerValueSet(['Storage','RobotRDPActive','OrchestratorToRobotResetStorage','SafeTurnOff'],true);" - #Force close button - lOnClickForceCloseButton=f"mGlobal.Controller.CMDRunText('taskkill /F /im {lProcessName}');" - # # # # # Add recieve file activity - lTestRecieveActivityList = [ - { - "ModulePath": f"{os.path.join(lRobotRDPActiveFolderPath,'Defs_SessionIndex.py')}", # "Session\\SessionDefs.py" - "DefName":"FileStoredRecieve", # Function name - "ArgList":[], # Args list - "ArgDict":{"inSessionIndex": 0, "inHostFilePath": "testRecieve.txt","inRDPFilePath": "C:\\Temp\\testRecieve.txt"} # Args dictionary - } - ] - lOnClickTestSendBaumanStr = f"mGlobal.Processor.ServerValueSet(['Storage','RobotRDPActive','OrchestratorToRobotResetStorage','ActivityList'],{json.dumps(lTestRecieveActivityList)});" - #Result template - lResultDict={ - "HeaderLeftText":"Keep active RDP sessions", - "HeaderRightText":"Tech", - "DataStorageKey":"RobotRDPActive", #Use key for set current dict in mGlobal.DataStorage["DataStorageKey"] on client side - "SubheaderText":lSubheaderRunFalseText, - "BodyKeyValueList":[ - {"Key":"Session list","Value":""} - ], - "FooterText":"Last update: 9:38:00 09.10.2019", - "FooterButtonX2List":[ - {"Text":"Turn on", "Color":"green", "Link":"", "OnClick": lOnClickRunButton.replace("\\","\\\\")}, - {"Text":"Safe turn off", "Color":"orange", "Link":"", "OnClick": lOnClickSafeTurnOff.replace("\\","\\\\")} - ], - "FooterButtonX1List":[ - {"Text":"Kill", "Color":"red", "Link":"", "OnClick": lOnClickForceCloseButton.replace("\\","\\\\")} - ]#, - #"GlobalStorage": inGlobalConfiguration.get("Storage",{}) - } - #Read RDPList - lRDPList = inGlobalConfiguration.get("Storage",{}).get("RobotRDPActive",{}).get("RobotToOrchestratorStorage",{}).get("RDPList",[]) - lFullScreenSessionIndex = inGlobalConfiguration.get("Storage",{}).get("RobotRDPActive",{}).get("RobotToOrchestratorStorage",{}).get("FullScreenSessionIndex",None) - lRDPListIndex = 0 - for lItem in lRDPList: - #Lable that session has fullscreen - lLabelSessionFullScreen = "" - lLabelIsIgnored = "" - #Link set full screen - ############################## - lOnClickSetFullScreen = f"mGlobal.Processor.ServerValueSet(['Storage','RobotRDPActive','OrchestratorToRobotStorage','FullScreenSessionIndex'],{lRDPListIndex});" - lSetFullScreenA = f'Set fullscreen' - if lRDPListIndex == lFullScreenSessionIndex: - lLabelSessionFullScreen = '[Fullscreen]' - lOnClickSetFullScreen = f"mGlobal.Processor.ServerValueSet(['Storage','RobotRDPActive','OrchestratorToRobotStorage','FullScreenSessionIndex'],null);" - lSetFullScreenA = f'Set minimized' - ################################# - lIgnoreIndexListOnClick = "$.ajax({type: 'POST', url: 'RobotRDPActive/IgnoreIndexListAppend', data: '"+str(lRDPListIndex)+"', success: function(lData,l2,l3){}, dataType: 'text'});" - lIgnoreIndexListLink = f'Ignore' - #Check if in ignore - if lRDPListIndex in inGlobalConfiguration.get("Storage",{}).get("RobotRDPActive",{}).get("OrchestratorToRobotStorage",{}).get("IgnoreIndexList",[]): - lLabelIsIgnored = '[Ignored]' - lIgnoreIndexListOnClick = "$.ajax({type: 'POST', url: 'RobotRDPActive/IgnoreIndexListRemove', data: '"+str(lRDPListIndex)+"', success: function(lData,l2,l3){}, dataType: 'text'});" - lIgnoreIndexListLink = f'Unignore' - ################################ - #Session state - lItemSessionState='Disconnected' - if lItem.get("SessionIsWindowResponsibleBool",False): - lItemSessionState='Connected' - lResultDict["BodyKeyValueList"].append({"Key":f"[{str(lRDPListIndex)}]{lLabelSessionFullScreen}{lLabelIsIgnored}{lItem.get('Host','localhost')}:{lItem.get('Port','--')}","Value":f"{lItem.get('Login','--')}, {lItem.get('SessionHex','--')}, State {lItemSessionState}, {lSetFullScreenA}, {lIgnoreIndexListLink}"}) - lRDPListIndex = lRDPListIndex + 1 - #Check if process running - if CheckIfProcessRunning("OpenRPA_RobotRDPActive"): - lResultDict["SubheaderText"]=lSubheaderRunTrueText - #Process not running - lResultDict["FooterText"]=f'Last update: {datetime.datetime.now().strftime("%H:%M:%S %d.%m.%Y")}' - return lResultDict -#Add to ignore list -def IgnoreIndexListAppend(inRequest,inConfiguration): - lIgnoreList = inConfiguration["Storage"]["RobotRDPActive"]["OrchestratorToRobotStorage"]["IgnoreIndexList"] - lIgnoreIndex={} - if inRequest.headers.get('Content-Length') is not None: - lInputByteArrayLength = int(inRequest.headers.get('Content-Length')) - lInputByteArray=inRequest.rfile.read(lInputByteArrayLength) - #Превращение массива байт в объект - lIgnoreIndex=int(lInputByteArray.decode('utf8')) - #check if index not in list - if lIgnoreIndex not in lIgnoreList: - #append to list - lIgnoreList.append(lIgnoreIndex) -#remove from Ignore list -def IgnoreIndexListRemove(inRequest,inConfiguration): - lIgnoreList = inConfiguration["Storage"]["RobotRDPActive"]["OrchestratorToRobotStorage"]["IgnoreIndexList"] - lIgnoreIndex={} - if inRequest.headers.get('Content-Length') is not None: - lInputByteArrayLength = int(inRequest.headers.get('Content-Length')) - lInputByteArray=inRequest.rfile.read(lInputByteArrayLength) - #Превращение массива байт в объект - lIgnoreIndex=int(lInputByteArray.decode('utf8')) - #check if index not in list - if lIgnoreIndex in lIgnoreList: - #append to list - lIgnoreList.remove(lIgnoreIndex) #Remove delete the element lIgnoreIndex -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; - -#Orchestrator settings -def SettingsUpdate(inDict): - #Add RobotRDPActive in control panel - inDict["ControlPanelDict"]["RobotList"].append({"RenderFunction": RenderRobotRDPActive}) - #Default structure - inDict["Storage"]["RobotRDPActive"]={ - "OrchestratorToRobotResetStorage":{"SafeTurnOff":False}, - "OrchestratorToRobotStorage":{ - "FullScreenSessionIndex":None, - "IgnoreIndexList": [] - } - } - #Add methods - inDict["Server"]["URLList"].append( - { - "Method":"POST", - "URL": "/RobotRDPActive/IgnoreIndexListAppend", #URL of the request - "MatchType": "Equal", #"BeginWith|Contains|Equal|EqualCase", - "ResponseDefRequestGlobal": IgnoreIndexListAppend #Function with str result - } - ) - inDict["Server"]["URLList"].append( - { - "Method":"POST", - "URL": "/RobotRDPActive/IgnoreIndexListRemove", #URL of the request - "MatchType": "Equal", #"BeginWith|Contains|Equal|EqualCase", - "ResponseDefRequestGlobal": IgnoreIndexListRemove #Function with str result - } - ) - return inDict \ No newline at end of file diff --git a/Orchestrator/Settings/ControlPanel_RobotScreenActive.py b/Orchestrator/Settings/ControlPanel_RobotScreenActive.py index a523952a..64dc7e64 100644 --- a/Orchestrator/Settings/ControlPanel_RobotScreenActive.py +++ b/Orchestrator/Settings/ControlPanel_RobotScreenActive.py @@ -56,5 +56,5 @@ def CheckIfProcessRunning(processName): #Orchestrator settings def SettingsUpdate(inDict): #Add RobotRDPActive in control panel - inDict["ControlPanelDict"]["RobotList"].append({"RenderFunction": RenderRobotScreenActive}) + inDict["ControlPanelDict"]["RobotList"].append({"RenderFunction": RenderRobotScreenActive , "KeyStr": "RobotScreenActive"}) return inDict \ No newline at end of file diff --git a/Orchestrator/Settings/SettingsOrchestratorExample.py b/Orchestrator/Settings/SettingsOrchestratorExample.py index e758444a..edc6392e 100644 --- a/Orchestrator/Settings/SettingsOrchestratorExample.py +++ b/Orchestrator/Settings/SettingsOrchestratorExample.py @@ -85,7 +85,7 @@ def Settings(): "AccessUsers": { #Default - all URL is blocked "FlagCredentialsAsk": True, #Turn on Authentication "RuleDomainUserDict": { - #("DOMAIN", "USER"): { !!!!!only in upper case!!!! + #("DOMAIN", "USER"): { !!!!! only in upper case !!!! # "MethodMatchURLBeforeList": [ # { # "Method":"GET|POST", @@ -94,7 +94,8 @@ def Settings(): # "FlagAccessDefRequestGlobalAuthenticate": None, #Return bool # "FlagAccess": True # } - # ] + # ], + # "ControlPanelKeyAllowedList":[] # If empty - all is allowed #} }, "RuleMethodMatchURLBeforeList": [ #General MethodMatchURL list (no domain/user) @@ -217,7 +218,8 @@ def Settings(): "RefreshSeconds": 5, "RobotList": [ { - "RenderFunction": RenderRobotR01 + "RenderFunction": RenderRobotR01, + "KeyStr":"TestControlPanelKey" } ] }, diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.42.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.0.dist-info/INSTALLER similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.42.dist-info/INSTALLER rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.0.dist-info/INSTALLER diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.42.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.0.dist-info/METADATA similarity index 99% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.42.dist-info/METADATA rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.0.dist-info/METADATA index b64dc49b..72ccee3c 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.0.42.dist-info/METADATA +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.0.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyOpenRPA -Version: 1.0.42 +Version: 1.1.0 Summary: First open source RPA platform for business Home-page: https://gitlab.com/UnicodeLabs/OpenRPA Author: Ivan Maslov diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.42.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.0.dist-info/RECORD similarity index 88% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.42.dist-info/RECORD rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.0.dist-info/RECORD index dcc1e92d..d4f57f76 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.42.dist-info/RECORD +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.0.dist-info/RECORD @@ -1,14 +1,38 @@ -pyOpenRPA-1.0.42.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pyOpenRPA-1.0.42.dist-info/METADATA,sha256=Spesv5ub8aq5ymKhq_1kDDFQ2lrCrTwXfF8PakH7OO8,3542 -pyOpenRPA-1.0.42.dist-info/RECORD,, -pyOpenRPA-1.0.42.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 -pyOpenRPA-1.0.42.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 -pyOpenRPA/Orchestrator/Orchestrator.py,sha256=UKp7eqvWDM91kYLwl2mo0UB8Pw-qu8eJCsR9NEXD1aU,6436 -pyOpenRPA/Orchestrator/Processor.py,sha256=kmGNIqe6AZMSrzCt1QlonEy58ecFeLunjo8AeRMsufU,11091 -pyOpenRPA/Orchestrator/Server.py,sha256=s1ujCuRX6YxRllqPn541Df4pJP7kOexiS3RIuoT4nyE,22053 -pyOpenRPA/Orchestrator/ServerSettings.py,sha256=jOXJTLwg8cJx6D-rN8J4dn5RCb2nepAhCH4F9hYVUdM,4912 -pyOpenRPA/Orchestrator/Timer.py,sha256=FQZ3y6G9d47Ybx7RewzePKQV77H4gCkx5SaeFVlsuhc,2095 -pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=su4tsDD_ZMbQz6Tbmqj55SM0ZZxuQw9tfPcytaB8wzs,32953 +pyOpenRPA-1.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pyOpenRPA-1.1.0.dist-info/METADATA,sha256=yrWtVmt4O4pYWpBBOCBXDwfe6CVB7Qpkfkb1TnBiBEs,3541 +pyOpenRPA-1.1.0.dist-info/RECORD,, +pyOpenRPA-1.1.0.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 +pyOpenRPA-1.1.0.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 +pyOpenRPA/Orchestrator/Orchestrator.py,sha256=0Q4VYZPdXV2qmLuowMWD_vERj1GQurQx_VFwfsxuucQ,7076 +pyOpenRPA/Orchestrator/Processor.py,sha256=wqhbAcR9-7OszRHSX2u7BSONPNIMkEbDexvW47h0xdM,11954 +pyOpenRPA/Orchestrator/RobotRDPActive/CMDStr.py,sha256=6otw1WnR2_evvQ5LGyOVh0BLk_nTdilViGub7p56fXQ,1531 +pyOpenRPA/Orchestrator/RobotRDPActive/Clipboard.py,sha256=YB5HJL-Qf4IlVrFHyRv_ZMJ0Vo4vjyYqWKjvrTnf1k4,1564 +pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py,sha256=2nm5S_FOfnLkDVdlm2MVag9vL3DlyJ98LnwYNMzFNho,15914 +pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py,sha256=WgGqWoPAnMeXpI_w3iuFX0KUBssvlSk9MuPBuIsNOuY,491 +pyOpenRPA/Orchestrator/RobotRDPActive/GlobalDictSessionIndex_Defs.py,sha256=4BbAozLyOlXJxNw0NAlHt38-AyV-B6-Nl1M1AY8CTtk,4212 +pyOpenRPA/Orchestrator/RobotRDPActive/Monitor.py,sha256=Y4mhNslK0EBS1LIDfK67j3lkjTZSU5xq-HUl9XNKW-U,10609 +pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=DrvRm6ZLgrGNcD8EjyKbZ4HZPfiGjQftuWDfqLeM6hw,7627 +pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py,sha256=vsISwvRTMbbEtL_u9PU-rP6W71VUhAUBLMblOSGp2BE,9893 +pyOpenRPA/Orchestrator/RobotRDPActive/Scheduler.py,sha256=21N0ilFzWI1mj3X5S9tPMgwvG7BviuBxfTuqBY85Hy4,9144 +pyOpenRPA/Orchestrator/RobotRDPActive/Timer.py,sha256=y8--fUvg10qEFomecl_cmdWpdGjarZBlFpMbs_GvzoQ,1077 +pyOpenRPA/Orchestrator/RobotRDPActive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pyOpenRPA/Orchestrator/RobotRDPActive/__main__.py,sha256=z9PaUK4_nBiGd0YJdYVHV_rFx6VjZaxrrmKxSyoTFwY,2508 +pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/CMDStr.cpython-37.pyc,, +pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Clipboard.cpython-37.pyc,, +pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Connector.cpython-37.pyc,, +pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/ConnectorExceptions.cpython-37.pyc,, +pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/GlobalDictSessionIndex_Defs.cpython-37.pyc,, +pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Monitor.cpython-37.pyc,, +pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Processor.cpython-37.pyc,, +pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/RobotRDPActive.cpython-37.pyc,, +pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Scheduler.cpython-37.pyc,, +pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Timer.cpython-37.pyc,, +pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/__init__.cpython-37.pyc,, +pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/__main__.cpython-37.pyc,, +pyOpenRPA/Orchestrator/Server.py,sha256=gqJO6FRDKTBZytJVdJgPF1PvOf05qYUyKDBJJkEpLzk,22755 +pyOpenRPA/Orchestrator/ServerSettings.py,sha256=mpPAxAe6PvmKaZlreaoQAy_5wV80edz_0qc-iFrEmBQ,7123 +pyOpenRPA/Orchestrator/Timer.py,sha256=HvYtEeH2Q5WVVjgds9XaBpWRmvZgwgBXurJDdVVq_T0,2097 +pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=t-s45l9APe-wUWazdFVRP2aIsKpsNtlwU_xuSuP2d0Q,36537 pyOpenRPA/Orchestrator/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430 pyOpenRPA/Orchestrator/__init__.py,sha256=qVH8fEPgXk54rmy-ol0PnT8GF5OlGE0a8mExwJ4tFqY,124 pyOpenRPA/Orchestrator/__main__.py,sha256=cOd8WU77VGgzTZUB0WmWpPmdYyMZY1zVyuU9yx26MKs,144 @@ -192,7 +216,7 @@ pyOpenRPA/Resources/Web/Semantic-UI-CSS-master/themes/default/assets/fonts/outli pyOpenRPA/Resources/Web/Semantic-UI-CSS-master/themes/default/assets/images/flags.png,sha256=lNXH8WYTAcSm3Ekdct1VmgYgzZF6gm8N8bAju5bqnd0,28123 pyOpenRPA/Resources/Web/jQuery/jquery-3.1.1.min.js,sha256=HPMOWdIdSuVgr3FD9ZE-_MgiK8qk_MdQjrgCtfqp6U4,86713 pyOpenRPA/Robot/Clipboard.py,sha256=q76X8L21zJwcwdoJJNPeCEwAV30xS6ylHP1WwvtxoWI,722 -pyOpenRPA/Robot/OrchestratorConnector.py,sha256=Fihxz-jH9M4VakXEE0SZ0Vo9tLEQk8Tcg_C4HoH45gI,20037 +pyOpenRPA/Robot/OrchestratorConnector.py,sha256=JUtdiUXCruqUqBD19gJBl9jk_b-tpWWx_v3MfBoKzoQ,20445 pyOpenRPA/Robot/SettingsTemplate.py,sha256=Rp5XPeV2I4tCS2uf4Zkqm_ERJ6pZMg4-e5_lMqGJYLk,1453 pyOpenRPA/Robot/Test.py,sha256=qXr990nXiFZX5SNv6QN9GLb_U4HZRmJnbZR2qSnwilY,2878 pyOpenRPA/Robot/UIDesktop.py,sha256=3I2bllTDvR9d10O2ltkjoKmYw34wkkDAZfPlRpwbj30,77476 @@ -221,8 +245,8 @@ pyOpenRPA/Robot/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Studio/JSONNormalize.py,sha256=g0Z8G2wojCgTAdZtyRiCfe0_FHSeAi72Va7R7mk27gg,3347 pyOpenRPA/Studio/ProcessCommunicator.py,sha256=HD3XASJae31_HV3OznFe8E2MgZFXnwt7YveVN82M8nU,7912 -pyOpenRPA/Studio/RobotConnector.py,sha256=tQVC8X0k1HMHAAwAtkhtmeNA0cLMY3wuO-RCbgshdMk,5036 -pyOpenRPA/Studio/Studio.py,sha256=zpIGLMM2FBsUt2pC3x3BBm2zZ0n42MPfG7zgqtKxF6o,8338 +pyOpenRPA/Studio/RobotConnector.py,sha256=CYO0dQoqfs44SYD_VZ_TJh3WFu_DXigHBLHj4GJ2Icc,5038 +pyOpenRPA/Studio/Studio.py,sha256=UoMDqnZm-MCiZHR8ToLTHHPN0Yx0Oa6-VOTJdUtoMKE,8352 pyOpenRPA/Studio/ValueVerify.py,sha256=ObskxU4fOMoCGw74_nzYt6-a5jjrAckb3sdBLYyhYxY,777 pyOpenRPA/Studio/Web/Index.xhtml,sha256=RqFW3qC1pFRr-qWEEDlCEhL9l3PwANyRbll3KZJnLvo,47927 pyOpenRPA/Studio/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430 @@ -236,8 +260,8 @@ pyOpenRPA/Studio/__pycache__/ValueVerify.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Tools/RobotDB/ExcelCom.py,sha256=hp0dvXOEC7Au00ueh7pqxkdixV-PC-km7tCt-wRunYs,343 -pyOpenRPA/Tools/RobotDB/RobotDB.py,sha256=DZSb17fiCAYLdNVTLFJ7nTbQhk29PjzxE9OL6ydCDcI,1645 -pyOpenRPA/Tools/RobotDB/Server.py,sha256=MYIbO5vGH1FKgJVu3dQnscKRgN8or0FV8ZxAQbdC2Rc,19865 +pyOpenRPA/Tools/RobotDB/RobotDB.py,sha256=qtGu8PS2atd0L8taCNpk-08Qpxp8Qz1lqwAcBkyLFLM,1655 +pyOpenRPA/Tools/RobotDB/Server.py,sha256=rjW9Sg-j9P8pFQD66Uih-rke6-f6sCulinwi4_W-3mc,19933 pyOpenRPA/Tools/RobotDB/ServerSettings.py,sha256=5p9JwrpKHh68oVHIWazTajB6AOfzeapARbvGcJOFmNc,7406 pyOpenRPA/Tools/RobotDB/__init__.py,sha256=qVH8fEPgXk54rmy-ol0PnT8GF5OlGE0a8mExwJ4tFqY,124 pyOpenRPA/Tools/RobotDB/__main__.py,sha256=w9sXIF4r_PeWJjHJutTuH8DSYpXxpgcAN0KUOjiJ6PI,140 @@ -247,15 +271,6 @@ pyOpenRPA/Tools/RobotDB/__pycache__/Server.cpython-37.pyc,, pyOpenRPA/Tools/RobotDB/__pycache__/ServerSettings.cpython-37.pyc,, pyOpenRPA/Tools/RobotDB/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Tools/RobotDB/__pycache__/__main__.cpython-37.pyc,, -pyOpenRPA/Tools/RobotRDPActive/Connector.py,sha256=qU5SXwHgQU177MjqEHyOwJDLAcSVnIkKKw76iD09J1w,7275 -pyOpenRPA/Tools/RobotRDPActive/Monitor.py,sha256=H7ciateTh-hml8z69EYZjYgqdTZGkDRtnFwuYnytrCw,3278 -pyOpenRPA/Tools/RobotRDPActive/Template.rdp,sha256=qPCLkjzTdYKURK7nRApkPUjRuS4K20vDPj9DIUNSSkE,2392 -pyOpenRPA/Tools/RobotRDPActive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pyOpenRPA/Tools/RobotRDPActive/__main__.py,sha256=mVk8zVqcBrzAwwn7tbZPXFWTQbWUkgU6w89nbY6GN-8,2340 -pyOpenRPA/Tools/RobotRDPActive/__pycache__/Connector.cpython-37.pyc,, -pyOpenRPA/Tools/RobotRDPActive/__pycache__/Monitor.cpython-37.pyc,, -pyOpenRPA/Tools/RobotRDPActive/__pycache__/__init__.cpython-37.pyc,, -pyOpenRPA/Tools/RobotRDPActive/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Tools/RobotScreenActive/ConsoleStart.bat,sha256=_HNadUKHOYI5y6foG3srh8wjSzhX33xaKNylFtDjOJk,114 pyOpenRPA/Tools/RobotScreenActive/Monitor.py,sha256=TV-YisVqa_uGiyJLG9oK4u-5aDjGiFYZFh1dPjOgYc8,492 pyOpenRPA/Tools/RobotScreenActive/Screen.py,sha256=VnYcvCVymrD35l2J4ln_tlVn7CilZhxE4Ggw9P-OhIw,606 @@ -267,15 +282,14 @@ pyOpenRPA/Tools/RobotScreenActive/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Tools/RobotScreenActive/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Tools/SafeSource/Crypter.py,sha256=VRrE5-oQxQtvMEPHM1lMXp2CKnceNBmIWJnsJoJkaVE,3616 pyOpenRPA/Tools/SafeSource/DistrCreate.py,sha256=-_8BTle57LBKVknnB_3af-LghxrRmRGfRNu08CLNIvY,3232 -pyOpenRPA/Tools/SafeSource/DistrRun.py,sha256=TH4uExbufnOubBrTiO8Ccw00E5K6zaJ59-vApSxQ0iY,6661 +pyOpenRPA/Tools/SafeSource/DistrRun.py,sha256=zwUh6Jy-rDAZHV6fcTUMupkukojntFMroHJHMsNQgrE,9637 pyOpenRPA/Tools/SafeSource/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pyOpenRPA/Tools/SafeSource/__main__.py,sha256=g5aYWnuUZoM2jDX2mSIl9tRAJg05tu5VxD2rGJWcACg,649 pyOpenRPA/Tools/SafeSource/__pycache__/Crypter.cpython-37.pyc,, pyOpenRPA/Tools/SafeSource/__pycache__/DistrCreate.cpython-37.pyc,, -pyOpenRPA/Tools/SafeSource/__pycache__/DistrRun.cpython-37.pyc,, pyOpenRPA/Tools/SafeSource/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Tools/SafeSource/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,, -pyOpenRPA/__init__.py,sha256=9w2hSRgGrWKyQb3T_j71u7VoYGZsrTZz189nKtqEmOQ,175 +pyOpenRPA/__init__.py,sha256=77eUDvkFqIZMsTqBvMu8L_kbwNSHWSXsJmPZaAgGrVQ,174 pyOpenRPA/__pycache__/__init__.cpython-37.pyc,, diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.42.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.0.dist-info/WHEEL similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.42.dist-info/WHEEL rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.0.dist-info/WHEEL diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.42.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.0.dist-info/top_level.txt similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.0.42.dist-info/top_level.txt rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.1.0.dist-info/top_level.txt diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Orchestrator.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Orchestrator.py index 04a4ca5b..93d99081 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Orchestrator.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Orchestrator.py @@ -15,9 +15,11 @@ import copy #from .Settings import Settings import importlib from importlib import util +import threading # Multi-threading for RobotRDPActive +from .RobotRDPActive import RobotRDPActive #Start robot rdp active #Единый глобальный словарь (За основу взять из Settings.py) -global mGlobalDict +global gSettingsDict #Call Settings function from argv[1] file ################################################ lSubmoduleFunctionName = "Settings" @@ -26,34 +28,41 @@ lModuleName = (lFileFullPath.split("\\")[-1])[0:-3] lTechSpecification = importlib.util.spec_from_file_location(lModuleName, lFileFullPath) lTechModuleFromSpec = importlib.util.module_from_spec(lTechSpecification) lTechSpecificationModuleLoader = lTechSpecification.loader.exec_module(lTechModuleFromSpec) -mGlobalDict = None +gSettingsDict = None if lSubmoduleFunctionName in dir(lTechModuleFromSpec): # Run SettingUpdate function in submodule - mGlobalDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)() + gSettingsDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)() ################################################# #mGlobalDict = Settings.Settings(sys.argv[1]) -Processor.mGlobalDict = mGlobalDict -Timer.mGlobalDict = mGlobalDict -Timer.Processor.mGlobalDict = mGlobalDict -Server.mGlobalDict = mGlobalDict -Server.Processor.mGlobalDict = mGlobalDict +Processor.gSettingsDict = gSettingsDict +Timer.gSettingsDict = gSettingsDict +Timer.Processor.gSettingsDict = gSettingsDict +Server.gSettingsDict = gSettingsDict +Server.Processor.gSettingsDict = gSettingsDict #Инициализация настроечных параметров -lDaemonLoopSeconds=mGlobalDict["Scheduler"]["ActivityTimeCheckLoopSeconds"] +lDaemonLoopSeconds=gSettingsDict["Scheduler"]["ActivityTimeCheckLoopSeconds"] lDaemonActivityLogDict={} #Словарь отработанных активностей, ключ - кортеж (, , , ) lDaemonStartDateTime=datetime.datetime.now() #Инициализация сервера -lThreadServer = Server.RobotDaemonServer("ServerThread", mGlobalDict) +lThreadServer = Server.RobotDaemonServer("ServerThread", gSettingsDict) lThreadServer.start() +# Init the RobotRDPActive in another thread +lRobotRDPActiveThread = threading.Thread(target= RobotRDPActive.RobotRDPActive, kwargs={"inGSettings":gSettingsDict}) +lRobotRDPActiveThread.daemon = True # Run the thread in daemon mode. +lRobotRDPActiveThread.start() # Start the thread execution. #Logging -mGlobalDict["Logger"].info("Scheduler loop init") +gSettingsDict["Logger"].info("Scheduler loop init") +# Выполнить активности при старте +for lActivityItem in gSettingsDict["OrchestratorStart"]["ActivityList"]: + Processor.ActivityListOrDict(lActivityItem) #Вечный цикл while True: lCurrentDateTime = datetime.datetime.now() #Циклический обход правил lFlagSearchActivityType=True - for lIndex, lItem in enumerate(mGlobalDict["Scheduler"]["ActivityTimeList"]): + for lIndex, lItem in enumerate(gSettingsDict["Scheduler"]["ActivityTimeList"]): #Проверка дней недели, в рамках которых можно запускать активность lItemWeekdayList=lItem.get("WeekdayList", [0, 1, 2, 3, 4, 5, 6]) if lCurrentDateTime.weekday() in lItemWeekdayList: @@ -61,7 +70,7 @@ while True: #Лог lItemCopy = copy.deepcopy(lItem) lItemCopy["DateTimeUTCStringStart"]=datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%dT%H:%M:%S.%f") - mGlobalDict["Scheduler"]["LogList"].append(lItemCopy) + gSettingsDict["Scheduler"]["LogList"].append(lItemCopy) ####################################################################### #Branch 1 - if has TimeHH:MM ####################################################################### diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Processor.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Processor.py index 7c10775e..c9ff0fcb 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Processor.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Processor.py @@ -29,6 +29,11 @@ import psutil # "Value": # }, # { +# "Type": "GlobalDictKeyListValueAppend", +# "KeyList": ["key1","key2",...], +# "Value": +# }, +# { # "Type": "GlobalDictKeyListValueGet", # "KeyList": ["key1","key2",...] # }, @@ -72,9 +77,10 @@ import psutil # "DateTimeUTCStringStart" # "DateTimeUTCStringStop" # "Result" +gSettingsDict = None def Activity(inActivity): #Глобальная переменная - глобальный словарь унаследованный от Settings.py - global mGlobalDict + global gSettingsDict #Fill DateTimeUTCStringStart inActivity["DateTimeUTCStringStart"] = datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%dT%H:%M:%S.%f") #Alias (compatibility) @@ -113,7 +119,7 @@ def Activity(inActivity): #Обработка команды GlobalDictKeyListValueSet ########################################################### if lItem["Type"]=="GlobalDictKeyListValueSet": - lDict = mGlobalDict + lDict = gSettingsDict for lItem2 in lItem["KeyList"][:-1]: #Check if key - value exists if lItem2 in lDict: @@ -125,10 +131,25 @@ def Activity(inActivity): lDict[lItem["KeyList"][-1]]=lItem["Value"] lItem["Result"] = True ########################################################### + # Обработка команды GlobalDictKeyListValueAppend + ########################################################### + if lItem["Type"] == "GlobalDictKeyListValueAppend": + lDict = gSettingsDict + for lItem2 in lItem["KeyList"][:-1]: + # Check if key - value exists + if lItem2 in lDict: + pass + else: + lDict[lItem2] = {} + lDict = lDict[lItem2] + # Set value + lDict[lItem["KeyList"][-1]].append(lItem["Value"]) + lItem["Result"] = True + ########################################################### #Обработка команды GlobalDictKeyListValueGet ########################################################### if lItem["Type"]=="GlobalDictKeyListValueGet": - lDict = mGlobalDict + lDict = gSettingsDict for lItem2 in lItem["KeyList"][:-1]: #Check if key - value exists if lItem2 in lDict: @@ -147,7 +168,7 @@ def Activity(inActivity): #Вид активности - запуск процесса #Запись в массив отработанных активностей #Лог - mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Path"], "activityStartDateTime":str(lCurrentDateTime)}) + gSettingsDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Path"], "activityStartDateTime":str(lCurrentDateTime)}) #Запустить процесс lItemArgs=[lItem["Path"]] lItemArgs.extend(lItem["ArgList"]) @@ -169,7 +190,7 @@ def Activity(inActivity): #Вид активности - запуск процесса #Запись в массив отработанных активностей #Лог - mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Path"], "activityStartDateTime":str(lCurrentDateTime)}) + gSettingsDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Path"], "activityStartDateTime":str(lCurrentDateTime)}) #Запустить процесс lItemArgs=[lItem["Path"]] lItemArgs.extend(lItem["ArgList"]) @@ -189,7 +210,7 @@ def Activity(inActivity): if lItem.get('User',"")!="": lActivityCloseCommand+=f' /fi "username eq {lItem["User"]}"' #Лог - mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Name"], "activityStartDateTime":str(lCurrentDateTime)}) + gSettingsDict["Processor"]["LogList"].append({"activityType":lItem["Type"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["Name"], "activityStartDateTime":str(lCurrentDateTime)}) #Завершить процесс os.system(lActivityCloseCommand) ################################# @@ -228,9 +249,9 @@ def Activity(inActivity): #Trace activity ################## #print(mGlobalDict) - if mGlobalDict["Processor"].get(f"LogType_{lItem['Type']}",True): + if gSettingsDict["Processor"].get(f"LogType_{lItem['Type']}", True): #Add activity in TransactionList if it is applicable - mGlobalDict["Processor"]["LogList"].append(copy.deepcopy(lItem)) + gSettingsDict["Processor"]["LogList"].append(copy.deepcopy(lItem)) #Вернуть результат return lItem diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/CMDStr.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/CMDStr.py new file mode 100644 index 00000000..cb03065f --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/CMDStr.py @@ -0,0 +1,26 @@ +import os # Get abs path of the file +# Create CMD str to run file if process.exe is not running +def ProcessStartIfNotRunning(inProcessName, inFilePath, inFlagGetAbsPath=True): + lFileAbsPath = inFilePath + if inFlagGetAbsPath: + lFileAbsPath = os.path.abspath(inFilePath) + lResult = f'tasklist /nh /fi "imagename eq {inProcessName}" | find /i "{inProcessName}" > nul || (start {lFileAbsPath})' + return lResult +# Create CMD str to stop process +def ProcessStop(inProcessName, inFlagForceClose): + lResult = f'taskkill /im "{inProcessName}" /fi "username eq %USERNAME%"' + if inFlagForceClose: + lResult+= " /F" + return lResult +# Send file from Host to Session RDP using shared drive in RDP (force copy) +def FileStoredSend(inHostFilePath, inRDPFilePath): + lHostFileAbsPath = os.path.join("\\\\tsclient", os.path.abspath(inHostFilePath).replace(":","")) # \\tsclient\C\path\to\file + lHostRDPFileAbsPath = os.path.abspath(inRDPFilePath) # File location in RDP + lResult = f'copy /Y "{lHostFileAbsPath}" "{lHostRDPFileAbsPath}"' + return lResult +# Send file from Session RDP to Host using shared drive in RDP (force copy) +def FileStoredRecieve(inRDPFilePath, inHostFilePath): + lHostFileAbsPath = os.path.join("\\\\tsclient", os.path.abspath(inHostFilePath).replace(":","")) # \\tsclient\C\path\to\file + lHostRDPFileAbsPath = os.path.abspath(inRDPFilePath) # File location in RDP + lResult = f'copy /Y "{lHostRDPFileAbsPath}" "{lHostFileAbsPath}"' + return lResult \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Clipboard.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Clipboard.py new file mode 100644 index 00000000..aa0c1a8c --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Clipboard.py @@ -0,0 +1,40 @@ +import win32clipboard +import keyboard # keyboard functions +import time # Some operations need wait +import random # random number for test +gWaitTextInClipboardSec = 1 # Second for wait text will be set in clipboard (for get operations) +# set clipboard data +def TextSet(inTextStr): + win32clipboard.OpenClipboard() + win32clipboard.EmptyClipboard() + win32clipboard.SetClipboardText(inTextStr) + win32clipboard.CloseClipboard() +# get clipboard data +def TextGet(inWaitTextInClipboardSec = gWaitTextInClipboardSec): + time.sleep(inWaitTextInClipboardSec) # Wait for clipboard will save + win32clipboard.OpenClipboard() + data = win32clipboard.GetClipboardData() + win32clipboard.CloseClipboard() + return data +# Test in has text cursor and ready to apply +def InputIsFocused(): + keyboard.press_and_release("ctrl+a") + keyboard.press_and_release("backspace") # remove old text + lTextForTest = str(random.randrange(100,99999)) + keyboard.write(lTextForTest) + keyboard.press_and_release("ctrl+a") + keyboard.press_and_release("ctrl+c") + time.sleep(2) + keyboard.press_and_release("backspace") # remove old text + lClipboardText = TextGet() + lResult = lClipboardText == lTextForTest + return lResult +# Check if cmd is opened +def CMDIsOpen(): + lTextForTest = str(random.randrange(100,99999)) + keyboard.write(lTextForTest+" |clip") + keyboard.press_and_release("enter") + time.sleep(2) + lClipboardText = TextGet() + lResult = lClipboardText == lTextForTest + return lResult \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py new file mode 100644 index 00000000..61fdc4e7 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py @@ -0,0 +1,308 @@ +#Import parent folder to import current / other packages +from pyOpenRPA.Robot import UIDesktop #Lib to access RDP window +from . import ConnectorExceptions # Exceptions classes +import os #os for process run +import uuid #temp id for Template.rdp +import tempfile #Temporary location +import subprocess +from . import Clipboard # Clipboard functions get/set +import keyboard # Keyboard functions +import time +import random # random integers +from win32api import GetSystemMetrics # Get Screen rect +#Connect to RDP session +""" +{ + "Host": "", #Host address + "Port": "", #RDP Port + "Login": "", # Login + "Password": "", #Password + "Screen": { + "Resolution":"FullScreen", #"640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen + "FlagUseAllMonitors": False, # True or False + "DepthBit":"" #"32" or "24" or "16" or "15" + } +} +""" +def Session(inRDPSessionConfiguration): + #RDPConnector.SessionConnect(mConfiguration) + #RDPConnector.LoginPassSet("111.222.222.111","ww","dd") + (lRDPFile, lSessionHex) = SessionConfigurationCreate(inRDPSessionConfiguration) + #Set session hex in globalDict + inRDPSessionConfiguration["SessionHex"] = lSessionHex + #Set login/password + SessionLoginPasswordSet(inRDPSessionConfiguration["Host"],inRDPSessionConfiguration["Login"],inRDPSessionConfiguration["Password"]) + #Start session + SessionRDPStart(lRDPFile) + #Remove temp file + time.sleep(4) #Delete file after some delay - one way to delete and run the RDP before because RDP is not read file in one moment + os.remove(lRDPFile) # delete the temp rdp + # Set the result + return inRDPSessionConfiguration +#Add login/ password to the windows credentials to run RDP +def SessionLoginPasswordSet(inHost, inLogin, inPassword): + #Clear old login/password if it exists + #os.system(f"cmdkey /delete:TERMSRV/{inHost}") #Dont need to delete because new user password will clear the previous creds + #Set login password for host + os.system(f'cmdkey /generic:TERMSRV/{inHost} /user:{inLogin} /pass:"{inPassword}"') + return None +#Create current .rdp file with settings +#Return (full path to file, session hex) +def SessionConfigurationCreate(inConfiguration): + #RobotRDPActive folder path + lFileFullPath=__file__ + lFileFullPath = lFileFullPath.replace("/","\\") + lRobotRDPActiveFolderPath = "\\".join(lFileFullPath.split("\\")[:-1]) + #Full path to Template.rdp file + lRDPTemplateFileFullPath = os.path.join(lRobotRDPActiveFolderPath, "Template.rdp") + #Open template file (.rdp encoding is USC-2 LE BOM = UTF-16 LE) http://qaru.site/questions/7156020/python-writing-a-ucs-2-little-endian-utf-16-le-file-with-bom + lRDPTemplateFileContent = open(lRDPTemplateFileFullPath, "r", encoding="utf-16-le").read() + #Prepare host:port + lHostPort=inConfiguration['Host'] + if 'Port' in inConfiguration: + if inConfiguration['Port']: + lHostPort=f"{lHostPort}:{inConfiguration['Port']}" + # Generate parameter for .rdp "drivestoredirect:s:C:\;" + lDriveStoreDirectStr = "" + for lItem in inConfiguration['SharedDriveList']: + lDriveStoreDirectStr+=f"{lItem.upper()}:\\;" # Attention - all drives must be only in upper case!!! + #Replace {Width}, {Height}, {BitDepth}, {HostPort}, {Login} + lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{Width}", str(inConfiguration.get('Screen',{}).get("Width",1680))) + lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{Height}", str(inConfiguration.get('Screen',{}).get("Height",1050))) + lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{BitDepth}", inConfiguration.get('Screen',{}).get("DepthBit","32")) + lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{HostPort}", lHostPort) + lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{Login}", inConfiguration['Login']) + lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{SharedDriveList}", lDriveStoreDirectStr) + #Save template to temp file + lRDPCurrentFileFullPath = os.path.join(tempfile.gettempdir(), f"{uuid.uuid4().hex}.rdp") + open(lRDPCurrentFileFullPath, "w", encoding="utf-16-le").write(lRDPTemplateFileContent) + #Return .rdp full path + return (lRDPCurrentFileFullPath, (lRDPCurrentFileFullPath.split("\\")[-1])[0:-4]) +#RDPSessionStart +def SessionRDPStart(inRDPFilePath): + #Disable certificate warning + lCMDString = 'reg add "HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client" /v "AuthenticationLevelOverride" /t "REG_DWORD" /d 0 /f' + os.system(lCMDString) + #run rdp session + lItemArgs = [inRDPFilePath] + subprocess.Popen(lItemArgs, shell=True) + #Wait for UAC unknown publisher exists + lRDPFileName = (inRDPFilePath.split("\\")[-1])[0:-4] + lWaitResult = UIDesktop.UIOSelectorsSecs_WaitAppear_List( + [ + [{"title": "Подключение к удаленному рабочему столу", "class_name": "#32770", "backend": "win32"}, + {"title": "Боль&ше не выводить запрос о подключениях к этому компьютеру", "friendly_class_name": "CheckBox"}], + [{"title": "Remote Desktop Connection", "class_name": "#32770", "backend": "win32"}, + {"title": "D&on't ask me again for connections to this computer", + "friendly_class_name": "CheckBox"}], + [{"title_re": f"{lRDPFileName}.*", + "class_name": "TscShellContainerClass", "backend": "win32"},{"depth_start":3, "depth_end": 3, "class_name":"UIMainClass"}] + ], + 30 + ) + #Enable certificate warning + lCMDString = 'reg add "HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client" /v "AuthenticationLevelOverride" /t "REG_DWORD" /d 2 /f' + os.system(lCMDString) + #Click if 0 is appear (RUS) + if 0 in lWaitResult: + #Check the box do not retry + UIDesktop.UIOSelector_Get_UIO([{"title": "Подключение к удаленному рабочему столу", "backend": "win32"}, + {"title": "Боль&ше не выводить запрос о подключениях к этому компьютеру", "friendly_class_name": "CheckBox"}]).check() + #Go to connection + UIDesktop.UIOSelector_Get_UIO([{"title": "Подключение к удаленному рабочему столу", "backend": "win32"}, + {"title":"Подкл&ючить", "class_name":"Button"}]).click() + lWaitResult = UIDesktop.UIOSelectorsSecs_WaitAppear_List( + [ + [{"title_re": f"{lRDPFileName}.*", + "class_name": "TscShellContainerClass", "backend": "win32"}] + ], + 30 + ) + # Click if 1 is appear (ENG) + if 1 in lWaitResult: + # Check the box do not retry + UIDesktop.UIOSelector_Get_UIO([{"title": "Remote Desktop Connection", "class_name": "#32770", "backend": "win32"}, + {"title": "D&on't ask me again for connections to this computer", + "friendly_class_name": "CheckBox"}]).check() + # Go to connection + UIDesktop.UIOSelector_Get_UIO([{"title": "Remote Desktop Connection", "class_name": "#32770", "backend": "win32"}, + {"title": "Co&nnect", "class_name": "Button"}]).click() + lWaitResult = UIDesktop.UIOSelectorsSecs_WaitAppear_List( + [ + [{"title_re": f"{lRDPFileName}.*", + "class_name": "TscShellContainerClass", "backend": "win32"}] + ], + 30 + ) + # Raise exception if RDP is not active + if len(lWaitResult) == 0: + raise ConnectorExceptions.SessionWindowNotExistError("Error when initialize the RDP session - No RDP windows has appreared!") + # Wait for init + time.sleep(3) + SessionScreenSize_X_Y_W_H(inSessionHex = lRDPFileName, inXInt = 10, inYInt = 10, inWInt = 550, inHInt = 350) #Prepare little window + return None + +#Set fullscreen for app +def SessionScreenFull(inSessionHex): + #Prepare little window + try: + lRDPWindow = UIDesktop.UIOSelector_Get_UIO([{"title_re": f"{inSessionHex}.*", "backend": "win32"}]) + except Exception as e: + return None + lRDPWindow.set_focus() + lRDPWindow.maximize() + #time.sleep(0.5) + if not SessionIsFullScreen(inSessionHex): + lRDPWindow.type_keys("^%{BREAK}") + time.sleep(0.5) + return None + +# Set the screen size +def SessionScreenSize_X_Y_W_H(inSessionHex, inXInt, inYInt, inWInt, inHInt): + lDoBool = True + while lDoBool: + #Prepare little window + try: + lRDPWindow = UIDesktop.UIOSelector_Get_UIO([{"title_re": f"{inSessionHex}.*", "backend": "win32"}]) + except Exception as e: + return None + try: + lRDPWindow.set_focus() + if SessionIsFullScreen(inSessionHex): + lRDPWindow.type_keys("^%{BREAK}") + time.sleep(0.5) + lRDPWindow.restore() + time.sleep(0.5) + lRDPWindow.move_window(inXInt,inYInt,inWInt,inHInt) + except Exception as e: + time.sleep(1) + else: + lDoBool = False + return None + +# Set Little window of the session +def SessionScreen100x550(inSessionHex): + SessionScreenSize_X_Y_W_H(inSessionHex = inSessionHex, inXInt = 10, inYInt = 10, inWInt = 550, inHInt = 100) + return None +# Session - close window +def SessionClose(inSessionHexStr): + #Close window + try: + UIDesktop.UIOSelector_Get_UIO([{"title_re": f"{inSessionHexStr}.*", "backend": "win32"}]).close() + except Exception as e: + pass +#Type command in CMD +# inSessionHex - SessionHex to catch window +# inModeStr "LISTEN", "CROSSCHECK", "RUN" +# "LISTEN" - Get result of the cmd command in result TODO get home script +# "CROSSCHECK" - Check if the command was successufully sent TODO get home script +# "RUN" - Run without crosscheck and get clipboard +# return { +# "OutStr": <> # Result string +# "IsResponsibleBool": True|False # Flag is RDP is responsible - works only when inModeStr = CROSSCHECK +# } +# example Connector.SessionCMDRun("4d1e48f3ff6c45cc810ea25d8adbeb50","start notepad", "RUN") +def SessionCMDRun(inSessionHex,inCMDCommandStr = "echo 1", inModeStr="CROSSCHECK", inClipboardTimeoutSec = 5): + # Init the result dict + lResult = {"OutStr": None,"IsResponsibleBool":True} + # Enter full screen mode + SessionScreenFull(inSessionHex) + time.sleep(2) + # Run CMD operations + lResult = SystemCMDRun(inCMDCommandStr = inCMDCommandStr, inModeStr = inModeStr, inClipboardTimeoutSec = inClipboardTimeoutSec) + # Exit fullscreen mode + SessionScreenSize_X_Y_W_H(inSessionHex=inSessionHex, inXInt=10, inYInt=10, inWInt=550, + inHInt=350) # Prepare little window +# Check if session is in Full screen mode +# Return True - is in fullscreen +# example print(Connector.SessionIsFullScreen("")) +def SessionIsFullScreen(inSessionHexStr): + #Default resul + lResult = False + lWeight = GetSystemMetrics(0) + lHeight = GetSystemMetrics(1) + #Get window screen + try: + lRectangle = UIDesktop.UIOSelector_Get_UIO([{"title_re": f"{inSessionHexStr}.*", "backend": "win32"}]).rectangle() + except Exception as e: + return lResult + # Get Height/Weight + lSessionWeight = lRectangle.right - lRectangle.left + lSessionHeight = lRectangle.bottom - lRectangle.top + #Case fullscreen + if lSessionHeight == lHeight and lSessionWeight == lWeight: + lResult = True + return lResult +# Check if RDP session is responsible (check with random combination in cmd) +# Attention - function will be work fine if RDP will be in full screen mode!!! (see def SessionScreenFull) +# Return True - is responsible; False - is not responsible +#Type command in CMD +# inFlagDoCrossCheck: True - Do check that CMD is executed (the text response will not be available) +# inModeStr "LISTEN", "CROSSCHECK", "RUN" +# "LISTEN" - Get result of the cmd command in result TODO get home script +# "CROSSCHECK" - Check if the command was successufully sent TODO get home script +# "RUN" - Run without crosscheck and get clipboard +# inClipboardTimeoutSec # Second for wait when clipboard will changed +# return { +# "OutStr": <> # Result string +# "IsResponsibleBool": True|False # Flag is RDP is responsible - works only when inModeStr = CROSSCHECK +# } +# example Connector.SessionCMDRun("4d1e48f3ff6c45cc810ea25d8adbeb50","start notepad", "RUN") +def SystemCMDRun(inCMDCommandStr = "echo 1", inModeStr="CROSSCHECK", inClipboardTimeoutSec = 5): + # Set random text to clipboard (for check purposes that clipboard text has been changed) + lClipboardTextOld = str(random.randrange(999,9999999)) + Clipboard.TextSet(lClipboardTextOld) + # Init the result dict + lResult = {"OutStr": None,"IsResponsibleBool":True} + lCrosscheckKeyStr = str(random.randrange(999,9999999)) + lCMDPostFixStr = "" # Case default "RUN" + if inModeStr == "CROSSCHECK": + lCMDPostFixStr = f"| echo {lCrosscheckKeyStr} | clip" + elif inModeStr == "LISTEN": + lCMDPostFixStr = f"| clip" + keyboard.press_and_release('win+r') + time.sleep(1) + # Remove old text + keyboard.press_and_release("ctrl+a") + keyboard.press_and_release("backspace") + # Write new text + keyboard.write(f"cmd /c {inCMDCommandStr} {lCMDPostFixStr}") + time.sleep(1) + # TODo cross check from clipboard + keyboard.press_and_release('enter') + # Get OutStr (Case CROSSCHECK and LISTEN) + if inModeStr == "CROSSCHECK" or inModeStr == "LISTEN": + lClipboardWaitTimeStartSec = time.time() + lResult["OutStr"] = Clipboard.TextGet() # Get text from clipboard + while lResult["OutStr"] == lClipboardTextOld and (time.time() - lClipboardWaitTimeStartSec) <= inClipboardTimeoutSec: + lResult["OutStr"] = Clipboard.TextGet() # Get text from clipboard + time.sleep(0.5) # wait some time for the next operation + # Do crosscheck + if inModeStr == "CROSSCHECK": + if lResult["OutStr"] == f"{lCrosscheckKeyStr} \r\n\x00\x00\x00\x00\x00": + lResult["IsResponsibleBool"] = True + else: + lResult["IsResponsibleBool"] = False + # return the result + return lResult +# Check if current RDP is responsible +def SystemRDPIsResponsible(): + return SystemCMDRun(inCMDCommandStr = "echo 1", inModeStr="CROSSCHECK")["IsResponsibleBool"] +# Click OK on error messages +def SystemRDPWarningClickOk(): + # Try to click OK Error window in RUS version + while UIDesktop.UIOSelector_Exist_Bool([{"title": "Подключение к удаленному рабочему столу", "class_name": "#32770", "backend": "win32"}, + {"title": "ОК", "class_name": "Button"}]): + try: + UIDesktop.UIOSelector_Get_UIO([{"title": "Подключение к удаленному рабочему столу", "class_name": "#32770", "backend": "win32"}, + {"title": "ОК", "class_name": "Button"}]).click() + except Exception as e: + pass + # Try to click OK Error window in ENG version + while UIDesktop.UIOSelector_Exist_Bool([{"title": "Remote Desktop Connection", "class_name": "#32770", "backend": "win32"}, + {"title": "OK", "class_name": "Button"}]): + try: + UIDesktop.UIOSelector_Get_UIO([{"title": "Remote Desktop Connection", "class_name": "#32770", "backend": "win32"}, + {"title": "OK", "class_name": "Button"}]).click() + except Exception as e: + pass \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py new file mode 100644 index 00000000..3ae91409 --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py @@ -0,0 +1,10 @@ +##################################### +# RobotRDPActive Exceptions class +##################################### +class SessionWindowNotExistError(Exception): pass #Error when Window not exists +class SessionWindowNotResponsibleError(Exception): pass # Error when Window not responding +class HostNoGUIError(Exception): pass # Orchestrator session has no GUI +#try: +# raise SessionWindowNotResponsibleError("Test") +#except SessionWindowNotResponsibleError as e: +# print("Catched") diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/GlobalDictSessionIndex_Defs.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/GlobalDictSessionIndex_Defs.py new file mode 100644 index 00000000..d4c7c82f --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/GlobalDictSessionIndex_Defs.py @@ -0,0 +1,66 @@ +# ATTENTION! HERE IS NO Relative import because it will be imported dynamically +# All function check the flag SessionIsWindowResponsibleBool == True else no cammand is processed +# All functions can return None, Bool or Dict { "IsSuccessful": True } +from pyOpenRPA.Tools.RobotRDPActive import CMDStr # Create CMD Strings +from pyOpenRPA.Tools.RobotRDPActive import Connector # RDP API +def ProcessStartIfNotRunning(inGlobalDict, inSessionIndex, inProcessName, inFilePath, inFlagGetAbsPath=True): + lResult = True + lCMDStr = CMDStr.ProcessStartIfNotRunning(inProcessName,inFilePath, inFlagGetAbsPath= inFlagGetAbsPath) + # Calculate the session Hex + lSessionHex = inGlobalDict["RDPList"][inSessionIndex]["SessionHex"] + # Check is Session is responsible + if inGlobalDict["RDPList"][inSessionIndex]["SessionIsWindowResponsibleBool"]: + # Run CMD + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN") + else: + # Write in logger - warning + inGlobalDict["Logger"].warning(f"GlobalDictSessionIndex_Defs.ProcessStartIfNotRunning: SessionIndex: {str(inSessionIndex)}, ProcessName: {inProcessName}:: Session is not responsible!") + lResult = False # Set false result - function has not been done + return lResult +# Create CMD str to stop process +def ProcessStop(inGlobalDict, inSessionIndex, inProcessName, inFlagForceClose): + lResult = True + lCMDStr = f'taskkill /im "{inProcessName}" /fi "username eq %USERNAME%"' + if inFlagForceClose: + lCMDStr+= " /F" + # Calculate the session Hex + lSessionHex = inGlobalDict["RDPList"][inSessionIndex]["SessionHex"] + # Check is Session is responsible + if inGlobalDict["RDPList"][inSessionIndex]["SessionIsWindowResponsibleBool"]: + # Run CMD + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN") + else: + # TODO Write in logger - warning + inGlobalDict["Logger"].warning(f"GlobalDictSessionIndex_Defs.ProcessStop: SessionIndex: {str(inSessionIndex)}, ProcessName: {inProcessName}:: Session is not responsible!") + lResult = False # Set false result - function has not been done + return lResult +# Send file from Host to Session RDP using shared drive in RDP +def FileStoredSend(inGlobalDict, inSessionIndex, inHostFilePath, inRDPFilePath): + lResult = True + lCMDStr = CMDStr.FileStoredSend(inHostFilePath = inHostFilePath, inRDPFilePath = inRDPFilePath) + # Calculate the session Hex + lSessionHex = inGlobalDict["RDPList"][inSessionIndex]["SessionHex"] + # Check is Session is responsible + if inGlobalDict["RDPList"][inSessionIndex]["SessionIsWindowResponsibleBool"]: + # Run CMD + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120) + else: + # Write in logger - warning + inGlobalDict["Logger"].warning(f"GlobalDictSessionIndex_Defs.FileStoredSend: SessionIndex: {str(inSessionIndex)}, HostFilePath: {inHostFilePath}:: Session is not responsible!") + lResult = False # Set false result - function has not been done + return lResult +# Recieve file from Session RDP to Host using shared drive in RDP +def FileStoredRecieve(inGlobalDict, inSessionIndex, inRDPFilePath, inHostFilePath): + lResult = True + lCMDStr = CMDStr.FileStoredRecieve(inRDPFilePath = inRDPFilePath, inHostFilePath = inHostFilePath) + # Calculate the session Hex + lSessionHex = inGlobalDict["RDPList"][inSessionIndex]["SessionHex"] + # Check is Session is responsible + if inGlobalDict["RDPList"][inSessionIndex]["SessionIsWindowResponsibleBool"]: + # Run CMD + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120) + else: + # Write in logger - warning + inGlobalDict["Logger"].warning(f"GlobalDictSessionIndex_Defs.FileStoredRecieve: SessionIndex: {str(inSessionIndex)}, HostFilePath: {inHostFilePath}:: Session is not responsible!") + lResult = False # Set false result - function has not been done + return lResult \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Monitor.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Monitor.py new file mode 100644 index 00000000..2f7777de --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Monitor.py @@ -0,0 +1,158 @@ +from pyOpenRPA.Robot import UIDesktop +from . import Connector +import os +import time # Time wait operations +import importlib # from dynamic import module +from . import ConnectorExceptions # Exceptions classes + + +#Check for session is closed. Reopen if detected. Always keep session is active +def Monitor(inGlobalDict, inListUpdateTimeout): + lFlagWhile = True + lResponsibilityCheckLastSec = time.time() # Get current time for check interval + while lFlagWhile: + try: + # UIOSelector list init + lUIOSelectorList = [] + #Prepare selectors list for check + for lIndex, lItem in enumerate(inGlobalDict["RDPList"]): + lUIOSelectorList.append([{"title_re": f"{lItem['SessionHex']}.*", "backend": "win32"}]) + #Run wait command + #import pdb + #pdb.set_trace() + lRDPDissappearList = UIDesktop.UIOSelectorsSecs_WaitDisappear_List(lUIOSelectorList, inListUpdateTimeout) + #print(lRDPDissappearList) + ########################################### + #Analyze if flag safeturn off is activated + if inGlobalDict.get("OrchestratorToRobotResetStorage",{}).get("SafeTurnOff",False): + lFlagWhile=False + #Set status disconnected for all RDP List + for lItem in inGlobalDict["RDPList"]: + lItem["SessionIsWindowExistBool"]=False + lItem["SessionIsWindowResponsibleBool"]=False + #Kill all RDP sessions + os.system('taskkill /F /im mstsc.exe') + #Return from function + return + ########################################### + ########################################### + for lItem in lRDPDissappearList: + inGlobalDict["RDPList"][lItem]["SessionIsWindowExistBool"] = False # Set flag that session is disconnected + inGlobalDict["RDPList"][lItem]["SessionIsWindowResponsibleBool"]=False + #pdb.set_trace() + #Session start if it is not in ignore list + #add check for selector if it is not in ignoreIndexList + if lItem not in inGlobalDict["OrchestratorToRobotStorage"]["IgnoreIndexList"]: + try: + Connector.Session(inGlobalDict["RDPList"][lItem]) + inGlobalDict["RDPList"][lItem]["SessionIsWindowExistBool"] = True # Flag that session is started + inGlobalDict["RDPList"][lItem]["SessionIsWindowResponsibleBool"]= True + # Write in logger - info + inGlobalDict["Logger"].info(f"SessionHex: {str(inGlobalDict['RDPList'][lItem]['SessionHex'])}:: Session has been initialized!") + # catch ConnectorExceptions.SessionWindowNotExistError + except ConnectorExceptions.SessionWindowNotExistError as e: + inGlobalDict["RDPList"][lItem]["SessionIsWindowExistBool"] = False # Set flag that session is disconnected + inGlobalDict["RDPList"][lItem]["SessionIsWindowResponsibleBool"]=False + # Write in logger - warning + inGlobalDict["Logger"].warning(f"SessionHex: {str(inGlobalDict['RDPList'][lItem]['SessionHex'])}:: Session is not exist!") + # catch ConnectorExceptions.SessionWindowNotResponsibleError + except ConnectorExceptions.SessionWindowNotResponsibleError as e: + inGlobalDict["RDPList"][lItem]["SessionIsWindowExistBool"] = True # Set flag that session is disconnected + inGlobalDict["RDPList"][lItem]["SessionIsWindowResponsibleBool"]=False + # Write in logger - warning + inGlobalDict["Logger"].warning(f"SessionHex: {str(inGlobalDict['RDPList'][lItem]['SessionHex'])}:: Session is not responsible!") + # general exceptions + except Exception as e: + # Write in logger - warning + inGlobalDict["Logger"].exception(f"!!! ATTENTION !!! Unrecognized error") + ####################### + # Click all warning messages + Connector.SystemRDPWarningClickOk() + ####################### + ########################################### + #Check if from Orchestrator full screen session is set + if inGlobalDict["OrchestratorToRobotStorage"]["FullScreenSessionIndex"] != inGlobalDict["FullScreenSessionIndex"]: + #Do some switches + #If full screen mode we have now + if inGlobalDict["FullScreenSessionIndex"] is not None: + if inGlobalDict["RDPList"][inGlobalDict["FullScreenSessionIndex"]]["SessionIsWindowExistBool"]: + Connector.SessionScreen100x550(inGlobalDict["RDPList"][inGlobalDict["FullScreenSessionIndex"]]["SessionHex"]) + #If new session is setted + if inGlobalDict["OrchestratorToRobotStorage"]["FullScreenSessionIndex"] is not None: + if inGlobalDict["RDPList"][inGlobalDict["OrchestratorToRobotStorage"]["FullScreenSessionIndex"]]["SessionIsWindowExistBool"]: + Connector.SessionScreenFull(inGlobalDict["RDPList"][inGlobalDict["OrchestratorToRobotStorage"]["FullScreenSessionIndex"]]["SessionHex"]) + #Set one to other equal + inGlobalDict["FullScreenSessionIndex"] = inGlobalDict["OrchestratorToRobotStorage"]["FullScreenSessionIndex"] + ########################################### + #################################### + ##### Block check responsibility interval [ResponsibilityCheckIntervalSec] + if inGlobalDict['ResponsibilityCheckIntervalSec']: # Do check if ResponsibilityCheckIntervalSec is not None + if (time.time - lResponsibilityCheckLastSec()) > inGlobalDict['ResponsibilityCheckIntervalSec']: + # Set new time + lResponsibilityCheckLastSec = time.time() + # Do responsibility check + for lIndex, lItem in enumerate(inGlobalDict["RDPList"]): + # Check RDP responsibility + lDoCheckResponsibilityBool = True + lDoCheckResponsibilityCountMax = 20 + lDoCheckResponsibilityCountCurrent = 0 + while lDoCheckResponsibilityBool: + # Enter full screen mode + Connector.SessionScreenFull(lItem['SessionHex']) + time.sleep(2) + # Check responding + lDoCheckResponsibilityBool = not Connector.SystemRDPIsResponsible() + # Check if counter is exceed - raise exception + if lDoCheckResponsibilityCountCurrent >= lDoCheckResponsibilityCountMax: + lItem["SessionIsWindowExistBool"] = False # Set flag that session is disconnected + lItem["SessionIsWindowResponsibleBool"]=False + # Session window is not responsible - restart RDP (close window here - next loop will reconnect) + Connector.SessionClose(lItem['SessionHex']) + # Turn off the loop + lDoCheckResponsibilityBool = False + else: + # Exit fullscreen mode + Connector.SessionScreen100x550(lItem['SessionHex']) + # Wait if is not responding + if lDoCheckResponsibilityBool: + time.sleep(3) + # increase the couter + lDoCheckResponsibilityCountCurrent+=1 + #################################### + # Check ActivityList from orchestrator + lActivityListNew = [] + lActivityListOld = inGlobalDict["OrchestratorToRobotResetStorage"]["ActivityList"]+inGlobalDict["ActivityListStart"] + inGlobalDict["ActivityListStart"] = [] + for lActivityItem in lActivityListOld: + ################# + #Call function from Activity structure + ################################################ + lSubmoduleFunctionName = lActivityItem["DefName"] + lFileFullPath = lActivityItem["ModulePath"] # "path\\to\\module.py" + lModuleName = (lFileFullPath.split("\\")[-1])[0:-3] + lTechSpecification = importlib.util.spec_from_file_location(lModuleName, lFileFullPath) + lTechModuleFromSpec = importlib.util.module_from_spec(lTechSpecification) + lTechSpecificationModuleLoader = lTechSpecification.loader.exec_module(lTechModuleFromSpec) + # Set gSettings in module + lTechModuleFromSpec.gSettings = inGlobalDict + if lSubmoduleFunctionName in dir(lTechModuleFromSpec): + # Run SettingUpdate function in submodule + #mGlobalDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)() + lActivityItemResult=getattr(lTechModuleFromSpec, lSubmoduleFunctionName)(*lActivityItem["ArgList"],**lActivityItem["ArgDict"]) + lActivityItemResultType = type(lActivityItemResult) + # Check if Result is bool + if lActivityItemResultType is bool: + if not lActivityItemResult: + # Activity is not done - add to list (retry in future) + lActivityListNew.append(lActivityItem) + ################################################# + inGlobalDict["OrchestratorToRobotResetStorage"]["ActivityList"] = lActivityListNew # Override the value + except RuntimeError as e: + # case noGUI error passed - do nothing + # Write in logger - warning + inGlobalDict["Logger"].warning(f"Host session has lost the GUI") + finally: + # Wait for the next iteration + time.sleep(0.7) + return None +#TODO Def garbage window cleaner (if connection was lost) \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py new file mode 100644 index 00000000..3d46674e --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py @@ -0,0 +1,147 @@ +# ATTENTION! HERE IS NO Relative import because it will be imported dynamically +# All function check the flag SessionIsWindowResponsibleBool == True else no cammand is processed +# All functions can return None, Bool or Dict { "IsSuccessful": True } +from . import CMDStr # Create CMD Strings +from . import Connector # RDP API +from . import ConnectorExceptions # Exceptions +import time # sleep function +# ATTENTION +gSettings = None # Gsettings will be initialized after the import module + +# Create new RDPSession in RobotRDPActive +def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPasswordStr): + lRDPConfigurationItem = { # Init the configuration item + "Host": inHostStr, # Host address, example "77.77.22.22" + "Port": inPortStr, # RDP Port, example "3389" + "Login": inLoginStr, # Login, example "test" + "Password": inPasswordStr, # Password, example "test" + "Screen": { + "Width": 1680, # Width of the remote desktop in pixels, example 1680 + "Height": 1050, # Height of the remote desktop in pixels, example 1050 + # "640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen, example + "FlagUseAllMonitors": False, # True or False, example False + "DepthBit": "32" # "32" or "24" or "16" or "15", example "32" + }, + "SharedDriveList": ["c"], # List of the Root sesion hard drives, example ["c"] + ###### Will updated in program ############ + "SessionHex": "77777sdfsdf77777dsfdfsf77777777", # Hex is created when robot runs, example "" + "SessionIsWindowExistBool": False, # Flag if the RDP window is exist, old name "FlagSessionIsActive". Check every n seconds , example False + "SessionIsWindowResponsibleBool": False, # Flag if RDP window is responsible (recieve commands). Check every nn seconds. If window is Responsible - window is Exist too , example False + "SessionIsIgnoredBool": False # Flag to ignore RDP window False - dont ignore, True - ignore, example False + } + # Add item in RDPList + gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr] = lRDPConfigurationItem + # Create the RDP session + Connector.Session(lRDPConfigurationItem) + return True + +# Disconnect the RDP session +def RDPSessionDisconnect(inRDPSessionKeyStr): + global gSettings + lSessionHex = gSettings["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) + if lSessionHex: + gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) + Connector.SessionClose(inSessionHexStr=lSessionHex) + return True + +# RDP Session reconnect +def RDPSessionReconnect(inRDPSessionKeyStr): + global gSettings + lRDPConfigurationItem = gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr] + RDPSessionDisconnect(inRDPSessionKeyStr=inRDPSessionKeyStr) # Disconnect the RDP + # Add item in RDPList + gSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr] = lRDPConfigurationItem + # Create the RDP session + Connector.Session(lRDPConfigurationItem) + return True + +# Logoff the RDP session +def RDPSessionLogoff(inRDPSessionKeyStr): + global gSettings + lResult = True + lCMDStr = "shutdown -L" # CMD logoff command + # Calculate the session Hex + lSessionHex = gSettings["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) + if lSessionHex: + gSettings["RobotRDPActive"]["RDPList"].pop(inRDPSessionKeyStr,None) + # Run CMD + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN") + return lResult + +# Check RDP Session responsibility TODO NEED DEV + TEST +def RDPSessionResponsibilityCheck(inRDPSessionKeyStr): + global gSettings + inGlobalDict = gSettings + lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]["SessionHex"] + # set the fullscreen + Connector.SessionScreenFull(inSessionHex=lSessionHex) + time.sleep(1) + # Check RDP responsibility + lDoCheckResponsibilityBool = True + lDoCheckResponsibilityCountMax = 20 + lDoCheckResponsibilityCountCurrent = 0 + while lDoCheckResponsibilityBool: + # Check if counter is exceed - raise exception + if lDoCheckResponsibilityCountCurrent >= lDoCheckResponsibilityCountMax: + pass + #raise ConnectorExceptions.SessionWindowNotResponsibleError("Error when initialize the RDP session - RDP window is not responding!") + # Check responding + lDoCheckResponsibilityBool = not Connector.SystemRDPIsResponsible() + # Wait if is not responding + if lDoCheckResponsibilityBool: + time.sleep(3) + # increase the couter + lDoCheckResponsibilityCountCurrent+=1 + return True + +# Start process if it is not running +def RDPSessionProcessStartIfNotRunning(inRDPSessionKeyStr, inProcessNameWEXEStr, inFilePathStr, inFlagGetAbsPathBool=True): + global gSettings + inGlobalDict = gSettings + lResult = True + lCMDStr = CMDStr.ProcessStartIfNotRunning(inProcessNameWEXEStr, inFilePathStr, inFlagGetAbsPath= inFlagGetAbsPathBool) + # Calculate the session Hex + lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) + # Run CMD + if lSessionHex: + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN") + return lResult +# Create CMD str to stop process +def RDPSessionProcessStop(inRDPSessionKeyStr, inProcessNameWEXEStr, inFlagForceCloseBool): + global gSettings + inGlobalDict = gSettings + lResult = True + lCMDStr = f'taskkill /im "{inProcessNameWEXEStr}" /fi "username eq %USERNAME%"' + if inFlagForceCloseBool: + lCMDStr+= " /F" + # Calculate the session Hex + lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) + # Run CMD + if lSessionHex: + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="RUN") + return lResult +# Send file from Host to Session RDP using shared drive in RDP +def RDPSessionFileStoredSend(inRDPSessionKeyStr, inHostFilePathStr, inRDPFilePathStr): + global gSettings + inGlobalDict = gSettings + lResult = True + lCMDStr = CMDStr.FileStoredSend(inHostFilePath = inHostFilePathStr, inRDPFilePath = inRDPFilePathStr) + # Calculate the session Hex + lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr, {}).get("SessionHex", None) + #lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr]["SessionHex"] + # Run CMD + if lSessionHex: + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120) + return lResult +# Recieve file from Session RDP to Host using shared drive in RDP +def RDPSessionFileStoredRecieve(inRDPSessionKeyStr, inRDPFilePathStr, inHostFilePathStr): + global gSettings + inGlobalDict = gSettings + lResult = True + lCMDStr = CMDStr.FileStoredRecieve(inRDPFilePath = inRDPFilePathStr, inHostFilePath = inHostFilePathStr) + # Calculate the session Hex + lSessionHex = inGlobalDict["RobotRDPActive"]["RDPList"].get(inRDPSessionKeyStr,{}).get("SessionHex", None) + # Run CMD + if lSessionHex: + Connector.SessionCMDRun(inSessionHex=lSessionHex, inCMDCommandStr=lCMDStr, inModeStr="LISTEN", inClipboardTimeoutSec = 120) + return lResult \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py new file mode 100644 index 00000000..bcb3e76f --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py @@ -0,0 +1,142 @@ +from pyOpenRPA.Robot import UIDesktop +import os +import time # Time wait operations +from . import ConnectorExceptions # Exceptions classes +from . import Connector +from . import Processor # Module for process some functions on thr RDP +# Main function +def RobotRDPActive(inGSettings): + # inGSettings = { + # ... "RobotRDPActive": {} ... + # } + #import pdb + #pdb.set_trace() + lLogger = inGSettings["Logger"] # Synonim + Processor.gSettings = inGSettings # Set gSettings in processor module + mGSettingsRDPActiveDict = inGSettings["RobotRDPActive"] # Get configuration from global dict settings + # Global error handler + try: + ######## Init the RDP List + for lRDPSessionKeyStrItem in mGSettingsRDPActiveDict["RDPList"]: + lConfigurationItem = mGSettingsRDPActiveDict["RDPList"][lRDPSessionKeyStrItem] + lConfigurationItem["SessionIsWindowExistBool"] = False # Flag that session is not started + lConfigurationItem["SessionIsWindowResponsibleBool"] = False # Flag that session is not started + lConfigurationItem["SessionHex"] = " 77777sdfsdf77777dsfdfsf77777777" # Flag that session is not started + ########## + # Run monitor - main loop + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + inGlobalDict = mGSettingsRDPActiveDict # Compatibility + inListUpdateTimeout = 1 # Compatibility + lFlagWhile = True + lResponsibilityCheckLastSec = time.time() # Get current time for check interval + while lFlagWhile: + try: + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # Check RDP window is OK - reconnect if connection was lost + lUIOSelectorList = [] + lRDPConfigurationDictList = [] + # Prepare selectors list for check + for lRDPSessionKeyStrItem in inGlobalDict["RDPList"]: + lItem = inGlobalDict["RDPList"][lRDPSessionKeyStrItem] + lRDPConfigurationDictList.append(lItem) # Add RDP Configuration in list + lUIOSelectorList.append([{"title_re": f"{lItem['SessionHex']}.*", "backend": "win32"}]) + # Run wait command + lRDPDissappearList = UIDesktop.UIOSelectorsSecs_WaitDisappear_List(lUIOSelectorList, inListUpdateTimeout) + for lItem in lRDPDissappearList: # Reconnect if connection was lost + lRDPConfigurationDict = lRDPConfigurationDictList[lItem] # Get RDP Configuration list + lRDPConfigurationDict["SessionIsWindowExistBool"] = False # Set flag that session is disconnected + # Check if RDP window is not ignored + if not lRDPConfigurationDict["SessionIsIgnoredBool"]: + try: + Connector.Session(lRDPConfigurationDict) + lRDPConfigurationDict["SessionIsWindowExistBool"] = True # Flag that session is started + # Write in logger - info + lLogger.info( + f"SessionHex: {str(lRDPConfigurationDict['SessionHex'])}:: Session has been initialized!") + # catch ConnectorExceptions.SessionWindowNotExistError + except ConnectorExceptions.SessionWindowNotExistError as e: + lRDPConfigurationDict["SessionIsWindowExistBool"] = False # Set flag that session is disconnected + # Write in logger - warning + lLogger.warning( + f"SessionHex: {str(lRDPConfigurationDict['SessionHex'])}:: Session is not exist!") + # general exceptions + except Exception as e: + # Write in logger - warning + lLogger.exception(f"!!! ATTENTION !!! Unrecognized error") + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # Safe turn off the - no need because of Orchestrator control + #if inGlobalDict.get("OrchestratorToRobotResetStorage", {}).get("SafeTurnOff", False): + # lFlagWhile = False + # # Set status disconnected for all RDP List + # for lItem in inGlobalDict["RDPList"]: + # lItem["SessionIsWindowExistBool"] = False + # lItem["SessionIsWindowResponsibleBool"] = False + # # Kill all RDP sessions + # os.system('taskkill /F /im mstsc.exe') + # # Return from function + # return + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + Connector.SystemRDPWarningClickOk() # Click all warning messages + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # Check if RDP session is full screen (if is not ignored) + if inGlobalDict["FullScreenRDPSessionKeyStr"] is not None: + lRDPSessionKeyStr = inGlobalDict["FullScreenRDPSessionKeyStr"] # Get the RDPSessionKeyStr + if lRDPSessionKeyStr in inGlobalDict["RDPList"]: # Session Key is in dict + lRDPConfigurationDict = inGlobalDict["RDPList"][lRDPSessionKeyStr] + #if not lRDPConfigurationDict["SessionIsIgnoredBool"]: # Session is not ignored + # Check if full screen + lIsFullScreenBool = Connector.SessionIsFullScreen(inSessionHexStr=lRDPConfigurationDict["SessionHex"]) + if not lIsFullScreenBool: # If not the full screen + # Check all RDP window and minimize it + for lRDPSessionKeyStrItem in inGlobalDict["RDPList"]: + lRDPConfigurationDictItem = inGlobalDict["RDPList"][lRDPSessionKeyStrItem] + if Connector.SessionIsFullScreen(inSessionHexStr=lRDPConfigurationDictItem["SessionHex"]): + Connector.SessionScreenSize_X_Y_W_H(inSessionHex=lRDPConfigurationDictItem["SessionHex"], inXInt=10, inYInt=10, + inWInt=550, + inHInt=350) # Prepare little window + # Set full screen for new window + Connector.SessionScreenFull(inSessionHex=lRDPConfigurationDict["SessionHex"]) + else: + # Check all RDP window and minimize it + for lRDPSessionKeyStrItem in inGlobalDict["RDPList"]: + lRDPConfigurationDictItem = inGlobalDict["RDPList"][lRDPSessionKeyStrItem] + if Connector.SessionIsFullScreen(inSessionHexStr=lRDPConfigurationDictItem["SessionHex"]): + Connector.SessionScreenSize_X_Y_W_H(inSessionHex=lRDPConfigurationDictItem["SessionHex"], + inXInt=10, inYInt=10, + inWInt=550, + inHInt=350) # Prepare little window + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + # Iterate the activity list in robot RDP active + lActivityListNew = [] + lActivityListOld = inGlobalDict["ActivityList"] + inGlobalDict["ActivityList"] = [] + for lActivityItem in lActivityListOld: + lSubmoduleFunctionName = lActivityItem["DefNameStr"] + if lSubmoduleFunctionName in dir(Processor): + # Run SettingUpdate function in submodule + # mGlobalDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)() + lActivityItemResult = getattr(Processor, lSubmoduleFunctionName)( + *lActivityItem["ArgList"], **lActivityItem["ArgDict"]) + lActivityItemResultType = type(lActivityItemResult) + # Check if Result is bool + if lActivityItemResultType is bool: + if not lActivityItemResult: + # Activity is not done - add to list (retry in future) + lActivityListNew.append(lActivityItem) + inGlobalDict["ActivityList"] = lActivityListNew # Override the value + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + except RuntimeError as e: + # case noGUI error passed - do nothing + # Write in logger - warning + lLogger.warning(f"Host session has lost the GUI") + finally: + # Wait for the next iteration + time.sleep(0.7) + # Scheduler.Scheduler(mGSettingsRDPActiveDict["Scheduler"]) # Init & Run Scheduler TODO remake in processor list + # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + #Monitor.Monitor(mGSettingsRDPActiveDict, 1) + except Exception as e: + # Write in logger - warning + lLogger.exception(f"!!! ATTENTION !!! Global error handler - look at code") \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Scheduler.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Scheduler.py new file mode 100644 index 00000000..dca0651a --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Scheduler.py @@ -0,0 +1,111 @@ +from . import Timer # Async thread +import threading # Create in another thread +import datetime # Datetime class +import time # time functions +import importlib # import lib functions +# Scheduler class - init and work by the configuration +# OOP +class Scheduler: + # Class properties + mSchedulerDict = None + mGSettings = None + ######################### + # Init class + def __init__(self,inSchedulerDict, inGSettings = None): + self.Init(inSchedulerDict = inSchedulerDict, inGSettings = inGSettings) + # Init the class instance + def Init(self,inSchedulerDict, inGSettings): + self.mGSettings = inGSettings + self.mSchedulerDict = inSchedulerDict + # Init the threads + lTimerMainThread = threading.Thread(target = self.TimerMainThreadRun) + lTimerMainThread.start() # Start the Timer main thread + #print (f"Class instance configuration: {self.mSchedulerDict}, Init has been completed") + ######################## + # Main timer thread - run when init class instance + def TimerMainThreadRun(self): + lDaemonStartDateTime=datetime.datetime.now() + lDaemonLoopSeconds=self.mSchedulerDict["ActivityTimeCheckLoopSeconds"] + lDaemonActivityLogDict={} #Словарь отработанных активностей, ключ - кортеж (, , , ) + #Вечный цикл + while True: + lCurrentDateTime = datetime.datetime.now() + #Циклический обход правил + lFlagSearchActivityType=True + for lIndex, lItem in enumerate(self.mSchedulerDict["ActivityTimeList"]): + #Проверка дней недели, в рамках которых можно запускать активность + lItemWeekdayList=lItem.get("WeekdayList", [0, 1, 2, 3, 4, 5, 6]) + if lCurrentDateTime.weekday() in lItemWeekdayList: + if lFlagSearchActivityType: + ####################################################################### + #Branch 1 - if has TimeHH:MM + ####################################################################### + if "TimeHH:MM" in lItem: + #Вид активности - запуск процесса + #Сформировать временной штамп, относительно которого надо будет проверять время + #часовой пояс пока не учитываем + lActivityDateTime=datetime.datetime.strptime(lItem["TimeHH:MM"],"%H:%M") + lActivityDateTime=lActivityDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day) + #Убедиться в том, что время наступило + if ( + lActivityDateTime>=lDaemonStartDateTime and + lCurrentDateTime>=lActivityDateTime and + (lIndex,lActivityDateTime) not in lDaemonActivityLogDict): + #Выполнить операцию + #Запись в массив отработанных активностей + lDaemonActivityLogDict[(lIndex,lActivityDateTime)]={"ActivityStartDateTime":lCurrentDateTime} + #Запустить процесс - new code + ################# + #Call function from Activity structure + ################################################ + lSubmoduleFunctionName = lItem["Activity"]["DefName"] + lFileFullPath = lItem["Activity"]["ModulePath"] # "path\\to\\module.py" + lModuleName = (lFileFullPath.split("\\")[-1])[0:-3] + lTechSpecification = importlib.util.spec_from_file_location(lModuleName, lFileFullPath) + lTechModuleFromSpec = importlib.util.module_from_spec(lTechSpecification) + lTechSpecificationModuleLoader = lTechSpecification.loader.exec_module(lTechModuleFromSpec) + # Set gSettings in module + lTechModuleFromSpec.gSettings = self.mGSettings + if lSubmoduleFunctionName in dir(lTechModuleFromSpec): + # Run SettingUpdate function in submodule + #mGlobalDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)() + getattr(lTechModuleFromSpec, lSubmoduleFunctionName)(*lItem["Activity"]["ArgList"],**lItem["Activity"]["ArgDict"]) + ################################################# + ####################################################################### + #Branch 2 - if TimeHH:MMStart, TimeHH:MMStop, ActivityIntervalSeconds + ####################################################################### + if "TimeHH:MMStart" in lItem and "TimeHH:MMStop" in lItem and "ActivityIntervalSeconds" in lItem: + #Сформировать временной штамп, относительно которого надо будет проверять время + #часовой пояс пока не учитываем + lActivityDateTime=datetime.datetime.strptime(lItem["TimeHH:MMStart"],"%H:%M") + lActivityDateTime=lActivityDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day) + lActivityTimeEndDateTime=datetime.datetime.strptime(lItem["TimeHH:MMStop"],"%H:%M") + lActivityTimeEndDateTime=lActivityTimeEndDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day) + #Убедиться в том, что время наступило + if ( + lCurrentDateTime=lActivityDateTime and + (lIndex,lActivityDateTime) not in lDaemonActivityLogDict): + #Запись в массив отработанных активностей + lDaemonActivityLogDict[(lIndex,lActivityDateTime)]={"ActivityStartDateTime":lCurrentDateTime} + #Call function from Activity structure + ################################################ + lSubmoduleFunctionName = lItem["Activity"]["DefName"] + lFileFullPath = lItem["Activity"]["ModulePath"] # "path\\to\\module.py" + lModuleName = (lFileFullPath.split("\\")[-1])[0:-3] + lTechSpecification = importlib.util.spec_from_file_location(lModuleName, lFileFullPath) + lTechModuleFromSpec = importlib.util.module_from_spec(lTechSpecification) + lTechSpecificationModuleLoader = lTechSpecification.loader.exec_module(lTechModuleFromSpec) + # Set gSettings in module + lTechModuleFromSpec.gSettings = self.mGSettings + if lSubmoduleFunctionName in dir(lTechModuleFromSpec): + # Run SettingUpdate function in submodule + #mGlobalDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)() + lDef = getattr(lTechModuleFromSpec, lSubmoduleFunctionName) #(*lItem["Activity"]["ArgList"],**lItem["Activity"]["ArgDict"]) + ################################################# + #Запуск циклической процедуры + #Timer.activityLoopStart(lItem["ActivityIntervalSeconds"], lActivityTimeEndDateTime, lItem["Activity"]) + lTimer = Timer.RepeatedTimer(lItem["ActivityIntervalSeconds"], lActivityTimeEndDateTime, lDef, *lItem["Activity"]["ArgList"], **lItem["Activity"]["ArgDict"]) # it auto-starts, no need of rt.start() + #Уснуть до следующего прогона + #print (f"Loop has been completed") + time.sleep(lDaemonLoopSeconds) \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Timer.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Timer.py new file mode 100644 index 00000000..3f1e4fcc --- /dev/null +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/Timer.py @@ -0,0 +1,31 @@ +from threading import Timer +import datetime +class RepeatedTimer(object): + def __init__(self, interval, inDateTimeEnd, function, *args, **kwargs): + self._timer = None + self.interval = interval + self.function = function + self.args = args + self.kwargs = kwargs + self.is_running = False + self.mDateTimeEnd = inDateTimeEnd # DateTime when stop + self.start() + def _run(self): + self.is_running = False + lResultGoLoop=True + lCurrentDateTime=datetime.datetime.now() + self.function(*self.args, **self.kwargs) + if lCurrentDateTime>=self.mDateTimeEnd: + lResultGoLoop=False + if lResultGoLoop is not None: + if lResultGoLoop: + self.start() + def start(self): + if not self.is_running: + self._timer = Timer(self.interval, self._run) + self._timer.start() + self.is_running = True + + def stop(self): + self._timer.cancel() + self.is_running = False \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/__init__.py similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__init__.py rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/__init__.py diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__main__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/__main__.py similarity index 57% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__main__.py rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/__main__.py index 7217dbed..b6ffa9e4 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Tools/RobotRDPActive/__main__.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/RobotRDPActive/__main__.py @@ -13,7 +13,7 @@ import importlib lFolderPath = "/".join(__file__.split("/")[:-4]) sys.path.insert(0, lFolderPath) #Единый глобальный словарь (За основу взять из Settings.py) -global mGlobalDict +global gSettingsDict #Call Settings function from argv[1] file ################################################ lSubmoduleFunctionName = "Settings" @@ -22,28 +22,30 @@ lModuleName = (lFileFullPath.split("\\")[-1])[0:-3] lTechSpecification = importlib.util.spec_from_file_location(lModuleName, lFileFullPath) lTechModuleFromSpec = importlib.util.module_from_spec(lTechSpecification) lTechSpecificationModuleLoader = lTechSpecification.loader.exec_module(lTechModuleFromSpec) -mGlobalDict = None +gSettingsDict = None if lSubmoduleFunctionName in dir(lTechModuleFromSpec): # Run SettingUpdate function in submodule - mGlobalDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)() + gSettingsDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)() ################################################# ######################################################### from pyOpenRPA.Tools.RobotRDPActive import Connector from pyOpenRPA.Tools.RobotRDPActive import Monitor -#Disable certificate warning -lCMDString = 'reg add "HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client" /v "AuthenticationLevelOverride" /t "REG_DWORD" /d 0 /f' -os.system(lCMDString) -#time.sleep() -for lConfigurationItem in mGlobalDict["RDPList"]: - try: - Connector.Session(lConfigurationItem) - lConfigurationItem["FlagSessionIsActive"]=True #Flag that session is started - except Exception: - pass -#Run monitor -Monitor.Monitor(mGlobalDict, 1) -#Enable certificate warning -lCMDString = 'reg add "HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client" /v "AuthenticationLevelOverride" /t "REG_DWORD" /d 2 /f' -os.system(lCMDString) -#Close all thread from OrchestratorConnection -mGlobalDict["OrchestratorConnectorTerminateAll"]() \ No newline at end of file +from pyOpenRPA.Tools.RobotRDPActive import Scheduler # Scheduler operations +#### Global error handler +try: + #time.sleep() + ######## Init the RDP List + for lConfigurationItem in gSettingsDict["RDPList"]: + lConfigurationItem["SessionIsWindowExistBool"]=False #Flag that session is not started + lConfigurationItem["SessionIsWindowResponsibleBool"]=False #Flag that session is not started + lConfigurationItem["SessionHex"]=" 77777sdfsdf77777dsfdfsf77777777" #Flag that session is not started + ########## + #Run monitor + Scheduler.Scheduler(gSettingsDict["Scheduler"]) # Init & Run Scheduler + Monitor.Monitor(gSettingsDict, 1) +except Exception as e: + # Write in logger - warning + gSettingsDict["Logger"].exception(f"!!! ATTENTION !!! Global error handler - look at code") +finally: + #Close all thread from OrchestratorConnection + gSettingsDict["OrchestratorConnectorTerminateAll"]() \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Server.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Server.py index 4a970585..be70002d 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Server.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Server.py @@ -1,3 +1,11 @@ +# inRequest.OpenRPA = {} +# inRequest.OpenRPA["AuthToken"] = None +# inRequest.OpenRPA["Domain"] = None +# inRequest.OpenRPA["User"] = None + +# lResponseDict = {"Headers": {}, "SetCookies": {}, "Body": b"", "StatusCode": None} +# self.OpenRPAResponseDict = lResponseDict + from http.server import BaseHTTPRequestHandler, HTTPServer from socketserver import ThreadingMixIn import threading @@ -11,8 +19,9 @@ import uuid import datetime import os #for path operations from http import cookies -global mGlobalDict +global gSettingsDict from . import ServerSettings +import copy #Authenticate function () # return dict # { @@ -26,17 +35,21 @@ def AuthenticateVerify(inRequest): lCookies = cookies.SimpleCookie(inRequest.headers.get("Cookie", "")) inRequest.OpenRPA = {} inRequest.OpenRPA["AuthToken"] = None + inRequest.OpenRPA["Domain"] = None + inRequest.OpenRPA["User"] = None #pdb.set_trace() if "AuthToken" in lCookies: lCookieAuthToken = lCookies.get("AuthToken", "").value if lCookieAuthToken: #Find AuthToken in GlobalDict - if lCookieAuthToken in mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("AuthTokensDict", {}): + if lCookieAuthToken in gSettingsDict.get("Server", {}).get("AccessUsers", {}).get("AuthTokensDict", {}): #Auth Token Has Been Founded - lResult["Domain"] = mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lCookieAuthToken]["Domain"] - lResult["User"] = mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lCookieAuthToken]["User"] + lResult["Domain"] = gSettingsDict["Server"]["AccessUsers"]["AuthTokensDict"][lCookieAuthToken]["Domain"] + lResult["User"] = gSettingsDict["Server"]["AccessUsers"]["AuthTokensDict"][lCookieAuthToken]["User"] #Set auth token inRequest.OpenRPA["AuthToken"] = lCookieAuthToken + inRequest.OpenRPA["Domain"] = lResult["Domain"] + inRequest.OpenRPA["User"] = lResult["User"] #Exit earlier return lResult ###################################### @@ -66,13 +79,15 @@ def AuthenticateVerify(inRequest): lResult["User"] = lLogonResult["User"] #Create token lAuthToken=str(uuid.uuid1()) - mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken] = {} - mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["Domain"] = lResult["Domain"] - mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["User"] = lResult["User"] - mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["FlagDoNotExpire"] = False - mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["TokenDatetime"] = datetime.datetime.now() + gSettingsDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken] = {} + gSettingsDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["Domain"] = lResult["Domain"] + gSettingsDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["User"] = lResult["User"] + gSettingsDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["FlagDoNotExpire"] = False + gSettingsDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["TokenDatetime"] = datetime.datetime.now() #Set-cookie inRequest.OpenRPA["AuthToken"] = lAuthToken + inRequest.OpenRPA["Domain"] = lResult["Domain"] + inRequest.OpenRPA["User"] = lResult["User"] inRequest.OpenRPASetCookie = {} #New engine of server inRequest.OpenRPAResponseDict["SetCookies"]["AuthToken"] = lAuthToken @@ -109,13 +124,13 @@ def UserAccessCheckBefore(inMethod, inRequest): #go next if user is identified lUserDict = None if lAuthToken: - lUserDict = mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken] + lUserDict = gSettingsDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken] #pdb.set_trace() ######################################## ######################################## #Check general before rule (without User domain) #Check rules - for lAccessRuleItem in mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("RuleMethodMatchURLBeforeList", []): + for lAccessRuleItem in gSettingsDict.get("Server", {}).get("AccessUsers", {}).get("RuleMethodMatchURLBeforeList", []): #Go next execution if flag is false if not lResult: #Check if Method is identical @@ -125,21 +140,21 @@ def UserAccessCheckBefore(inMethod, inRequest): lURLPath = inRequest.path lURLPath = lURLPath.upper() if lURLPath.startswith(lAccessRuleItem["URL"].upper()): - lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict) + lResult = HelpGetFlag(lAccessRuleItem, inRequest, gSettingsDict, lUserDict) # check Match type variant: Contains elif lAccessRuleItem["MatchType"].upper() == "CONTAINS": lURLPath = inRequest.path lURLPath = lURLPath.upper() if lURLPath.contains(lAccessRuleItem["URL"].upper()): - lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict) + lResult = HelpGetFlag(lAccessRuleItem, inRequest, gSettingsDict, lUserDict) # check Match type variant: Equal elif lAccessRuleItem["MatchType"].upper() == "EQUAL": if lAccessRuleItem["URL"].upper() == inRequest.path.upper(): - lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict) + lResult = HelpGetFlag(lAccessRuleItem, inRequest, gSettingsDict, lUserDict) # check Match type variant: EqualCase elif lAccessRuleItem["MatchType"].upper() == "EQUALCASE": if lAccessRuleItem["URL"] == inRequest.path: - lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict) + lResult = HelpGetFlag(lAccessRuleItem, inRequest, gSettingsDict, lUserDict) ######################################### ######################################### #Do check if lResult is false @@ -147,7 +162,7 @@ def UserAccessCheckBefore(inMethod, inRequest): #Check access by User Domain #Check rules to find first appicable #Check rules - for lAccessRuleItem in mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("RuleDomainUserDict", {}).get((lUserDict["Domain"].upper(), lUserDict["User"].upper()), {}).get("MethodMatchURLBeforeList", []): + for lAccessRuleItem in gSettingsDict.get("Server", {}).get("AccessUsers", {}).get("RuleDomainUserDict", {}).get((lUserDict["Domain"].upper(), lUserDict["User"].upper()), {}).get("MethodMatchURLBeforeList", []): #Go next execution if flag is false if not lResult: #Check if Method is identical @@ -157,21 +172,21 @@ def UserAccessCheckBefore(inMethod, inRequest): lURLPath = inRequest.path lURLPath = lURLPath.upper() if lURLPath.startswith(lAccessRuleItem["URL"].upper()): - lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict) + lResult = HelpGetFlag(lAccessRuleItem, inRequest, gSettingsDict, lUserDict) #check Match type variant: Contains elif lAccessRuleItem["MatchType"].upper() == "CONTAINS": lURLPath = inRequest.path lURLPath = lURLPath.upper() if lURLPath.contains(lAccessRuleItem["URL"].upper()): - lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict) + lResult = HelpGetFlag(lAccessRuleItem, inRequest, gSettingsDict, lUserDict) # check Match type variant: Equal elif lAccessRuleItem["MatchType"].upper() == "EQUAL": if lAccessRuleItem["URL"].upper() == inRequest.path.upper(): - lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict) + lResult = HelpGetFlag(lAccessRuleItem, inRequest, gSettingsDict, lUserDict) # check Match type variant: EqualCase elif lAccessRuleItem["MatchType"].upper() == "EQUALCASE": if lAccessRuleItem["URL"] == inRequest.path: - lResult = HelpGetFlag(lAccessRuleItem, inRequest, mGlobalDict, lUserDict) + lResult = HelpGetFlag(lAccessRuleItem, inRequest, gSettingsDict, lUserDict) ##################################### ##################################### #Return lResult @@ -221,24 +236,24 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): lURLPath = self.path lURLPath = lURLPath.upper() if lURLPath.startswith(inURLItem["URL"].upper()): - URLItemDo(inURLItem, self, mGlobalDict) + URLItemDo(inURLItem, self, gSettingsDict) return True # check Match type variant: Contains elif inURLItem["MatchType"].upper() == "CONTAINS": lURLPath = self.path lURLPath = lURLPath.upper() if lURLPath.contains(inURLItem["URL"].upper()): - URLItemDo(inURLItem, self, mGlobalDict) + URLItemDo(inURLItem, self, gSettingsDict) return True # check Match type variant: Equal elif inURLItem["MatchType"].upper() == "EQUAL": if inURLItem["URL"].upper() == self.path.upper(): - URLItemDo(inURLItem, self, mGlobalDict) + URLItemDo(inURLItem, self, gSettingsDict) return True # check Match type variant: EqualCase elif inURLItem["MatchType"].upper() == "EQUALCASE": if inURLItem["URL"] == self.path: - URLItemDo(inURLItem, self, mGlobalDict) + URLItemDo(inURLItem, self, gSettingsDict) return True return False #ResponseContentTypeFile @@ -281,12 +296,12 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): ##################################### lFlagAccessUserBlock=False lAuthenticateDict = {"Domain": "", "User": ""} - if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False): + if gSettingsDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False): lAuthenticateDict = AuthenticateVerify(self) if not lAuthenticateDict["User"]: lFlagAccessUserBlock=True # Logging - mGlobalDict["Logger"].info(f"HTTP request /. Domain: {lAuthenticateDict['Domain']}, User: {lAuthenticateDict['User']}") + # gSettingsDict["Logger"].info(f"HTTP request /. Domain: {lAuthenticateDict['Domain']}, User: {lAuthenticateDict['User']}") if lFlagAccessUserBlock: AuthenticateBlock(self) ##################################### @@ -295,7 +310,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): #################################### lFlagUserAccess = True #If need user authentication - if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False): + if gSettingsDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False): lFlagUserAccess = UserAccessCheckBefore("GET", self) ###################################### if lFlagUserAccess: @@ -303,7 +318,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): ############################ #New server engine (url from global dict (URLList)) ############################ - for lURLItem in mGlobalDict["Server"]["URLList"]: + for lURLItem in gSettingsDict["Server"]["URLList"]: #Check if all condition are applied lFlagURLIsApplied=False lFlagURLIsApplied=self.URLItemCheckDo(lURLItem, "GET") @@ -318,15 +333,15 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): self.send_header('Content-type','application/json') self.end_headers() # Send message back to client - message = json.dumps(mGlobalDict) + message = json.dumps(gSettingsDict) # Write content as utf-8 data self.wfile.write(bytes(message, "utf8")) #Filemanager function if self.path.lower().startswith('/filemanager/'): lFileURL=self.path[13:] # check if file in FileURL - File Path Mapping Dict - if lFileURL.lower() in mGlobalDict["FileManager"]["FileURLFilePathDict"]: - self.SendResponseContentTypeFile('application/octet-stream',mGlobalDict["FileManager"]["FileURLFilePathDict"][lFileURL]) + if lFileURL.lower() in gSettingsDict["FileManager"]["FileURLFilePathDict"]: + self.SendResponseContentTypeFile('application/octet-stream', gSettingsDict["FileManager"]["FileURLFilePathDict"][lFileURL]) else: #Set access denied code # Send response status code @@ -345,7 +360,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): ##################################### lFlagAccessUserBlock=False lAuthenticateDict = {"Domain": "", "User": ""} - if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False): + if gSettingsDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False): lAuthenticateDict = AuthenticateVerify(self) if not lAuthenticateDict["User"]: lFlagAccessUserBlock=True @@ -357,7 +372,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): #################################### lFlagUserAccess = True #If need user authentication - if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False): + if gSettingsDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False): lFlagUserAccess = UserAccessCheckBefore("POST", self) ###################################### if lFlagUserAccess: @@ -365,7 +380,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): ############################ #New server engine (url from global dict (URLList)) ############################ - for lURLItem in mGlobalDict["Server"]["URLList"]: + for lURLItem in gSettingsDict["Server"]["URLList"]: #Check if all condition are applied lFlagURLIsApplied=False lFlagURLIsApplied=self.URLItemCheckDo(lURLItem, "POST") @@ -416,16 +431,16 @@ class RobotDaemonServer(Thread): Thread.__init__(self) self.name = name # Update the global dict - ServerSettings.SettingsUpdate(mGlobalDict) + ServerSettings.SettingsUpdate(inGlobalDict) def run(self): inServerAddress=""; - inPort = mGlobalDict["Server"]["ListenPort"]; + inPort = gSettingsDict["Server"]["ListenPort"]; # Server settings # Choose port 8080, for port 80, which is normally used for a http server, you need root access server_address = (inServerAddress, inPort) #httpd = HTTPServer(server_address, testHTTPServer_RequestHandler) # Logging - mGlobalDict["Logger"].info(f"Server init. Listen URL: {inServerAddress}, Listen port: {inPort}") + gSettingsDict["Logger"].info(f"Server init. Listen URL: {inServerAddress}, Listen port: {inPort}") #httpd.serve_forever() httpd = ThreadedHTTPServer(server_address, testHTTPServer_RequestHandler) #print('Starting server, use to stop') diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/ServerSettings.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/ServerSettings.py index 881a799c..e30e1c30 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/ServerSettings.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/ServerSettings.py @@ -3,16 +3,45 @@ import json from desktopmagic.screengrab_win32 import ( getDisplayRects, saveScreenToBmp, saveRectToBmp, getScreenAsImage, getRectAsImage, getDisplaysAsImages) + +# /Orchestrator/RobotRDPActive/ControlPanelDictGet +def RobotRDPActive_ControlPanelDictGet(inRequest,inGlobalDict): + inResponseDict = inRequest.OpenRPAResponseDict + lResultDict = { + "DataList":[ + # {"SessionKeyStr":"", "SessionHexStr": "", "IsFullScreenBool": False, "IsIgnoredBool": False} + ] + } + # Iterate throught the RDP List + for lRDPSessionKeyStrItem in inGlobalDict["RobotRDPActive"]["RDPList"]: + lRDPConfiguration = inGlobalDict["RobotRDPActive"]["RDPList"][lRDPSessionKeyStrItem] # Get the configuration dict + lDataItemDict = {"SessionKeyStr":"", "SessionHexStr": "", "IsFullScreenBool": False, "IsIgnoredBool": False} # Template + lDataItemDict["SessionKeyStr"] = lRDPSessionKeyStrItem # Session key str + lDataItemDict["SessionHexStr"] = lRDPConfiguration["SessionHex"] # Session Hex + lDataItemDict["IsFullScreenBool"] = True if lRDPSessionKeyStrItem == inGlobalDict["RobotRDPActive"]["FullScreenRDPSessionKeyStr"] else False # Check the full screen for rdp window + lDataItemDict["IsIgnoredBool"] = lRDPConfiguration["SessionIsIgnoredBool"] # Is ignored + lResultDict["DataList"].append(lDataItemDict) + # Send message back to client + message = json.dumps(lResultDict) + # Write content as utf-8 data + inResponseDict["Body"] = bytes(message, "utf8") + def Monitor_ControlPanelDictGet(inRequest,inGlobalDict): inResponseDict = inRequest.OpenRPAResponseDict # Create result JSON lResultJSON = {"RenderRobotList": []} lRenderFunctionsRobotList = inGlobalDict["ControlPanelDict"]["RobotList"] for lItem in lRenderFunctionsRobotList: - # Выполнить вызов и записать результат - lItemResultDict = lItem["RenderFunction"](inGlobalDict) - # RunFunction - lResultJSON["RenderRobotList"].append(lItemResultDict) + lUACBool = True # Check if render function is applicable User Access Rights (UAC) + if inGlobalDict["Server"]["AccessUsers"]["FlagCredentialsAsk"] is True: + lUserRights = inGlobalDict["Server"]["AccessUsers"]["RuleDomainUserDict"][(inRequest.OpenRPA["Domain"].upper(),inRequest.OpenRPA["User"].upper())] + if len(lUserRights["ControlPanelKeyAllowedList"]) > 0 and lItem["KeyStr"] not in lUserRights["ControlPanelKeyAllowedList"]: + lUACBool = False # UAC Check is not passed - False for user + if lUACBool: # Run function if UAC is TRUE + # Выполнить вызов и записать результат + lItemResultDict = lItem["RenderFunction"](inGlobalDict) + # RunFunction + lResultJSON["RenderRobotList"].append(lItemResultDict) # Send message back to client message = json.dumps(lResultJSON) # Write content as utf-8 data @@ -60,7 +89,8 @@ def SettingsUpdate(inGlobalConfiguration): {"Method":"GET", "URL": "/favicon.ico", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "Web\\favicon.ico"), "ResponseContentType": "image/x-icon"}, {"Method":"GET", "URL": "/3rdParty/Handlebars/handlebars-v4.1.2.js", "MatchType": "EqualCase", "ResponseFilePath": os.path.join(lOrchestratorFolder, "..\\Resources\\Web\\Handlebars\\handlebars-v4.1.2.js"), "ResponseContentType": "application/javascript"}, {"Method": "GET", "URL": "/Monitor/ControlPanelDictGet", "MatchType": "Equal", "ResponseDefRequestGlobal": Monitor_ControlPanelDictGet, "ResponseContentType": "application/json"}, - {"Method": "GET", "URL": "/GetScreenshot", "MatchType": "BeginWith", "ResponseDefRequestGlobal": GetScreenshot, "ResponseContentType": "image/png"} - ] + {"Method": "GET", "URL": "/GetScreenshot", "MatchType": "BeginWith", "ResponseDefRequestGlobal": GetScreenshot, "ResponseContentType": "image/png"}, + {"Method": "GET", "URL": "/Orchestrator/RobotRDPActive/ControlPanelDictGet", "MatchType": "Equal","ResponseDefRequestGlobal": RobotRDPActive_ControlPanelDictGet, "ResponseContentType": "application/json"} + ] inGlobalConfiguration["Server"]["URLList"]=inGlobalConfiguration["Server"]["URLList"]+lURLList return inGlobalConfiguration \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Timer.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Timer.py index 9449f1a6..28f4dfd5 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Timer.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Timer.py @@ -5,7 +5,7 @@ import importlib import logging from . import Processor -global mGlobalDict +global gSettingsDict class RepeatedTimer(object): def __init__(self, interval, function, *args, **kwargs): diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Web/Index.xhtml b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Web/Index.xhtml index f2efeae6..12a061d7 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Web/Index.xhtml +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Web/Index.xhtml @@ -292,7 +292,49 @@ } mGlobal.Monitor.fControlPanelRefresh() mGlobal.Monitor.fControlPanelAutoUpdateRun(3); - + //////////////////////////////// + /////// /Orchestrator/RobotRDPActive/ControlPanelDictGet + /////////////////////////////// + mGlobal.RobotRDPActive = {} + ///Refresh control panel + mGlobal.RobotRDPActive.fControlPanelRefresh=function() { + ///Загрузка данных + $.ajax({ + type: "GET", + url: 'Orchestrator/RobotRDPActive/ControlPanelDictGet', + data: '', + success: + function(lData,l2,l3) + { + var lResponseJSON=JSON.parse(lData) + ///Сформировать HTML код новой таблицы + lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-robotrdpactive-control-panel",lResponseJSON) + //Присвоить ответ в mGlobal.RobotRDPActive.mResponseList + mGlobal.RobotRDPActive.mResponseList = lResponseJSON + ///Прогрузить новую таблицу + $(".openrpa-robotrdpactive-control-panel").html(lHTMLCode) + }, + dataType: "text" + }); + } + /// + mGlobal.RobotRDPActive.mControlPanelAutoUpdateSeconds=3; + mGlobal.RobotRDPActive.mControlPanelAutoUpdateSecondsCurrent=3; + mGlobal.RobotRDPActive.fControlPanelAutoUpdateRun=function(inRefreshSeconds) { + mGlobal.RobotRDPActive.mControlPanelAutoUpdateSeconds=inRefreshSeconds; + //Функция обновления текста кнопки обновления + lControlPanelUpdate=function() { + mGlobal.RobotRDPActive.mControlPanelAutoUpdateSecondsCurrent=mGlobal.RobotRDPActive.mControlPanelAutoUpdateSecondsCurrent-1 + if (mGlobal.RobotRDPActive.mControlPanelAutoUpdateSecondsCurrent==-1) { + mGlobal.RobotRDPActive.mControlPanelAutoUpdateSecondsCurrent=mGlobal.RobotRDPActive.mControlPanelAutoUpdateSecondsCurrent=mGlobal.RobotRDPActive.mControlPanelAutoUpdateSeconds; + mGlobal.RobotRDPActive.fControlPanelRefresh() + } + $(".openrpa-robotrdpactive-control-panel-general .openrpa-refresh-button").html("Refresh "+mGlobal.RobotRDPActive.mControlPanelAutoUpdateSecondsCurrent); + } + mGlobal.RobotRDPActive.mControlPanelAutoUpdateTimerId=setInterval(lControlPanelUpdate,1000) + } + mGlobal.RobotRDPActive.fControlPanelRefresh() + mGlobal.RobotRDPActive.fControlPanelAutoUpdateRun(3); mGlobal.Test=function() { ///Обнулить таблицу lData = [ @@ -339,9 +381,9 @@ function(lData,l2,l3) { var lResponseJSON=JSON.parse(lData) - lResponseJSON["actionListResult"][0]["result"].forEach(function(lItem){lItem["processPathName"]=("processPath" in lItem ? lItem["processPath"] : lItem["processName"])}) + lResponseJSON[0]["Result"].forEach(function(lItem){lItem["processPathName"]=("processPath" in lItem ? lItem["processPath"] : lItem["processName"])}) ///Отправить запрос на формирование таблицы - lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-info-table-planloglist",lResponseJSON["actionListResult"][0]); + lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-info-table-planloglist",lResponseJSON[0]); ///Установить HTML код $('.ui.modal.basic .content').html(lHTMLCode); $('.ui.modal.basic').modal('show'); @@ -349,12 +391,33 @@ dataType: "text" }); } - /////////////////////////////// ///Processor functions /////////////////////////////// - mGlobal.Processor = {} + mGlobal.Processor.ServerValueAppend = function(inKeyList,inValue) { + lData = [ + { + "Type":"GlobalDictKeyListValueAppend", + "KeyList": inKeyList, + "Value": inValue + } + ] + ///Обнулить таблицу + $('.ui.modal.basic .content').html(""); + $.ajax({ + type: "POST", + url: 'Utils/Processor', + data: JSON.stringify(lData), + success: + function(lData,l2,l3) + { + var lResponseJSON=JSON.parse(lData) + ///TODO Show error if exist error + }, + dataType: "text" + }); + } mGlobal.Processor.ServerValueSet = function(inKeyList,inValue) { lData = [ { @@ -532,58 +595,17 @@ ///Установить HTML код lElementParentElement.insertAdjacentHTML("beforeend",lHTMLCode); } - ///Test - lTestDataTable = { - "Title":"Test", - "Columns":["Дата/Время","Статус","Клиент","Файл"], - "Rows":[ - ["2019.10.31 13:21","Успешно", "ООО БалтКам", "test.xml"], - ["2019.10.31 13:21","Успешно", "ООО Гренодер", "test.xml"], - ["2019.10.31 13:21","Успешно", "ООО БалтКам", "test.xml"], - ["2019.10.31 13:21","Успешно", "ООО Гренодер", "test.xml"], - ["2019.10.31 13:21","Отказ", "ООО Сударь", "test.xml"], - ["2019.10.31 13:21","Успешно", "ООО БалтКам", "test.xml"], - ["2019.10.31 13:21","Отказ", "ООО Гренодер", "test.xml"], - ["2019.10.31 13:21","Успешно", "ООО Гренодер", "test.xml"], - ["2019.10.31 13:21","Успешно", "ООО Сударь", "test.xml"], - ["2019.10.31 13:21","Успешно", "ООО БалтКам", "test.xml"], - ["2019.10.31 13:21","Успешно", "ООО Гренодер", "test.xml"], - ["2019.10.31 13:21","Отказ", "ООО Сударь", "test.xml"], - ["2019.10.31 13:21","Успешно", "ООО БалтКам", "test.xml"], - ["f","s"] - ] - } - //mGlobal.Modal.TableFilter.Show(lTestData) - ///Test - lTestData = { - "Title":"Test", - "List":[ - {"Header":"Head 09","Description":"Test 21.02.2019"}, - {"Header":"Head 09","Description":"Test 21.02.2019"}, - {"Header":"Head 09","Description":"Test 21.02.2019"}, - {"Header":"Head 09","Description":"TestNew 21.02.2019"}, - {"Header":"Head 09","Description":"Test 21.02.2019"}, - {"Header":"Head 09","Description":"TestNew 21.02.2019"}, - {"Header":"Head 09","Description":"Test 21.02.2019"}, - {"Header":"Head 09","Description":"Test 21.02.2019"} - ] - } - // mGlobal.Modal.ListFilter.Show(lTestData) }) ;