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) - 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 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 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 ## Copyrights & Contacts
pyOpenRPA is created by Ivan Maslov (Russia). Use it for free (MIT)! 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: My contacts:
- E-mail: Ivan.Maslov@UnicodeLabs.ru - E-mail: I.Maslov@mail.ru
- Skype: MegaFinder - Skype: MegaFinder
- Facebook: https://www.facebook.com/RU.IT4Business - Facebook: https://www.facebook.com/RU.IT4Business
- LinkedIn: https://www.linkedin.com/in/RU-IvanMaslov/ - LinkedIn: https://www.linkedin.com/in/RU-IvanMaslov/

@ -32,12 +32,18 @@ def O2A_Loop(inGSettings):
time.sleep(inGSettings["O2ADict"]["RetryTimeoutSecFloat"]) time.sleep(inGSettings["O2ADict"]["RetryTimeoutSecFloat"])
else: else:
lRequestBody = lResponse.text 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 lQueueItem = lResponse.json() # Try to get JSON
# Append QUEUE item in ProcessorDict > ActivityList # Append QUEUE item in ProcessorDict > ActivityList
lActivityLastGUIDStr = lQueueItem["GUIDStr"] lActivityLastGUIDStr = lQueueItem["GUIDStr"]
inGSettings["ProcessorDict"]["ActivityList"].append(lQueueItem) 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: else:
if lL: lL.debug(f"Empty response from the orchestrator - loop when refresh the connection between Orc and Agent"); 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: except requests.exceptions.ConnectionError as e:

@ -481,3 +481,11 @@ def Update(inGSettings):
inGSettings["ServerDict"]["AgentFileChunkCheckIntervalSecFloat"]= 0.2 inGSettings["ServerDict"]["AgentFileChunkCheckIntervalSecFloat"]= 0.2
if lL: lL.warning( 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) lReturnActivityItemDict = copy.deepcopy(lReturnActivityItemDict)
if "CreatedByDatetime" in lReturnActivityItemDict: if "CreatedByDatetime" in lReturnActivityItemDict:
del lReturnActivityItemDict["CreatedByDatetime"] 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") 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 lDoLoopBool = False # CLose the connection
else: # Nothing to send - sleep for the next iteration else: # Nothing to send - sleep for the next iteration
time.sleep(lAgentLoopSleepSecFloat) time.sleep(lAgentLoopSleepSecFloat)

@ -39,6 +39,8 @@ def __Create__():
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
}, },
"ServerDict": { "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 "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 "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 "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()) lAgentDictItemKeyTurple = (inHostNameStr.upper(),inUserStr.upper())
lResultBool = False lResultBool = False
if lAgentDictItemKeyTurple in inGSettings["AgentDict"]: if lAgentDictItemKeyTurple in inGSettings["AgentDict"]:
inGSettings["AgentDict"][lAgentDictItemKeyTurple] = SettingsTemplate.__AgentDictItemCreate__()
for lActivityItem in inGSettings["AgentDict"][lAgentDictItemKeyTurple]["ActivityList"]: for lActivityItem in inGSettings["AgentDict"][lAgentDictItemKeyTurple]["ActivityList"]:
if inGUIDStr == lActivityItem.get("GUIDStr",None): if inGUIDStr == lActivityItem.get("GUIDStr",None):
lResultBool = True 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). Send the file from the Orchestrator to Agent (synchroniously) pyOpenRPA.Agent daemon process (safe for JSON transmition).
Work safety with big files 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 inGSettings: Global settings dict (singleton)
:param inHostNameStr: :param inHostNameStr:
@ -152,6 +152,20 @@ def AgentOSFileSend(inGSettings, inHostNameStr, inUserStr, inOrchestratorFilePat
:param inFileDataBytes: :param inFileDataBytes:
:return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid!
""" """
# 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"] lActivityItemCheckIntervalSecFloat = inGSettings["ServerDict"]["AgentFileChunkCheckIntervalSecFloat"]
# Get the chunk limit # Get the chunk limit
@ -163,7 +177,8 @@ def AgentOSFileSend(inGSettings, inHostNameStr, inUserStr, inOrchestratorFilePat
lFile = open(inOrchestratorFilePathStr,"rb") lFile = open(inOrchestratorFilePathStr,"rb")
lFileSizeBytesInt = lFile.seek(0,2) lFileSizeBytesInt = lFile.seek(0,2)
lFile.seek(0) lFile.seek(0)
#import pdb
#pdb.set_trace()
lChunkCountInt = math.ceil(lFileSizeBytesInt/lChunkByteSizeInt) 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}") 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): for lChunkNumberInt in range(lChunkCountInt):
@ -185,6 +200,8 @@ def AgentOSFileSend(inGSettings, inHostNameStr, inUserStr, inOrchestratorFilePat
time.sleep(lActivityItemCheckIntervalSecFloat) time.sleep(lActivityItemCheckIntervalSecFloat)
if lL: lL.debug( if lL: lL.debug(
f"O2A: BINARY SEND: Current chunk index: {lChunkNumberInt}") f"O2A: BINARY SEND: Current chunk index: {lChunkNumberInt}")
if lL: lL.info(
f"O2A: BINARY SEND: Transmition has been complete")
# Close the file # Close the file
lFile.close() lFile.close()
@ -2131,6 +2148,7 @@ def Orchestrator(inGSettings, inDumpRestoreBool = True, inRunAsAdministratorBool
lItemDict = lListenDict[lItemKeyStr] lItemDict = lListenDict[lItemKeyStr]
lThreadServer = Server.RobotDaemonServer(lItemKeyStr, gSettingsDict) lThreadServer = Server.RobotDaemonServer(lItemKeyStr, gSettingsDict)
lThreadServer.start() lThreadServer.start()
gSettingsDict["ServerDict"]["ServerThread"] = lThreadServer
lItemDict["ServerInstance"] = lThreadServer lItemDict["ServerInstance"] = lThreadServer
# Init the RobotScreenActive in another thread # Init the RobotScreenActive in another thread

@ -53,7 +53,7 @@ setup(name='pyOpenRPA',
install_requires=[ install_requires=[
'pywinauto>=0.6.8;platform_system=="win32" and python_version>="3.0"', 'pywinauto>=0.6.8;platform_system=="win32" and python_version>="3.0"',
'WMI>=1.4.9;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=="win32" and python_version>="3.0"', 'crypto>=1.4.1'
#'pywin32>=224;platform_system=="Linux" 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