fixes from issues from the gitlab

dev-linux
Ivan Maslov 3 years ago
parent e361775027
commit 103483a20b

@ -36,9 +36,9 @@ Now you can use the following docs:
- ENG Guide PDF [|OPEN GITLAB|](Wiki/ENG_Guide/pdf/pyOpenRPA_Guide_ENG.pdf)
- RUS Article: Less cost - no paid RPA [|OPEN HABR|](https://habr.com/ru/post/506766/)
- RUS Tutorial Desktop UI [|OPEN HABR|](https://habr.com/ru/post/509644/); [|OPEN GITLAB|](Wiki/RUS_Tutorial/DesktopGUI_Habr/index.md)
- RUS Tutorial Desktop UI [|OPEN HABR|](https://habr.com/ru/post/509644/); [|OPEN GITLAB|](Wiki/RUS_Tutorial/DesktopGUI_Habr/README.md)
- RUS Tutorial Web UI [|OPEN HABR|](https://habr.com/ru/post/515310/); [|OPEN GITLAB|](Wiki/RUS_Tutorial/WebGUI_Habr/3.%20WebGUI_Habr.md)
- RUS Leaflet pyOpenRPA v4.pdf [|OPEN GITLAB|](Wiki/RUS_Leaflet/RUS%20Leaflet%20pyOpenRPA%20v4.pdf)
- RUS Leaflet pyOpenRPA v5.pdf [|OPEN GITLAB|](Wiki/RUS_Leaflet/RUS%20Leaflet%20pyOpenRPA%20v5.pdf)
## Copyrights & Contacts
pyOpenRPA is created by Ivan Maslov (Russia). Use it for free (MIT)!
@ -47,7 +47,7 @@ If you need IT help feel free to contact me.
My contacts:
- E-mail: Ivan.Maslov@UnicodeLabs.ru
- E-mail: I.Maslov@mail.ru
- Skype: MegaFinder
- Facebook: https://www.facebook.com/RU.IT4Business
- LinkedIn: https://www.linkedin.com/in/RU-IvanMaslov/

@ -32,12 +32,18 @@ def O2A_Loop(inGSettings):
time.sleep(inGSettings["O2ADict"]["RetryTimeoutSecFloat"])
else:
lRequestBody = lResponse.text
if len(lRequestBody) != 0: # CHeck if not empty result when close the connection from orch
lBodyLenInt = len(lRequestBody)
if lBodyLenInt != 0: # CHeck if not empty result when close the connection from orch
lQueueItem = lResponse.json() # Try to get JSON
# Append QUEUE item in ProcessorDict > ActivityList
lActivityLastGUIDStr = lQueueItem["GUIDStr"]
inGSettings["ProcessorDict"]["ActivityList"].append(lQueueItem)
if lL: lL.debug(f"ActivityItem was received from orchestrator: {lQueueItem}");
# Log full version if bytes size is less than limit . else short
lAgentLimitLogSizeBytesInt = 500
if lBodyLenInt <= lAgentLimitLogSizeBytesInt:
if lL: lL.info(f"ActivityItem was received from orchestrator: {lQueueItem}");
else:
if lL: lL.info(f"ActivityItem was received from orchestrator: Was supressed because of big size. Max is {lAgentLimitLogSizeBytesInt} bytes");
else:
if lL: lL.debug(f"Empty response from the orchestrator - loop when refresh the connection between Orc and Agent");
except requests.exceptions.ConnectionError as e:

@ -480,4 +480,12 @@ def Update(inGSettings):
if "AgentFileChunkCheckIntervalSecFloat" not in inGSettings["ServerDict"]:
inGSettings["ServerDict"]["AgentFileChunkCheckIntervalSecFloat"]= 0.2
if lL: lL.warning(
f"Backward compatibility (v1.2.3 to v1.2.4): Add new key ServerDict > AgentFileChunkCheckIntervalSecFloat") # Log about compatibility
f"Backward compatibility (v1.2.3 to v1.2.4): Add new key ServerDict > AgentFileChunkCheckIntervalSecFloat") # Log about compatibility
if "ServerThread" not in inGSettings["ServerDict"]:
inGSettings["ServerDict"]["ServerThread"]= None
if lL: lL.warning(
f"Backward compatibility (v1.2.3 to v1.2.4): Add new key ServerDict > ServerThread") # Log about compatibility
if "AgentLimitLogSizeBytesInt" not in inGSettings["ServerDict"]:
inGSettings["ServerDict"]["AgentLimitLogSizeBytesInt"] = 300
if lL: lL.warning(
f"Backward compatibility (v1.2.3 to v1.2.4): Add new key ServerDict > AgentLimitLogSizeBytesInt") # Log about compatibility

@ -397,8 +397,16 @@ def pyOpenRPA_Agent_O2A(inRequest, inGSettings):
lReturnActivityItemDict = copy.deepcopy(lReturnActivityItemDict)
if "CreatedByDatetime" in lReturnActivityItemDict:
del lReturnActivityItemDict["CreatedByDatetime"]
if lL: lL.info(f"Activity item to agent Hostname {lInput['HostNameUpperStr']}, User {lInput['UserUpperStr']}. Activity item: {lReturnActivityItemDict}")
inRequest.OpenRPAResponseDict["Body"] = bytes(json.dumps(lReturnActivityItemDict), "utf8")
# Log full version if bytes size is less than limit . else short
lBodyLenInt = len(inRequest.OpenRPAResponseDict["Body"])
lAgentLimitLogSizeBytesInt = inGSettings["ServerDict"]["AgentLimitLogSizeBytesInt"]
if lBodyLenInt <= lAgentLimitLogSizeBytesInt:
if lL: lL.info(f"Activity item to agent Hostname {lInput['HostNameUpperStr']}, User {lInput['UserUpperStr']}. Activity item: {lReturnActivityItemDict}")
else:
if lL: lL.info(
f"Activity item to agent Hostname {lInput['HostNameUpperStr']}, User {lInput['UserUpperStr']}. "
f"Activity item: Was suppressed because of body size of {lBodyLenInt} bytes. Max is {lAgentLimitLogSizeBytesInt}")
lDoLoopBool = False # CLose the connection
else: # Nothing to send - sleep for the next iteration
time.sleep(lAgentLoopSleepSecFloat)

@ -39,6 +39,8 @@ def __Create__():
# # # # # # # # # # # # # # # # # #
},
"ServerDict": {
"AgentLimitLogSizeBytesInt": 300, # Don't show body if json body of transmition is more than
"ServerThread": None, # Server thread is there
"AgentActivityLifetimeSecFloat": 1200.0, # Time in seconds to life for activity for the agent
"AgentConnectionLifetimeSecFloat": 300.0, # Time in seconds to handle the open connection to the Agent
"AgentLoopSleepSecFloat": 2.0, # Time in seconds to sleep between loops when check to send some activity to the agent

@ -75,7 +75,6 @@ def AgentActivityItemExists(inGSettings, inHostNameStr, inUserStr, inGUIDStr):
lAgentDictItemKeyTurple = (inHostNameStr.upper(),inUserStr.upper())
lResultBool = False
if lAgentDictItemKeyTurple in inGSettings["AgentDict"]:
inGSettings["AgentDict"][lAgentDictItemKeyTurple] = SettingsTemplate.__AgentDictItemCreate__()
for lActivityItem in inGSettings["AgentDict"][lAgentDictItemKeyTurple]["ActivityList"]:
if inGUIDStr == lActivityItem.get("GUIDStr",None):
lResultBool = True
@ -144,6 +143,7 @@ def AgentOSFileSend(inGSettings, inHostNameStr, inUserStr, inOrchestratorFilePat
"""
Send the file from the Orchestrator to Agent (synchroniously) pyOpenRPA.Agent daemon process (safe for JSON transmition).
Work safety with big files
Thread safe - you can call def even if you dont init the orchestrator - def will be executed later
:param inGSettings: Global settings dict (singleton)
:param inHostNameStr:
@ -152,41 +152,58 @@ def AgentOSFileSend(inGSettings, inHostNameStr, inUserStr, inOrchestratorFilePat
:param inFileDataBytes:
:return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid!
"""
lActivityItemCheckIntervalSecFloat = inGSettings["ServerDict"]["AgentFileChunkCheckIntervalSecFloat"]
# Get the chunk limit
lChunkByteSizeInt = inGSettings["ServerDict"]["AgentFileChunkBytesSizeInt"]
lL = inGSettings.get("Logger",None)
# Open the file and get the size (in bytes)
lFile = open(inOrchestratorFilePathStr,"rb")
lFileSizeBytesInt = lFile.seek(0,2)
lFile.seek(0)
lChunkCountInt = math.ceil(lFileSizeBytesInt/lChunkByteSizeInt)
if lL: lL.info(f"O2A: Start to send binary file via chunks. Chunk count: {lChunkCountInt}, From (Orch side): {inOrchestratorFilePathStr}, To (Agent side): {inAgentFilePathStr}")
for lChunkNumberInt in range(lChunkCountInt):
# Read chunk
lFileChunkBytes = lFile.read(lChunkByteSizeInt)
# Convert to base64
lFileChunkBase64Str = base64.b64encode(lFileChunkBytes).decode("utf-8")
# Send chunk
if lChunkNumberInt == 0:
lActivityItemGUIDStr = AgentOSFileBinaryDataBase64StrCreate(inGSettings=inGSettings,inHostNameStr=inHostNameStr,
inUserStr=inUserStr,inFilePathStr=inAgentFilePathStr,
inFileDataBase64Str=lFileChunkBase64Str)
else:
lActivityItemGUIDStr = AgentOSFileBinaryDataBase64StrAppend(inGSettings=inGSettings, inHostNameStr=inHostNameStr,
inUserStr=inUserStr, inFilePathStr=inAgentFilePathStr,
inFileDataBase64Str=lFileChunkBase64Str)
# Wait for the activity will be deleted
while AgentActivityItemExists(inGSettings=inGSettings,inHostNameStr=inHostNameStr,inUserStr=inUserStr,inGUIDStr=lActivityItemGUIDStr):
time.sleep(lActivityItemCheckIntervalSecFloat)
if lL: lL.debug(
f"O2A: BINARY SEND: Current chunk index: {lChunkNumberInt}")
# Close the file
lFile.close()
# Check thread
if inGSettings["ServerDict"]["ServerThread"] is None:
if inGSettings["Logger"]: inGSettings["Logger"].warning(f"AgentOSFileSend run before server init - activity will be append in the processor queue.")
lResult = {
"Def": AgentOSFileSend, # def link or def alias (look gSettings["Processor"]["AliasDefDict"])
"ArgList": [], # Args list
"ArgDict": {"inHostNameStr":inHostNameStr, "inUserStr":inUserStr, "inOrchestratorFilePathStr":inOrchestratorFilePathStr, "inAgentFilePathStr": inAgentFilePathStr}, # 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)
}
inGSettings["ProcessorDict"]["ActivityList"].append(lResult)
else: # In processor - do execution
lActivityItemCheckIntervalSecFloat = inGSettings["ServerDict"]["AgentFileChunkCheckIntervalSecFloat"]
# Get the chunk limit
lChunkByteSizeInt = inGSettings["ServerDict"]["AgentFileChunkBytesSizeInt"]
lL = inGSettings.get("Logger",None)
# Open the file and get the size (in bytes)
lFile = open(inOrchestratorFilePathStr,"rb")
lFileSizeBytesInt = lFile.seek(0,2)
lFile.seek(0)
#import pdb
#pdb.set_trace()
lChunkCountInt = math.ceil(lFileSizeBytesInt/lChunkByteSizeInt)
if lL: lL.info(f"O2A: Start to send binary file via chunks. Chunk count: {lChunkCountInt}, From (Orch side): {inOrchestratorFilePathStr}, To (Agent side): {inAgentFilePathStr}")
for lChunkNumberInt in range(lChunkCountInt):
# Read chunk
lFileChunkBytes = lFile.read(lChunkByteSizeInt)
# Convert to base64
lFileChunkBase64Str = base64.b64encode(lFileChunkBytes).decode("utf-8")
# Send chunk
if lChunkNumberInt == 0:
lActivityItemGUIDStr = AgentOSFileBinaryDataBase64StrCreate(inGSettings=inGSettings,inHostNameStr=inHostNameStr,
inUserStr=inUserStr,inFilePathStr=inAgentFilePathStr,
inFileDataBase64Str=lFileChunkBase64Str)
else:
lActivityItemGUIDStr = AgentOSFileBinaryDataBase64StrAppend(inGSettings=inGSettings, inHostNameStr=inHostNameStr,
inUserStr=inUserStr, inFilePathStr=inAgentFilePathStr,
inFileDataBase64Str=lFileChunkBase64Str)
# Wait for the activity will be deleted
while AgentActivityItemExists(inGSettings=inGSettings,inHostNameStr=inHostNameStr,inUserStr=inUserStr,inGUIDStr=lActivityItemGUIDStr):
time.sleep(lActivityItemCheckIntervalSecFloat)
if lL: lL.debug(
f"O2A: BINARY SEND: Current chunk index: {lChunkNumberInt}")
if lL: lL.info(
f"O2A: BINARY SEND: Transmition has been complete")
# Close the file
lFile.close()
def AgentOSFileBinaryDataBytesCreate(inGSettings, inHostNameStr, inUserStr, inFilePathStr, inFileDataBytes):
"""
@ -2131,6 +2148,7 @@ def Orchestrator(inGSettings, inDumpRestoreBool = True, inRunAsAdministratorBool
lItemDict = lListenDict[lItemKeyStr]
lThreadServer = Server.RobotDaemonServer(lItemKeyStr, gSettingsDict)
lThreadServer.start()
gSettingsDict["ServerDict"]["ServerThread"] = lThreadServer
lItemDict["ServerInstance"] = lThreadServer
# Init the RobotScreenActive in another thread

@ -53,7 +53,7 @@ setup(name='pyOpenRPA',
install_requires=[
'pywinauto>=0.6.8;platform_system=="win32" and python_version>="3.0"',
'WMI>=1.4.9;platform_system=="win32" and python_version>="3.0"',
'pillow>=6.0.0','keyboard>=0.13.3','pyautogui>=0.9.44',
'pillow>=6.0.0','keyboard>=0.13.3','pyautogui>=0.9.44 and pyautogui<=0.9.52',
'pywin32>=224;platform_system=="win32" and python_version>="3.0"', 'crypto>=1.4.1'
#'pywin32>=224;platform_system=="Linux" and python_version>="3.0"', 'crypto>=1.4.1'
],

Loading…
Cancel
Save