Orc: turn off the clipboard in RDP, AgentFileRecieve check if file not exists, ProcessorMonitorFix - print info about current item. New def to work with files in agent

dev-linux
Ivan Maslov 3 years ago
parent ac160e8562
commit 16eb821b0d

@ -2,6 +2,9 @@ import threading, socket, getpass, sys, uuid, subprocess, base64, psutil, getpas
from . import O2A, A2O # Data flow Orchestrator To Agent
from . import Processor # Processor Queue
from subprocess import CREATE_NEW_CONSOLE # Flag to create new process in another CMD
import os
gSettings = None
# Create binary file by the base64 string (safe for JSON transmition)
def OSFileBinaryDataBase64StrCreate(inFilePathStr, inFileDataBase64Str,inGSettings = None):
@ -58,16 +61,37 @@ def OSFileBinaryDataBase64StrReceive(inFilePathStr, inGSettings=None):
:param inGSettings: global settings of the Agent (singleton)
:return: File content in string base64 format (use base64.b64decode to decode data). Return None if file is not exist
"""
lFile = open(inFilePathStr, "rb")
lFileDataBytes = lFile.read()
lFile.close()
lFileDataBase64Str = base64.b64encode(lFileDataBytes).decode("utf-8")
lL = inGSettings.get("Logger", None) if type(inGSettings) is dict else None
lMessageStr = f"AGENT Binary file {inFilePathStr} has been read."
if lL: lL.info(lMessageStr)
A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
lFileDataBase64Str = None
if os.path.exists(inFilePathStr):
lFile = open(inFilePathStr, "rb")
lFileDataBytes = lFile.read()
lFile.close()
lFileDataBase64Str = base64.b64encode(lFileDataBytes).decode("utf-8")
lMessageStr = f"OSFileBinaryDataBase64StrReceive: file {inFilePathStr} has been read"
if lL: lL.debug(lMessageStr)
#A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
else:
if lL: lL.debug(f"OSFileBinaryDataBase64StrReceive: file {inFilePathStr} is not exists - return None")
return lFileDataBase64Str
def OSFileMTimeGet(inFilePathStr: str) -> float or None:
"""
Read file modification time timestamp format (float)
:param inFilePathStr: File path to read
:return: timestamp (float) Return None if file is not exist
"""
global gSettings
lL = gSettings.get("Logger", None) if type(gSettings) is dict else None
lFileMTimeFloat = None
if os.path.exists(inFilePathStr):
lFileMTimeFloat = os.path.getmtime(inFilePathStr)
if lL: lL.debug(f"OSFileMTimeGet: file {inFilePathStr} has been read")
else:
if lL: lL.debug(f"OSFileMTimeGet: file {inFilePathStr} is not exists - return None")
return lFileMTimeFloat
def OSFileTextDataStrReceive(inFilePathStr, inEncodingStr="utf-8", inGSettings=None):
"""
Read text file in the agent GUI session
@ -77,13 +101,17 @@ def OSFileTextDataStrReceive(inFilePathStr, inEncodingStr="utf-8", inGSettings=N
:param inGSettings: global settings of the Agent (singleton)
:return: File text content in string format (use base64.b64decode to decode data). Return None if file is not exist
"""
lFile = open(inFilePathStr, "r", encoding=inEncodingStr)
lFileDataStr = lFile.read()
lFile.close()
lFileDataStr = None
lL = inGSettings.get("Logger", None) if type(inGSettings) is dict else None
lMessageStr = f"AGENT Text file {inFilePathStr} has been read."
if lL: lL.info(lMessageStr)
A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
if os.path.exists(inFilePathStr):
lFile = open(inFilePathStr, "r", encoding=inEncodingStr)
lFileDataStr = lFile.read()
lFile.close()
lMessageStr = f"OSFileTextDataStrReceive: file {inFilePathStr} has been read"
if lL: lL.info(lMessageStr)
#A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
else:
if lL: lL.info(f"OSFileTextDataStrReceive: file {inFilePathStr} is not exists - return None")
return lFileDataStr
# Send CMD to OS. Result return to log + Orchestrator by the A2O connection
@ -185,7 +213,8 @@ def ProcessWOExeUpperUserListGet():
# Main def
def Agent(inGSettings):
lL = inGSettings["Logger"]
global gSettings
gSettings = inGSettings
# Append Orchestrator def to ProcessorDictAlias
lModule = sys.modules[__name__]
lModuleDefList = dir(lModule)

@ -521,3 +521,8 @@ def Update(inGSettings):
inGSettings["ManagersGitDict"]={}
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Create new key: ManagersGitDict") # Log about compatibility
# ProcessorDict > ActivityItemNowDict
if "ActivityItemNowDict" not in inGSettings["ProcessorDict"]:
inGSettings["ProcessorDict"]["ActivityItemNowDict"]=None
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Create new key: ProcessorDict > ActivityItemNowDict") # Log about compatibility

@ -29,7 +29,9 @@ def ProcessorRunSync(inGSettings, inRobotRDPThreadControlDict):
lActivityItem = inGSettings["ProcessorDict"]["ActivityList"].pop(0) # Extract the first item from processor queue
if lActivityItem.get("ThreadBool", False) is False:
inRobotRDPThreadControlDict["ThreadExecuteBool"]=False # Stop the RobotRDPActive monitoring
inGSettings["ProcessorDict"]["ActivityItemNowDict"]=lActivityItem
ActivityListExecute(inGSettings = inGSettings, inActivityList = [lActivityItem]) # execute the activity item
inGSettings["ProcessorDict"]["ActivityItemNowDict"]=None
inRobotRDPThreadControlDict["ThreadExecuteBool"] = True # Continue the RobotRDPActive monitoring
else:
ProcessorRunAsync(inGSettings = inGSettings, inActivityList=[lActivityItem])
@ -139,8 +141,8 @@ def ProcessorMonitorRunSync(inGSettings):
lActiveTimeStart = time.time()
try:
while True:
if len(inGSettings["ProcessorDict"]["ActivityList"])>0:
lItemDict = inGSettings["ProcessorDict"]["ActivityList"][0]
if inGSettings["ProcessorDict"]["ActivityItemNowDict"] is not None:
lItemDict = inGSettings["ProcessorDict"]["ActivityItemNowDict"]
if "GUIDStr" not in lItemDict:
lGUIDStr = str(uuid.uuid4()) # generate new GUID
lItemDict["GUIDStr"] = lGUIDStr

@ -79,13 +79,15 @@ def SessionConfigurationCreate(inConfiguration):
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}
#Replace {Width}, {Height}, {BitDepth}, {HostPort}, {Login} {redirectclipboard}
lRedirectClipboardStr = "1" if inConfiguration.get('RedirectClipboardBool',True) == True else "0"
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)
lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{redirectclipboard}", lRedirectClipboardStr)
#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)

@ -10,7 +10,7 @@ import psutil
gSettings = None # Gsettings will be initialized after the import module
# Create new RDPSession in RobotRDPActive
def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPasswordStr):
def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPasswordStr, inRedirectClipboardBool = True):
global gSettings
# ATTENTION - dont connect if RDP session is exist
if inRDPSessionKeyStr not in gSettings["RobotRDPActive"]["RDPList"]:
@ -27,6 +27,7 @@ def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPa
"DepthBit": "32" # "32" or "24" or "16" or "15", example "32"
},
"SharedDriveList": ["c"], # List of the Root sesion hard drives, example ["c"]
"RedirectClipboardBool": inRedirectClipboardBool, # True - share clipboard to RDP; False - else
###### 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

@ -424,9 +424,12 @@ def pyOpenRPA_Agent_A2O(inRequest, inGSettings):
lActivityReturnItemValue = lInput["ActivityReturnDict"][lActivityReturnItemKeyStr]
# Create item in gSettings
inGSettings["AgentActivityReturnDict"][lActivityReturnItemKeyStr]=SettingsTemplate.__AgentActivityReturnDictItemCreate__(inReturn=lActivityReturnItemValue)
lLogStr = "0 bytes"
if lActivityReturnItemValue is not None:
lLogStr = f"{len(lActivityReturnItemValue)} bytes"
lLogStr = "x bytes"
try:
if lActivityReturnItemValue is not None:
lLogStr = f"{len(lActivityReturnItemValue)} bytes"
except Exception as e:
pass
if lL: lL.debug(f"SERVER: pyOpenRPA_Agent_A2O:: Has recieved result of the activity items from agent! ActivityItem GUID Str: {lActivityReturnItemKeyStr}; Return value len: {lLogStr}")
# Delete the source activity item from AgentDict
if lAgentDictItemKeyTurple in inGSettings["AgentDict"]:

@ -163,6 +163,7 @@ def __Create__():
# "GUIDStr": ..., # GUID of the activity
# },
],
"ActivityItemNowDict": None, # Activity Item which is executing now
"AliasDefDict": {}, # Storage for def with Str alias. To use it see pyOpenRPA.Orchestrator.ControlPanel
"CheckIntervalSecFloat": 1.0, # Interval for check gSettings in ProcessorDict > ActivityList
"ExecuteBool": True, # Flag to execute thread processor

@ -348,6 +348,45 @@ def AgentOSFileBinaryDataBase64StrReceive(inHostNameStr, inUserStr, inFilePathSt
#Send item in AgentDict for the futher data transmition
return AgentActivityItemAdd(inGSettings=inGSettings, inHostNameStr=inHostNameStr, inUserStr=inUserStr, inActivityItemDict=lActivityItemDict)
def AgentOSFileBinaryDataReceive(inHostNameStr, inUserStr, inFilePathStr):
"""
Read binary file from agent (synchronious)
:param inGSettings: Global settings dict (singleton)
:param inHostNameStr:
:param inUserStr:
:param inFilePathStr: File path to read
:return: file data bytes
"""
lFileDataBytes = None
inGSettings = GSettingsGet() # Set the global settings
# Check thread
if OrchestratorIsInited() == False:
if inGSettings["Logger"]: inGSettings["Logger"].warning(f"AgentOSFileBinaryDataReceive run before orc init - activity will be append in the processor queue.")
lResult = {
"Def": AgentOSFileBinaryDataReceive, # def link or def alias (look gSettings["Processor"]["AliasDefDict"])
"ArgList": [], # Args list
"ArgDict": {"inHostNameStr":inHostNameStr, "inUserStr":inUserStr, "inFilePathStr":inFilePathStr}, # Args dictionary
"ArgGSettings": None, # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
"ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
}
inGSettings["ProcessorDict"]["ActivityList"].append(lResult)
else: # In processor - do execution
lActivityItemDict = {
"Def":"OSFileBinaryDataBase64StrReceive", # def alias (look pyOpeRPA.Agent gSettings["ProcessorDict"]["AliasDefDict"])
"ArgList":[], # Args list
"ArgDict":{"inFilePathStr":inFilePathStr}, # Args dictionary
"ArgGSettings": "inGSettings", # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
"ArgLogger": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
}
#Send item in AgentDict for the futher data transmition
lGUIDStr = AgentActivityItemAdd(inGSettings=inGSettings, inHostNameStr=inHostNameStr, inUserStr=inUserStr, inActivityItemDict=lActivityItemDict)
lFileBase64Str = AgentActivityItemReturnGet(inGUIDStr=lGUIDStr)
if lFileBase64Str is not None: lFileDataBytes = base64.b64decode(lFileBase64Str)
return lFileDataBytes
def AgentOSFileTextDataStrReceive(inHostNameStr, inUserStr, inFilePathStr, inEncodingStr="utf-8", inGSettings = None):
"""
Read text file in the agent GUI session
@ -1987,7 +2026,7 @@ def SchedulerActivityTimeAddWeekly(inTimeHHMMStr="23:55:", inWeekdayList=None, i
# # # # # # # # # # # # # # # # # # # # # # #
def RDPTemplateCreate(inLoginStr, inPasswordStr, inHostStr="127.0.0.1", inPortInt = 3389, inWidthPXInt = 1680, inHeightPXInt = 1050,
inUseBothMonitorBool = False, inDepthBitInt = 32, inSharedDriveList=None):
inUseBothMonitorBool = False, inDepthBitInt = 32, inSharedDriveList=None, inRedirectClipboardBool=True):
"""
Create RDP connect dict item/ Use it connect/reconnect (Orchestrator.RDPSessionConnect)
@ -2010,6 +2049,7 @@ def RDPTemplateCreate(inLoginStr, inPasswordStr, inHostStr="127.0.0.1", inPortIn
# "Host": "127.0.0.1", "Port": "3389", "Login": "USER_99", "Password": "USER_PASS_HERE",
# "Screen": { "Width": 1680, "Height": 1050, "FlagUseAllMonitors": False, "DepthBit": "32" },
# "SharedDriveList": ["c"],
# "RedirectClipboardBool": True, # True - share clipboard to RDP; False - else
# ###### Will updated in program ############
# "SessionHex": "77777sdfsdf77777dsfdfsf77777777", # Hex is created when robot runs, example ""
# "SessionIsWindowExistBool": False, "SessionIsWindowResponsibleBool": False, "SessionIsIgnoredBool": False
@ -2024,6 +2064,7 @@ def RDPTemplateCreate(inLoginStr, inPasswordStr, inHostStr="127.0.0.1", inPortIn
:param inUseBothMonitorBool: True - connect to the RDP with both monitors. False - else case
:param inDepthBitInt: Remote desktop bitness. Available: 32 or 24 or 16 or 15, example 32
:param inSharedDriveList: Host local disc to connect to the RDP session. Example: ["c", "d"]
:param inRedirectClipboardBool: # True - share clipboard to RDP; False - else
:return:
{
"Host": inHostStr, # Host address, example "77.77.22.22"
@ -2038,6 +2079,7 @@ def RDPTemplateCreate(inLoginStr, inPasswordStr, inHostStr="127.0.0.1", inPortIn
"DepthBit": str(inDepthBitInt) # "32" or "24" or "16" or "15", example "32"
},
"SharedDriveList": inSharedDriveList, # List of the Root sesion hard drives, example ["c"]
"RedirectClipboardBool": True, # True - share clipboard to RDP; False - else
###### Will updated in program ############
"SessionHex": "77777sdfsdf77777dsfdfsf77777777", # Hex is created when robot runs, example ""
"SessionIsWindowExistBool": False,
@ -2050,6 +2092,7 @@ def RDPTemplateCreate(inLoginStr, inPasswordStr, inHostStr="127.0.0.1", inPortIn
"""
if inSharedDriveList is None: inSharedDriveList = ["c"]
if inPortInt is None: inPortInt = 3389
if inRedirectClipboardBool is None: inRedirectClipboardBool = True
lRDPTemplateDict= { # Init the configuration item
"Host": inHostStr, # Host address, example "77.77.22.22"
"Port": str(inPortInt), # RDP Port, example "3389"
@ -2062,7 +2105,8 @@ def RDPTemplateCreate(inLoginStr, inPasswordStr, inHostStr="127.0.0.1", inPortIn
"FlagUseAllMonitors": inUseBothMonitorBool, # True or False, example False
"DepthBit": str(inDepthBitInt) # "32" or "24" or "16" or "15", example "32"
},
"SharedDriveList": inSharedDriveList, # List of the Root sesion hard drives, example ["c"]
"SharedDriveList": inSharedDriveList, # List of the Root sesion hard drives, example ["c"],
"RedirectClipboardBool": inRedirectClipboardBool, # True - share clipboard to RDP; False - else
###### Will updated in program ############
"SessionHex": "77777sdfsdf77777dsfdfsf77777777", # Hex is created when robot runs, example ""
"SessionIsWindowExistBool": False,
@ -2087,7 +2131,7 @@ def RDPSessionDublicatesResolve(inGSettings):
#for lItemKeyStr in inGSettings["RobotRDPActive"]["RDPList"]:
# lItemDict = inGSettings["RobotRDPActive"]["RDPList"][lItemKeyStr]
def RDPSessionConnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inHostStr=None, inPortStr=None, inLoginStr=None, inPasswordStr=None, inGSettings = None):
def RDPSessionConnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inHostStr=None, inPortStr=None, inLoginStr=None, inPasswordStr=None, inGSettings = None, inRedirectClipboardBool=True):
"""
Create new RDPSession in RobotRDPActive. Attention - activity will be ignored if RDP key is already exists
2 way of the use
@ -2137,7 +2181,7 @@ def RDPSessionConnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inHostStr=None
# Var 2 - backward compatibility
if lRDPConfigurationItem is None:
lRDPConfigurationItem = RDPTemplateCreate(inLoginStr=inLoginStr, inPasswordStr=inPasswordStr,
inHostStr=inHostStr, inPortInt = int(inPortStr)) # ATTENTION - dont connect if RDP session is exist
inHostStr=inHostStr, inPortInt = int(inPortStr), inRedirectClipboardBool=inRedirectClipboardBool) # ATTENTION - dont connect if RDP session is exist
# Start the connect
if inRDPSessionKeyStr not in inGSettings["RobotRDPActive"]["RDPList"]:
inGSettings["RobotRDPActive"]["RDPList"][inRDPSessionKeyStr] = lRDPConfigurationItem # Add item in RDPList

Loading…
Cancel
Save