#Upgrade python/s

dev-linux v1.0.34
Ivan Maslov 5 years ago
parent f6a364518e
commit 90f2b6a568

@ -1,4 +1,4 @@
cd %~dp0\..\Sources cd %~dp0\..\Sources
copy /Y ..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe ..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_Orchestrator.exe copy /Y ..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe ..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_Orchestrator.exe
.\..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_Orchestrator.exe -m pyOpenRPA.Orchestrator "..\Orchestrator\Settings\Settings.py" .\..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_Orchestrator.exe -m pyOpenRPA.Orchestrator "..\Orchestrator\Settings\SettingsOrchestratorExample.py"
pause >nul pause >nul

@ -1,6 +1,6 @@
Metadata-Version: 2.1 Metadata-Version: 2.1
Name: pyOpenRPA Name: pyOpenRPA
Version: 1.0.32 Version: 1.0.34
Summary: First open source RPA platform for business Summary: First open source RPA platform for business
Home-page: https://gitlab.com/UnicodeLabs/OpenRPA Home-page: https://gitlab.com/UnicodeLabs/OpenRPA
Author: Ivan Maslov Author: Ivan Maslov

@ -1,14 +1,14 @@
pyOpenRPA-1.0.32.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 pyOpenRPA-1.0.34.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.0.32.dist-info/METADATA,sha256=hwB02rO7bJ84-CJNqzZfm4jVgnNbuBkKuAr8SsRwZq0,3510 pyOpenRPA-1.0.34.dist-info/METADATA,sha256=WakfkUg30wJGLxsmqvPERvkd2agMGOzXa84qcPG5f5Q,3510
pyOpenRPA-1.0.32.dist-info/RECORD,, pyOpenRPA-1.0.34.dist-info/RECORD,,
pyOpenRPA-1.0.32.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 pyOpenRPA-1.0.34.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.0.32.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 pyOpenRPA-1.0.34.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA/Orchestrator/Orchestrator.py,sha256=iM-DZ7TU7o51pzIJYEkNIlVG_GzzaVUESi7Tu0Ppw8g,6717 pyOpenRPA/Orchestrator/Orchestrator.py,sha256=UKp7eqvWDM91kYLwl2mo0UB8Pw-qu8eJCsR9NEXD1aU,6436
pyOpenRPA/Orchestrator/Processor.py,sha256=GHXwC1B2py4mAtk9oZa-FVSJhx3no9oD2bvkj20uhNA,9051 pyOpenRPA/Orchestrator/Processor.py,sha256=HQQyOVX-d5vPO-YULyTxVOtXtUMfvpAaSVO4xXxaKVI,9107
pyOpenRPA/Orchestrator/Server.py,sha256=TgKkqgMivzvh4cM4zpbDUdv9AXbUiPPy9uLjR1lTiJU,20229 pyOpenRPA/Orchestrator/Server.py,sha256=5tjhfU0QVEfg4zjT2jWOuOADWeHXMBxX2Fe8lj1bnCA,20839
pyOpenRPA/Orchestrator/ServerSettings.py,sha256=ZrNEt_UoHYGOeAKN5X5jQHz-XNl1lBW47ttKUF8_cmM,4948 pyOpenRPA/Orchestrator/ServerSettings.py,sha256=jOXJTLwg8cJx6D-rN8J4dn5RCb2nepAhCH4F9hYVUdM,4912
pyOpenRPA/Orchestrator/Timer.py,sha256=FQZ3y6G9d47Ybx7RewzePKQV77H4gCkx5SaeFVlsuhc,2095 pyOpenRPA/Orchestrator/Timer.py,sha256=FQZ3y6G9d47Ybx7RewzePKQV77H4gCkx5SaeFVlsuhc,2095
pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=wWDxguk0q4ylePllPzZvTdaOzlpolqYiBXIGp_a5udI,31744 pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=7wwEJ8lEI_2AElITUk9yyX91Sq6pNccqPsuAVlm7enQ,32322
pyOpenRPA/Orchestrator/Web/favicon.ico,sha256=jO3pjFWbmJEPQ2KroXSKYtXIesBq46PCBlKSouewODU,5430 pyOpenRPA/Orchestrator/Web/favicon.ico,sha256=jO3pjFWbmJEPQ2KroXSKYtXIesBq46PCBlKSouewODU,5430
pyOpenRPA/Orchestrator/__init__.py,sha256=qVH8fEPgXk54rmy-ol0PnT8GF5OlGE0a8mExwJ4tFqY,124 pyOpenRPA/Orchestrator/__init__.py,sha256=qVH8fEPgXk54rmy-ol0PnT8GF5OlGE0a8mExwJ4tFqY,124
pyOpenRPA/Orchestrator/__main__.py,sha256=cOd8WU77VGgzTZUB0WmWpPmdYyMZY1zVyuU9yx26MKs,144 pyOpenRPA/Orchestrator/__main__.py,sha256=cOd8WU77VGgzTZUB0WmWpPmdYyMZY1zVyuU9yx26MKs,144
@ -192,52 +192,56 @@ 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/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/Resources/Web/jQuery/jquery-3.1.1.min.js,sha256=HPMOWdIdSuVgr3FD9ZE-_MgiK8qk_MdQjrgCtfqp6U4,86713
pyOpenRPA/Robot/Clipboard.py,sha256=q76X8L21zJwcwdoJJNPeCEwAV30xS6ylHP1WwvtxoWI,722 pyOpenRPA/Robot/Clipboard.py,sha256=q76X8L21zJwcwdoJJNPeCEwAV30xS6ylHP1WwvtxoWI,722
pyOpenRPA/Robot/IntegrationOrchestrator.py,sha256=T1g1jJM7_JMTSVP50DTM5WHrMh1w8wovvcBXl1nEokU,2656 pyOpenRPA/Robot/OrchestratorConnector.py,sha256=Fihxz-jH9M4VakXEE0SZ0Vo9tLEQk8Tcg_C4HoH45gI,20037
pyOpenRPA/Robot/JSONNormalize.py,sha256=aIuVzuZDazhxkCOzoOjfhHVz66mp2FWdfPv5E7KWF5Y,3890 pyOpenRPA/Robot/SettingsTemplate.py,sha256=Rp5XPeV2I4tCS2uf4Zkqm_ERJ6pZMg4-e5_lMqGJYLk,1453
pyOpenRPA/Robot/ProcessCommunicator.py,sha256=Mpo2WoCrEUmY6aCSbQEXkT4qVKtN1N5NcVvG_UZxGVo,8245 pyOpenRPA/Robot/Test.py,sha256=qXr990nXiFZX5SNv6QN9GLb_U4HZRmJnbZR2qSnwilY,2878
pyOpenRPA/Robot/Robot.py,sha256=AVR8jzO-e_ZkW5DrLY_W9ta0eHSul997Y3U6uNVU8WE,9442 pyOpenRPA/Robot/UIDesktop.py,sha256=MWdWr0dZpk1PL1rsD91q6_8v687CSDBx1_T7IuHd3-E,77473
pyOpenRPA/Robot/UIDesktop.py,sha256=ehqMQmKLbkwW6iqA9bkw9tvDRni5QriLkG9P3AP_TMs,78377 pyOpenRPA/Robot/Utils/JSONNormalize.py,sha256=aIuVzuZDazhxkCOzoOjfhHVz66mp2FWdfPv5E7KWF5Y,3890
pyOpenRPA/Robot/Utils/ProcessBitness.py,sha256=WlKL-DklGaoTnchtapOTM_ydxSB4yOeo9lcG3zr2VME,4524 pyOpenRPA/Robot/Utils/ProcessBitness.py,sha256=WlKL-DklGaoTnchtapOTM_ydxSB4yOeo9lcG3zr2VME,4524
pyOpenRPA/Robot/Utils/ProcessCommunicator.py,sha256=8GfmLnOvAdosmt7YNT86uEV9cjhKippssCX62wOMJwM,8039
pyOpenRPA/Robot/Utils/TimerRepeat.py,sha256=_kTct3X9SIEvS3DKM5bGNnjRBVJasmMFZntQaVbPX_E,961
pyOpenRPA/Robot/Utils/ValueVerify.py,sha256=ObskxU4fOMoCGw74_nzYt6-a5jjrAckb3sdBLYyhYxY,777
pyOpenRPA/Robot/Utils/__init__.py,sha256=pHlSQGRFKmn5RCTHIf-3a2ooA9T2xNOWridckynP7W4,28 pyOpenRPA/Robot/Utils/__init__.py,sha256=pHlSQGRFKmn5RCTHIf-3a2ooA9T2xNOWridckynP7W4,28
pyOpenRPA/Robot/Utils/__pycache__/JSONNormalize.cpython-37.pyc,,
pyOpenRPA/Robot/Utils/__pycache__/ProcessBitness.cpython-37.pyc,, pyOpenRPA/Robot/Utils/__pycache__/ProcessBitness.cpython-37.pyc,,
pyOpenRPA/Robot/Utils/__pycache__/ProcessCommunicator.cpython-37.pyc,,
pyOpenRPA/Robot/Utils/__pycache__/TimerRepeat.cpython-37.pyc,,
pyOpenRPA/Robot/Utils/__pycache__/ValueVerify.cpython-37.pyc,,
pyOpenRPA/Robot/Utils/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Robot/Utils/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Robot/ValueVerify.py,sha256=ObskxU4fOMoCGw74_nzYt6-a5jjrAckb3sdBLYyhYxY,777
pyOpenRPA/Robot/Window.py,sha256=UJl-sg4RvvJ35aG9jZOzqGVwE15XK7qPHqoOBD13xFk,431 pyOpenRPA/Robot/Window.py,sha256=UJl-sg4RvvJ35aG9jZOzqGVwE15XK7qPHqoOBD13xFk,431
pyOpenRPA/Robot/__init__.py,sha256=iEW3SGBJf3kYa1zocGH5vEK0woejzJpnQfOmQtIA3P0,324 pyOpenRPA/Robot/__init__.py,sha256=L-5tPm6evytGWOzlqIq-2oiIhmQnruaxwIstyyaMkVI,253
pyOpenRPA/Robot/__main__.py,sha256=NlwxAG68mwoWNB4YIX15Fc2gWlL1RQ5HN8i1NyjGFdo,1965 pyOpenRPA/Robot/__main__.py,sha256=l6II8JuXCsnVOcfs6-2jvogKYTVhbfj3Jl2ld3OIP7s,1992
pyOpenRPA/Robot/__pycache__/Clipboard.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/Clipboard.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/IntegrationOrchestrator.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/OrchestratorConnector.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/JSONNormalize.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/SettingsTemplate.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/ProcessCommunicator.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/Test.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/Robot.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/UIDesktop.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/UIDesktop.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/ValueVerify.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/Window.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/Window.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Studio/JSONNormalize.py,sha256=g0Z8G2wojCgTAdZtyRiCfe0_FHSeAi72Va7R7mk27gg,3347 pyOpenRPA/Studio/JSONNormalize.py,sha256=g0Z8G2wojCgTAdZtyRiCfe0_FHSeAi72Va7R7mk27gg,3347
pyOpenRPA/Studio/ProcessCommunicator.py,sha256=5hXDMa4ONBgeJBoDIfDCAW9MoiRO8cq-DdfqQSAysgk,8080 pyOpenRPA/Studio/ProcessCommunicator.py,sha256=HD3XASJae31_HV3OznFe8E2MgZFXnwt7YveVN82M8nU,7912
pyOpenRPA/Studio/Studio.py,sha256=7X46k0l33sgQoG6sxFFJmI5G0KKxgDggvEnzux8aonw,7014 pyOpenRPA/Studio/RobotConnector.py,sha256=tQVC8X0k1HMHAAwAtkhtmeNA0cLMY3wuO-RCbgshdMk,5036
pyOpenRPA/Studio/Studio.py,sha256=wiVGWZZx-yC8jp-Wjz-B5GC1cqTcftDulZfYe-4hU8w,8125
pyOpenRPA/Studio/ValueVerify.py,sha256=ObskxU4fOMoCGw74_nzYt6-a5jjrAckb3sdBLYyhYxY,777 pyOpenRPA/Studio/ValueVerify.py,sha256=ObskxU4fOMoCGw74_nzYt6-a5jjrAckb3sdBLYyhYxY,777
pyOpenRPA/Studio/Web/Index.xhtml,sha256=74z3eWlmB6Yedbp91xgGtDjymUSlBcduAQ09ZxQ67f8,44241 pyOpenRPA/Studio/Web/Index.xhtml,sha256=RqFW3qC1pFRr-qWEEDlCEhL9l3PwANyRbll3KZJnLvo,47927
pyOpenRPA/Studio/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430 pyOpenRPA/Studio/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430
pyOpenRPA/Studio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pyOpenRPA/Studio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Studio/__main__.py,sha256=_57Rnq9DKbmmlpGFqIwVrWn_LRcU8jjmMTOny4_zlP8,308 pyOpenRPA/Studio/__main__.py,sha256=_57Rnq9DKbmmlpGFqIwVrWn_LRcU8jjmMTOny4_zlP8,308
pyOpenRPA/Studio/__pycache__/JSONNormalize.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/JSONNormalize.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/ProcessCommunicator.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/ProcessCommunicator.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/RobotConnector.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/Studio.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/Studio.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/ValueVerify.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/ValueVerify.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/Connector.py,sha256=vpXFO1irhLTHgIwWn5PCsTq-6E3Sx3sYOweIBNyiYEw,6164 pyOpenRPA/Tools/RobotRDPActive/Connector.py,sha256=9Y9zA92Zw9QF6dadW53NLekV_1r2STISFn5RzI08GDo,7272
pyOpenRPA/Tools/RobotRDPActive/Monitor.py,sha256=INkiX4Gi4KjvWRoe4jWV_NJGKgjDId6zEyqBHpegUxw,760 pyOpenRPA/Tools/RobotRDPActive/Monitor.py,sha256=X8ZhJFdDnA88OHlgRuinPvhZ_eS4R7y0xRchbo7LPCc,1525
pyOpenRPA/Tools/RobotRDPActive/SettingsExample.py,sha256=5eEhjk7NDXf9Q4yvkeRICE7x9npiMkazuMITQX24Ooc,857
pyOpenRPA/Tools/RobotRDPActive/Template.rdp,sha256=qPCLkjzTdYKURK7nRApkPUjRuS4K20vDPj9DIUNSSkE,2392 pyOpenRPA/Tools/RobotRDPActive/Template.rdp,sha256=qPCLkjzTdYKURK7nRApkPUjRuS4K20vDPj9DIUNSSkE,2392
pyOpenRPA/Tools/RobotRDPActive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pyOpenRPA/Tools/RobotRDPActive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/RobotRDPActive/__main__.py,sha256=qC_LyXI2MjJkidTRpV3abyyPO0qASGTvNkeAkfnA7J0,2108 pyOpenRPA/Tools/RobotRDPActive/__main__.py,sha256=mVk8zVqcBrzAwwn7tbZPXFWTQbWUkgU6w89nbY6GN-8,2340
pyOpenRPA/Tools/RobotRDPActive/__pycache__/Connector.cpython-37.pyc,, pyOpenRPA/Tools/RobotRDPActive/__pycache__/Connector.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/__pycache__/Monitor.cpython-37.pyc,, pyOpenRPA/Tools/RobotRDPActive/__pycache__/Monitor.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/__pycache__/SettingsExample.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Tools/RobotRDPActive/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Tools/RobotRDPActive/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotScreenActive/ConsoleStart.bat,sha256=_HNadUKHOYI5y6foG3srh8wjSzhX33xaKNylFtDjOJk,114 pyOpenRPA/Tools/RobotScreenActive/ConsoleStart.bat,sha256=_HNadUKHOYI5y6foG3srh8wjSzhX33xaKNylFtDjOJk,114
@ -251,5 +255,5 @@ pyOpenRPA/Tools/RobotScreenActive/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotScreenActive/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Tools/RobotScreenActive/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/__init__.py,sha256=mqY50pRbV4Tk-vj2-Z2CiY8u2qSB0HRfKNcduM36Zdo,175 pyOpenRPA/__init__.py,sha256=6g2t0dHUhbsJm87H07rs_6y5XDub0C_nWd2B-w-0XGg,175
pyOpenRPA/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/__pycache__/__init__.cpython-37.pyc,,

@ -15,11 +15,6 @@ import copy
#from .Settings import Settings #from .Settings import Settings
import importlib import importlib
from importlib import util from importlib import util
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
os.makedirs("Reports")
logging.basicConfig(filename="Reports\ReportRun_"+datetime.datetime.now().strftime("%Y_%m_%d__%H_%M_%S")+".log", level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
#Единый глобальный словарь (За основу взять из Settings.py) #Единый глобальный словарь (За основу взять из Settings.py)
global mGlobalDict global mGlobalDict
@ -51,6 +46,8 @@ lDaemonStartDateTime=datetime.datetime.now()
#Инициализация сервера #Инициализация сервера
lThreadServer = Server.RobotDaemonServer("ServerThread", mGlobalDict) lThreadServer = Server.RobotDaemonServer("ServerThread", mGlobalDict)
lThreadServer.start() lThreadServer.start()
#Logging
mGlobalDict["Logger"].info("Scheduler loop init")
#Вечный цикл #Вечный цикл
while True: while True:
lCurrentDateTime = datetime.datetime.now() lCurrentDateTime = datetime.datetime.now()

@ -97,35 +97,38 @@ def Activity(inActivity):
#Обработка команды OrchestratorRestart #Обработка команды OrchestratorRestart
########################################################### ###########################################################
if lItem["Type"]=="OrchestratorRestart": if lItem["Type"]=="OrchestratorRestart":
os.execl(sys.executable,os.path.abspath(__file__),*sys.argv) os.execl(sys.executable, os.path.abspath(__file__), *sys.argv)
lItem["Result"] = True lItem["Result"] = True
sys.exit(0) sys.exit(0)
########################################################### ###########################################################
#Обработка команды GlobalDictKeyListValueSet #Обработка команды GlobalDictKeyListValueSet
########################################################### ###########################################################
if lItem["Type"]=="GlobalDictKeyListValueSet": if lItem["Type"]=="GlobalDictKeyListValueSet":
lDict = mGlobalDict
for lItem2 in lItem["KeyList"][:-1]: for lItem2 in lItem["KeyList"][:-1]:
#Check if key - value exists #Check if key - value exists
if lItem2 in mGlobalDict: if lItem2 in lDict:
pass pass
else: else:
mGlobalDict[lItem2]={} lDict[lItem2]={}
mGlobalDict=mGlobalDict[lItem2] lDict=lDict[lItem2]
#Set value #Set value
mGlobalDict[lItem["KeyList"][-1]]=lItem["value"] lDict[lItem["KeyList"][-1]]=lItem["Value"]
lItem["Result"] = True
########################################################### ###########################################################
#Обработка команды GlobalDictKeyListValueGet #Обработка команды GlobalDictKeyListValueGet
########################################################### ###########################################################
if lItem["Type"]=="GlobalDictKeyListValueGet": if lItem["Type"]=="GlobalDictKeyListValueGet":
lDict = mGlobalDict
for lItem2 in lItem["KeyList"][:-1]: for lItem2 in lItem["KeyList"][:-1]:
#Check if key - value exists #Check if key - value exists
if lItem2 in mGlobalDict: if lItem2 in lDict:
pass pass
else: else:
mGlobalDict[lItem2]={} lDict[lItem2]={}
mGlobalDict=mGlobalDict[lItem2] lDict=lDict[lItem2]
#Return value #Return value
lItem["Result"]==mGlobalDict.get(lItem["KeyList"][-1],None) lItem["Result"]=lDict.get(lItem["KeyList"][-1],None)
#Определить вид активности #Определить вид активности
lActivityDateTime=inActivity["DateTimeUTCStringStart"] lActivityDateTime=inActivity["DateTimeUTCStringStart"]
##################################### #####################################
@ -193,6 +196,7 @@ def Activity(inActivity):
################## ##################
#Trace activity #Trace activity
################## ##################
#print(mGlobalDict)
if mGlobalDict["Processor"].get(f"LogType_{lItem['Type']}",True): if mGlobalDict["Processor"].get(f"LogType_{lItem['Type']}",True):
#Add activity in TransactionList if it is applicable #Add activity in TransactionList if it is applicable
mGlobalDict["Processor"]["LogList"].append(copy.deepcopy(lItem)) mGlobalDict["Processor"]["LogList"].append(copy.deepcopy(lItem))

@ -22,12 +22,14 @@ class RobotDaemonServer(Thread):
def run(self): def run(self):
inServerAddress=""; inServerAddress="";
inPort = mGlobalDict["Server"]["ListenPort"]; inPort = mGlobalDict["Server"]["ListenPort"];
print('starting server..., port:'+str(inPort)+" inAddress:"+inServerAddress)
# Server settings # Server settings
# Choose port 8080, for port 80, which is normally used for a http server, you need root access # Choose port 8080, for port 80, which is normally used for a http server, you need root access
server_address = (inServerAddress, inPort) server_address = (inServerAddress, inPort)
httpd = HTTPServer(server_address, testHTTPServer_RequestHandler) httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
print('running server...') # Logging
mGlobalDict["Logger"].info(f"Server init. Listen URL: {inServerAddress}, Listen port: {inPort}")
# Запуск адреса в браузере
os.system("explorer http://127.0.0.1:8081")
httpd.serve_forever() httpd.serve_forever()
#Authenticate function () #Authenticate function ()
@ -86,6 +88,7 @@ def AuthenticateVerify(inRequest):
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken] = {} mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken] = {}
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["Domain"] = lResult["Domain"] mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["Domain"] = lResult["Domain"]
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["User"] = lResult["User"] mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["User"] = lResult["User"]
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["FlagDoNotExpire"] = False
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["TokenDatetime"] = datetime.datetime.now() mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["TokenDatetime"] = datetime.datetime.now()
#Set-cookie #Set-cookie
inRequest.OpenRPA["AuthToken"] = lAuthToken inRequest.OpenRPA["AuthToken"] = lAuthToken
@ -110,6 +113,7 @@ def AuthenticateBlock(inRequest):
#return bool True - go execute, False - dont execute #return bool True - go execute, False - dont execute
def UserAccessCheckBefore(inMethod, inRequest): def UserAccessCheckBefore(inMethod, inRequest):
# Help def - Get access flag from dict # Help def - Get access flag from dict
#pdb.set_trace()
def HelpGetFlag(inAccessRuleItem, inRequest, inGlobalDict, inAuthenticateDict): def HelpGetFlag(inAccessRuleItem, inRequest, inGlobalDict, inAuthenticateDict):
if "FlagAccess" in inAccessRuleItem: if "FlagAccess" in inAccessRuleItem:
return inAccessRuleItem["FlagAccess"] return inAccessRuleItem["FlagAccess"]
@ -288,7 +292,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
self.wfile.write(inResponseDict["Body"]) self.wfile.write(inResponseDict["Body"])
def do_GET(self): def do_GET(self):
# Prepare result dict # Prepare result dict
lResponseDict = {"Headers": {}, "SetCookies":{}, "Body": "", "StatusCode": None} lResponseDict = {"Headers": {}, "SetCookies": {}, "Body": "", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict self.OpenRPAResponseDict = lResponseDict
##################################### #####################################
#Do authentication #Do authentication
@ -300,6 +304,8 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
lAuthenticateDict = AuthenticateVerify(self) lAuthenticateDict = AuthenticateVerify(self)
if not lAuthenticateDict["User"]: if not lAuthenticateDict["User"]:
lFlagAccessUserBlock=True lFlagAccessUserBlock=True
# Logging
mGlobalDict["Logger"].info(f"HTTP request /. Domain: {lAuthenticateDict['Domain']}, User: {lAuthenticateDict['User']}")
if lFlagAccessUserBlock: if lFlagAccessUserBlock:
AuthenticateBlock(self) AuthenticateBlock(self)
##################################### #####################################
@ -321,7 +327,6 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
lFlagURLIsApplied=False lFlagURLIsApplied=False
lFlagURLIsApplied=self.URLItemCheckDo(lURLItem, "GET") lFlagURLIsApplied=self.URLItemCheckDo(lURLItem, "GET")
if lFlagURLIsApplied: if lFlagURLIsApplied:
#print("New engine")
self.ResponseDictSend() self.ResponseDictSend()
return return
#Monitor #Monitor
@ -350,6 +355,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# POST # POST
def do_POST(self): def do_POST(self):
# Prepare result dict # Prepare result dict
#pdb.set_trace()
lResponseDict = {"Headers": {}, "SetCookies":{}, "Body": "", "StatusCode": None} lResponseDict = {"Headers": {}, "SetCookies":{}, "Body": "", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict self.OpenRPAResponseDict = lResponseDict
##################################### #####################################
@ -371,7 +377,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
lFlagUserAccess = True lFlagUserAccess = True
#If need user authentication #If need user authentication
if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False): if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False):
lFlagUserAccess = UserAccessCheckBefore("GET", self) lFlagUserAccess = UserAccessCheckBefore("POST", self)
###################################### ######################################
if lFlagUserAccess: if lFlagUserAccess:
#Централизованная функция получения запросов/отправки #Централизованная функция получения запросов/отправки
@ -393,3 +399,10 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# Write content as utf-8 data # Write content as utf-8 data
self.wfile.write(bytes(message, "utf8")) self.wfile.write(bytes(message, "utf8"))
return return
else:
#Set access denied code
# Send response status code
self.send_response(403)
# Send headers
self.end_headers()
return

@ -16,7 +16,6 @@ def Monitor_ControlPanelDictGet(inRequest,inGlobalDict):
# Send message back to client # Send message back to client
message = json.dumps(lResultJSON) message = json.dumps(lResultJSON)
# Write content as utf-8 data # Write content as utf-8 data
#print(bytes(message, "utf8"))
inResponseDict["Body"] = bytes(message, "utf8") inResponseDict["Body"] = bytes(message, "utf8")
def GetScreenshot(inRequest,inGlobalDict): def GetScreenshot(inRequest,inGlobalDict):

@ -275,8 +275,8 @@
}); });
} }
/// ///
mGlobal.Monitor.mControlPanelAutoUpdateSeconds=5; mGlobal.Monitor.mControlPanelAutoUpdateSeconds=3;
mGlobal.Monitor.mControlPanelAutoUpdateSecondsCurrent=5; mGlobal.Monitor.mControlPanelAutoUpdateSecondsCurrent=3;
mGlobal.Monitor.fControlPanelAutoUpdateRun=function(inRefreshSeconds) { mGlobal.Monitor.fControlPanelAutoUpdateRun=function(inRefreshSeconds) {
mGlobal.Monitor.mControlPanelAutoUpdateSeconds=inRefreshSeconds; mGlobal.Monitor.mControlPanelAutoUpdateSeconds=inRefreshSeconds;
//Функция обновления текста кнопки обновления //Функция обновления текста кнопки обновления
@ -291,7 +291,7 @@
mGlobal.Monitor.mControlPanelAutoUpdateTimerId=setInterval(lControlPanelUpdate,1000) mGlobal.Monitor.mControlPanelAutoUpdateTimerId=setInterval(lControlPanelUpdate,1000)
} }
mGlobal.Monitor.fControlPanelRefresh() mGlobal.Monitor.fControlPanelRefresh()
mGlobal.Monitor.fControlPanelAutoUpdateRun(5); mGlobal.Monitor.fControlPanelAutoUpdateRun(3);
mGlobal.Test=function() { mGlobal.Test=function() {
///Обнулить таблицу ///Обнулить таблицу
@ -355,6 +355,29 @@
/////////////////////////////// ///////////////////////////////
mGlobal.Processor = {} mGlobal.Processor = {}
mGlobal.Processor.ServerValueSet = function(inKeyList,inValue) {
lData = [
{
"Type":"GlobalDictKeyListValueSet",
"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.LogListShow = function() { mGlobal.Processor.LogListShow = function() {
lData = [ lData = [
{ {
@ -633,7 +656,7 @@
<div class="ui basic {{Color}} button" onclick="{{OnClick}}">{{{Text}}}</div> <div class="ui basic {{Color}} button" onclick="{{OnClick}}">{{{Text}}}</div>
{{/FooterButtonX2List}} {{/FooterButtonX2List}}
</div> </div>
<div class="ui horizontal divider">Доп. управление</div> <div class="ui horizontal divider">Add. controls</div>
<div class="ui one buttons"> <div class="ui one buttons">
{{#FooterButtonX1List}} {{#FooterButtonX1List}}
<div class="ui basic {{Color}} button" onclick="{{OnClick}}">{{{Text}}}</div> <div class="ui basic {{Color}} button" onclick="{{OnClick}}">{{{Text}}}</div>

@ -1,46 +0,0 @@
import requests
import grequests
#from requests import async
import json
###################################
##Orchestrator integration module (safe use when orchestrator is turned off)
###################################
################################################################################
#Send data to orchestrator (asynchronyous)
#Example: t=IntegrationOrchestrator.DataSend(["Storage","Robot_R01"],{"RunDateTimeString":"Test1","StepCurrentName":"Test2","StepCurrentDuration":"Test333","SafeStopSignal":True},"localhost",8081)
def DataSend(inKeyList,inValue,inOrchestratorHost="localhost",inOrchestratorPort=80):
lURL = f'http://{inOrchestratorHost}:{inOrchestratorPort}/ProcessingRun'
lDataJSON = {"actionList":[{"type":"AdministrationGlobalDictSetKeyListValue","key_list":inKeyList,"value":inValue}]}
#lAsyncList = []
lResultItem = [grequests.post(lURL, json=lDataJSON)]
return grequests.map(lResultItem)
#lAsyncList.append(lResultItem)
#return async.map(lAsyncList)
################################################################################
#recieve Data from orchestrator
#t=IntegrationOrchestrator.DataRecieve(["Storage","Robot_R01"],"localhost",8081)
def DataRecieve(inKeyList,inOrchestratorHost="localhost",inOrchestratorPort=80):
lURL = f'http://{inOrchestratorHost}:{inOrchestratorPort}/ProcessingRun'
lDataJSON = {"actionList":[{"type":"AdministrationGlobalDictGetKeyListValue","key_list":inKeyList}]}
try:
lResult = requests.post(lURL, json=lDataJSON)
lResultJSON = json.loads(lResult.text)
return lResultJSON["actionListResult"][0]["value"]
except Exception:
return None
################################################################################
#Check if orchestrator has safe stop signal
#Example: IntegrationOrchestrator.SafeStopSignalIs(["Storage","Robot_R01","SafeStopSignal"],"localhost",8081)
def SafeStopSignalIs(inKeyList,inOrchestratorHost="localhost",inOrchestratorPort=80):
lResult=False
lResponse=DataRecieve(inKeyList,inOrchestratorHost,inOrchestratorPort)
if lResponse is not None:
lResult = lResponse
return lResult
################################################################################
#Reset SafeStop signal in orchestrator
#Example: t=IntegrationOrchestrator.SafeStopSignalReset(["Storage","Robot_R01","SafeStopSignal"],"localhost",8081)
def SafeStopSignalReset(inKeyList,inOrchestratorHost="localhost",inOrchestratorPort=80):
lResponse=DataSend(inKeyList,False,inOrchestratorHost,inOrchestratorPort)
return lResponse

@ -0,0 +1,401 @@
import requests
#Logging
import os
import logging
import datetime
import copy
from .Utils import TimerRepeat # Timer which can repeating
mLogger=logging.getLogger("OrchestratorConnector")
#########################
mTimerList=[]
def IntervalTerminateAll():
for lItem in mTimerList:
lItem.stop()
#########################
# Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
os.makedirs("Reports")
##########################
# Подготовка логгера Robot
#########################
mLogger.setLevel(logging.INFO)
# create the logging file handler
mLoggerFH = logging.FileHandler("Reports\ReportOrchestratorConnector_" + datetime.datetime.now().strftime("%Y_%m_%d") + ".log")
mLoggerFormatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
mLoggerFH.setFormatter(mLoggerFormatter)
# add handler to logger object
mLogger.addHandler(mLoggerFH)
############################################
#Turn loggin level ERROR
def LoggerSetLevelError():
mLogger.setLevel(logging.ERROR)
#from requests import async
import json
###################################
##Orchestrator integration module (safe use when orchestrator is turned off)
###################################
################################################################################
# Recieve data from orchestrator (synchronyous)
# Example:
# t=IntegrationOrchestrator.DataRecieveAsync(
# RobotStorage=mGlobal["Storage"],
# RobotStorageKey="R01_OrchestratorToRobot",
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
def DataReceiveSync(
OrchestratorKeyList, OrchestratorProtocol="http",
OrchestratorHost="localhost", OrchestratorPort=80, OrchestratorAuthToken=None
):
lCookies = {}
# Set auth token if authorization is needed
if OrchestratorAuthToken:
lCookies["AuthToken"] = OrchestratorAuthToken
lURL = f'{OrchestratorProtocol}://{OrchestratorHost}:{OrchestratorPort}/Utils/Processor'
lDataJSON = [{"Type": "GlobalDictKeyListValueGet", "KeyList": OrchestratorKeyList}]
try:
lResult = requests.post(lURL, json=lDataJSON, cookies=lCookies)
lResultJSON = json.loads(lResult.text)
return (True, lResultJSON[0]["Result"]) # (Flag response is ok, Data)
except Exception:
mLogger.warning(
f"Orchestrator not responding. Def DataRecieveSync, OrchestratorKeyList: {str(OrchestratorKeyList)}, OrchestratorProtocol: {str(OrchestratorProtocol)}, OrchestratorHost: {str(OrchestratorHost)}, OrchestratorPort: {str(OrchestratorPort)}")
return (False, None) # (Flag response is not ok, Data None)
################################################################################
# Recieve data from orchestrator (asynchronyous)
# Example:
# t=IntegrationOrchestrator.DataRecieveAsync(
# RobotStorage=mGlobal["Storage"],
# RobotStorageKey="R01_OrchestratorToRobot",
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
def DataReceiveAsync(
RobotStorage, RobotStorageKey, OrchestratorKeyList, OrchestratorProtocol="http",
OrchestratorHost="localhost", OrchestratorPort=80, OrchestratorAuthToken=None
):
from threading import Thread
import uuid
global mGlobalDict
class ThreadAsync(Thread):
def DataRecieveSync(self):
lCookies = {}
#Set auth token if authorization is needed
if OrchestratorAuthToken:
lCookies["AuthToken"] = OrchestratorAuthToken
lURL = f'{OrchestratorProtocol}://{OrchestratorHost}:{OrchestratorPort}/Utils/Processor'
lDataJSON = [{"Type": "GlobalDictKeyListValueGet", "KeyList": OrchestratorKeyList}]
try:
lResult = requests.post(lURL, json=lDataJSON, cookies = lCookies)
lResultJSON = json.loads(lResult.text)
return (True,lResultJSON[0]["Result"]) #(Flag response is ok, Data)
except Exception:
mLogger.warning(
f"Orchestrator not responding. Def DataRecieveAsync, OrchestratorKeyList: {str(OrchestratorKeyList)}, OrchestratorProtocol: {str(OrchestratorProtocol)}, OrchestratorHost: {str(OrchestratorHost)}, OrchestratorPort: {str(OrchestratorPort)}")
return (False,None) #(Flag response is not ok, Data None)
# Thread init
def __init__(self, name):
Thread.__init__(self)
self.name = name
#Thread start
def run(self):
(lFlagResponseOK,lResponseData) = self.DataRecieveSync()
if lFlagResponseOK:
RobotStorage[RobotStorageKey] = lResponseData
ThreadObject = ThreadAsync(f"ThreadAsync{str(uuid.uuid1())}")
ThreadObject.start()
return True
################################################################################
#IntervalDataRecieveAsync - Periodic recieve data from orchestrator and update storage
def IntervalDataReceiveAsync(*args, **kwargs):
lInterval=3
#Delete index 0 from args
lArgs=copy.copy(args)
if len(lArgs)>0:
lInterval = lArgs[0]
lArgs = lArgs[1:]
#Delete Interval from kwargs
lKwargs = copy.copy(kwargs)
if "Interval" in lKwargs:
lInterval = lKwargs["Interval"]
del lKwargs["Interval"]
lTimer = TimerRepeat.TimerRepeat(lInterval, DataReceiveAsync, lArgs, lKwargs)
lTimer.start()
#Add timer to general list to stop this when needed
mTimerList.append(lTimer)
return lTimer
################################################################################
###################################
################################
###################################
################################################################################
# Send data from orchestrator (synchronyous)
# Example:
# t=IntegrationOrchestrator.DataSendSync(
# RobotValue="Value",
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
def DataSendSync(
RobotValue, OrchestratorKeyList, OrchestratorProtocol="http",
OrchestratorHost="localhost", OrchestratorPort=80, OrchestratorAuthToken=None
):
lCookies = {}
# Set auth token if authorization is needed
if OrchestratorAuthToken:
lCookies["AuthToken"] = OrchestratorAuthToken
lURL = f'{OrchestratorProtocol}://{OrchestratorHost}:{OrchestratorPort}/Utils/Processor'
lDataJSON = [{"Type": "GlobalDictKeyListValueSet", "KeyList": OrchestratorKeyList, "Value": RobotValue}]
try:
lResult = requests.post(lURL, json=lDataJSON, cookies=lCookies)
lResultJSON = json.loads(lResult.text)
return (True, lResultJSON[0]["Result"]) # (Flag response is ok, Data)
except Exception:
mLogger.warning(
f"Orchestrator not responding. Def: DataSendSync, RobotValue: {str(RobotValue)}, OrchestratorKeyList: {str(OrchestratorKeyList)}, OrchestratorProtocol: {str(OrchestratorProtocol)}, OrchestratorHost: {str(OrchestratorHost)}, OrchestratorPort: {str(OrchestratorPort)}")
return (False, None) # (Flag response is not ok, Data None)
################################################################################
# Send data from orchestrator (asynchronyous)
# Example:
# t=IntegrationOrchestrator.DataSendAsync(
# RobotStorage=mGlobal["Storage"],
# RobotStorageKey="R01_OrchestratorToRobot",
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
def DataSendAsync(
RobotStorage, RobotStorageKey, OrchestratorKeyList, OrchestratorProtocol="http",
OrchestratorHost="localhost", OrchestratorPort=80, OrchestratorAuthToken=None
):
from threading import Thread
import uuid
global mGlobalDict
class ThreadAsync(Thread):
def DataSendSync(self):
RobotValue = RobotStorage[RobotStorageKey]
lCookies = {}
# Set auth token if authorization is needed
if OrchestratorAuthToken:
lCookies["AuthToken"] = OrchestratorAuthToken
lURL = f'{OrchestratorProtocol}://{OrchestratorHost}:{OrchestratorPort}/Utils/Processor'
lDataJSON = [{"Type": "GlobalDictKeyListValueSet", "KeyList": OrchestratorKeyList, "Value": RobotValue}]
try:
lResult = requests.post(lURL, json=lDataJSON, cookies=lCookies)
lResultJSON = json.loads(lResult.text)
return (True, lResultJSON[0]["Result"]) # (Flag response is ok, Data)
except Exception:
mLogger.warning(
f"Orchestrator not responding. Def: DataSendAsync, RobotValue: {str(RobotValue)}, OrchestratorKeyList: {str(OrchestratorKeyList)}, OrchestratorProtocol: {str(OrchestratorProtocol)}, OrchestratorHost: {str(OrchestratorHost)}, OrchestratorPort: {str(OrchestratorPort)}")
return (False, None) # (Flag response is not ok, Data None)
# Thread init
def __init__(self, name):
Thread.__init__(self)
self.name = name
#Thread start
def run(self):
self.DataSendSync()
ThreadObject = ThreadAsync(f"ThreadAsync{str(uuid.uuid1())}")
ThreadObject.start()
return True
################################################################################
#IntervalDataSendAsync - Periodic send data from robot to orchestrator
def IntervalDataSendAsync(*args,**kwargs):
lInterval=3
#Delete index 0 from args
lArgs=copy.copy(args)
if len(lArgs)>0:
lInterval = lArgs[0]
lArgs = lArgs[1:]
#Delete Interval from kwargs
lKwargs = copy.copy(kwargs)
if "Interval" in lKwargs:
lInterval = lKwargs["Interval"]
del lKwargs["Interval"]
lTimer = TimerRepeat.TimerRepeat(lInterval, DataSendAsync, lArgs, lKwargs)
lTimer.start()
#Add timer to general list to stop this when needed
mTimerList.append(lTimer)
return lTimer
################################################################################
###################################
################################
###################################
################################################################################
# Check if RobotStorage[Key] Value has been changed > then send data + reset to orchestrator (asynchronyous) timeout 2 seconds
# Example:
# t=IntegrationOrchestrator.DataSendResetAsync(
# RobotStorage=mGlobal["Storage"],
# RobotStorageKey="R01_OrchestratorToRobot",
# RobotResetValue="Test",
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
def DataSendResetAsync(
RobotStorage, RobotStorageKey, RobotResetValue, OrchestratorKeyList, OrchestratorProtocol="http",
OrchestratorHost="localhost", OrchestratorPort=80, OrchestratorAuthToken=None
):
#Do operations if data not equal to ResetValue
if RobotStorage[RobotStorageKey] != RobotResetValue:
#Get value
lRobotValue = copy.deepcopy(RobotStorage[RobotStorageKey])
#Reset value
RobotStorage[RobotStorageKey] = copy.deepcopy(RobotResetValue)
#Send data (retry while data will be transferred completele)
from threading import Thread
import uuid
import time
global mGlobalDict
class ThreadAsync(Thread):
def DataSendSync(self):
RobotValue = lRobotValue
lCookies = {}
# Set auth token if authorization is needed
if OrchestratorAuthToken:
lCookies["AuthToken"] = OrchestratorAuthToken
lURL = f'{OrchestratorProtocol}://{OrchestratorHost}:{OrchestratorPort}/Utils/Processor'
lDataJSON = [{"Type": "GlobalDictKeyListValueSet", "KeyList": OrchestratorKeyList, "Value": RobotValue}]
lFlagDataTransmit = False
while not lFlagDataTransmit:
try:
lResult = requests.post(lURL, json=lDataJSON, cookies=lCookies)
lResultJSON = json.loads(lResult.text)
lFlagDataTransmit = True
except Exception:
mLogger.warning(
f"Orchestrator not responding - will retry to send update. Timeout 2 seconds. Def: DataSendResetAsync, RobotValue: {str(RobotValue)}, OrchestratorKeyList: {str(OrchestratorKeyList)}, OrchestratorProtocol: {str(OrchestratorProtocol)}, OrchestratorHost: {str(OrchestratorHost)}, OrchestratorPort: {str(OrchestratorPort)}")
time.sleep(2) #Timout for next loop
return (True,True) # Only True can be returned
# Thread init
def __init__(self, name):
Thread.__init__(self)
self.name = name
# Thread start
def run(self):
self.DataSendSync()
ThreadObject = ThreadAsync(f"ThreadAsync{str(uuid.uuid1())}")
ThreadObject.start()
return True
return True
################################################################################
################################################################################
#IntervalDataSendResetAsync - Periodic check changed and send + reset data from robot to orchestrator
def IntervalDataSendResetAsync(*args,**kwargs):
lInterval=3
#Delete index 0 from args
lArgs=copy.copy(args)
if len(lArgs)>0:
lInterval = lArgs[0]
lArgs = lArgs[1:]
#Delete Interval from kwargs
lKwargs = copy.copy(kwargs)
if "Interval" in lKwargs:
lInterval = lKwargs["Interval"]
del lKwargs["Interval"]
lTimer = TimerRepeat.TimerRepeat(lInterval, DataSendResetAsync, lArgs, lKwargs)
lTimer.start()
#Add timer to general list to stop this when needed
mTimerList.append(lTimer)
return lTimer
################################################################################
# Check changes in orchestrator - then replace in RobotStorage if not equeal. Has no timeout because You can use function IntervalDataReceiveResetAsync (asynchronyous)
#Next iteration do not rewrite value until new change has come from orchestrator
# Example:
# t=IntegrationOrchestrator.DataRecieveAsync(
# RobotStorage=mGlobal["Storage"],
# RobotStorageKey="R01_OrchestratorToRobot",
# RobotResetValue={"Test":"Test"},
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
def DataReceiveResetAsync(
RobotStorage, RobotStorageKey, RobotResetValue, OrchestratorKeyList, OrchestratorProtocol="http",
OrchestratorHost="localhost", OrchestratorPort=80, OrchestratorAuthToken=None
):
from threading import Thread
import uuid
global mGlobalDict
class ThreadAsync(Thread):
def DataRecieveSync(self):
lCookies = {}
#Set auth token if authorization is needed
if OrchestratorAuthToken:
lCookies["AuthToken"] = OrchestratorAuthToken
lURL = f'{OrchestratorProtocol}://{OrchestratorHost}:{OrchestratorPort}/Utils/Processor'
lDataJSON = [
{"Type": "GlobalDictKeyListValueGet", "KeyList": OrchestratorKeyList},
{"Type": "GlobalDictKeyListValueSet", "KeyList": OrchestratorKeyList, "Value": RobotResetValue}
]
try:
lResult = requests.post(lURL, json=lDataJSON, cookies = lCookies)
lResultJSON = json.loads(lResult.text)
#Change data if it changes with ResetValue
if lResultJSON[0]["Result"] != RobotResetValue:
return (True,lResultJSON[0]["Result"]) #(Flag data changes is ok, Data)
else:
return (False, lResultJSON[0]["Result"]) # (Flag data changes is false - dont rewrite in RobotStorage, Data)
except Exception:
mLogger.warning(
f"Orchestrator not responding. Def DataReceiveResetAsync, RobotResetValue: {str(RobotResetValue)}, OrchestratorKeyList: {str(OrchestratorKeyList)}, OrchestratorProtocol: {str(OrchestratorProtocol)}, OrchestratorHost: {str(OrchestratorHost)}, OrchestratorPort: {str(OrchestratorPort)}")
return (False,None) #(Flag response is not ok, Data None)
# Thread init
def __init__(self, name):
Thread.__init__(self)
self.name = name
#Thread start
def run(self):
(lFlagResponseOK,lResponseData) = self.DataRecieveSync()
if lFlagResponseOK:
RobotStorage[RobotStorageKey] = lResponseData
ThreadObject = ThreadAsync(f"ThreadAsync{str(uuid.uuid1())}")
ThreadObject.start()
return True
################################################################################
################################################################################
#IntervalDataReceiveResetAsync - Periodic receive + every time reset and check changed and reset data on robot storage
def IntervalDataReceiveResetAsync(*args,**kwargs):
lInterval=3
#Delete index 0 from args
lArgs=copy.copy(args)
if len(lArgs)>0:
lInterval = lArgs[0]
lArgs = lArgs[1:]
#Delete Interval from kwargs
lKwargs = copy.copy(kwargs)
if "Interval" in lKwargs:
lInterval = lKwargs["Interval"]
del lKwargs["Interval"]
lTimer = TimerRepeat.TimerRepeat(lInterval, DataReceiveResetAsync, lArgs, lKwargs)
lTimer.start()
#Add timer to general list to stop this when needed
mTimerList.append(lTimer)
return lTimer
#################################################################################
#################################################################################
################################################################################
#ConfigurationInit - Get dict configuration and init interval functions
def ConfigurationInit(inConfigurationDict):
for lItem in inConfigurationDict.keys():
lFunction = globals()[lItem]
#Iterate throught the nested list
for lFunctionConfigurationDict in inConfigurationDict[lItem]:
lFunction(**lFunctionConfigurationDict)
return True

@ -1,159 +0,0 @@
import pdb
import json
import subprocess
import zlib
import os
from . import ProcessCommunicator
import importlib
import traceback
import logging
import sys
import datetime
import struct
import shutil
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
os.makedirs("Reports")
logging.basicConfig(filename="Reports\ReportRobotRun_"+datetime.datetime.now().strftime("%Y_%m_%d")+".log", level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
####################################
#Info: Main module of the Robot app (OpenRPA - Robot)
####################################
#Usage:
#Here you can run some activity or list of activities
#After import this module you can use the folowing functions:
#ActivityRun(inActivitySpecificationDict): outActivityResultDict - function - run activity (function or procedure)
#ActivityRunJSON(inActivitySpecificationDictJSON): outActivityResultDictJSON
#ActivityListRun(inActivitySpecificationDictList): outActivityResultDictList - function - run list of activities (function or procedure)
#ActivityListRunJSON(inActivitySpecificationDictListJSON): outActivityResultDictListJSON
#Naming:
#Activity - some action/list of actions
#Module - Any *.py file, which consist of area specific functions
#Argument
#inActivitySpecificationDict:
#{
# ModuleName: <"GUI"|..., str>,
# ActivityName: <Function or procedure name in module, str>,
# ArgumentList: [<Argument 1, any type>, ...] - optional,
# ArgumentDict: {<Argument 1 name, str>:<Argument 1 value, any type>, ...} - optional
#}
#outActivityResultDict:
#{
# ActivitySpecificationDict: {
# ModuleName: <"GUI"|..., str>,
# ActivityName: <Function or procedure name in module, str>,
# ArgumentList: [<Argument 1, any type>, ...] - optional,
# ArgumentDict: {<Argument 1 name, str>: <Argument 1 value, any type>, ...} - optional
# },
# ErrorFlag: <Boolean flag - Activity result has error (true) or not (false), boolean>,
# ErrorMessage: <Error message, str> - required if ErrorFlag is true,
# ErrorTraceback: <Error traceback log, str> - required if ErrorFlag is true,
# Result: <Result, returned from the Activity, int, str, boolean, list, dict> - required if ErrorFlag is false
#}
####################
#Section: Module initialization
####################
#Start childprocess - GUI Module 32 bit
#pdb.set_trace()
if not os.path.isfile("..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe"):
shutil.copyfile('..\\Resources\\WPy32-3720\\python-3.7.2\\python.exe',"..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe")
mProcessGUI_x32 = subprocess.Popen(['..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe',"-m",'pyOpenRPA.Robot'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#Start childprocess - GUI Module 64 bit - uncomment after WPy64 installation
ProcessCommunicator.ProcessChildSendObject(mProcessGUI_x32,{"ModuleName":"UIDesktop","ActivityName":"Get_OSBitnessInt","ArgumentList":[],"ArgumentDict":{}})
lOSBitness = ProcessCommunicator.ProcessChildReadWaitObject(mProcessGUI_x32)["Result"]
lProcessBitnessStr = str(struct.calcsize("P") * 8)
#start 64 if system support 64
mProcessGUI_x64 = None
if lOSBitness == 64:
if not os.path.isfile("..\\Resources\\WPy64-3720\\python-3.7.2.amd64\\OpenRPARobotGUIx64.exe"):
shutil.copyfile('..\\Resources\\WPy64-3720\\python-3.7.2.amd64\\python.exe',"..\\Resources\\WPy64-3720\\python-3.7.2.amd64\\OpenRPARobotGUIx64.exe")
mProcessGUI_x64 = subprocess.Popen(['..\\Resources\\WPy64-3720\\python-3.7.2.amd64\\OpenRPARobotGUIx64.exe',"-m",'pyOpenRPA.Robot'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
####################
#Section: Activity
####################
def ActivityRun(inActivitySpecificationDict):
#Выполнить отправку в модуль UIDesktop, если ModuleName == "UIDesktop"
#pdb.set_trace()
if inActivitySpecificationDict["ModuleName"] == "UIDesktop":
if "ArgumentList" not in inActivitySpecificationDict:
inActivitySpecificationDict["ArgumentList"]=[]
if "ArgumentDict" not in inActivitySpecificationDict:
inActivitySpecificationDict["ArgumentDict"]={}
#Если mProcessGUI_x64 не инициализирован
lFlagRun64=True
if mProcessGUI_x64 is None:
lFlagRun64=False
else:
if inActivitySpecificationDict["ActivityName"]=="UIOSelectorsSecs_WaitAppear_List":
#Функция ожидания появления элементов (тк элементы могут быть недоступны, неизвестно в каком фреймворке каждый из них может появиться)
lFlagRun64=True
elif inActivitySpecificationDict["ActivityName"].startswith("UIOSelector") or inActivitySpecificationDict["ActivityName"].startswith("PWASpecification"):
if len(inActivitySpecificationDict["ArgumentList"])>0:
if len(inActivitySpecificationDict["ArgumentList"][0])>0:
#Определение разрядности (32 и 64) для тех функций, где это необходимо
######################################################
#Выполнить проверку разрядности через UIOSelector_Get_BitnessInt
#Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
#pdb.set_trace()
#Внимание! Проверка разрядности специально делается на процессе 64 бита, тк процесс 32 бита зависает на 35 итерации проверки
ProcessCommunicator.ProcessChildSendObject(mProcessGUI_x64,{"ModuleName":"UIDesktop","ActivityName":"UIOSelector_Get_BitnessInt","ArgumentList":[inActivitySpecificationDict["ArgumentList"][0]],"ArgumentDict":inActivitySpecificationDict["ArgumentDict"]})
#Получить ответ от дочернего процесса
lResponseObject=ProcessCommunicator.ProcessChildReadWaitObject(mProcessGUI_x64)
#pdb.set_trace()
if lResponseObject["Result"]==32:
lFlagRun64=False
#Запуск 64
#pdb.set_trace()
if lFlagRun64:
#Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(mProcessGUI_x64,inActivitySpecificationDict)
#Получить ответ от дочернего процесса
lResponseObject=ProcessCommunicator.ProcessChildReadWaitObject(mProcessGUI_x64)
else:
#Запуск 32
#Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(mProcessGUI_x32,inActivitySpecificationDict)
#Получить ответ от дочернего процесса
lResponseObject=ProcessCommunicator.ProcessChildReadWaitObject(mProcessGUI_x32)
#Остальные модули подключать и выполнять здесь
else:
lArgumentList=[]
if "ArgumentList" in inActivitySpecificationDict:
lArgumentList=inActivitySpecificationDict["ArgumentList"]
lArgumentDict={}
if "ArgumentDict" in inActivitySpecificationDict:
lArgumentDict=inActivitySpecificationDict["ArgumentDict"]
#Подготовить результирующую структуру
lResponseObject={"ActivitySpecificationDict":inActivitySpecificationDict,"ErrorFlag":False}
try:
#Подключить модуль для вызова
lModule=importlib.import_module(inActivitySpecificationDict["ModuleName"])
#Найти функцию
lFunction=getattr(lModule,inActivitySpecificationDict["ActivityName"])
#Выполнить вызов и записать результат
lResponseObject["Result"]=lFunction(*lArgumentList,**lArgumentDict)
except Exception as e:
#Установить флаг ошибки и передать тело ошибки
lResponseObject["ErrorFlag"]=True
lResponseObject["ErrorMessage"]=str(e)
lResponseObject["ErrorTraceback"]=traceback.format_exc()
return lResponseObject
#########################################################
#Run list of activities
#########################################################
def ActivityListRun(inActivitySpecificationDictList):
lResult=[]
for lItem in inActivitySpecificationDictList:
lResult.append(ActivityRun(lItem))
return lResult

@ -0,0 +1,34 @@
import logging
import datetime
#Robot settings
def Settings():
import os
mDict = {
"Logger": logging.getLogger("Robot"),
"Storage": {
"Robot_R01_help": "Robot data storage in orchestrator env",
"Robot_R01": {}
},
"ProcessBitness": {
"Python32FullPath": None, #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe"
"Python64FullPath": None, #Set from user
"Python32ProcessName": "OpenRPAUIDesktopX32.exe", #Config set once
"Python64ProcessName": "OpenRPAUIDesktopX64.exe" #Config set once
}
}
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
os.makedirs("Reports")
##########################
#Подготовка логгера Robot
#########################
mRobotLogger=mDict["Logger"]
mRobotLogger.setLevel(logging.INFO)
# create the logging file handler
mRobotLoggerFH = logging.FileHandler("Reports\ReportRobot_"+datetime.datetime.now().strftime("%Y_%m_%d")+".log")
mRobotLoggerFormatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
mRobotLoggerFH.setFormatter(mRobotLoggerFormatter)
# add handler to logger object
mRobotLogger.addHandler(mRobotLoggerFH)
############################################

@ -0,0 +1,65 @@
import unittest
from threading import Timer
import sys
lFolderPath = "/".join(__file__.split("\\")[:-3])
sys.path.insert(0, lFolderPath)
from pyOpenRPA.Robot import OrchestratorConnector
from pyOpenRPA.Robot import Utils
class MyTestCase(unittest.TestCase):
def test_something(self):
#self.assertEqual(True, False)
mGlobal={"Storage":{"R01_OrchestratorToRobot":{"Test":"Test2"}}}
# t=OrchestratorConnector.IntervalDataSendAsync(
# Interval=1,
# RobotStorage=mGlobal["Storage"],
# RobotStorageKey="R01_OrchestratorToRobot",
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
# t=OrchestratorConnector.DataSendSync(
# RobotValue="Test",
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
import time
#def Func(lT,inl):
# print(lT)
# return True
#lTimer= Utils.TimerRepeat.TimerRepeat(1, Func, ["dddd"],{"inl":9})
#lTimer.start()
OrchestratorConnector.ConfigurationInit({
"IntervalDataSendResetAsync": [
{
"Interval": 2,
"RobotStorage": mGlobal["Storage"],
"RobotStorageKey": "R01_OrchestratorToRobot",
"RobotResetValue": {"Test": "Test"},
"OrchestratorKeyList": ["Storage", "R01_OrchestratorToRobot"],
"OrchestratorProtocol": "http",
"OrchestratorHost": "localhost",
"OrchestratorPort": 8081,
"OrchestratorAuthToken": "1992-04-03-0643-ru-b4ff-openrpa52zzz"
}
]
})
while True:
print(mGlobal["Storage"]["R01_OrchestratorToRobot"])
# t = OrchestratorConnector.DataSendResetAsync(
# RobotStorage=mGlobal["Storage"],
# RobotStorageKey="R01_OrchestratorToRobot",
# RobotResetValue={"Test": "Test"},
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
time.sleep(0.5)
if __name__ == '__main__':
unittest.main()

@ -1,45 +1,19 @@
from pywinauto import win32defines, win32structures, win32functions from pywinauto import win32defines, win32structures, win32functions
import pdb
import pywinauto import pywinauto
import json
import sys
import ctypes import ctypes
import struct import struct
import os
import select
import zlib
import win32api import win32api
import win32clipboard
import time import time
import traceback from .Utils import ProcessCommunicator
from . import ProcessCommunicator
from . import JSONNormalize
from . import Utils #For ProcessBitness from . import Utils #For ProcessBitness
from threading import Timer
import datetime
import logging
import re import re
import copy import copy
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
os.makedirs("Reports")
##########################
#Подготовка логгера Robot
#########################
mRobotLogger=logging.getLogger("RobotLogger")
mRobotLogger.setLevel(logging.INFO)
# create the logging file handler
mRobotLoggerFH = logging.FileHandler("Reports\ReportRobotGUIRun_"+datetime.datetime.now().strftime("%Y_%m_%d")+".log")
mRobotLoggerFormatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
mRobotLoggerFH.setFormatter(mRobotLoggerFormatter)
# add handler to logger object
mRobotLogger.addHandler(mRobotLoggerFH)
############################################ ############################################
#When import UIDesktop init the other bitness python # When import UIDesktop init the other bitness python
#For this type UIDesktop.Utils.ProcessBitness.SettingsInit(inSettingsDict) # For this type
#inSettingsDict = { # UIDesktop.Utils.ProcessBitness.SettingsInit(inSettingsDict)
# inSettingsDict = {
# "Python32FullPath": None, #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe" # "Python32FullPath": None, #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe"
# "Python64FullPath": None, #Set from user # "Python64FullPath": None, #Set from user
# "Python32ProcessName": "OpenRPAUIDesktopX32.exe", #Config set once # "Python32ProcessName": "OpenRPAUIDesktopX32.exe", #Config set once

@ -1,10 +1,9 @@
import json import json
import subprocess
import zlib import zlib
import sys import sys
import os
from . import JSONNormalize from . import JSONNormalize
import pdb
############################################ ############################################
####Межпроцессное взаимодействие ####Межпроцессное взаимодействие
############################################ ############################################
@ -41,7 +40,6 @@ def ProcessParentWriteString(lString):
#Вернуть \f #Вернуть \f
lByteString = lByteString.replace(b'\f',b'{{{f}}}') lByteString = lByteString.replace(b'\f',b'{{{f}}}')
############################ ############################
#print(b"Result: "+lByteString)
#lByteString= b'x\x9c\xdd\x95]O\xc20\x14\x86\xffJ\xb3[5\xa1Cqz\x07\xc4\xe8\x8d\x1fQ\x13.\x0cYJw\xb6U\xbav\xe9\xce"\x84\xf0\xdfm\'"\xb8\xa0L%Q\xb3\x9b\xf6=\xdfO\x9a\xb3\x99\x17\x97\x8a\xa3\xd0\xea\x8ae\xe0\x9d\x12\xaf[\xa2\xce\x98S\xee\x80\x19\x9e^\xea\xb2\x803\t\x19(\xbc\x10`\x9c6\xf5\xf6\x89\xc7LRt\x8daS\x1b\xf5\xf00\xf3\xd4"\xc1u\x0e\xea\xf6\xa6K\x0e\xc8\xb9\xd6\x89\x04\xd2O\x8d\xb6&\x1bb\x04OC\x84\t~\xe2\x97\x1b\xcd\xa1(B\x11YG\xdaj\xfb\xc1\x9b\xb8\xa2\xa4LE\xd2\xd5\xa4\xf6\xdenY\x85Kf\xc3^;yI\x18\x0eD\x94\x00\x0e\x84{{n}}\xa9K\xce\xb5B\xa3e\x88\xd3\xbc\xf2Z\xd5\xaa\x82\xaa\x94\xd25\x0b\x1c\x99J\xaa\x023OB\xec\xbavEP\xe7\x8b\x93\x11I\xeaTz\xe2\xbb\xebH\xa3eW5\xe8\xb7\xe6\xce^*\x14\xb6\x83e\xda\xf9phe]b^\xe2\xf5\xe8\xd1Vp\xf0\xfe.\xbb\x1b\xa6`\x87\xfc8\x1a\x9bSE0q\xa2\x15\xeer\xe0"\x16\xbcz\x9f\xfdT\xc8h\x9d\xdf\xc7\xd4\xbe\xcdj1\xd9:\xa9\x1f\xe1B7\x81\xa1\xef\xc0\xd0:\x98\xc3-\xc0\xd4X\xfc\xda\xf1i\xbb\xe9\xfc\xdb<\x8c\xff2\x7f\'\xa8\x8d\xdf\xdab\xfc\x9e\xd6\xe3\x8c\x99qQ\xe3\xb0f\xd9\x19\x90{\xade\x8f\x99/3\xa1AC(\xfe\x16P\x06F \x90\xb3\t\x07Iba\x17\x83P\xa4\xbf\xb7G\x9e\x04\xa6vE\x13\xb6\xfc\x13\xd6\xa85\x0b\xdd\x19\xd6^i\x11\xa8FT;G\xfe\x06\xac\xc1q\xb0N\x956\xd84\xae\xe4p\xbe\xfa=\x03\x01\xce\x95\x9a' #lByteString= b'x\x9c\xdd\x95]O\xc20\x14\x86\xffJ\xb3[5\xa1Cqz\x07\xc4\xe8\x8d\x1fQ\x13.\x0cYJw\xb6U\xbav\xe9\xce"\x84\xf0\xdfm\'"\xb8\xa0L%Q\xb3\x9b\xf6=\xdfO\x9a\xb3\x99\x17\x97\x8a\xa3\xd0\xea\x8ae\xe0\x9d\x12\xaf[\xa2\xce\x98S\xee\x80\x19\x9e^\xea\xb2\x803\t\x19(\xbc\x10`\x9c6\xf5\xf6\x89\xc7LRt\x8daS\x1b\xf5\xf00\xf3\xd4"\xc1u\x0e\xea\xf6\xa6K\x0e\xc8\xb9\xd6\x89\x04\xd2O\x8d\xb6&\x1bb\x04OC\x84\t~\xe2\x97\x1b\xcd\xa1(B\x11YG\xdaj\xfb\xc1\x9b\xb8\xa2\xa4LE\xd2\xd5\xa4\xf6\xdenY\x85Kf\xc3^;yI\x18\x0eD\x94\x00\x0e\x84{{n}}\xa9K\xce\xb5B\xa3e\x88\xd3\xbc\xf2Z\xd5\xaa\x82\xaa\x94\xd25\x0b\x1c\x99J\xaa\x023OB\xec\xbavEP\xe7\x8b\x93\x11I\xeaTz\xe2\xbb\xebH\xa3eW5\xe8\xb7\xe6\xce^*\x14\xb6\x83e\xda\xf9phe]b^\xe2\xf5\xe8\xd1Vp\xf0\xfe.\xbb\x1b\xa6`\x87\xfc8\x1a\x9bSE0q\xa2\x15\xeer\xe0"\x16\xbcz\x9f\xfdT\xc8h\x9d\xdf\xc7\xd4\xbe\xcdj1\xd9:\xa9\x1f\xe1B7\x81\xa1\xef\xc0\xd0:\x98\xc3-\xc0\xd4X\xfc\xda\xf1i\xbb\xe9\xfc\xdb<\x8c\xff2\x7f\'\xa8\x8d\xdf\xdab\xfc\x9e\xd6\xe3\x8c\x99qQ\xe3\xb0f\xd9\x19\x90{\xade\x8f\x99/3\xa1AC(\xfe\x16P\x06F \x90\xb3\t\x07Iba\x17\x83P\xa4\xbf\xb7G\x9e\x04\xa6vE\x13\xb6\xfc\x13\xd6\xa85\x0b\xdd\x19\xd6^i\x11\xa8FT;G\xfe\x06\xac\xc1q\xb0N\x956\xd84\xae\xe4p\xbe\xfa=\x03\x01\xce\x95\x9a'
#lByteString = b"x\x9c\xb5\x91\xcfO\xc3 \x14\xc7\xff\x95\xa6\xd7uI\xf9Q\x8a\xde\xd4\x93\x07\xbdx\xf00\x97\x05)[I(\x90\x8ef3\xcb\xfew\x81M\xbb\xd9M]\x8c!y\xd0\xf7}\xbc\xef\xe3\xd3\xc9&\xd5\xac\x11\xe9u\x92j\xb1J@2N\x1e\x8d\x13\x96U\xa3Q\x9a%i+y=sb\xed\xceV\xd8\xd6p\xb1\\\xced\xe5K{{n}}\x80`\x9f\xeb\x135\xd3\x95{{n}}.\x08RR\xe4>\xc3\x15\xf3\x97>\xbc\x8f:r\xa3]k\xd4\xcc\xbd\xd9(>K]\x99\xd5\xa1\x12\xbd\x00\xc6\xb0\xcc\xcb0\xa4\xe0\x8e\xe9E4\xd8\xa4J\xcc\xc3\xb44\x07^r\xc6\xfa3\x04(\xbeeQ\x07\x05P\x1a\xa4W\xe3\x9ci\xfc\xf7\x15(\xb6A\xee\xb4\x93\x8d\xd85\x9f`?\xf6n\xd8i0v\xadw\xd5\x95X\x87n>\xf1d\x05\x97s\xc9\x99\x93F\xdf\xd5R\xc5K=\xcc\x1bk\xd5^\x1d`\xfc\xa2]\x06PwJ\r\xf0\x9d\xa2\xf6 tw\xcb\xda\x01\xb6}\x83\xd3\xcc\x00\xec\x99\x15\xf4\x88Y\x99\x1f2\x83\xb4\xfc\x8e\x99\xdf\xb3d\x0c\x01.1E\x04\x93l\xff\x8e\xcf\x7f6\xa4Z\xfc\x82\xeaK\x97c BD\xf3\x101\x89g\xba\x8b\x03\xd0?\x97\xff#\xfb{'\x9a\x8b\xe0\x03H\xc89\xfa\x08\x15\x7f\xa2\x0f >\x80_\x0e\xe0\x93\xb3\xf0\xc3\xc4\xd3m\\\xef\xf8\x958\xa0" #lByteString = b"x\x9c\xb5\x91\xcfO\xc3 \x14\xc7\xff\x95\xa6\xd7uI\xf9Q\x8a\xde\xd4\x93\x07\xbdx\xf00\x97\x05)[I(\x90\x8ef3\xcb\xfew\x81M\xbb\xd9M]\x8c!y\xd0\xf7}\xbc\xef\xe3\xd3\xc9&\xd5\xac\x11\xe9u\x92j\xb1J@2N\x1e\x8d\x13\x96U\xa3Q\x9a%i+y=sb\xed\xceV\xd8\xd6p\xb1\\\xced\xe5K{{n}}\x80`\x9f\xeb\x135\xd3\x95{{n}}.\x08RR\xe4>\xc3\x15\xf3\x97>\xbc\x8f:r\xa3]k\xd4\xcc\xbd\xd9(>K]\x99\xd5\xa1\x12\xbd\x00\xc6\xb0\xcc\xcb0\xa4\xe0\x8e\xe9E4\xd8\xa4J\xcc\xc3\xb44\x07^r\xc6\xfa3\x04(\xbeeQ\x07\x05P\x1a\xa4W\xe3\x9ci\xfc\xf7\x15(\xb6A\xee\xb4\x93\x8d\xd85\x9f`?\xf6n\xd8i0v\xadw\xd5\x95X\x87n>\xf1d\x05\x97s\xc9\x99\x93F\xdf\xd5R\xc5K=\xcc\x1bk\xd5^\x1d`\xfc\xa2]\x06PwJ\r\xf0\x9d\xa2\xf6 tw\xcb\xda\x01\xb6}\x83\xd3\xcc\x00\xec\x99\x15\xf4\x88Y\x99\x1f2\x83\xb4\xfc\x8e\x99\xdf\xb3d\x0c\x01.1E\x04\x93l\xff\x8e\xcf\x7f6\xa4Z\xfc\x82\xeaK\x97c BD\xf3\x101\x89g\xba\x8b\x03\xd0?\x97\xff#\xfb{'\x9a\x8b\xe0\x03H\xc89\xfa\x08\x15\x7f\xa2\x0f >\x80_\x0e\xe0\x93\xb3\xf0\xc3\xc4\xd3m\\\xef\xf8\x958\xa0"
#lt=open("logSendByteStringWithoutN.log","wb") #lt=open("logSendByteStringWithoutN.log","wb")
@ -71,7 +69,6 @@ def ProcessChildSendString(lProcess,lString):
lByteString = lByteString.replace(b'\n',b'{{n}}') lByteString = lByteString.replace(b'\n',b'{{n}}')
#Отправить сообщение в дочерний процесс #Отправить сообщение в дочерний процесс
lProcess.stdin.write(lByteString+bytes('\n',"utf-8")) lProcess.stdin.write(lByteString+bytes('\n',"utf-8"))
#print(str(lByteString+bytes('\n',"utf-8")))
lProcess.stdin.flush() lProcess.stdin.flush()
#Вернуть результат #Вернуть результат
return return
@ -82,7 +79,6 @@ def ProcessChildReadWaitString(lProcess):
#pdb.set_trace() #pdb.set_trace()
lResult = lProcess.stdout.readline() lResult = lProcess.stdout.readline()
#Обработка спец символов #Обработка спец символов
#print(b'NewLine: '+lResult)
#Вернуть потенциальные \n #Вернуть потенциальные \n
lResult = lResult.replace(b'{{{n}}}',b'\n') lResult = lResult.replace(b'{{{n}}}',b'\n')
#Вернуть \r #Вернуть \r
@ -99,8 +95,6 @@ def ProcessChildReadWaitString(lProcess):
lResult = lResult.replace(b'{{{v}}}',b'\v') lResult = lResult.replace(b'{{{v}}}',b'\v')
#Вернуть \f #Вернуть \f
lResult = lResult.replace(b'{{{f}}}',b'\f') lResult = lResult.replace(b'{{{f}}}',b'\f')
#print("check")
#print(str(lResult))
try: try:
lResult = zlib.decompress(lResult[0:-1]) lResult = zlib.decompress(lResult[0:-1])
lResult = lResult.decode("utf-8") lResult = lResult.decode("utf-8")

@ -0,0 +1,28 @@
from threading import Timer
import datetime
# lTimer = RepeatedTimer(3, def, [], {}) # it auto-starts, no need of rt.start()
# if def return None = timer stops
# lTimer.start()
class TimerRepeat(object):
def __init__(self, interval, function, args, kwargs):
self._timer = None
self.interval = interval
self.function = function
self.args = args
self.kwargs = kwargs
self.is_running = False
self.start()
def _run(self):
self.is_running = False
lResult = self.function(*self.args, **self.kwargs)
if lResult is not None:
if lResult:
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

@ -4,10 +4,9 @@ The OpenRPA package (from UnicodeLabs)
""" """
__all__ = [ __all__ = [
'UIDesktop', 'Clipboard', 'IntegrationOrchestrator', 'Window', 'ProcessCommunicator' 'Clipboard', 'OrchestratorConnector.py', 'Window'
] ]
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>' __author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'
#from . import UIDesktop #from . import UIDesktop
from . import Clipboard from . import Clipboard
from . import Window from . import Window
from . import ProcessCommunicator

@ -8,8 +8,8 @@ lFolderPath = "\\".join(__file__.split("\\")[:-2])
sys.path.append(lFolderPath) sys.path.append(lFolderPath)
################################ ################################
import traceback import traceback
from Robot import ProcessCommunicator from Robot.Utils import ProcessCommunicator
from Robot import JSONNormalize from Robot.Utils import JSONNormalize
from Robot import UIDesktop from Robot import UIDesktop
########################################## ##########################################
#Run UIDesktop from new process. Communication with paren process by PIPE channel #Run UIDesktop from new process. Communication with paren process by PIPE channel
@ -19,22 +19,22 @@ buffer = ""
lJSONInputString = "" lJSONInputString = ""
while True: while True:
#Reset the lProcessResponse #Reset the lProcessResponse
lProcessResponse={"ErrorFlag":False} lProcessResponse = {"ErrorFlag": False}
try: try:
#Ожидаем синхронно поступление объекта #Ожидаем синхронно поступление объекта
lJSONInput = ProcessCommunicator.ProcessParentReadWaitObject() lJSONInput = ProcessCommunicator.ProcessParentReadWaitObject()
lProcessResponse["ActivitySpecificationDict"]=lJSONInput lProcessResponse["ActivitySpecificationDict"] = lJSONInput
#Выполнить вызов функции #Выполнить вызов функции
lFunction = getattr(UIDesktop,lJSONInput['ActivityName']) lFunction = getattr(UIDesktop, lJSONInput['ActivityName'])
lProcessResponse["Result"]=JSONNormalize.JSONNormalizeDictListStrIntBool(lFunction(*lJSONInput['ArgumentList'],**lJSONInput['ArgumentDict'])) lProcessResponse["Result"] = JSONNormalize.JSONNormalizeDictListStrIntBool(lFunction(*lJSONInput['ArgumentList'], **lJSONInput['ArgumentDict']))
except Exception as e: except Exception as e:
lProcessResponse["Result"] = None lProcessResponse["Result"] = None
#Установить флаг ошибки #Установить флаг ошибки
lProcessResponse["ErrorFlag"]=True lProcessResponse["ErrorFlag"] = True
#Зафиксировать traceback #Зафиксировать traceback
lProcessResponse["ErrorTraceback"]=traceback.format_exc() lProcessResponse["ErrorTraceback"] = traceback.format_exc()
#Зафиксировать Error message #Зафиксировать Error message
lProcessResponse["ErrorMessage"]=str(e) lProcessResponse["ErrorMessage"] = str(e)
#lProcessResponse["ErrorArgs"]=str(e.args) #lProcessResponse["ErrorArgs"]=str(e.args)
#Отправить ответ в родительский процесс #Отправить ответ в родительский процесс
ProcessCommunicator.ProcessParentWriteObject(lProcessResponse) ProcessCommunicator.ProcessParentWriteObject(lProcessResponse)

@ -40,7 +40,6 @@ def ProcessParentWriteString(lString):
#Вернуть \f #Вернуть \f
lByteString = lByteString.replace(b'\f',b'{{{f}}}') lByteString = lByteString.replace(b'\f',b'{{{f}}}')
############################ ############################
#print(b"Result: "+lByteString)
#lByteString= b'x\x9c\xdd\x95]O\xc20\x14\x86\xffJ\xb3[5\xa1Cqz\x07\xc4\xe8\x8d\x1fQ\x13.\x0cYJw\xb6U\xbav\xe9\xce"\x84\xf0\xdfm\'"\xb8\xa0L%Q\xb3\x9b\xf6=\xdfO\x9a\xb3\x99\x17\x97\x8a\xa3\xd0\xea\x8ae\xe0\x9d\x12\xaf[\xa2\xce\x98S\xee\x80\x19\x9e^\xea\xb2\x803\t\x19(\xbc\x10`\x9c6\xf5\xf6\x89\xc7LRt\x8daS\x1b\xf5\xf00\xf3\xd4"\xc1u\x0e\xea\xf6\xa6K\x0e\xc8\xb9\xd6\x89\x04\xd2O\x8d\xb6&\x1bb\x04OC\x84\t~\xe2\x97\x1b\xcd\xa1(B\x11YG\xdaj\xfb\xc1\x9b\xb8\xa2\xa4LE\xd2\xd5\xa4\xf6\xdenY\x85Kf\xc3^;yI\x18\x0eD\x94\x00\x0e\x84{{n}}\xa9K\xce\xb5B\xa3e\x88\xd3\xbc\xf2Z\xd5\xaa\x82\xaa\x94\xd25\x0b\x1c\x99J\xaa\x023OB\xec\xbavEP\xe7\x8b\x93\x11I\xeaTz\xe2\xbb\xebH\xa3eW5\xe8\xb7\xe6\xce^*\x14\xb6\x83e\xda\xf9phe]b^\xe2\xf5\xe8\xd1Vp\xf0\xfe.\xbb\x1b\xa6`\x87\xfc8\x1a\x9bSE0q\xa2\x15\xeer\xe0"\x16\xbcz\x9f\xfdT\xc8h\x9d\xdf\xc7\xd4\xbe\xcdj1\xd9:\xa9\x1f\xe1B7\x81\xa1\xef\xc0\xd0:\x98\xc3-\xc0\xd4X\xfc\xda\xf1i\xbb\xe9\xfc\xdb<\x8c\xff2\x7f\'\xa8\x8d\xdf\xdab\xfc\x9e\xd6\xe3\x8c\x99qQ\xe3\xb0f\xd9\x19\x90{\xade\x8f\x99/3\xa1AC(\xfe\x16P\x06F \x90\xb3\t\x07Iba\x17\x83P\xa4\xbf\xb7G\x9e\x04\xa6vE\x13\xb6\xfc\x13\xd6\xa85\x0b\xdd\x19\xd6^i\x11\xa8FT;G\xfe\x06\xac\xc1q\xb0N\x956\xd84\xae\xe4p\xbe\xfa=\x03\x01\xce\x95\x9a' #lByteString= b'x\x9c\xdd\x95]O\xc20\x14\x86\xffJ\xb3[5\xa1Cqz\x07\xc4\xe8\x8d\x1fQ\x13.\x0cYJw\xb6U\xbav\xe9\xce"\x84\xf0\xdfm\'"\xb8\xa0L%Q\xb3\x9b\xf6=\xdfO\x9a\xb3\x99\x17\x97\x8a\xa3\xd0\xea\x8ae\xe0\x9d\x12\xaf[\xa2\xce\x98S\xee\x80\x19\x9e^\xea\xb2\x803\t\x19(\xbc\x10`\x9c6\xf5\xf6\x89\xc7LRt\x8daS\x1b\xf5\xf00\xf3\xd4"\xc1u\x0e\xea\xf6\xa6K\x0e\xc8\xb9\xd6\x89\x04\xd2O\x8d\xb6&\x1bb\x04OC\x84\t~\xe2\x97\x1b\xcd\xa1(B\x11YG\xdaj\xfb\xc1\x9b\xb8\xa2\xa4LE\xd2\xd5\xa4\xf6\xdenY\x85Kf\xc3^;yI\x18\x0eD\x94\x00\x0e\x84{{n}}\xa9K\xce\xb5B\xa3e\x88\xd3\xbc\xf2Z\xd5\xaa\x82\xaa\x94\xd25\x0b\x1c\x99J\xaa\x023OB\xec\xbavEP\xe7\x8b\x93\x11I\xeaTz\xe2\xbb\xebH\xa3eW5\xe8\xb7\xe6\xce^*\x14\xb6\x83e\xda\xf9phe]b^\xe2\xf5\xe8\xd1Vp\xf0\xfe.\xbb\x1b\xa6`\x87\xfc8\x1a\x9bSE0q\xa2\x15\xeer\xe0"\x16\xbcz\x9f\xfdT\xc8h\x9d\xdf\xc7\xd4\xbe\xcdj1\xd9:\xa9\x1f\xe1B7\x81\xa1\xef\xc0\xd0:\x98\xc3-\xc0\xd4X\xfc\xda\xf1i\xbb\xe9\xfc\xdb<\x8c\xff2\x7f\'\xa8\x8d\xdf\xdab\xfc\x9e\xd6\xe3\x8c\x99qQ\xe3\xb0f\xd9\x19\x90{\xade\x8f\x99/3\xa1AC(\xfe\x16P\x06F \x90\xb3\t\x07Iba\x17\x83P\xa4\xbf\xb7G\x9e\x04\xa6vE\x13\xb6\xfc\x13\xd6\xa85\x0b\xdd\x19\xd6^i\x11\xa8FT;G\xfe\x06\xac\xc1q\xb0N\x956\xd84\xae\xe4p\xbe\xfa=\x03\x01\xce\x95\x9a'
#lByteString = b"x\x9c\xb5\x91\xcfO\xc3 \x14\xc7\xff\x95\xa6\xd7uI\xf9Q\x8a\xde\xd4\x93\x07\xbdx\xf00\x97\x05)[I(\x90\x8ef3\xcb\xfew\x81M\xbb\xd9M]\x8c!y\xd0\xf7}\xbc\xef\xe3\xd3\xc9&\xd5\xac\x11\xe9u\x92j\xb1J@2N\x1e\x8d\x13\x96U\xa3Q\x9a%i+y=sb\xed\xceV\xd8\xd6p\xb1\\\xced\xe5K{{n}}\x80`\x9f\xeb\x135\xd3\x95{{n}}.\x08RR\xe4>\xc3\x15\xf3\x97>\xbc\x8f:r\xa3]k\xd4\xcc\xbd\xd9(>K]\x99\xd5\xa1\x12\xbd\x00\xc6\xb0\xcc\xcb0\xa4\xe0\x8e\xe9E4\xd8\xa4J\xcc\xc3\xb44\x07^r\xc6\xfa3\x04(\xbeeQ\x07\x05P\x1a\xa4W\xe3\x9ci\xfc\xf7\x15(\xb6A\xee\xb4\x93\x8d\xd85\x9f`?\xf6n\xd8i0v\xadw\xd5\x95X\x87n>\xf1d\x05\x97s\xc9\x99\x93F\xdf\xd5R\xc5K=\xcc\x1bk\xd5^\x1d`\xfc\xa2]\x06PwJ\r\xf0\x9d\xa2\xf6 tw\xcb\xda\x01\xb6}\x83\xd3\xcc\x00\xec\x99\x15\xf4\x88Y\x99\x1f2\x83\xb4\xfc\x8e\x99\xdf\xb3d\x0c\x01.1E\x04\x93l\xff\x8e\xcf\x7f6\xa4Z\xfc\x82\xeaK\x97c BD\xf3\x101\x89g\xba\x8b\x03\xd0?\x97\xff#\xfb{'\x9a\x8b\xe0\x03H\xc89\xfa\x08\x15\x7f\xa2\x0f >\x80_\x0e\xe0\x93\xb3\xf0\xc3\xc4\xd3m\\\xef\xf8\x958\xa0" #lByteString = b"x\x9c\xb5\x91\xcfO\xc3 \x14\xc7\xff\x95\xa6\xd7uI\xf9Q\x8a\xde\xd4\x93\x07\xbdx\xf00\x97\x05)[I(\x90\x8ef3\xcb\xfew\x81M\xbb\xd9M]\x8c!y\xd0\xf7}\xbc\xef\xe3\xd3\xc9&\xd5\xac\x11\xe9u\x92j\xb1J@2N\x1e\x8d\x13\x96U\xa3Q\x9a%i+y=sb\xed\xceV\xd8\xd6p\xb1\\\xced\xe5K{{n}}\x80`\x9f\xeb\x135\xd3\x95{{n}}.\x08RR\xe4>\xc3\x15\xf3\x97>\xbc\x8f:r\xa3]k\xd4\xcc\xbd\xd9(>K]\x99\xd5\xa1\x12\xbd\x00\xc6\xb0\xcc\xcb0\xa4\xe0\x8e\xe9E4\xd8\xa4J\xcc\xc3\xb44\x07^r\xc6\xfa3\x04(\xbeeQ\x07\x05P\x1a\xa4W\xe3\x9ci\xfc\xf7\x15(\xb6A\xee\xb4\x93\x8d\xd85\x9f`?\xf6n\xd8i0v\xadw\xd5\x95X\x87n>\xf1d\x05\x97s\xc9\x99\x93F\xdf\xd5R\xc5K=\xcc\x1bk\xd5^\x1d`\xfc\xa2]\x06PwJ\r\xf0\x9d\xa2\xf6 tw\xcb\xda\x01\xb6}\x83\xd3\xcc\x00\xec\x99\x15\xf4\x88Y\x99\x1f2\x83\xb4\xfc\x8e\x99\xdf\xb3d\x0c\x01.1E\x04\x93l\xff\x8e\xcf\x7f6\xa4Z\xfc\x82\xeaK\x97c BD\xf3\x101\x89g\xba\x8b\x03\xd0?\x97\xff#\xfb{'\x9a\x8b\xe0\x03H\xc89\xfa\x08\x15\x7f\xa2\x0f >\x80_\x0e\xe0\x93\xb3\xf0\xc3\xc4\xd3m\\\xef\xf8\x958\xa0"
#lt=open("logSendByteStringWithoutN.log","wb") #lt=open("logSendByteStringWithoutN.log","wb")
@ -70,7 +69,6 @@ def ProcessChildSendString(lProcess,lString):
lByteString = lByteString.replace(b'\n',b'{{n}}') lByteString = lByteString.replace(b'\n',b'{{n}}')
#Отправить сообщение в дочерний процесс #Отправить сообщение в дочерний процесс
lProcess.stdin.write(lByteString+bytes('\n',"utf-8")) lProcess.stdin.write(lByteString+bytes('\n',"utf-8"))
#print(str(lByteString+bytes('\n',"utf-8")))
lProcess.stdin.flush() lProcess.stdin.flush()
#Вернуть результат #Вернуть результат
return return
@ -80,7 +78,6 @@ def ProcessChildReadWaitString(lProcess):
#Ожидаем ответ от процесса #Ожидаем ответ от процесса
lResult = lProcess.stdout.readline() lResult = lProcess.stdout.readline()
#Обработка спец символов #Обработка спец символов
#print(b'NewLine: '+lResult)
#Вернуть потенциальные \n #Вернуть потенциальные \n
lResult = lResult.replace(b'{{{n}}}',b'\n') lResult = lResult.replace(b'{{{n}}}',b'\n')
#Вернуть \r #Вернуть \r
@ -97,8 +94,6 @@ def ProcessChildReadWaitString(lProcess):
lResult = lResult.replace(b'{{{v}}}',b'\v') lResult = lResult.replace(b'{{{v}}}',b'\v')
#Вернуть \f #Вернуть \f
lResult = lResult.replace(b'{{{f}}}',b'\f') lResult = lResult.replace(b'{{{f}}}',b'\f')
#print("check")
#print(str(lResult))
lResult = zlib.decompress(lResult[0:-1]) lResult = zlib.decompress(lResult[0:-1])
lResult = lResult.decode("utf-8") lResult = lResult.decode("utf-8")
#Вернуть результат #Вернуть результат

@ -0,0 +1,108 @@
import pdb
import json
import subprocess
import zlib
import os
from . import ProcessCommunicator
import importlib
import traceback
import logging
import sys
import datetime
import struct
import shutil
from pyOpenRPA.Robot import UIDesktop
global mGlobalDict
####################################
#Info: Main module of the Robot app (OpenRPA - Robot)
####################################
#Usage:
#Here you can run some activity or list of activities
#After import this module you can use the folowing functions:
#ActivityRun(inActivitySpecificationDict): outActivityResultDict - function - run activity (function or procedure)
#ActivityRunJSON(inActivitySpecificationDictJSON): outActivityResultDictJSON
#ActivityListRun(inActivitySpecificationDictList): outActivityResultDictList - function - run list of activities (function or procedure)
#ActivityListRunJSON(inActivitySpecificationDictListJSON): outActivityResultDictListJSON
#Naming:
#Activity - some action/list of actions
#Module - Any *.py file, which consist of area specific functions
#Argument
#inActivitySpecificationDict:
#{
# ModuleName: <"GUI"|..., str>,
# ActivityName: <Function or procedure name in module, str>,
# ArgumentList: [<Argument 1, any type>, ...] - optional,
# ArgumentDict: {<Argument 1 name, str>:<Argument 1 value, any type>, ...} - optional
#}
#outActivityResultDict:
#{
# ActivitySpecificationDict: {
# ModuleName: <"GUI"|..., str>,
# ActivityName: <Function or procedure name in module, str>,
# ArgumentList: [<Argument 1, any type>, ...] - optional,
# ArgumentDict: {<Argument 1 name, str>: <Argument 1 value, any type>, ...} - optional
# },
# ErrorFlag: <Boolean flag - Activity result has error (true) or not (false), boolean>,
# ErrorMessage: <Error message, str> - required if ErrorFlag is true,
# ErrorTraceback: <Error traceback log, str> - required if ErrorFlag is true,
# Result: <Result, returned from the Activity, int, str, boolean, list, dict> - required if ErrorFlag is false
#}
####################
#Section: Activity
####################
def ActivityRun(inActivitySpecificationDict):
lResponseObject = {}
#Выполнить отправку в модуль UIDesktop, если ModuleName == "UIDesktop"
if inActivitySpecificationDict["ModuleName"] == "UIDesktop":
if "ArgumentList" not in inActivitySpecificationDict:
inActivitySpecificationDict["ArgumentList"]=[]
if "ArgumentDict" not in inActivitySpecificationDict:
inActivitySpecificationDict["ArgumentDict"]={}
#Run the activity
try:
#Найти функцию
lFunction=getattr(UIDesktop,inActivitySpecificationDict["ActivityName"])
#Выполнить вызов и записать результат
lResponseObject["Result"]=lFunction(*inActivitySpecificationDict["ArgumentList"],**inActivitySpecificationDict["ArgumentDict"])
except Exception as e:
#Установить флаг ошибки и передать тело ошибки
lResponseObject["ErrorFlag"]=True
lResponseObject["ErrorMessage"]=str(e)
lResponseObject["ErrorTraceback"]=traceback.format_exc()
#Остальные модули подключать и выполнять здесь
else:
lArgumentList=[]
if "ArgumentList" in inActivitySpecificationDict:
lArgumentList=inActivitySpecificationDict["ArgumentList"]
lArgumentDict={}
if "ArgumentDict" in inActivitySpecificationDict:
lArgumentDict=inActivitySpecificationDict["ArgumentDict"]
#Подготовить результирующую структуру
lResponseObject={"ActivitySpecificationDict":inActivitySpecificationDict,"ErrorFlag":False}
try:
#Подключить модуль для вызова
lModule=importlib.import_module(inActivitySpecificationDict["ModuleName"])
#Найти функцию
lFunction=getattr(lModule,inActivitySpecificationDict["ActivityName"])
#Выполнить вызов и записать результат
lResponseObject["Result"]=lFunction(*lArgumentList,**lArgumentDict)
except Exception as e:
#Установить флаг ошибки и передать тело ошибки
lResponseObject["ErrorFlag"]=True
lResponseObject["ErrorMessage"]=str(e)
lResponseObject["ErrorTraceback"]=traceback.format_exc()
return lResponseObject
#########################################################
#Run list of activities
#########################################################
def ActivityListRun(inActivitySpecificationDictList):
lResult=[]
for lItem in inActivitySpecificationDictList:
lResult.append(ActivityRun(lItem))
return lResult

@ -5,12 +5,30 @@ import json
import subprocess import subprocess
import zlib import zlib
import os import os
from . import ProcessCommunicator
import sys import sys
import traceback import traceback
from pyOpenRPA.Robot import Robot from . import RobotConnector
import importlib
#Единый глобальный словарь (За основу взять из Settings.py)
global mGlobalDict
#Call Settings function from argv[1] file
################################################
lSubmoduleFunctionName = "Settings"
lFileFullPath = sys.argv[1]
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
if lSubmoduleFunctionName in dir(lTechModuleFromSpec):
# Run SettingUpdate function in submodule
mGlobalDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)()
#################################################
RobotConnector.mGlobalDict = mGlobalDict
#Init the robot
RobotConnector.UIDesktop.Utils.ProcessBitness.SettingsInit(mGlobalDict["ProcessBitness"])
# HTTPRequestHandler class # HTTP Studio web server class
class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
#ResponseContentTypeFile #ResponseContentTypeFile
def SendResponseContentTypeFile(self,inContentType,inFilePath): def SendResponseContentTypeFile(self,inContentType,inFilePath):
@ -82,7 +100,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
#pdb.set_trace() #pdb.set_trace()
lRequestObject=lInputObject lRequestObject=lInputObject
#Отправить команду роботу #Отправить команду роботу
lResponseObject=Robot.ActivityRun(lRequestObject) lResponseObject=RobotConnector.ActivityRun(lRequestObject)
message = json.dumps(lResponseObject) message = json.dumps(lResponseObject)
except Exception as e: except Exception as e:
#Установить флаг ошибки #Установить флаг ошибки
@ -113,7 +131,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
lRequestObject=lInputObject lRequestObject=lInputObject
lOutputObject=[] lOutputObject=[]
#pdb.set_trace() #pdb.set_trace()
lResponseObject=Robot.ActivityListRun(lRequestObject) lResponseObject=RobotConnector.ActivityListRun(lRequestObject)
#Сформировать текстовый ответ #Сформировать текстовый ответ
message = json.dumps(lResponseObject) message = json.dumps(lResponseObject)
# Write content as utf-8 data # Write content as utf-8 data
@ -121,14 +139,15 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
return return
def run(): def run():
print('starting server...') inServerAddress = "";
inPort = mGlobalDict["Server"]["ListenPort"];
# Server settings # Server settings
# Choose port 8080, for port 80, which is normally used for a http server, you need root access # Choose port 8080, for port 80, which is normally used for a http server, you need root access
server_address = ('127.0.0.1', 8081) server_address = (inServerAddress, inPort)
httpd = HTTPServer(server_address, testHTTPServer_RequestHandler) httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
print('running server...') # Logging
#Запуск адреса в браузере mGlobalDict["Logger"].info(f"Server init. Listen URL: {inServerAddress}, Listen port: {inPort}")
os.system("explorer http://127.0.0.1:8081") # Запуск адреса в браузере
os.system(f"explorer http://127.0.0.1:{str(inPort)}")
httpd.serve_forever() httpd.serve_forever()
#print(ChildProcessReadWaitString(p))
run() run()

@ -9,6 +9,115 @@
crossorigin="anonymous"></script> crossorigin="anonymous"></script>
<script src="3rdParty/Semantic-UI-CSS-master/semantic.min.js"></script> <script src="3rdParty/Semantic-UI-CSS-master/semantic.min.js"></script>
<script> <script>
// Production steps of ECMA-262, Edition 6, 22.1.2.1
if (!Array.from) {
Array.from = (function () {
var toStr = Object.prototype.toString;
var isCallable = function (fn) {
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
};
var toInteger = function (value) {
var number = Number(value);
if (isNaN(number)) { return 0; }
if (number === 0 || !isFinite(number)) { return number; }
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
};
var maxSafeInteger = Math.pow(2, 53) - 1;
var toLength = function (value) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
};
// The length property of the from method is 1.
return function from(arrayLike/*, mapFn, thisArg */) {
// 1. Let C be the this value.
var C = this;
// 2. Let items be ToObject(arrayLike).
var items = Object(arrayLike);
// 3. ReturnIfAbrupt(items).
if (arrayLike == null) {
throw new TypeError('Array.from requires an array-like object - not null or undefined');
}
// 4. If mapfn is undefined, then let mapping be false.
var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
var T;
if (typeof mapFn !== 'undefined') {
// 5. else
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
if (!isCallable(mapFn)) {
throw new TypeError('Array.from: when provided, the second argument must be a function');
}
// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (arguments.length > 2) {
T = arguments[2];
}
}
// 10. Let lenValue be Get(items, "length").
// 11. Let len be ToLength(lenValue).
var len = toLength(items.length);
// 13. If IsConstructor(C) is true, then
// 13. a. Let A be the result of calling the [[Construct]] internal method
// of C with an argument list containing the single item len.
// 14. a. Else, Let A be ArrayCreate(len).
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
// 16. Let k be 0.
var k = 0;
// 17. Repeat, while k < len (also steps a - h)
var kValue;
while (k < len) {
kValue = items[k];
if (mapFn) {
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
} else {
A[k] = kValue;
}
k += 1;
}
// 18. Let putStatus be Put(A, "length", len, true).
A.length = len;
// 20. Return A.
return A;
};
}());
}
if (!Object.assign) {
Object.defineProperty(Object, 'assign', {
enumerable: false,
configurable: true,
writable: true,
value: function(target, firstSource) {
'use strict';
if (target === undefined || target === null) {
throw new TypeError('Cannot convert first argument to object');
}
var to = Object(target);
for (var i = 1; i < arguments.length; i++) {
var nextSource = arguments[i];
if (nextSource === undefined || nextSource === null) {
continue;
}
var keysArray = Object.keys(Object(nextSource));
for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
var nextKey = keysArray[nextIndex];
var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
if (desc !== undefined && desc.enumerable) {
to[nextKey] = nextSource[nextKey];
}
}
}
return to;
}
});
}
var mGlobal={} var mGlobal={}
$(document) $(document)
.ready(function() { .ready(function() {
@ -17,11 +126,8 @@
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
mGlobal.Settings={} mGlobal.Settings={}
mGlobal.Settings.mUIOTreeHeight=450 mGlobal.Settings.mUIOTreeHeight=450
mGlobal.GUIElement={} mGlobal.GUIElement={}
mGlobal.GenerateUniqueID=function(inPrefix="ID") { mGlobal.GenerateUniqueID=function(inPrefix) {
return inPrefix+Math.round(Math.random()*1000)+"-"+Math.round(Math.random()*10000)+"-"+Math.round(Math.random()*1000) return inPrefix+Math.round(Math.random()*1000)+"-"+Math.round(Math.random()*10000)+"-"+Math.round(Math.random()*1000)
} }
///Инициализация ///Инициализация
@ -158,7 +264,7 @@
} }
///Функция визуализации дерева ///Функция визуализации дерева
mGlobal.ElementTree.fRender = function(inElementsTreeDataArray,inBackendString="-") mGlobal.ElementTree.fRender = function(inElementsTreeDataArray,inBackendString)
{ {
var lHTMLList= var lHTMLList=
'<b style="font-size:10px;" >Backend: '+inBackendString+'</b>\ '<b style="font-size:10px;" >Backend: '+inBackendString+'</b>\
@ -166,7 +272,7 @@
///Циклический обход списка ///Циклический обход списка
for (var i = 0; i< inElementsTreeDataArray.length;i++) { for (var i = 0; i< inElementsTreeDataArray.length;i++) {
///Добавить HTML код позиции ///Добавить HTML код позиции
lHTMLList+=mGlobal.ElementTree.fItemGenerateHTML_JS(inElementsTreeDataArray[i]) lHTMLList+=mGlobal.ElementTree.fItemGenerateHTML_JS(inElementsTreeDataArray[i],[])
} }
///Закрывающая список HTML ///Закрывающая список HTML
lHTMLList+="</div>" lHTMLList+="</div>"
@ -176,9 +282,9 @@
} }
///Функция визуализации дерева ///Функция визуализации дерева
///Вызов создания вложенного листа, если имеется атрибут SpecificationChild ///Вызов создания вложенного листа, если имеется атрибут SpecificationChild
mGlobal.ElementTree.fItemGenerateHTML_JS = function(inItem,inParentSpecification=[]){ mGlobal.ElementTree.fItemGenerateHTML_JS = function(inItem,inParentSpecification){
///Генерация уникального кода для элемента ///Генерация уникального кода для элемента
var lElementId = mGlobal.GenerateUniqueID() var lElementId = mGlobal.GenerateUniqueID("ID")
//Добавить информацию об элементе в словарь JS //Добавить информацию об элементе в словарь JS
///Урезанная часть селектора (сделать, чтобы была без SpecificationChild) ///Урезанная часть селектора (сделать, чтобы была без SpecificationChild)
var lSelectorLocal={}; var lSelectorLocal={};
@ -245,7 +351,7 @@
var lHTMLTree='<div class="ui list">' var lHTMLTree='<div class="ui list">'
var lResponseJSON=JSON.parse(lData) var lResponseJSON=JSON.parse(lData)
for (i=0;i<lResponseJSON.Result.length;i++) { for (i=0;i<lResponseJSON.Result.length;i++) {
var lElementId = mGlobal.GenerateUniqueID() var lElementId = mGlobal.GenerateUniqueID("ID")
var lSubItemHandleId=lResponseJSON.Result[i].handle; var lSubItemHandleId=lResponseJSON.Result[i].handle;
var lSubItemActionOnClick=' onclick="mGlobal.TreeLoadSubTree(\''+lElementId+'\');" ' var lSubItemActionOnClick=' onclick="mGlobal.TreeLoadSubTree(\''+lElementId+'\');" '
var lSubItemActionOnRightClick=' onclick="mGlobal.ElementHighlightNew(\''+lElementId+'\');" ' var lSubItemActionOnRightClick=' onclick="mGlobal.ElementHighlightNew(\''+lElementId+'\');" '
@ -293,7 +399,7 @@
var lSpecificationArrayNew=[] var lSpecificationArrayNew=[]
for (i=0;i<lSpecificationArray.length;i++) { for (i=0;i<lSpecificationArray.length;i++) {
lSpecificationArrayNew.push(lSpecificationArray[i]) lSpecificationArrayNew.push(lSpecificationArray[i])
var lElementId = mGlobal.GenerateUniqueID() var lElementId = mGlobal.GenerateUniqueID("ID")
var lOnClickSelect= ' onclick="mGlobal.ElementPropertyListLoad(\''+lElementId+'\');" ' var lOnClickSelect= ' onclick="mGlobal.ElementPropertyListLoad(\''+lElementId+'\');" '
lHTMLList+='\ lHTMLList+='\
<div class="item" id="'+lElementId+'" '+lOnClickSelect+'>\ <div class="item" id="'+lElementId+'" '+lOnClickSelect+'>\
@ -679,7 +785,7 @@
///Очистить дерево ///Очистить дерево
mGlobal.ElementTree.fClear(); mGlobal.ElementTree.fClear();
///Прогрузить новое дерево ///Прогрузить новое дерево
mGlobal.ElementTree.fRender(lResponseJSON.Result,$(".openrpa-value-backend")[0].value); mGlobal.ElementTree.fRender(lResponseJSON.Result,$(".openrpa-value-backend")[0].value,"-");
///Показать ошибку, если таковая возникла ///Показать ошибку, если таковая возникла
if (lResponseJSON["ErrorFlag"]) { if (lResponseJSON["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lResponseJSON.ErrorMessage+" \nTraceback: "+lResponseJSON.ErrorTraceback); mGlobal.ShowModal("GUI Error",lResponseJSON.ErrorMessage+" \nTraceback: "+lResponseJSON.ErrorTraceback);

@ -78,12 +78,15 @@ def SessionRDPStart(inRDPFilePath):
[ [
[{"title": "Подключение к удаленному рабочему столу", "class_name": "#32770", "backend": "win32"}, [{"title": "Подключение к удаленному рабочему столу", "class_name": "#32770", "backend": "win32"},
{"title": "Боль&ше не выводить запрос о подключениях к этому компьютеру", "friendly_class_name": "CheckBox"}], {"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} — .*", [{"title_re": f"{lRDPFileName} — .*",
"class_name": "TscShellContainerClass", "backend": "win32"}] "class_name": "TscShellContainerClass", "backend": "win32"}]
], ],
60 30
) )
#Click if 0 is appear #Click if 0 is appear (RUS)
if 0 in lWaitResult: if 0 in lWaitResult:
#Check the box do not retry #Check the box do not retry
UIDesktop.UIOSelector_Get_UIO([{"title": "Подключение к удаленному рабочему столу", "backend": "win32"}, UIDesktop.UIOSelector_Get_UIO([{"title": "Подключение к удаленному рабочему столу", "backend": "win32"},
@ -96,7 +99,23 @@ def SessionRDPStart(inRDPFilePath):
[{"title_re": f"{lRDPFileName} — .*", [{"title_re": f"{lRDPFileName} — .*",
"class_name": "TscShellContainerClass", "backend": "win32"}] "class_name": "TscShellContainerClass", "backend": "win32"}]
], ],
60 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
) )
#Prepare little window #Prepare little window
SessionScreen100x550(lRDPFileName) SessionScreen100x550(lRDPFileName)

@ -1,17 +1,34 @@
from pyOpenRPA.Robot import UIDesktop from pyOpenRPA.Robot import UIDesktop
from . import Connector from . import Connector
import os
import pdb import pdb
#Check for session is closed. Reopen if detected. Always keep session is active #Check for session is closed. Reopen if detected. Always keep session is active
def Monitor(inGlobalDict, inListUpdateTimeout): def Monitor(inGlobalDict, inListUpdateTimeout):
while True: lFlagWhile = True
while lFlagWhile:
# UIOSelector list init # UIOSelector list init
lUIOSelectorList = [] lUIOSelectorList = []
for lItem in inGlobalDict["RDPList"]: for lItem in inGlobalDict["RDPList"]:
lUIOSelectorList.append([{"title_re": f"{lItem['SessionHex']} — .*", "backend": "win32"}]) lUIOSelectorList.append([{"title_re": f"{lItem['SessionHex']} — .*", "backend": "win32"}])
#Run wait command #Run wait command
lRDPDissappearList = UIDesktop.UIOSelectorsSecs_WaitDisappear_List(lUIOSelectorList, inListUpdateTimeout) lRDPDissappearList = UIDesktop.UIOSelectorsSecs_WaitDisappear_List(lUIOSelectorList, inListUpdateTimeout)
#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["FlagSessionIsActive"]=False
#Kill all RDP sessions
os.system('taskkill /F /im mstsc.exe')
#Return from function
return
for lItem in lRDPDissappearList: for lItem in lRDPDissappearList:
inGlobalDict["RDPList"][lItem]["FlagSessionIsActive"] = False # Set flag that session is disconnected
#pdb.set_trace() #pdb.set_trace()
#Session start #Session start
try:
Connector.Session(inGlobalDict["RDPList"][lItem]) Connector.Session(inGlobalDict["RDPList"][lItem])
except Exception:
pass
return None return None
#TODO Def garbage window cleaner (if connection was lost)

@ -1,22 +0,0 @@
#Robot RDPActive settings
def Settings():
mDict = {
"RDPList":
[
{
"Host": "77.77.22.22", # Host address
"Port": "7777", # RDP Port
"Login": "test", # Login
"Password": "test", # Password
"Screen": {
"Width": 1680, #Width of the remote desktop in pixels
"Height": 1050, #Height of the remote desktop in pixels
# "640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen
"FlagUseAllMonitors": False, # True or False
"DepthBit": "32" # "32" or "24" or "16" or "15"
},
"SessionHex":"" # Hex is created when robot runs
}
]
}
return mDict

@ -35,9 +35,15 @@ lCMDString = 'reg add "HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server C
os.system(lCMDString) os.system(lCMDString)
#time.sleep() #time.sleep()
for lConfigurationItem in mGlobalDict["RDPList"]: for lConfigurationItem in mGlobalDict["RDPList"]:
try:
Connector.Session(lConfigurationItem) Connector.Session(lConfigurationItem)
lConfigurationItem["FlagSessionIsActive"]=True #Flag that session is started
except Exception:
pass
#Run monitor #Run monitor
Monitor.Monitor(mGlobalDict, 1) Monitor.Monitor(mGlobalDict, 1)
#Enable certificate warning #Enable certificate warning
lCMDString = 'reg add "HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client" /v "AuthenticationLevelOverride" /t "REG_DWORD" /d 2 /f' lCMDString = 'reg add "HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client" /v "AuthenticationLevelOverride" /t "REG_DWORD" /d 2 /f'
os.system(lCMDString) os.system(lCMDString)
#Close all thread from OrchestratorConnection
mGlobalDict["OrchestratorConnectorTerminateAll"]()

@ -3,7 +3,7 @@ r"""
The OpenRPA package (from UnicodeLabs) The OpenRPA package (from UnicodeLabs)
""" """
__version__ = 'v1.0.32' __version__ = 'v1.0.34'
__all__ = [] __all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>' __author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'
#from .Core import Robot #from .Core import Robot

@ -1,6 +1,6 @@
Metadata-Version: 2.1 Metadata-Version: 2.1
Name: pyOpenRPA Name: pyOpenRPA
Version: 1.0.32 Version: 1.0.34
Summary: First open source RPA platform for business Summary: First open source RPA platform for business
Home-page: https://gitlab.com/UnicodeLabs/OpenRPA Home-page: https://gitlab.com/UnicodeLabs/OpenRPA
Author: Ivan Maslov Author: Ivan Maslov

@ -1,14 +1,14 @@
pyOpenRPA-1.0.32.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 pyOpenRPA-1.0.34.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.0.32.dist-info/METADATA,sha256=hwB02rO7bJ84-CJNqzZfm4jVgnNbuBkKuAr8SsRwZq0,3510 pyOpenRPA-1.0.34.dist-info/METADATA,sha256=WakfkUg30wJGLxsmqvPERvkd2agMGOzXa84qcPG5f5Q,3510
pyOpenRPA-1.0.32.dist-info/RECORD,, pyOpenRPA-1.0.34.dist-info/RECORD,,
pyOpenRPA-1.0.32.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 pyOpenRPA-1.0.34.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.0.32.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 pyOpenRPA-1.0.34.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA/Orchestrator/Orchestrator.py,sha256=iM-DZ7TU7o51pzIJYEkNIlVG_GzzaVUESi7Tu0Ppw8g,6717 pyOpenRPA/Orchestrator/Orchestrator.py,sha256=UKp7eqvWDM91kYLwl2mo0UB8Pw-qu8eJCsR9NEXD1aU,6436
pyOpenRPA/Orchestrator/Processor.py,sha256=GHXwC1B2py4mAtk9oZa-FVSJhx3no9oD2bvkj20uhNA,9051 pyOpenRPA/Orchestrator/Processor.py,sha256=HQQyOVX-d5vPO-YULyTxVOtXtUMfvpAaSVO4xXxaKVI,9107
pyOpenRPA/Orchestrator/Server.py,sha256=TgKkqgMivzvh4cM4zpbDUdv9AXbUiPPy9uLjR1lTiJU,20229 pyOpenRPA/Orchestrator/Server.py,sha256=5tjhfU0QVEfg4zjT2jWOuOADWeHXMBxX2Fe8lj1bnCA,20839
pyOpenRPA/Orchestrator/ServerSettings.py,sha256=ZrNEt_UoHYGOeAKN5X5jQHz-XNl1lBW47ttKUF8_cmM,4948 pyOpenRPA/Orchestrator/ServerSettings.py,sha256=jOXJTLwg8cJx6D-rN8J4dn5RCb2nepAhCH4F9hYVUdM,4912
pyOpenRPA/Orchestrator/Timer.py,sha256=FQZ3y6G9d47Ybx7RewzePKQV77H4gCkx5SaeFVlsuhc,2095 pyOpenRPA/Orchestrator/Timer.py,sha256=FQZ3y6G9d47Ybx7RewzePKQV77H4gCkx5SaeFVlsuhc,2095
pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=wWDxguk0q4ylePllPzZvTdaOzlpolqYiBXIGp_a5udI,31744 pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=7wwEJ8lEI_2AElITUk9yyX91Sq6pNccqPsuAVlm7enQ,32322
pyOpenRPA/Orchestrator/Web/favicon.ico,sha256=jO3pjFWbmJEPQ2KroXSKYtXIesBq46PCBlKSouewODU,5430 pyOpenRPA/Orchestrator/Web/favicon.ico,sha256=jO3pjFWbmJEPQ2KroXSKYtXIesBq46PCBlKSouewODU,5430
pyOpenRPA/Orchestrator/__init__.py,sha256=qVH8fEPgXk54rmy-ol0PnT8GF5OlGE0a8mExwJ4tFqY,124 pyOpenRPA/Orchestrator/__init__.py,sha256=qVH8fEPgXk54rmy-ol0PnT8GF5OlGE0a8mExwJ4tFqY,124
pyOpenRPA/Orchestrator/__main__.py,sha256=cOd8WU77VGgzTZUB0WmWpPmdYyMZY1zVyuU9yx26MKs,144 pyOpenRPA/Orchestrator/__main__.py,sha256=cOd8WU77VGgzTZUB0WmWpPmdYyMZY1zVyuU9yx26MKs,144
@ -192,52 +192,56 @@ 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/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/Resources/Web/jQuery/jquery-3.1.1.min.js,sha256=HPMOWdIdSuVgr3FD9ZE-_MgiK8qk_MdQjrgCtfqp6U4,86713
pyOpenRPA/Robot/Clipboard.py,sha256=q76X8L21zJwcwdoJJNPeCEwAV30xS6ylHP1WwvtxoWI,722 pyOpenRPA/Robot/Clipboard.py,sha256=q76X8L21zJwcwdoJJNPeCEwAV30xS6ylHP1WwvtxoWI,722
pyOpenRPA/Robot/IntegrationOrchestrator.py,sha256=T1g1jJM7_JMTSVP50DTM5WHrMh1w8wovvcBXl1nEokU,2656 pyOpenRPA/Robot/OrchestratorConnector.py,sha256=Fihxz-jH9M4VakXEE0SZ0Vo9tLEQk8Tcg_C4HoH45gI,20037
pyOpenRPA/Robot/JSONNormalize.py,sha256=aIuVzuZDazhxkCOzoOjfhHVz66mp2FWdfPv5E7KWF5Y,3890 pyOpenRPA/Robot/SettingsTemplate.py,sha256=Rp5XPeV2I4tCS2uf4Zkqm_ERJ6pZMg4-e5_lMqGJYLk,1453
pyOpenRPA/Robot/ProcessCommunicator.py,sha256=Mpo2WoCrEUmY6aCSbQEXkT4qVKtN1N5NcVvG_UZxGVo,8245 pyOpenRPA/Robot/Test.py,sha256=qXr990nXiFZX5SNv6QN9GLb_U4HZRmJnbZR2qSnwilY,2878
pyOpenRPA/Robot/Robot.py,sha256=AVR8jzO-e_ZkW5DrLY_W9ta0eHSul997Y3U6uNVU8WE,9442 pyOpenRPA/Robot/UIDesktop.py,sha256=MWdWr0dZpk1PL1rsD91q6_8v687CSDBx1_T7IuHd3-E,77473
pyOpenRPA/Robot/UIDesktop.py,sha256=ehqMQmKLbkwW6iqA9bkw9tvDRni5QriLkG9P3AP_TMs,78377 pyOpenRPA/Robot/Utils/JSONNormalize.py,sha256=aIuVzuZDazhxkCOzoOjfhHVz66mp2FWdfPv5E7KWF5Y,3890
pyOpenRPA/Robot/Utils/ProcessBitness.py,sha256=WlKL-DklGaoTnchtapOTM_ydxSB4yOeo9lcG3zr2VME,4524 pyOpenRPA/Robot/Utils/ProcessBitness.py,sha256=WlKL-DklGaoTnchtapOTM_ydxSB4yOeo9lcG3zr2VME,4524
pyOpenRPA/Robot/Utils/ProcessCommunicator.py,sha256=8GfmLnOvAdosmt7YNT86uEV9cjhKippssCX62wOMJwM,8039
pyOpenRPA/Robot/Utils/TimerRepeat.py,sha256=_kTct3X9SIEvS3DKM5bGNnjRBVJasmMFZntQaVbPX_E,961
pyOpenRPA/Robot/Utils/ValueVerify.py,sha256=ObskxU4fOMoCGw74_nzYt6-a5jjrAckb3sdBLYyhYxY,777
pyOpenRPA/Robot/Utils/__init__.py,sha256=pHlSQGRFKmn5RCTHIf-3a2ooA9T2xNOWridckynP7W4,28 pyOpenRPA/Robot/Utils/__init__.py,sha256=pHlSQGRFKmn5RCTHIf-3a2ooA9T2xNOWridckynP7W4,28
pyOpenRPA/Robot/Utils/__pycache__/JSONNormalize.cpython-37.pyc,,
pyOpenRPA/Robot/Utils/__pycache__/ProcessBitness.cpython-37.pyc,, pyOpenRPA/Robot/Utils/__pycache__/ProcessBitness.cpython-37.pyc,,
pyOpenRPA/Robot/Utils/__pycache__/ProcessCommunicator.cpython-37.pyc,,
pyOpenRPA/Robot/Utils/__pycache__/TimerRepeat.cpython-37.pyc,,
pyOpenRPA/Robot/Utils/__pycache__/ValueVerify.cpython-37.pyc,,
pyOpenRPA/Robot/Utils/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Robot/Utils/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Robot/ValueVerify.py,sha256=ObskxU4fOMoCGw74_nzYt6-a5jjrAckb3sdBLYyhYxY,777
pyOpenRPA/Robot/Window.py,sha256=UJl-sg4RvvJ35aG9jZOzqGVwE15XK7qPHqoOBD13xFk,431 pyOpenRPA/Robot/Window.py,sha256=UJl-sg4RvvJ35aG9jZOzqGVwE15XK7qPHqoOBD13xFk,431
pyOpenRPA/Robot/__init__.py,sha256=iEW3SGBJf3kYa1zocGH5vEK0woejzJpnQfOmQtIA3P0,324 pyOpenRPA/Robot/__init__.py,sha256=L-5tPm6evytGWOzlqIq-2oiIhmQnruaxwIstyyaMkVI,253
pyOpenRPA/Robot/__main__.py,sha256=NlwxAG68mwoWNB4YIX15Fc2gWlL1RQ5HN8i1NyjGFdo,1965 pyOpenRPA/Robot/__main__.py,sha256=l6II8JuXCsnVOcfs6-2jvogKYTVhbfj3Jl2ld3OIP7s,1992
pyOpenRPA/Robot/__pycache__/Clipboard.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/Clipboard.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/IntegrationOrchestrator.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/OrchestratorConnector.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/JSONNormalize.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/SettingsTemplate.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/ProcessCommunicator.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/Test.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/Robot.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/UIDesktop.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/UIDesktop.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/ValueVerify.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/Window.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/Window.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Robot/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Robot/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Studio/JSONNormalize.py,sha256=g0Z8G2wojCgTAdZtyRiCfe0_FHSeAi72Va7R7mk27gg,3347 pyOpenRPA/Studio/JSONNormalize.py,sha256=g0Z8G2wojCgTAdZtyRiCfe0_FHSeAi72Va7R7mk27gg,3347
pyOpenRPA/Studio/ProcessCommunicator.py,sha256=5hXDMa4ONBgeJBoDIfDCAW9MoiRO8cq-DdfqQSAysgk,8080 pyOpenRPA/Studio/ProcessCommunicator.py,sha256=HD3XASJae31_HV3OznFe8E2MgZFXnwt7YveVN82M8nU,7912
pyOpenRPA/Studio/Studio.py,sha256=7X46k0l33sgQoG6sxFFJmI5G0KKxgDggvEnzux8aonw,7014 pyOpenRPA/Studio/RobotConnector.py,sha256=tQVC8X0k1HMHAAwAtkhtmeNA0cLMY3wuO-RCbgshdMk,5036
pyOpenRPA/Studio/Studio.py,sha256=wiVGWZZx-yC8jp-Wjz-B5GC1cqTcftDulZfYe-4hU8w,8125
pyOpenRPA/Studio/ValueVerify.py,sha256=ObskxU4fOMoCGw74_nzYt6-a5jjrAckb3sdBLYyhYxY,777 pyOpenRPA/Studio/ValueVerify.py,sha256=ObskxU4fOMoCGw74_nzYt6-a5jjrAckb3sdBLYyhYxY,777
pyOpenRPA/Studio/Web/Index.xhtml,sha256=74z3eWlmB6Yedbp91xgGtDjymUSlBcduAQ09ZxQ67f8,44241 pyOpenRPA/Studio/Web/Index.xhtml,sha256=RqFW3qC1pFRr-qWEEDlCEhL9l3PwANyRbll3KZJnLvo,47927
pyOpenRPA/Studio/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430 pyOpenRPA/Studio/Web/favicon.ico,sha256=0vdsnwKGh6pgB0FDB5mOKO7RwbxQ9F13Zg16F1pkvXs,5430
pyOpenRPA/Studio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pyOpenRPA/Studio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Studio/__main__.py,sha256=_57Rnq9DKbmmlpGFqIwVrWn_LRcU8jjmMTOny4_zlP8,308 pyOpenRPA/Studio/__main__.py,sha256=_57Rnq9DKbmmlpGFqIwVrWn_LRcU8jjmMTOny4_zlP8,308
pyOpenRPA/Studio/__pycache__/JSONNormalize.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/JSONNormalize.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/ProcessCommunicator.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/ProcessCommunicator.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/RobotConnector.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/Studio.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/Studio.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/ValueVerify.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/ValueVerify.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Studio/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Studio/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/Connector.py,sha256=vpXFO1irhLTHgIwWn5PCsTq-6E3Sx3sYOweIBNyiYEw,6164 pyOpenRPA/Tools/RobotRDPActive/Connector.py,sha256=9Y9zA92Zw9QF6dadW53NLekV_1r2STISFn5RzI08GDo,7272
pyOpenRPA/Tools/RobotRDPActive/Monitor.py,sha256=INkiX4Gi4KjvWRoe4jWV_NJGKgjDId6zEyqBHpegUxw,760 pyOpenRPA/Tools/RobotRDPActive/Monitor.py,sha256=X8ZhJFdDnA88OHlgRuinPvhZ_eS4R7y0xRchbo7LPCc,1525
pyOpenRPA/Tools/RobotRDPActive/SettingsExample.py,sha256=5eEhjk7NDXf9Q4yvkeRICE7x9npiMkazuMITQX24Ooc,857
pyOpenRPA/Tools/RobotRDPActive/Template.rdp,sha256=qPCLkjzTdYKURK7nRApkPUjRuS4K20vDPj9DIUNSSkE,2392 pyOpenRPA/Tools/RobotRDPActive/Template.rdp,sha256=qPCLkjzTdYKURK7nRApkPUjRuS4K20vDPj9DIUNSSkE,2392
pyOpenRPA/Tools/RobotRDPActive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pyOpenRPA/Tools/RobotRDPActive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/RobotRDPActive/__main__.py,sha256=qC_LyXI2MjJkidTRpV3abyyPO0qASGTvNkeAkfnA7J0,2108 pyOpenRPA/Tools/RobotRDPActive/__main__.py,sha256=mVk8zVqcBrzAwwn7tbZPXFWTQbWUkgU6w89nbY6GN-8,2340
pyOpenRPA/Tools/RobotRDPActive/__pycache__/Connector.cpython-37.pyc,, pyOpenRPA/Tools/RobotRDPActive/__pycache__/Connector.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/__pycache__/Monitor.cpython-37.pyc,, pyOpenRPA/Tools/RobotRDPActive/__pycache__/Monitor.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/__pycache__/SettingsExample.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Tools/RobotRDPActive/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotRDPActive/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Tools/RobotRDPActive/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotScreenActive/ConsoleStart.bat,sha256=_HNadUKHOYI5y6foG3srh8wjSzhX33xaKNylFtDjOJk,114 pyOpenRPA/Tools/RobotScreenActive/ConsoleStart.bat,sha256=_HNadUKHOYI5y6foG3srh8wjSzhX33xaKNylFtDjOJk,114
@ -251,5 +255,5 @@ pyOpenRPA/Tools/RobotScreenActive/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Tools/RobotScreenActive/__pycache__/__main__.cpython-37.pyc,, pyOpenRPA/Tools/RobotScreenActive/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/__init__.py,sha256=mqY50pRbV4Tk-vj2-Z2CiY8u2qSB0HRfKNcduM36Zdo,175 pyOpenRPA/__init__.py,sha256=6g2t0dHUhbsJm87H07rs_6y5XDub0C_nWd2B-w-0XGg,175
pyOpenRPA/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/__pycache__/__init__.cpython-37.pyc,,

@ -15,11 +15,6 @@ import copy
#from .Settings import Settings #from .Settings import Settings
import importlib import importlib
from importlib import util from importlib import util
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
os.makedirs("Reports")
logging.basicConfig(filename="Reports\ReportRun_"+datetime.datetime.now().strftime("%Y_%m_%d__%H_%M_%S")+".log", level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
#Единый глобальный словарь (За основу взять из Settings.py) #Единый глобальный словарь (За основу взять из Settings.py)
global mGlobalDict global mGlobalDict
@ -51,6 +46,8 @@ lDaemonStartDateTime=datetime.datetime.now()
#Инициализация сервера #Инициализация сервера
lThreadServer = Server.RobotDaemonServer("ServerThread", mGlobalDict) lThreadServer = Server.RobotDaemonServer("ServerThread", mGlobalDict)
lThreadServer.start() lThreadServer.start()
#Logging
mGlobalDict["Logger"].info("Scheduler loop init")
#Вечный цикл #Вечный цикл
while True: while True:
lCurrentDateTime = datetime.datetime.now() lCurrentDateTime = datetime.datetime.now()

@ -97,35 +97,38 @@ def Activity(inActivity):
#Обработка команды OrchestratorRestart #Обработка команды OrchestratorRestart
########################################################### ###########################################################
if lItem["Type"]=="OrchestratorRestart": if lItem["Type"]=="OrchestratorRestart":
os.execl(sys.executable,os.path.abspath(__file__),*sys.argv) os.execl(sys.executable, os.path.abspath(__file__), *sys.argv)
lItem["Result"] = True lItem["Result"] = True
sys.exit(0) sys.exit(0)
########################################################### ###########################################################
#Обработка команды GlobalDictKeyListValueSet #Обработка команды GlobalDictKeyListValueSet
########################################################### ###########################################################
if lItem["Type"]=="GlobalDictKeyListValueSet": if lItem["Type"]=="GlobalDictKeyListValueSet":
lDict = mGlobalDict
for lItem2 in lItem["KeyList"][:-1]: for lItem2 in lItem["KeyList"][:-1]:
#Check if key - value exists #Check if key - value exists
if lItem2 in mGlobalDict: if lItem2 in lDict:
pass pass
else: else:
mGlobalDict[lItem2]={} lDict[lItem2]={}
mGlobalDict=mGlobalDict[lItem2] lDict=lDict[lItem2]
#Set value #Set value
mGlobalDict[lItem["KeyList"][-1]]=lItem["value"] lDict[lItem["KeyList"][-1]]=lItem["Value"]
lItem["Result"] = True
########################################################### ###########################################################
#Обработка команды GlobalDictKeyListValueGet #Обработка команды GlobalDictKeyListValueGet
########################################################### ###########################################################
if lItem["Type"]=="GlobalDictKeyListValueGet": if lItem["Type"]=="GlobalDictKeyListValueGet":
lDict = mGlobalDict
for lItem2 in lItem["KeyList"][:-1]: for lItem2 in lItem["KeyList"][:-1]:
#Check if key - value exists #Check if key - value exists
if lItem2 in mGlobalDict: if lItem2 in lDict:
pass pass
else: else:
mGlobalDict[lItem2]={} lDict[lItem2]={}
mGlobalDict=mGlobalDict[lItem2] lDict=lDict[lItem2]
#Return value #Return value
lItem["Result"]==mGlobalDict.get(lItem["KeyList"][-1],None) lItem["Result"]=lDict.get(lItem["KeyList"][-1],None)
#Определить вид активности #Определить вид активности
lActivityDateTime=inActivity["DateTimeUTCStringStart"] lActivityDateTime=inActivity["DateTimeUTCStringStart"]
##################################### #####################################
@ -193,6 +196,7 @@ def Activity(inActivity):
################## ##################
#Trace activity #Trace activity
################## ##################
#print(mGlobalDict)
if mGlobalDict["Processor"].get(f"LogType_{lItem['Type']}",True): if mGlobalDict["Processor"].get(f"LogType_{lItem['Type']}",True):
#Add activity in TransactionList if it is applicable #Add activity in TransactionList if it is applicable
mGlobalDict["Processor"]["LogList"].append(copy.deepcopy(lItem)) mGlobalDict["Processor"]["LogList"].append(copy.deepcopy(lItem))

@ -22,12 +22,14 @@ class RobotDaemonServer(Thread):
def run(self): def run(self):
inServerAddress=""; inServerAddress="";
inPort = mGlobalDict["Server"]["ListenPort"]; inPort = mGlobalDict["Server"]["ListenPort"];
print('starting server..., port:'+str(inPort)+" inAddress:"+inServerAddress)
# Server settings # Server settings
# Choose port 8080, for port 80, which is normally used for a http server, you need root access # Choose port 8080, for port 80, which is normally used for a http server, you need root access
server_address = (inServerAddress, inPort) server_address = (inServerAddress, inPort)
httpd = HTTPServer(server_address, testHTTPServer_RequestHandler) httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
print('running server...') # Logging
mGlobalDict["Logger"].info(f"Server init. Listen URL: {inServerAddress}, Listen port: {inPort}")
# Запуск адреса в браузере
os.system("explorer http://127.0.0.1:8081")
httpd.serve_forever() httpd.serve_forever()
#Authenticate function () #Authenticate function ()
@ -86,6 +88,7 @@ def AuthenticateVerify(inRequest):
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken] = {} mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken] = {}
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["Domain"] = lResult["Domain"] mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["Domain"] = lResult["Domain"]
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["User"] = lResult["User"] mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["User"] = lResult["User"]
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["FlagDoNotExpire"] = False
mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["TokenDatetime"] = datetime.datetime.now() mGlobalDict["Server"]["AccessUsers"]["AuthTokensDict"][lAuthToken]["TokenDatetime"] = datetime.datetime.now()
#Set-cookie #Set-cookie
inRequest.OpenRPA["AuthToken"] = lAuthToken inRequest.OpenRPA["AuthToken"] = lAuthToken
@ -110,6 +113,7 @@ def AuthenticateBlock(inRequest):
#return bool True - go execute, False - dont execute #return bool True - go execute, False - dont execute
def UserAccessCheckBefore(inMethod, inRequest): def UserAccessCheckBefore(inMethod, inRequest):
# Help def - Get access flag from dict # Help def - Get access flag from dict
#pdb.set_trace()
def HelpGetFlag(inAccessRuleItem, inRequest, inGlobalDict, inAuthenticateDict): def HelpGetFlag(inAccessRuleItem, inRequest, inGlobalDict, inAuthenticateDict):
if "FlagAccess" in inAccessRuleItem: if "FlagAccess" in inAccessRuleItem:
return inAccessRuleItem["FlagAccess"] return inAccessRuleItem["FlagAccess"]
@ -288,7 +292,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
self.wfile.write(inResponseDict["Body"]) self.wfile.write(inResponseDict["Body"])
def do_GET(self): def do_GET(self):
# Prepare result dict # Prepare result dict
lResponseDict = {"Headers": {}, "SetCookies":{}, "Body": "", "StatusCode": None} lResponseDict = {"Headers": {}, "SetCookies": {}, "Body": "", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict self.OpenRPAResponseDict = lResponseDict
##################################### #####################################
#Do authentication #Do authentication
@ -300,6 +304,8 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
lAuthenticateDict = AuthenticateVerify(self) lAuthenticateDict = AuthenticateVerify(self)
if not lAuthenticateDict["User"]: if not lAuthenticateDict["User"]:
lFlagAccessUserBlock=True lFlagAccessUserBlock=True
# Logging
mGlobalDict["Logger"].info(f"HTTP request /. Domain: {lAuthenticateDict['Domain']}, User: {lAuthenticateDict['User']}")
if lFlagAccessUserBlock: if lFlagAccessUserBlock:
AuthenticateBlock(self) AuthenticateBlock(self)
##################################### #####################################
@ -321,7 +327,6 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
lFlagURLIsApplied=False lFlagURLIsApplied=False
lFlagURLIsApplied=self.URLItemCheckDo(lURLItem, "GET") lFlagURLIsApplied=self.URLItemCheckDo(lURLItem, "GET")
if lFlagURLIsApplied: if lFlagURLIsApplied:
#print("New engine")
self.ResponseDictSend() self.ResponseDictSend()
return return
#Monitor #Monitor
@ -350,6 +355,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# POST # POST
def do_POST(self): def do_POST(self):
# Prepare result dict # Prepare result dict
#pdb.set_trace()
lResponseDict = {"Headers": {}, "SetCookies":{}, "Body": "", "StatusCode": None} lResponseDict = {"Headers": {}, "SetCookies":{}, "Body": "", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict self.OpenRPAResponseDict = lResponseDict
##################################### #####################################
@ -371,7 +377,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
lFlagUserAccess = True lFlagUserAccess = True
#If need user authentication #If need user authentication
if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False): if mGlobalDict.get("Server", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False):
lFlagUserAccess = UserAccessCheckBefore("GET", self) lFlagUserAccess = UserAccessCheckBefore("POST", self)
###################################### ######################################
if lFlagUserAccess: if lFlagUserAccess:
#Централизованная функция получения запросов/отправки #Централизованная функция получения запросов/отправки
@ -393,3 +399,10 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# Write content as utf-8 data # Write content as utf-8 data
self.wfile.write(bytes(message, "utf8")) self.wfile.write(bytes(message, "utf8"))
return return
else:
#Set access denied code
# Send response status code
self.send_response(403)
# Send headers
self.end_headers()
return

@ -16,7 +16,6 @@ def Monitor_ControlPanelDictGet(inRequest,inGlobalDict):
# Send message back to client # Send message back to client
message = json.dumps(lResultJSON) message = json.dumps(lResultJSON)
# Write content as utf-8 data # Write content as utf-8 data
#print(bytes(message, "utf8"))
inResponseDict["Body"] = bytes(message, "utf8") inResponseDict["Body"] = bytes(message, "utf8")
def GetScreenshot(inRequest,inGlobalDict): def GetScreenshot(inRequest,inGlobalDict):

@ -275,8 +275,8 @@
}); });
} }
/// ///
mGlobal.Monitor.mControlPanelAutoUpdateSeconds=5; mGlobal.Monitor.mControlPanelAutoUpdateSeconds=3;
mGlobal.Monitor.mControlPanelAutoUpdateSecondsCurrent=5; mGlobal.Monitor.mControlPanelAutoUpdateSecondsCurrent=3;
mGlobal.Monitor.fControlPanelAutoUpdateRun=function(inRefreshSeconds) { mGlobal.Monitor.fControlPanelAutoUpdateRun=function(inRefreshSeconds) {
mGlobal.Monitor.mControlPanelAutoUpdateSeconds=inRefreshSeconds; mGlobal.Monitor.mControlPanelAutoUpdateSeconds=inRefreshSeconds;
//Функция обновления текста кнопки обновления //Функция обновления текста кнопки обновления
@ -291,7 +291,7 @@
mGlobal.Monitor.mControlPanelAutoUpdateTimerId=setInterval(lControlPanelUpdate,1000) mGlobal.Monitor.mControlPanelAutoUpdateTimerId=setInterval(lControlPanelUpdate,1000)
} }
mGlobal.Monitor.fControlPanelRefresh() mGlobal.Monitor.fControlPanelRefresh()
mGlobal.Monitor.fControlPanelAutoUpdateRun(5); mGlobal.Monitor.fControlPanelAutoUpdateRun(3);
mGlobal.Test=function() { mGlobal.Test=function() {
///Обнулить таблицу ///Обнулить таблицу
@ -355,6 +355,29 @@
/////////////////////////////// ///////////////////////////////
mGlobal.Processor = {} mGlobal.Processor = {}
mGlobal.Processor.ServerValueSet = function(inKeyList,inValue) {
lData = [
{
"Type":"GlobalDictKeyListValueSet",
"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.LogListShow = function() { mGlobal.Processor.LogListShow = function() {
lData = [ lData = [
{ {
@ -633,7 +656,7 @@
<div class="ui basic {{Color}} button" onclick="{{OnClick}}">{{{Text}}}</div> <div class="ui basic {{Color}} button" onclick="{{OnClick}}">{{{Text}}}</div>
{{/FooterButtonX2List}} {{/FooterButtonX2List}}
</div> </div>
<div class="ui horizontal divider">Доп. управление</div> <div class="ui horizontal divider">Add. controls</div>
<div class="ui one buttons"> <div class="ui one buttons">
{{#FooterButtonX1List}} {{#FooterButtonX1List}}
<div class="ui basic {{Color}} button" onclick="{{OnClick}}">{{{Text}}}</div> <div class="ui basic {{Color}} button" onclick="{{OnClick}}">{{{Text}}}</div>

@ -1,46 +0,0 @@
import requests
import grequests
#from requests import async
import json
###################################
##Orchestrator integration module (safe use when orchestrator is turned off)
###################################
################################################################################
#Send data to orchestrator (asynchronyous)
#Example: t=IntegrationOrchestrator.DataSend(["Storage","Robot_R01"],{"RunDateTimeString":"Test1","StepCurrentName":"Test2","StepCurrentDuration":"Test333","SafeStopSignal":True},"localhost",8081)
def DataSend(inKeyList,inValue,inOrchestratorHost="localhost",inOrchestratorPort=80):
lURL = f'http://{inOrchestratorHost}:{inOrchestratorPort}/ProcessingRun'
lDataJSON = {"actionList":[{"type":"AdministrationGlobalDictSetKeyListValue","key_list":inKeyList,"value":inValue}]}
#lAsyncList = []
lResultItem = [grequests.post(lURL, json=lDataJSON)]
return grequests.map(lResultItem)
#lAsyncList.append(lResultItem)
#return async.map(lAsyncList)
################################################################################
#recieve Data from orchestrator
#t=IntegrationOrchestrator.DataRecieve(["Storage","Robot_R01"],"localhost",8081)
def DataRecieve(inKeyList,inOrchestratorHost="localhost",inOrchestratorPort=80):
lURL = f'http://{inOrchestratorHost}:{inOrchestratorPort}/ProcessingRun'
lDataJSON = {"actionList":[{"type":"AdministrationGlobalDictGetKeyListValue","key_list":inKeyList}]}
try:
lResult = requests.post(lURL, json=lDataJSON)
lResultJSON = json.loads(lResult.text)
return lResultJSON["actionListResult"][0]["value"]
except Exception:
return None
################################################################################
#Check if orchestrator has safe stop signal
#Example: IntegrationOrchestrator.SafeStopSignalIs(["Storage","Robot_R01","SafeStopSignal"],"localhost",8081)
def SafeStopSignalIs(inKeyList,inOrchestratorHost="localhost",inOrchestratorPort=80):
lResult=False
lResponse=DataRecieve(inKeyList,inOrchestratorHost,inOrchestratorPort)
if lResponse is not None:
lResult = lResponse
return lResult
################################################################################
#Reset SafeStop signal in orchestrator
#Example: t=IntegrationOrchestrator.SafeStopSignalReset(["Storage","Robot_R01","SafeStopSignal"],"localhost",8081)
def SafeStopSignalReset(inKeyList,inOrchestratorHost="localhost",inOrchestratorPort=80):
lResponse=DataSend(inKeyList,False,inOrchestratorHost,inOrchestratorPort)
return lResponse

@ -0,0 +1,401 @@
import requests
#Logging
import os
import logging
import datetime
import copy
from .Utils import TimerRepeat # Timer which can repeating
mLogger=logging.getLogger("OrchestratorConnector")
#########################
mTimerList=[]
def IntervalTerminateAll():
for lItem in mTimerList:
lItem.stop()
#########################
# Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
os.makedirs("Reports")
##########################
# Подготовка логгера Robot
#########################
mLogger.setLevel(logging.INFO)
# create the logging file handler
mLoggerFH = logging.FileHandler("Reports\ReportOrchestratorConnector_" + datetime.datetime.now().strftime("%Y_%m_%d") + ".log")
mLoggerFormatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
mLoggerFH.setFormatter(mLoggerFormatter)
# add handler to logger object
mLogger.addHandler(mLoggerFH)
############################################
#Turn loggin level ERROR
def LoggerSetLevelError():
mLogger.setLevel(logging.ERROR)
#from requests import async
import json
###################################
##Orchestrator integration module (safe use when orchestrator is turned off)
###################################
################################################################################
# Recieve data from orchestrator (synchronyous)
# Example:
# t=IntegrationOrchestrator.DataRecieveAsync(
# RobotStorage=mGlobal["Storage"],
# RobotStorageKey="R01_OrchestratorToRobot",
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
def DataReceiveSync(
OrchestratorKeyList, OrchestratorProtocol="http",
OrchestratorHost="localhost", OrchestratorPort=80, OrchestratorAuthToken=None
):
lCookies = {}
# Set auth token if authorization is needed
if OrchestratorAuthToken:
lCookies["AuthToken"] = OrchestratorAuthToken
lURL = f'{OrchestratorProtocol}://{OrchestratorHost}:{OrchestratorPort}/Utils/Processor'
lDataJSON = [{"Type": "GlobalDictKeyListValueGet", "KeyList": OrchestratorKeyList}]
try:
lResult = requests.post(lURL, json=lDataJSON, cookies=lCookies)
lResultJSON = json.loads(lResult.text)
return (True, lResultJSON[0]["Result"]) # (Flag response is ok, Data)
except Exception:
mLogger.warning(
f"Orchestrator not responding. Def DataRecieveSync, OrchestratorKeyList: {str(OrchestratorKeyList)}, OrchestratorProtocol: {str(OrchestratorProtocol)}, OrchestratorHost: {str(OrchestratorHost)}, OrchestratorPort: {str(OrchestratorPort)}")
return (False, None) # (Flag response is not ok, Data None)
################################################################################
# Recieve data from orchestrator (asynchronyous)
# Example:
# t=IntegrationOrchestrator.DataRecieveAsync(
# RobotStorage=mGlobal["Storage"],
# RobotStorageKey="R01_OrchestratorToRobot",
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
def DataReceiveAsync(
RobotStorage, RobotStorageKey, OrchestratorKeyList, OrchestratorProtocol="http",
OrchestratorHost="localhost", OrchestratorPort=80, OrchestratorAuthToken=None
):
from threading import Thread
import uuid
global mGlobalDict
class ThreadAsync(Thread):
def DataRecieveSync(self):
lCookies = {}
#Set auth token if authorization is needed
if OrchestratorAuthToken:
lCookies["AuthToken"] = OrchestratorAuthToken
lURL = f'{OrchestratorProtocol}://{OrchestratorHost}:{OrchestratorPort}/Utils/Processor'
lDataJSON = [{"Type": "GlobalDictKeyListValueGet", "KeyList": OrchestratorKeyList}]
try:
lResult = requests.post(lURL, json=lDataJSON, cookies = lCookies)
lResultJSON = json.loads(lResult.text)
return (True,lResultJSON[0]["Result"]) #(Flag response is ok, Data)
except Exception:
mLogger.warning(
f"Orchestrator not responding. Def DataRecieveAsync, OrchestratorKeyList: {str(OrchestratorKeyList)}, OrchestratorProtocol: {str(OrchestratorProtocol)}, OrchestratorHost: {str(OrchestratorHost)}, OrchestratorPort: {str(OrchestratorPort)}")
return (False,None) #(Flag response is not ok, Data None)
# Thread init
def __init__(self, name):
Thread.__init__(self)
self.name = name
#Thread start
def run(self):
(lFlagResponseOK,lResponseData) = self.DataRecieveSync()
if lFlagResponseOK:
RobotStorage[RobotStorageKey] = lResponseData
ThreadObject = ThreadAsync(f"ThreadAsync{str(uuid.uuid1())}")
ThreadObject.start()
return True
################################################################################
#IntervalDataRecieveAsync - Periodic recieve data from orchestrator and update storage
def IntervalDataReceiveAsync(*args, **kwargs):
lInterval=3
#Delete index 0 from args
lArgs=copy.copy(args)
if len(lArgs)>0:
lInterval = lArgs[0]
lArgs = lArgs[1:]
#Delete Interval from kwargs
lKwargs = copy.copy(kwargs)
if "Interval" in lKwargs:
lInterval = lKwargs["Interval"]
del lKwargs["Interval"]
lTimer = TimerRepeat.TimerRepeat(lInterval, DataReceiveAsync, lArgs, lKwargs)
lTimer.start()
#Add timer to general list to stop this when needed
mTimerList.append(lTimer)
return lTimer
################################################################################
###################################
################################
###################################
################################################################################
# Send data from orchestrator (synchronyous)
# Example:
# t=IntegrationOrchestrator.DataSendSync(
# RobotValue="Value",
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
def DataSendSync(
RobotValue, OrchestratorKeyList, OrchestratorProtocol="http",
OrchestratorHost="localhost", OrchestratorPort=80, OrchestratorAuthToken=None
):
lCookies = {}
# Set auth token if authorization is needed
if OrchestratorAuthToken:
lCookies["AuthToken"] = OrchestratorAuthToken
lURL = f'{OrchestratorProtocol}://{OrchestratorHost}:{OrchestratorPort}/Utils/Processor'
lDataJSON = [{"Type": "GlobalDictKeyListValueSet", "KeyList": OrchestratorKeyList, "Value": RobotValue}]
try:
lResult = requests.post(lURL, json=lDataJSON, cookies=lCookies)
lResultJSON = json.loads(lResult.text)
return (True, lResultJSON[0]["Result"]) # (Flag response is ok, Data)
except Exception:
mLogger.warning(
f"Orchestrator not responding. Def: DataSendSync, RobotValue: {str(RobotValue)}, OrchestratorKeyList: {str(OrchestratorKeyList)}, OrchestratorProtocol: {str(OrchestratorProtocol)}, OrchestratorHost: {str(OrchestratorHost)}, OrchestratorPort: {str(OrchestratorPort)}")
return (False, None) # (Flag response is not ok, Data None)
################################################################################
# Send data from orchestrator (asynchronyous)
# Example:
# t=IntegrationOrchestrator.DataSendAsync(
# RobotStorage=mGlobal["Storage"],
# RobotStorageKey="R01_OrchestratorToRobot",
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
def DataSendAsync(
RobotStorage, RobotStorageKey, OrchestratorKeyList, OrchestratorProtocol="http",
OrchestratorHost="localhost", OrchestratorPort=80, OrchestratorAuthToken=None
):
from threading import Thread
import uuid
global mGlobalDict
class ThreadAsync(Thread):
def DataSendSync(self):
RobotValue = RobotStorage[RobotStorageKey]
lCookies = {}
# Set auth token if authorization is needed
if OrchestratorAuthToken:
lCookies["AuthToken"] = OrchestratorAuthToken
lURL = f'{OrchestratorProtocol}://{OrchestratorHost}:{OrchestratorPort}/Utils/Processor'
lDataJSON = [{"Type": "GlobalDictKeyListValueSet", "KeyList": OrchestratorKeyList, "Value": RobotValue}]
try:
lResult = requests.post(lURL, json=lDataJSON, cookies=lCookies)
lResultJSON = json.loads(lResult.text)
return (True, lResultJSON[0]["Result"]) # (Flag response is ok, Data)
except Exception:
mLogger.warning(
f"Orchestrator not responding. Def: DataSendAsync, RobotValue: {str(RobotValue)}, OrchestratorKeyList: {str(OrchestratorKeyList)}, OrchestratorProtocol: {str(OrchestratorProtocol)}, OrchestratorHost: {str(OrchestratorHost)}, OrchestratorPort: {str(OrchestratorPort)}")
return (False, None) # (Flag response is not ok, Data None)
# Thread init
def __init__(self, name):
Thread.__init__(self)
self.name = name
#Thread start
def run(self):
self.DataSendSync()
ThreadObject = ThreadAsync(f"ThreadAsync{str(uuid.uuid1())}")
ThreadObject.start()
return True
################################################################################
#IntervalDataSendAsync - Periodic send data from robot to orchestrator
def IntervalDataSendAsync(*args,**kwargs):
lInterval=3
#Delete index 0 from args
lArgs=copy.copy(args)
if len(lArgs)>0:
lInterval = lArgs[0]
lArgs = lArgs[1:]
#Delete Interval from kwargs
lKwargs = copy.copy(kwargs)
if "Interval" in lKwargs:
lInterval = lKwargs["Interval"]
del lKwargs["Interval"]
lTimer = TimerRepeat.TimerRepeat(lInterval, DataSendAsync, lArgs, lKwargs)
lTimer.start()
#Add timer to general list to stop this when needed
mTimerList.append(lTimer)
return lTimer
################################################################################
###################################
################################
###################################
################################################################################
# Check if RobotStorage[Key] Value has been changed > then send data + reset to orchestrator (asynchronyous) timeout 2 seconds
# Example:
# t=IntegrationOrchestrator.DataSendResetAsync(
# RobotStorage=mGlobal["Storage"],
# RobotStorageKey="R01_OrchestratorToRobot",
# RobotResetValue="Test",
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
def DataSendResetAsync(
RobotStorage, RobotStorageKey, RobotResetValue, OrchestratorKeyList, OrchestratorProtocol="http",
OrchestratorHost="localhost", OrchestratorPort=80, OrchestratorAuthToken=None
):
#Do operations if data not equal to ResetValue
if RobotStorage[RobotStorageKey] != RobotResetValue:
#Get value
lRobotValue = copy.deepcopy(RobotStorage[RobotStorageKey])
#Reset value
RobotStorage[RobotStorageKey] = copy.deepcopy(RobotResetValue)
#Send data (retry while data will be transferred completele)
from threading import Thread
import uuid
import time
global mGlobalDict
class ThreadAsync(Thread):
def DataSendSync(self):
RobotValue = lRobotValue
lCookies = {}
# Set auth token if authorization is needed
if OrchestratorAuthToken:
lCookies["AuthToken"] = OrchestratorAuthToken
lURL = f'{OrchestratorProtocol}://{OrchestratorHost}:{OrchestratorPort}/Utils/Processor'
lDataJSON = [{"Type": "GlobalDictKeyListValueSet", "KeyList": OrchestratorKeyList, "Value": RobotValue}]
lFlagDataTransmit = False
while not lFlagDataTransmit:
try:
lResult = requests.post(lURL, json=lDataJSON, cookies=lCookies)
lResultJSON = json.loads(lResult.text)
lFlagDataTransmit = True
except Exception:
mLogger.warning(
f"Orchestrator not responding - will retry to send update. Timeout 2 seconds. Def: DataSendResetAsync, RobotValue: {str(RobotValue)}, OrchestratorKeyList: {str(OrchestratorKeyList)}, OrchestratorProtocol: {str(OrchestratorProtocol)}, OrchestratorHost: {str(OrchestratorHost)}, OrchestratorPort: {str(OrchestratorPort)}")
time.sleep(2) #Timout for next loop
return (True,True) # Only True can be returned
# Thread init
def __init__(self, name):
Thread.__init__(self)
self.name = name
# Thread start
def run(self):
self.DataSendSync()
ThreadObject = ThreadAsync(f"ThreadAsync{str(uuid.uuid1())}")
ThreadObject.start()
return True
return True
################################################################################
################################################################################
#IntervalDataSendResetAsync - Periodic check changed and send + reset data from robot to orchestrator
def IntervalDataSendResetAsync(*args,**kwargs):
lInterval=3
#Delete index 0 from args
lArgs=copy.copy(args)
if len(lArgs)>0:
lInterval = lArgs[0]
lArgs = lArgs[1:]
#Delete Interval from kwargs
lKwargs = copy.copy(kwargs)
if "Interval" in lKwargs:
lInterval = lKwargs["Interval"]
del lKwargs["Interval"]
lTimer = TimerRepeat.TimerRepeat(lInterval, DataSendResetAsync, lArgs, lKwargs)
lTimer.start()
#Add timer to general list to stop this when needed
mTimerList.append(lTimer)
return lTimer
################################################################################
# Check changes in orchestrator - then replace in RobotStorage if not equeal. Has no timeout because You can use function IntervalDataReceiveResetAsync (asynchronyous)
#Next iteration do not rewrite value until new change has come from orchestrator
# Example:
# t=IntegrationOrchestrator.DataRecieveAsync(
# RobotStorage=mGlobal["Storage"],
# RobotStorageKey="R01_OrchestratorToRobot",
# RobotResetValue={"Test":"Test"},
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
def DataReceiveResetAsync(
RobotStorage, RobotStorageKey, RobotResetValue, OrchestratorKeyList, OrchestratorProtocol="http",
OrchestratorHost="localhost", OrchestratorPort=80, OrchestratorAuthToken=None
):
from threading import Thread
import uuid
global mGlobalDict
class ThreadAsync(Thread):
def DataRecieveSync(self):
lCookies = {}
#Set auth token if authorization is needed
if OrchestratorAuthToken:
lCookies["AuthToken"] = OrchestratorAuthToken
lURL = f'{OrchestratorProtocol}://{OrchestratorHost}:{OrchestratorPort}/Utils/Processor'
lDataJSON = [
{"Type": "GlobalDictKeyListValueGet", "KeyList": OrchestratorKeyList},
{"Type": "GlobalDictKeyListValueSet", "KeyList": OrchestratorKeyList, "Value": RobotResetValue}
]
try:
lResult = requests.post(lURL, json=lDataJSON, cookies = lCookies)
lResultJSON = json.loads(lResult.text)
#Change data if it changes with ResetValue
if lResultJSON[0]["Result"] != RobotResetValue:
return (True,lResultJSON[0]["Result"]) #(Flag data changes is ok, Data)
else:
return (False, lResultJSON[0]["Result"]) # (Flag data changes is false - dont rewrite in RobotStorage, Data)
except Exception:
mLogger.warning(
f"Orchestrator not responding. Def DataReceiveResetAsync, RobotResetValue: {str(RobotResetValue)}, OrchestratorKeyList: {str(OrchestratorKeyList)}, OrchestratorProtocol: {str(OrchestratorProtocol)}, OrchestratorHost: {str(OrchestratorHost)}, OrchestratorPort: {str(OrchestratorPort)}")
return (False,None) #(Flag response is not ok, Data None)
# Thread init
def __init__(self, name):
Thread.__init__(self)
self.name = name
#Thread start
def run(self):
(lFlagResponseOK,lResponseData) = self.DataRecieveSync()
if lFlagResponseOK:
RobotStorage[RobotStorageKey] = lResponseData
ThreadObject = ThreadAsync(f"ThreadAsync{str(uuid.uuid1())}")
ThreadObject.start()
return True
################################################################################
################################################################################
#IntervalDataReceiveResetAsync - Periodic receive + every time reset and check changed and reset data on robot storage
def IntervalDataReceiveResetAsync(*args,**kwargs):
lInterval=3
#Delete index 0 from args
lArgs=copy.copy(args)
if len(lArgs)>0:
lInterval = lArgs[0]
lArgs = lArgs[1:]
#Delete Interval from kwargs
lKwargs = copy.copy(kwargs)
if "Interval" in lKwargs:
lInterval = lKwargs["Interval"]
del lKwargs["Interval"]
lTimer = TimerRepeat.TimerRepeat(lInterval, DataReceiveResetAsync, lArgs, lKwargs)
lTimer.start()
#Add timer to general list to stop this when needed
mTimerList.append(lTimer)
return lTimer
#################################################################################
#################################################################################
################################################################################
#ConfigurationInit - Get dict configuration and init interval functions
def ConfigurationInit(inConfigurationDict):
for lItem in inConfigurationDict.keys():
lFunction = globals()[lItem]
#Iterate throught the nested list
for lFunctionConfigurationDict in inConfigurationDict[lItem]:
lFunction(**lFunctionConfigurationDict)
return True

@ -1,159 +0,0 @@
import pdb
import json
import subprocess
import zlib
import os
from . import ProcessCommunicator
import importlib
import traceback
import logging
import sys
import datetime
import struct
import shutil
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
os.makedirs("Reports")
logging.basicConfig(filename="Reports\ReportRobotRun_"+datetime.datetime.now().strftime("%Y_%m_%d")+".log", level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
####################################
#Info: Main module of the Robot app (OpenRPA - Robot)
####################################
#Usage:
#Here you can run some activity or list of activities
#After import this module you can use the folowing functions:
#ActivityRun(inActivitySpecificationDict): outActivityResultDict - function - run activity (function or procedure)
#ActivityRunJSON(inActivitySpecificationDictJSON): outActivityResultDictJSON
#ActivityListRun(inActivitySpecificationDictList): outActivityResultDictList - function - run list of activities (function or procedure)
#ActivityListRunJSON(inActivitySpecificationDictListJSON): outActivityResultDictListJSON
#Naming:
#Activity - some action/list of actions
#Module - Any *.py file, which consist of area specific functions
#Argument
#inActivitySpecificationDict:
#{
# ModuleName: <"GUI"|..., str>,
# ActivityName: <Function or procedure name in module, str>,
# ArgumentList: [<Argument 1, any type>, ...] - optional,
# ArgumentDict: {<Argument 1 name, str>:<Argument 1 value, any type>, ...} - optional
#}
#outActivityResultDict:
#{
# ActivitySpecificationDict: {
# ModuleName: <"GUI"|..., str>,
# ActivityName: <Function or procedure name in module, str>,
# ArgumentList: [<Argument 1, any type>, ...] - optional,
# ArgumentDict: {<Argument 1 name, str>: <Argument 1 value, any type>, ...} - optional
# },
# ErrorFlag: <Boolean flag - Activity result has error (true) or not (false), boolean>,
# ErrorMessage: <Error message, str> - required if ErrorFlag is true,
# ErrorTraceback: <Error traceback log, str> - required if ErrorFlag is true,
# Result: <Result, returned from the Activity, int, str, boolean, list, dict> - required if ErrorFlag is false
#}
####################
#Section: Module initialization
####################
#Start childprocess - GUI Module 32 bit
#pdb.set_trace()
if not os.path.isfile("..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe"):
shutil.copyfile('..\\Resources\\WPy32-3720\\python-3.7.2\\python.exe',"..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe")
mProcessGUI_x32 = subprocess.Popen(['..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe',"-m",'pyOpenRPA.Robot'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#Start childprocess - GUI Module 64 bit - uncomment after WPy64 installation
ProcessCommunicator.ProcessChildSendObject(mProcessGUI_x32,{"ModuleName":"UIDesktop","ActivityName":"Get_OSBitnessInt","ArgumentList":[],"ArgumentDict":{}})
lOSBitness = ProcessCommunicator.ProcessChildReadWaitObject(mProcessGUI_x32)["Result"]
lProcessBitnessStr = str(struct.calcsize("P") * 8)
#start 64 if system support 64
mProcessGUI_x64 = None
if lOSBitness == 64:
if not os.path.isfile("..\\Resources\\WPy64-3720\\python-3.7.2.amd64\\OpenRPARobotGUIx64.exe"):
shutil.copyfile('..\\Resources\\WPy64-3720\\python-3.7.2.amd64\\python.exe',"..\\Resources\\WPy64-3720\\python-3.7.2.amd64\\OpenRPARobotGUIx64.exe")
mProcessGUI_x64 = subprocess.Popen(['..\\Resources\\WPy64-3720\\python-3.7.2.amd64\\OpenRPARobotGUIx64.exe',"-m",'pyOpenRPA.Robot'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
####################
#Section: Activity
####################
def ActivityRun(inActivitySpecificationDict):
#Выполнить отправку в модуль UIDesktop, если ModuleName == "UIDesktop"
#pdb.set_trace()
if inActivitySpecificationDict["ModuleName"] == "UIDesktop":
if "ArgumentList" not in inActivitySpecificationDict:
inActivitySpecificationDict["ArgumentList"]=[]
if "ArgumentDict" not in inActivitySpecificationDict:
inActivitySpecificationDict["ArgumentDict"]={}
#Если mProcessGUI_x64 не инициализирован
lFlagRun64=True
if mProcessGUI_x64 is None:
lFlagRun64=False
else:
if inActivitySpecificationDict["ActivityName"]=="UIOSelectorsSecs_WaitAppear_List":
#Функция ожидания появления элементов (тк элементы могут быть недоступны, неизвестно в каком фреймворке каждый из них может появиться)
lFlagRun64=True
elif inActivitySpecificationDict["ActivityName"].startswith("UIOSelector") or inActivitySpecificationDict["ActivityName"].startswith("PWASpecification"):
if len(inActivitySpecificationDict["ArgumentList"])>0:
if len(inActivitySpecificationDict["ArgumentList"][0])>0:
#Определение разрядности (32 и 64) для тех функций, где это необходимо
######################################################
#Выполнить проверку разрядности через UIOSelector_Get_BitnessInt
#Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
#pdb.set_trace()
#Внимание! Проверка разрядности специально делается на процессе 64 бита, тк процесс 32 бита зависает на 35 итерации проверки
ProcessCommunicator.ProcessChildSendObject(mProcessGUI_x64,{"ModuleName":"UIDesktop","ActivityName":"UIOSelector_Get_BitnessInt","ArgumentList":[inActivitySpecificationDict["ArgumentList"][0]],"ArgumentDict":inActivitySpecificationDict["ArgumentDict"]})
#Получить ответ от дочернего процесса
lResponseObject=ProcessCommunicator.ProcessChildReadWaitObject(mProcessGUI_x64)
#pdb.set_trace()
if lResponseObject["Result"]==32:
lFlagRun64=False
#Запуск 64
#pdb.set_trace()
if lFlagRun64:
#Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(mProcessGUI_x64,inActivitySpecificationDict)
#Получить ответ от дочернего процесса
lResponseObject=ProcessCommunicator.ProcessChildReadWaitObject(mProcessGUI_x64)
else:
#Запуск 32
#Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
ProcessCommunicator.ProcessChildSendObject(mProcessGUI_x32,inActivitySpecificationDict)
#Получить ответ от дочернего процесса
lResponseObject=ProcessCommunicator.ProcessChildReadWaitObject(mProcessGUI_x32)
#Остальные модули подключать и выполнять здесь
else:
lArgumentList=[]
if "ArgumentList" in inActivitySpecificationDict:
lArgumentList=inActivitySpecificationDict["ArgumentList"]
lArgumentDict={}
if "ArgumentDict" in inActivitySpecificationDict:
lArgumentDict=inActivitySpecificationDict["ArgumentDict"]
#Подготовить результирующую структуру
lResponseObject={"ActivitySpecificationDict":inActivitySpecificationDict,"ErrorFlag":False}
try:
#Подключить модуль для вызова
lModule=importlib.import_module(inActivitySpecificationDict["ModuleName"])
#Найти функцию
lFunction=getattr(lModule,inActivitySpecificationDict["ActivityName"])
#Выполнить вызов и записать результат
lResponseObject["Result"]=lFunction(*lArgumentList,**lArgumentDict)
except Exception as e:
#Установить флаг ошибки и передать тело ошибки
lResponseObject["ErrorFlag"]=True
lResponseObject["ErrorMessage"]=str(e)
lResponseObject["ErrorTraceback"]=traceback.format_exc()
return lResponseObject
#########################################################
#Run list of activities
#########################################################
def ActivityListRun(inActivitySpecificationDictList):
lResult=[]
for lItem in inActivitySpecificationDictList:
lResult.append(ActivityRun(lItem))
return lResult

@ -0,0 +1,34 @@
import logging
import datetime
#Robot settings
def Settings():
import os
mDict = {
"Logger": logging.getLogger("Robot"),
"Storage": {
"Robot_R01_help": "Robot data storage in orchestrator env",
"Robot_R01": {}
},
"ProcessBitness": {
"Python32FullPath": None, #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe"
"Python64FullPath": None, #Set from user
"Python32ProcessName": "OpenRPAUIDesktopX32.exe", #Config set once
"Python64ProcessName": "OpenRPAUIDesktopX64.exe" #Config set once
}
}
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
os.makedirs("Reports")
##########################
#Подготовка логгера Robot
#########################
mRobotLogger=mDict["Logger"]
mRobotLogger.setLevel(logging.INFO)
# create the logging file handler
mRobotLoggerFH = logging.FileHandler("Reports\ReportRobot_"+datetime.datetime.now().strftime("%Y_%m_%d")+".log")
mRobotLoggerFormatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
mRobotLoggerFH.setFormatter(mRobotLoggerFormatter)
# add handler to logger object
mRobotLogger.addHandler(mRobotLoggerFH)
############################################

@ -0,0 +1,65 @@
import unittest
from threading import Timer
import sys
lFolderPath = "/".join(__file__.split("\\")[:-3])
sys.path.insert(0, lFolderPath)
from pyOpenRPA.Robot import OrchestratorConnector
from pyOpenRPA.Robot import Utils
class MyTestCase(unittest.TestCase):
def test_something(self):
#self.assertEqual(True, False)
mGlobal={"Storage":{"R01_OrchestratorToRobot":{"Test":"Test2"}}}
# t=OrchestratorConnector.IntervalDataSendAsync(
# Interval=1,
# RobotStorage=mGlobal["Storage"],
# RobotStorageKey="R01_OrchestratorToRobot",
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
# t=OrchestratorConnector.DataSendSync(
# RobotValue="Test",
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
import time
#def Func(lT,inl):
# print(lT)
# return True
#lTimer= Utils.TimerRepeat.TimerRepeat(1, Func, ["dddd"],{"inl":9})
#lTimer.start()
OrchestratorConnector.ConfigurationInit({
"IntervalDataSendResetAsync": [
{
"Interval": 2,
"RobotStorage": mGlobal["Storage"],
"RobotStorageKey": "R01_OrchestratorToRobot",
"RobotResetValue": {"Test": "Test"},
"OrchestratorKeyList": ["Storage", "R01_OrchestratorToRobot"],
"OrchestratorProtocol": "http",
"OrchestratorHost": "localhost",
"OrchestratorPort": 8081,
"OrchestratorAuthToken": "1992-04-03-0643-ru-b4ff-openrpa52zzz"
}
]
})
while True:
print(mGlobal["Storage"]["R01_OrchestratorToRobot"])
# t = OrchestratorConnector.DataSendResetAsync(
# RobotStorage=mGlobal["Storage"],
# RobotStorageKey="R01_OrchestratorToRobot",
# RobotResetValue={"Test": "Test"},
# OrchestratorKeyList=["Storage", "R01_OrchestratorToRobot"],
# OrchestratorProtocol="http",
# OrchestratorHost="localhost",
# OrchestratorPort=8081,
# OrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
# )
time.sleep(0.5)
if __name__ == '__main__':
unittest.main()

@ -1,45 +1,19 @@
from pywinauto import win32defines, win32structures, win32functions from pywinauto import win32defines, win32structures, win32functions
import pdb
import pywinauto import pywinauto
import json
import sys
import ctypes import ctypes
import struct import struct
import os
import select
import zlib
import win32api import win32api
import win32clipboard
import time import time
import traceback from .Utils import ProcessCommunicator
from . import ProcessCommunicator
from . import JSONNormalize
from . import Utils #For ProcessBitness from . import Utils #For ProcessBitness
from threading import Timer
import datetime
import logging
import re import re
import copy import copy
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
os.makedirs("Reports")
##########################
#Подготовка логгера Robot
#########################
mRobotLogger=logging.getLogger("RobotLogger")
mRobotLogger.setLevel(logging.INFO)
# create the logging file handler
mRobotLoggerFH = logging.FileHandler("Reports\ReportRobotGUIRun_"+datetime.datetime.now().strftime("%Y_%m_%d")+".log")
mRobotLoggerFormatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
mRobotLoggerFH.setFormatter(mRobotLoggerFormatter)
# add handler to logger object
mRobotLogger.addHandler(mRobotLoggerFH)
############################################ ############################################
#When import UIDesktop init the other bitness python # When import UIDesktop init the other bitness python
#For this type UIDesktop.Utils.ProcessBitness.SettingsInit(inSettingsDict) # For this type
#inSettingsDict = { # UIDesktop.Utils.ProcessBitness.SettingsInit(inSettingsDict)
# inSettingsDict = {
# "Python32FullPath": None, #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe" # "Python32FullPath": None, #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe"
# "Python64FullPath": None, #Set from user # "Python64FullPath": None, #Set from user
# "Python32ProcessName": "OpenRPAUIDesktopX32.exe", #Config set once # "Python32ProcessName": "OpenRPAUIDesktopX32.exe", #Config set once

@ -1,10 +1,9 @@
import json import json
import subprocess
import zlib import zlib
import sys import sys
import os
from . import JSONNormalize from . import JSONNormalize
import pdb
############################################ ############################################
####Межпроцессное взаимодействие ####Межпроцессное взаимодействие
############################################ ############################################
@ -41,7 +40,6 @@ def ProcessParentWriteString(lString):
#Вернуть \f #Вернуть \f
lByteString = lByteString.replace(b'\f',b'{{{f}}}') lByteString = lByteString.replace(b'\f',b'{{{f}}}')
############################ ############################
#print(b"Result: "+lByteString)
#lByteString= b'x\x9c\xdd\x95]O\xc20\x14\x86\xffJ\xb3[5\xa1Cqz\x07\xc4\xe8\x8d\x1fQ\x13.\x0cYJw\xb6U\xbav\xe9\xce"\x84\xf0\xdfm\'"\xb8\xa0L%Q\xb3\x9b\xf6=\xdfO\x9a\xb3\x99\x17\x97\x8a\xa3\xd0\xea\x8ae\xe0\x9d\x12\xaf[\xa2\xce\x98S\xee\x80\x19\x9e^\xea\xb2\x803\t\x19(\xbc\x10`\x9c6\xf5\xf6\x89\xc7LRt\x8daS\x1b\xf5\xf00\xf3\xd4"\xc1u\x0e\xea\xf6\xa6K\x0e\xc8\xb9\xd6\x89\x04\xd2O\x8d\xb6&\x1bb\x04OC\x84\t~\xe2\x97\x1b\xcd\xa1(B\x11YG\xdaj\xfb\xc1\x9b\xb8\xa2\xa4LE\xd2\xd5\xa4\xf6\xdenY\x85Kf\xc3^;yI\x18\x0eD\x94\x00\x0e\x84{{n}}\xa9K\xce\xb5B\xa3e\x88\xd3\xbc\xf2Z\xd5\xaa\x82\xaa\x94\xd25\x0b\x1c\x99J\xaa\x023OB\xec\xbavEP\xe7\x8b\x93\x11I\xeaTz\xe2\xbb\xebH\xa3eW5\xe8\xb7\xe6\xce^*\x14\xb6\x83e\xda\xf9phe]b^\xe2\xf5\xe8\xd1Vp\xf0\xfe.\xbb\x1b\xa6`\x87\xfc8\x1a\x9bSE0q\xa2\x15\xeer\xe0"\x16\xbcz\x9f\xfdT\xc8h\x9d\xdf\xc7\xd4\xbe\xcdj1\xd9:\xa9\x1f\xe1B7\x81\xa1\xef\xc0\xd0:\x98\xc3-\xc0\xd4X\xfc\xda\xf1i\xbb\xe9\xfc\xdb<\x8c\xff2\x7f\'\xa8\x8d\xdf\xdab\xfc\x9e\xd6\xe3\x8c\x99qQ\xe3\xb0f\xd9\x19\x90{\xade\x8f\x99/3\xa1AC(\xfe\x16P\x06F \x90\xb3\t\x07Iba\x17\x83P\xa4\xbf\xb7G\x9e\x04\xa6vE\x13\xb6\xfc\x13\xd6\xa85\x0b\xdd\x19\xd6^i\x11\xa8FT;G\xfe\x06\xac\xc1q\xb0N\x956\xd84\xae\xe4p\xbe\xfa=\x03\x01\xce\x95\x9a' #lByteString= b'x\x9c\xdd\x95]O\xc20\x14\x86\xffJ\xb3[5\xa1Cqz\x07\xc4\xe8\x8d\x1fQ\x13.\x0cYJw\xb6U\xbav\xe9\xce"\x84\xf0\xdfm\'"\xb8\xa0L%Q\xb3\x9b\xf6=\xdfO\x9a\xb3\x99\x17\x97\x8a\xa3\xd0\xea\x8ae\xe0\x9d\x12\xaf[\xa2\xce\x98S\xee\x80\x19\x9e^\xea\xb2\x803\t\x19(\xbc\x10`\x9c6\xf5\xf6\x89\xc7LRt\x8daS\x1b\xf5\xf00\xf3\xd4"\xc1u\x0e\xea\xf6\xa6K\x0e\xc8\xb9\xd6\x89\x04\xd2O\x8d\xb6&\x1bb\x04OC\x84\t~\xe2\x97\x1b\xcd\xa1(B\x11YG\xdaj\xfb\xc1\x9b\xb8\xa2\xa4LE\xd2\xd5\xa4\xf6\xdenY\x85Kf\xc3^;yI\x18\x0eD\x94\x00\x0e\x84{{n}}\xa9K\xce\xb5B\xa3e\x88\xd3\xbc\xf2Z\xd5\xaa\x82\xaa\x94\xd25\x0b\x1c\x99J\xaa\x023OB\xec\xbavEP\xe7\x8b\x93\x11I\xeaTz\xe2\xbb\xebH\xa3eW5\xe8\xb7\xe6\xce^*\x14\xb6\x83e\xda\xf9phe]b^\xe2\xf5\xe8\xd1Vp\xf0\xfe.\xbb\x1b\xa6`\x87\xfc8\x1a\x9bSE0q\xa2\x15\xeer\xe0"\x16\xbcz\x9f\xfdT\xc8h\x9d\xdf\xc7\xd4\xbe\xcdj1\xd9:\xa9\x1f\xe1B7\x81\xa1\xef\xc0\xd0:\x98\xc3-\xc0\xd4X\xfc\xda\xf1i\xbb\xe9\xfc\xdb<\x8c\xff2\x7f\'\xa8\x8d\xdf\xdab\xfc\x9e\xd6\xe3\x8c\x99qQ\xe3\xb0f\xd9\x19\x90{\xade\x8f\x99/3\xa1AC(\xfe\x16P\x06F \x90\xb3\t\x07Iba\x17\x83P\xa4\xbf\xb7G\x9e\x04\xa6vE\x13\xb6\xfc\x13\xd6\xa85\x0b\xdd\x19\xd6^i\x11\xa8FT;G\xfe\x06\xac\xc1q\xb0N\x956\xd84\xae\xe4p\xbe\xfa=\x03\x01\xce\x95\x9a'
#lByteString = b"x\x9c\xb5\x91\xcfO\xc3 \x14\xc7\xff\x95\xa6\xd7uI\xf9Q\x8a\xde\xd4\x93\x07\xbdx\xf00\x97\x05)[I(\x90\x8ef3\xcb\xfew\x81M\xbb\xd9M]\x8c!y\xd0\xf7}\xbc\xef\xe3\xd3\xc9&\xd5\xac\x11\xe9u\x92j\xb1J@2N\x1e\x8d\x13\x96U\xa3Q\x9a%i+y=sb\xed\xceV\xd8\xd6p\xb1\\\xced\xe5K{{n}}\x80`\x9f\xeb\x135\xd3\x95{{n}}.\x08RR\xe4>\xc3\x15\xf3\x97>\xbc\x8f:r\xa3]k\xd4\xcc\xbd\xd9(>K]\x99\xd5\xa1\x12\xbd\x00\xc6\xb0\xcc\xcb0\xa4\xe0\x8e\xe9E4\xd8\xa4J\xcc\xc3\xb44\x07^r\xc6\xfa3\x04(\xbeeQ\x07\x05P\x1a\xa4W\xe3\x9ci\xfc\xf7\x15(\xb6A\xee\xb4\x93\x8d\xd85\x9f`?\xf6n\xd8i0v\xadw\xd5\x95X\x87n>\xf1d\x05\x97s\xc9\x99\x93F\xdf\xd5R\xc5K=\xcc\x1bk\xd5^\x1d`\xfc\xa2]\x06PwJ\r\xf0\x9d\xa2\xf6 tw\xcb\xda\x01\xb6}\x83\xd3\xcc\x00\xec\x99\x15\xf4\x88Y\x99\x1f2\x83\xb4\xfc\x8e\x99\xdf\xb3d\x0c\x01.1E\x04\x93l\xff\x8e\xcf\x7f6\xa4Z\xfc\x82\xeaK\x97c BD\xf3\x101\x89g\xba\x8b\x03\xd0?\x97\xff#\xfb{'\x9a\x8b\xe0\x03H\xc89\xfa\x08\x15\x7f\xa2\x0f >\x80_\x0e\xe0\x93\xb3\xf0\xc3\xc4\xd3m\\\xef\xf8\x958\xa0" #lByteString = b"x\x9c\xb5\x91\xcfO\xc3 \x14\xc7\xff\x95\xa6\xd7uI\xf9Q\x8a\xde\xd4\x93\x07\xbdx\xf00\x97\x05)[I(\x90\x8ef3\xcb\xfew\x81M\xbb\xd9M]\x8c!y\xd0\xf7}\xbc\xef\xe3\xd3\xc9&\xd5\xac\x11\xe9u\x92j\xb1J@2N\x1e\x8d\x13\x96U\xa3Q\x9a%i+y=sb\xed\xceV\xd8\xd6p\xb1\\\xced\xe5K{{n}}\x80`\x9f\xeb\x135\xd3\x95{{n}}.\x08RR\xe4>\xc3\x15\xf3\x97>\xbc\x8f:r\xa3]k\xd4\xcc\xbd\xd9(>K]\x99\xd5\xa1\x12\xbd\x00\xc6\xb0\xcc\xcb0\xa4\xe0\x8e\xe9E4\xd8\xa4J\xcc\xc3\xb44\x07^r\xc6\xfa3\x04(\xbeeQ\x07\x05P\x1a\xa4W\xe3\x9ci\xfc\xf7\x15(\xb6A\xee\xb4\x93\x8d\xd85\x9f`?\xf6n\xd8i0v\xadw\xd5\x95X\x87n>\xf1d\x05\x97s\xc9\x99\x93F\xdf\xd5R\xc5K=\xcc\x1bk\xd5^\x1d`\xfc\xa2]\x06PwJ\r\xf0\x9d\xa2\xf6 tw\xcb\xda\x01\xb6}\x83\xd3\xcc\x00\xec\x99\x15\xf4\x88Y\x99\x1f2\x83\xb4\xfc\x8e\x99\xdf\xb3d\x0c\x01.1E\x04\x93l\xff\x8e\xcf\x7f6\xa4Z\xfc\x82\xeaK\x97c BD\xf3\x101\x89g\xba\x8b\x03\xd0?\x97\xff#\xfb{'\x9a\x8b\xe0\x03H\xc89\xfa\x08\x15\x7f\xa2\x0f >\x80_\x0e\xe0\x93\xb3\xf0\xc3\xc4\xd3m\\\xef\xf8\x958\xa0"
#lt=open("logSendByteStringWithoutN.log","wb") #lt=open("logSendByteStringWithoutN.log","wb")
@ -71,7 +69,6 @@ def ProcessChildSendString(lProcess,lString):
lByteString = lByteString.replace(b'\n',b'{{n}}') lByteString = lByteString.replace(b'\n',b'{{n}}')
#Отправить сообщение в дочерний процесс #Отправить сообщение в дочерний процесс
lProcess.stdin.write(lByteString+bytes('\n',"utf-8")) lProcess.stdin.write(lByteString+bytes('\n',"utf-8"))
#print(str(lByteString+bytes('\n',"utf-8")))
lProcess.stdin.flush() lProcess.stdin.flush()
#Вернуть результат #Вернуть результат
return return
@ -82,7 +79,6 @@ def ProcessChildReadWaitString(lProcess):
#pdb.set_trace() #pdb.set_trace()
lResult = lProcess.stdout.readline() lResult = lProcess.stdout.readline()
#Обработка спец символов #Обработка спец символов
#print(b'NewLine: '+lResult)
#Вернуть потенциальные \n #Вернуть потенциальные \n
lResult = lResult.replace(b'{{{n}}}',b'\n') lResult = lResult.replace(b'{{{n}}}',b'\n')
#Вернуть \r #Вернуть \r
@ -99,8 +95,6 @@ def ProcessChildReadWaitString(lProcess):
lResult = lResult.replace(b'{{{v}}}',b'\v') lResult = lResult.replace(b'{{{v}}}',b'\v')
#Вернуть \f #Вернуть \f
lResult = lResult.replace(b'{{{f}}}',b'\f') lResult = lResult.replace(b'{{{f}}}',b'\f')
#print("check")
#print(str(lResult))
try: try:
lResult = zlib.decompress(lResult[0:-1]) lResult = zlib.decompress(lResult[0:-1])
lResult = lResult.decode("utf-8") lResult = lResult.decode("utf-8")

@ -0,0 +1,28 @@
from threading import Timer
import datetime
# lTimer = RepeatedTimer(3, def, [], {}) # it auto-starts, no need of rt.start()
# if def return None = timer stops
# lTimer.start()
class TimerRepeat(object):
def __init__(self, interval, function, args, kwargs):
self._timer = None
self.interval = interval
self.function = function
self.args = args
self.kwargs = kwargs
self.is_running = False
self.start()
def _run(self):
self.is_running = False
lResult = self.function(*self.args, **self.kwargs)
if lResult is not None:
if lResult:
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

@ -4,10 +4,9 @@ The OpenRPA package (from UnicodeLabs)
""" """
__all__ = [ __all__ = [
'UIDesktop', 'Clipboard', 'IntegrationOrchestrator', 'Window', 'ProcessCommunicator' 'Clipboard', 'OrchestratorConnector.py', 'Window'
] ]
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>' __author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'
#from . import UIDesktop #from . import UIDesktop
from . import Clipboard from . import Clipboard
from . import Window from . import Window
from . import ProcessCommunicator

@ -8,8 +8,8 @@ lFolderPath = "\\".join(__file__.split("\\")[:-2])
sys.path.append(lFolderPath) sys.path.append(lFolderPath)
################################ ################################
import traceback import traceback
from Robot import ProcessCommunicator from Robot.Utils import ProcessCommunicator
from Robot import JSONNormalize from Robot.Utils import JSONNormalize
from Robot import UIDesktop from Robot import UIDesktop
########################################## ##########################################
#Run UIDesktop from new process. Communication with paren process by PIPE channel #Run UIDesktop from new process. Communication with paren process by PIPE channel
@ -19,22 +19,22 @@ buffer = ""
lJSONInputString = "" lJSONInputString = ""
while True: while True:
#Reset the lProcessResponse #Reset the lProcessResponse
lProcessResponse={"ErrorFlag":False} lProcessResponse = {"ErrorFlag": False}
try: try:
#Ожидаем синхронно поступление объекта #Ожидаем синхронно поступление объекта
lJSONInput = ProcessCommunicator.ProcessParentReadWaitObject() lJSONInput = ProcessCommunicator.ProcessParentReadWaitObject()
lProcessResponse["ActivitySpecificationDict"]=lJSONInput lProcessResponse["ActivitySpecificationDict"] = lJSONInput
#Выполнить вызов функции #Выполнить вызов функции
lFunction = getattr(UIDesktop,lJSONInput['ActivityName']) lFunction = getattr(UIDesktop, lJSONInput['ActivityName'])
lProcessResponse["Result"]=JSONNormalize.JSONNormalizeDictListStrIntBool(lFunction(*lJSONInput['ArgumentList'],**lJSONInput['ArgumentDict'])) lProcessResponse["Result"] = JSONNormalize.JSONNormalizeDictListStrIntBool(lFunction(*lJSONInput['ArgumentList'], **lJSONInput['ArgumentDict']))
except Exception as e: except Exception as e:
lProcessResponse["Result"] = None lProcessResponse["Result"] = None
#Установить флаг ошибки #Установить флаг ошибки
lProcessResponse["ErrorFlag"]=True lProcessResponse["ErrorFlag"] = True
#Зафиксировать traceback #Зафиксировать traceback
lProcessResponse["ErrorTraceback"]=traceback.format_exc() lProcessResponse["ErrorTraceback"] = traceback.format_exc()
#Зафиксировать Error message #Зафиксировать Error message
lProcessResponse["ErrorMessage"]=str(e) lProcessResponse["ErrorMessage"] = str(e)
#lProcessResponse["ErrorArgs"]=str(e.args) #lProcessResponse["ErrorArgs"]=str(e.args)
#Отправить ответ в родительский процесс #Отправить ответ в родительский процесс
ProcessCommunicator.ProcessParentWriteObject(lProcessResponse) ProcessCommunicator.ProcessParentWriteObject(lProcessResponse)

@ -40,7 +40,6 @@ def ProcessParentWriteString(lString):
#Вернуть \f #Вернуть \f
lByteString = lByteString.replace(b'\f',b'{{{f}}}') lByteString = lByteString.replace(b'\f',b'{{{f}}}')
############################ ############################
#print(b"Result: "+lByteString)
#lByteString= b'x\x9c\xdd\x95]O\xc20\x14\x86\xffJ\xb3[5\xa1Cqz\x07\xc4\xe8\x8d\x1fQ\x13.\x0cYJw\xb6U\xbav\xe9\xce"\x84\xf0\xdfm\'"\xb8\xa0L%Q\xb3\x9b\xf6=\xdfO\x9a\xb3\x99\x17\x97\x8a\xa3\xd0\xea\x8ae\xe0\x9d\x12\xaf[\xa2\xce\x98S\xee\x80\x19\x9e^\xea\xb2\x803\t\x19(\xbc\x10`\x9c6\xf5\xf6\x89\xc7LRt\x8daS\x1b\xf5\xf00\xf3\xd4"\xc1u\x0e\xea\xf6\xa6K\x0e\xc8\xb9\xd6\x89\x04\xd2O\x8d\xb6&\x1bb\x04OC\x84\t~\xe2\x97\x1b\xcd\xa1(B\x11YG\xdaj\xfb\xc1\x9b\xb8\xa2\xa4LE\xd2\xd5\xa4\xf6\xdenY\x85Kf\xc3^;yI\x18\x0eD\x94\x00\x0e\x84{{n}}\xa9K\xce\xb5B\xa3e\x88\xd3\xbc\xf2Z\xd5\xaa\x82\xaa\x94\xd25\x0b\x1c\x99J\xaa\x023OB\xec\xbavEP\xe7\x8b\x93\x11I\xeaTz\xe2\xbb\xebH\xa3eW5\xe8\xb7\xe6\xce^*\x14\xb6\x83e\xda\xf9phe]b^\xe2\xf5\xe8\xd1Vp\xf0\xfe.\xbb\x1b\xa6`\x87\xfc8\x1a\x9bSE0q\xa2\x15\xeer\xe0"\x16\xbcz\x9f\xfdT\xc8h\x9d\xdf\xc7\xd4\xbe\xcdj1\xd9:\xa9\x1f\xe1B7\x81\xa1\xef\xc0\xd0:\x98\xc3-\xc0\xd4X\xfc\xda\xf1i\xbb\xe9\xfc\xdb<\x8c\xff2\x7f\'\xa8\x8d\xdf\xdab\xfc\x9e\xd6\xe3\x8c\x99qQ\xe3\xb0f\xd9\x19\x90{\xade\x8f\x99/3\xa1AC(\xfe\x16P\x06F \x90\xb3\t\x07Iba\x17\x83P\xa4\xbf\xb7G\x9e\x04\xa6vE\x13\xb6\xfc\x13\xd6\xa85\x0b\xdd\x19\xd6^i\x11\xa8FT;G\xfe\x06\xac\xc1q\xb0N\x956\xd84\xae\xe4p\xbe\xfa=\x03\x01\xce\x95\x9a' #lByteString= b'x\x9c\xdd\x95]O\xc20\x14\x86\xffJ\xb3[5\xa1Cqz\x07\xc4\xe8\x8d\x1fQ\x13.\x0cYJw\xb6U\xbav\xe9\xce"\x84\xf0\xdfm\'"\xb8\xa0L%Q\xb3\x9b\xf6=\xdfO\x9a\xb3\x99\x17\x97\x8a\xa3\xd0\xea\x8ae\xe0\x9d\x12\xaf[\xa2\xce\x98S\xee\x80\x19\x9e^\xea\xb2\x803\t\x19(\xbc\x10`\x9c6\xf5\xf6\x89\xc7LRt\x8daS\x1b\xf5\xf00\xf3\xd4"\xc1u\x0e\xea\xf6\xa6K\x0e\xc8\xb9\xd6\x89\x04\xd2O\x8d\xb6&\x1bb\x04OC\x84\t~\xe2\x97\x1b\xcd\xa1(B\x11YG\xdaj\xfb\xc1\x9b\xb8\xa2\xa4LE\xd2\xd5\xa4\xf6\xdenY\x85Kf\xc3^;yI\x18\x0eD\x94\x00\x0e\x84{{n}}\xa9K\xce\xb5B\xa3e\x88\xd3\xbc\xf2Z\xd5\xaa\x82\xaa\x94\xd25\x0b\x1c\x99J\xaa\x023OB\xec\xbavEP\xe7\x8b\x93\x11I\xeaTz\xe2\xbb\xebH\xa3eW5\xe8\xb7\xe6\xce^*\x14\xb6\x83e\xda\xf9phe]b^\xe2\xf5\xe8\xd1Vp\xf0\xfe.\xbb\x1b\xa6`\x87\xfc8\x1a\x9bSE0q\xa2\x15\xeer\xe0"\x16\xbcz\x9f\xfdT\xc8h\x9d\xdf\xc7\xd4\xbe\xcdj1\xd9:\xa9\x1f\xe1B7\x81\xa1\xef\xc0\xd0:\x98\xc3-\xc0\xd4X\xfc\xda\xf1i\xbb\xe9\xfc\xdb<\x8c\xff2\x7f\'\xa8\x8d\xdf\xdab\xfc\x9e\xd6\xe3\x8c\x99qQ\xe3\xb0f\xd9\x19\x90{\xade\x8f\x99/3\xa1AC(\xfe\x16P\x06F \x90\xb3\t\x07Iba\x17\x83P\xa4\xbf\xb7G\x9e\x04\xa6vE\x13\xb6\xfc\x13\xd6\xa85\x0b\xdd\x19\xd6^i\x11\xa8FT;G\xfe\x06\xac\xc1q\xb0N\x956\xd84\xae\xe4p\xbe\xfa=\x03\x01\xce\x95\x9a'
#lByteString = b"x\x9c\xb5\x91\xcfO\xc3 \x14\xc7\xff\x95\xa6\xd7uI\xf9Q\x8a\xde\xd4\x93\x07\xbdx\xf00\x97\x05)[I(\x90\x8ef3\xcb\xfew\x81M\xbb\xd9M]\x8c!y\xd0\xf7}\xbc\xef\xe3\xd3\xc9&\xd5\xac\x11\xe9u\x92j\xb1J@2N\x1e\x8d\x13\x96U\xa3Q\x9a%i+y=sb\xed\xceV\xd8\xd6p\xb1\\\xced\xe5K{{n}}\x80`\x9f\xeb\x135\xd3\x95{{n}}.\x08RR\xe4>\xc3\x15\xf3\x97>\xbc\x8f:r\xa3]k\xd4\xcc\xbd\xd9(>K]\x99\xd5\xa1\x12\xbd\x00\xc6\xb0\xcc\xcb0\xa4\xe0\x8e\xe9E4\xd8\xa4J\xcc\xc3\xb44\x07^r\xc6\xfa3\x04(\xbeeQ\x07\x05P\x1a\xa4W\xe3\x9ci\xfc\xf7\x15(\xb6A\xee\xb4\x93\x8d\xd85\x9f`?\xf6n\xd8i0v\xadw\xd5\x95X\x87n>\xf1d\x05\x97s\xc9\x99\x93F\xdf\xd5R\xc5K=\xcc\x1bk\xd5^\x1d`\xfc\xa2]\x06PwJ\r\xf0\x9d\xa2\xf6 tw\xcb\xda\x01\xb6}\x83\xd3\xcc\x00\xec\x99\x15\xf4\x88Y\x99\x1f2\x83\xb4\xfc\x8e\x99\xdf\xb3d\x0c\x01.1E\x04\x93l\xff\x8e\xcf\x7f6\xa4Z\xfc\x82\xeaK\x97c BD\xf3\x101\x89g\xba\x8b\x03\xd0?\x97\xff#\xfb{'\x9a\x8b\xe0\x03H\xc89\xfa\x08\x15\x7f\xa2\x0f >\x80_\x0e\xe0\x93\xb3\xf0\xc3\xc4\xd3m\\\xef\xf8\x958\xa0" #lByteString = b"x\x9c\xb5\x91\xcfO\xc3 \x14\xc7\xff\x95\xa6\xd7uI\xf9Q\x8a\xde\xd4\x93\x07\xbdx\xf00\x97\x05)[I(\x90\x8ef3\xcb\xfew\x81M\xbb\xd9M]\x8c!y\xd0\xf7}\xbc\xef\xe3\xd3\xc9&\xd5\xac\x11\xe9u\x92j\xb1J@2N\x1e\x8d\x13\x96U\xa3Q\x9a%i+y=sb\xed\xceV\xd8\xd6p\xb1\\\xced\xe5K{{n}}\x80`\x9f\xeb\x135\xd3\x95{{n}}.\x08RR\xe4>\xc3\x15\xf3\x97>\xbc\x8f:r\xa3]k\xd4\xcc\xbd\xd9(>K]\x99\xd5\xa1\x12\xbd\x00\xc6\xb0\xcc\xcb0\xa4\xe0\x8e\xe9E4\xd8\xa4J\xcc\xc3\xb44\x07^r\xc6\xfa3\x04(\xbeeQ\x07\x05P\x1a\xa4W\xe3\x9ci\xfc\xf7\x15(\xb6A\xee\xb4\x93\x8d\xd85\x9f`?\xf6n\xd8i0v\xadw\xd5\x95X\x87n>\xf1d\x05\x97s\xc9\x99\x93F\xdf\xd5R\xc5K=\xcc\x1bk\xd5^\x1d`\xfc\xa2]\x06PwJ\r\xf0\x9d\xa2\xf6 tw\xcb\xda\x01\xb6}\x83\xd3\xcc\x00\xec\x99\x15\xf4\x88Y\x99\x1f2\x83\xb4\xfc\x8e\x99\xdf\xb3d\x0c\x01.1E\x04\x93l\xff\x8e\xcf\x7f6\xa4Z\xfc\x82\xeaK\x97c BD\xf3\x101\x89g\xba\x8b\x03\xd0?\x97\xff#\xfb{'\x9a\x8b\xe0\x03H\xc89\xfa\x08\x15\x7f\xa2\x0f >\x80_\x0e\xe0\x93\xb3\xf0\xc3\xc4\xd3m\\\xef\xf8\x958\xa0"
#lt=open("logSendByteStringWithoutN.log","wb") #lt=open("logSendByteStringWithoutN.log","wb")
@ -70,7 +69,6 @@ def ProcessChildSendString(lProcess,lString):
lByteString = lByteString.replace(b'\n',b'{{n}}') lByteString = lByteString.replace(b'\n',b'{{n}}')
#Отправить сообщение в дочерний процесс #Отправить сообщение в дочерний процесс
lProcess.stdin.write(lByteString+bytes('\n',"utf-8")) lProcess.stdin.write(lByteString+bytes('\n',"utf-8"))
#print(str(lByteString+bytes('\n',"utf-8")))
lProcess.stdin.flush() lProcess.stdin.flush()
#Вернуть результат #Вернуть результат
return return
@ -80,7 +78,6 @@ def ProcessChildReadWaitString(lProcess):
#Ожидаем ответ от процесса #Ожидаем ответ от процесса
lResult = lProcess.stdout.readline() lResult = lProcess.stdout.readline()
#Обработка спец символов #Обработка спец символов
#print(b'NewLine: '+lResult)
#Вернуть потенциальные \n #Вернуть потенциальные \n
lResult = lResult.replace(b'{{{n}}}',b'\n') lResult = lResult.replace(b'{{{n}}}',b'\n')
#Вернуть \r #Вернуть \r
@ -97,8 +94,6 @@ def ProcessChildReadWaitString(lProcess):
lResult = lResult.replace(b'{{{v}}}',b'\v') lResult = lResult.replace(b'{{{v}}}',b'\v')
#Вернуть \f #Вернуть \f
lResult = lResult.replace(b'{{{f}}}',b'\f') lResult = lResult.replace(b'{{{f}}}',b'\f')
#print("check")
#print(str(lResult))
lResult = zlib.decompress(lResult[0:-1]) lResult = zlib.decompress(lResult[0:-1])
lResult = lResult.decode("utf-8") lResult = lResult.decode("utf-8")
#Вернуть результат #Вернуть результат

@ -0,0 +1,108 @@
import pdb
import json
import subprocess
import zlib
import os
from . import ProcessCommunicator
import importlib
import traceback
import logging
import sys
import datetime
import struct
import shutil
from pyOpenRPA.Robot import UIDesktop
global mGlobalDict
####################################
#Info: Main module of the Robot app (OpenRPA - Robot)
####################################
#Usage:
#Here you can run some activity or list of activities
#After import this module you can use the folowing functions:
#ActivityRun(inActivitySpecificationDict): outActivityResultDict - function - run activity (function or procedure)
#ActivityRunJSON(inActivitySpecificationDictJSON): outActivityResultDictJSON
#ActivityListRun(inActivitySpecificationDictList): outActivityResultDictList - function - run list of activities (function or procedure)
#ActivityListRunJSON(inActivitySpecificationDictListJSON): outActivityResultDictListJSON
#Naming:
#Activity - some action/list of actions
#Module - Any *.py file, which consist of area specific functions
#Argument
#inActivitySpecificationDict:
#{
# ModuleName: <"GUI"|..., str>,
# ActivityName: <Function or procedure name in module, str>,
# ArgumentList: [<Argument 1, any type>, ...] - optional,
# ArgumentDict: {<Argument 1 name, str>:<Argument 1 value, any type>, ...} - optional
#}
#outActivityResultDict:
#{
# ActivitySpecificationDict: {
# ModuleName: <"GUI"|..., str>,
# ActivityName: <Function or procedure name in module, str>,
# ArgumentList: [<Argument 1, any type>, ...] - optional,
# ArgumentDict: {<Argument 1 name, str>: <Argument 1 value, any type>, ...} - optional
# },
# ErrorFlag: <Boolean flag - Activity result has error (true) or not (false), boolean>,
# ErrorMessage: <Error message, str> - required if ErrorFlag is true,
# ErrorTraceback: <Error traceback log, str> - required if ErrorFlag is true,
# Result: <Result, returned from the Activity, int, str, boolean, list, dict> - required if ErrorFlag is false
#}
####################
#Section: Activity
####################
def ActivityRun(inActivitySpecificationDict):
lResponseObject = {}
#Выполнить отправку в модуль UIDesktop, если ModuleName == "UIDesktop"
if inActivitySpecificationDict["ModuleName"] == "UIDesktop":
if "ArgumentList" not in inActivitySpecificationDict:
inActivitySpecificationDict["ArgumentList"]=[]
if "ArgumentDict" not in inActivitySpecificationDict:
inActivitySpecificationDict["ArgumentDict"]={}
#Run the activity
try:
#Найти функцию
lFunction=getattr(UIDesktop,inActivitySpecificationDict["ActivityName"])
#Выполнить вызов и записать результат
lResponseObject["Result"]=lFunction(*inActivitySpecificationDict["ArgumentList"],**inActivitySpecificationDict["ArgumentDict"])
except Exception as e:
#Установить флаг ошибки и передать тело ошибки
lResponseObject["ErrorFlag"]=True
lResponseObject["ErrorMessage"]=str(e)
lResponseObject["ErrorTraceback"]=traceback.format_exc()
#Остальные модули подключать и выполнять здесь
else:
lArgumentList=[]
if "ArgumentList" in inActivitySpecificationDict:
lArgumentList=inActivitySpecificationDict["ArgumentList"]
lArgumentDict={}
if "ArgumentDict" in inActivitySpecificationDict:
lArgumentDict=inActivitySpecificationDict["ArgumentDict"]
#Подготовить результирующую структуру
lResponseObject={"ActivitySpecificationDict":inActivitySpecificationDict,"ErrorFlag":False}
try:
#Подключить модуль для вызова
lModule=importlib.import_module(inActivitySpecificationDict["ModuleName"])
#Найти функцию
lFunction=getattr(lModule,inActivitySpecificationDict["ActivityName"])
#Выполнить вызов и записать результат
lResponseObject["Result"]=lFunction(*lArgumentList,**lArgumentDict)
except Exception as e:
#Установить флаг ошибки и передать тело ошибки
lResponseObject["ErrorFlag"]=True
lResponseObject["ErrorMessage"]=str(e)
lResponseObject["ErrorTraceback"]=traceback.format_exc()
return lResponseObject
#########################################################
#Run list of activities
#########################################################
def ActivityListRun(inActivitySpecificationDictList):
lResult=[]
for lItem in inActivitySpecificationDictList:
lResult.append(ActivityRun(lItem))
return lResult

@ -5,12 +5,30 @@ import json
import subprocess import subprocess
import zlib import zlib
import os import os
from . import ProcessCommunicator
import sys import sys
import traceback import traceback
from pyOpenRPA.Robot import Robot from . import RobotConnector
import importlib
#Единый глобальный словарь (За основу взять из Settings.py)
global mGlobalDict
#Call Settings function from argv[1] file
################################################
lSubmoduleFunctionName = "Settings"
lFileFullPath = sys.argv[1]
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
if lSubmoduleFunctionName in dir(lTechModuleFromSpec):
# Run SettingUpdate function in submodule
mGlobalDict = getattr(lTechModuleFromSpec, lSubmoduleFunctionName)()
#################################################
RobotConnector.mGlobalDict = mGlobalDict
#Init the robot
RobotConnector.UIDesktop.Utils.ProcessBitness.SettingsInit(mGlobalDict["ProcessBitness"])
# HTTPRequestHandler class # HTTP Studio web server class
class testHTTPServer_RequestHandler(BaseHTTPRequestHandler): class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
#ResponseContentTypeFile #ResponseContentTypeFile
def SendResponseContentTypeFile(self,inContentType,inFilePath): def SendResponseContentTypeFile(self,inContentType,inFilePath):
@ -82,7 +100,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
#pdb.set_trace() #pdb.set_trace()
lRequestObject=lInputObject lRequestObject=lInputObject
#Отправить команду роботу #Отправить команду роботу
lResponseObject=Robot.ActivityRun(lRequestObject) lResponseObject=RobotConnector.ActivityRun(lRequestObject)
message = json.dumps(lResponseObject) message = json.dumps(lResponseObject)
except Exception as e: except Exception as e:
#Установить флаг ошибки #Установить флаг ошибки
@ -113,7 +131,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
lRequestObject=lInputObject lRequestObject=lInputObject
lOutputObject=[] lOutputObject=[]
#pdb.set_trace() #pdb.set_trace()
lResponseObject=Robot.ActivityListRun(lRequestObject) lResponseObject=RobotConnector.ActivityListRun(lRequestObject)
#Сформировать текстовый ответ #Сформировать текстовый ответ
message = json.dumps(lResponseObject) message = json.dumps(lResponseObject)
# Write content as utf-8 data # Write content as utf-8 data
@ -121,14 +139,15 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
return return
def run(): def run():
print('starting server...') inServerAddress = "";
inPort = mGlobalDict["Server"]["ListenPort"];
# Server settings # Server settings
# Choose port 8080, for port 80, which is normally used for a http server, you need root access # Choose port 8080, for port 80, which is normally used for a http server, you need root access
server_address = ('127.0.0.1', 8081) server_address = (inServerAddress, inPort)
httpd = HTTPServer(server_address, testHTTPServer_RequestHandler) httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
print('running server...') # Logging
#Запуск адреса в браузере mGlobalDict["Logger"].info(f"Server init. Listen URL: {inServerAddress}, Listen port: {inPort}")
os.system("explorer http://127.0.0.1:8081") # Запуск адреса в браузере
os.system(f"explorer http://127.0.0.1:{str(inPort)}")
httpd.serve_forever() httpd.serve_forever()
#print(ChildProcessReadWaitString(p))
run() run()

@ -9,6 +9,115 @@
crossorigin="anonymous"></script> crossorigin="anonymous"></script>
<script src="3rdParty/Semantic-UI-CSS-master/semantic.min.js"></script> <script src="3rdParty/Semantic-UI-CSS-master/semantic.min.js"></script>
<script> <script>
// Production steps of ECMA-262, Edition 6, 22.1.2.1
if (!Array.from) {
Array.from = (function () {
var toStr = Object.prototype.toString;
var isCallable = function (fn) {
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
};
var toInteger = function (value) {
var number = Number(value);
if (isNaN(number)) { return 0; }
if (number === 0 || !isFinite(number)) { return number; }
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
};
var maxSafeInteger = Math.pow(2, 53) - 1;
var toLength = function (value) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
};
// The length property of the from method is 1.
return function from(arrayLike/*, mapFn, thisArg */) {
// 1. Let C be the this value.
var C = this;
// 2. Let items be ToObject(arrayLike).
var items = Object(arrayLike);
// 3. ReturnIfAbrupt(items).
if (arrayLike == null) {
throw new TypeError('Array.from requires an array-like object - not null or undefined');
}
// 4. If mapfn is undefined, then let mapping be false.
var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
var T;
if (typeof mapFn !== 'undefined') {
// 5. else
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
if (!isCallable(mapFn)) {
throw new TypeError('Array.from: when provided, the second argument must be a function');
}
// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (arguments.length > 2) {
T = arguments[2];
}
}
// 10. Let lenValue be Get(items, "length").
// 11. Let len be ToLength(lenValue).
var len = toLength(items.length);
// 13. If IsConstructor(C) is true, then
// 13. a. Let A be the result of calling the [[Construct]] internal method
// of C with an argument list containing the single item len.
// 14. a. Else, Let A be ArrayCreate(len).
var A = isCallable(C) ? Object(new C(len)) : new Array(len);
// 16. Let k be 0.
var k = 0;
// 17. Repeat, while k < len (also steps a - h)
var kValue;
while (k < len) {
kValue = items[k];
if (mapFn) {
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
} else {
A[k] = kValue;
}
k += 1;
}
// 18. Let putStatus be Put(A, "length", len, true).
A.length = len;
// 20. Return A.
return A;
};
}());
}
if (!Object.assign) {
Object.defineProperty(Object, 'assign', {
enumerable: false,
configurable: true,
writable: true,
value: function(target, firstSource) {
'use strict';
if (target === undefined || target === null) {
throw new TypeError('Cannot convert first argument to object');
}
var to = Object(target);
for (var i = 1; i < arguments.length; i++) {
var nextSource = arguments[i];
if (nextSource === undefined || nextSource === null) {
continue;
}
var keysArray = Object.keys(Object(nextSource));
for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
var nextKey = keysArray[nextIndex];
var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
if (desc !== undefined && desc.enumerable) {
to[nextKey] = nextSource[nextKey];
}
}
}
return to;
}
});
}
var mGlobal={} var mGlobal={}
$(document) $(document)
.ready(function() { .ready(function() {
@ -17,11 +126,8 @@
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
mGlobal.Settings={} mGlobal.Settings={}
mGlobal.Settings.mUIOTreeHeight=450 mGlobal.Settings.mUIOTreeHeight=450
mGlobal.GUIElement={} mGlobal.GUIElement={}
mGlobal.GenerateUniqueID=function(inPrefix="ID") { mGlobal.GenerateUniqueID=function(inPrefix) {
return inPrefix+Math.round(Math.random()*1000)+"-"+Math.round(Math.random()*10000)+"-"+Math.round(Math.random()*1000) return inPrefix+Math.round(Math.random()*1000)+"-"+Math.round(Math.random()*10000)+"-"+Math.round(Math.random()*1000)
} }
///Инициализация ///Инициализация
@ -158,7 +264,7 @@
} }
///Функция визуализации дерева ///Функция визуализации дерева
mGlobal.ElementTree.fRender = function(inElementsTreeDataArray,inBackendString="-") mGlobal.ElementTree.fRender = function(inElementsTreeDataArray,inBackendString)
{ {
var lHTMLList= var lHTMLList=
'<b style="font-size:10px;" >Backend: '+inBackendString+'</b>\ '<b style="font-size:10px;" >Backend: '+inBackendString+'</b>\
@ -166,7 +272,7 @@
///Циклический обход списка ///Циклический обход списка
for (var i = 0; i< inElementsTreeDataArray.length;i++) { for (var i = 0; i< inElementsTreeDataArray.length;i++) {
///Добавить HTML код позиции ///Добавить HTML код позиции
lHTMLList+=mGlobal.ElementTree.fItemGenerateHTML_JS(inElementsTreeDataArray[i]) lHTMLList+=mGlobal.ElementTree.fItemGenerateHTML_JS(inElementsTreeDataArray[i],[])
} }
///Закрывающая список HTML ///Закрывающая список HTML
lHTMLList+="</div>" lHTMLList+="</div>"
@ -176,9 +282,9 @@
} }
///Функция визуализации дерева ///Функция визуализации дерева
///Вызов создания вложенного листа, если имеется атрибут SpecificationChild ///Вызов создания вложенного листа, если имеется атрибут SpecificationChild
mGlobal.ElementTree.fItemGenerateHTML_JS = function(inItem,inParentSpecification=[]){ mGlobal.ElementTree.fItemGenerateHTML_JS = function(inItem,inParentSpecification){
///Генерация уникального кода для элемента ///Генерация уникального кода для элемента
var lElementId = mGlobal.GenerateUniqueID() var lElementId = mGlobal.GenerateUniqueID("ID")
//Добавить информацию об элементе в словарь JS //Добавить информацию об элементе в словарь JS
///Урезанная часть селектора (сделать, чтобы была без SpecificationChild) ///Урезанная часть селектора (сделать, чтобы была без SpecificationChild)
var lSelectorLocal={}; var lSelectorLocal={};
@ -245,7 +351,7 @@
var lHTMLTree='<div class="ui list">' var lHTMLTree='<div class="ui list">'
var lResponseJSON=JSON.parse(lData) var lResponseJSON=JSON.parse(lData)
for (i=0;i<lResponseJSON.Result.length;i++) { for (i=0;i<lResponseJSON.Result.length;i++) {
var lElementId = mGlobal.GenerateUniqueID() var lElementId = mGlobal.GenerateUniqueID("ID")
var lSubItemHandleId=lResponseJSON.Result[i].handle; var lSubItemHandleId=lResponseJSON.Result[i].handle;
var lSubItemActionOnClick=' onclick="mGlobal.TreeLoadSubTree(\''+lElementId+'\');" ' var lSubItemActionOnClick=' onclick="mGlobal.TreeLoadSubTree(\''+lElementId+'\');" '
var lSubItemActionOnRightClick=' onclick="mGlobal.ElementHighlightNew(\''+lElementId+'\');" ' var lSubItemActionOnRightClick=' onclick="mGlobal.ElementHighlightNew(\''+lElementId+'\');" '
@ -293,7 +399,7 @@
var lSpecificationArrayNew=[] var lSpecificationArrayNew=[]
for (i=0;i<lSpecificationArray.length;i++) { for (i=0;i<lSpecificationArray.length;i++) {
lSpecificationArrayNew.push(lSpecificationArray[i]) lSpecificationArrayNew.push(lSpecificationArray[i])
var lElementId = mGlobal.GenerateUniqueID() var lElementId = mGlobal.GenerateUniqueID("ID")
var lOnClickSelect= ' onclick="mGlobal.ElementPropertyListLoad(\''+lElementId+'\');" ' var lOnClickSelect= ' onclick="mGlobal.ElementPropertyListLoad(\''+lElementId+'\');" '
lHTMLList+='\ lHTMLList+='\
<div class="item" id="'+lElementId+'" '+lOnClickSelect+'>\ <div class="item" id="'+lElementId+'" '+lOnClickSelect+'>\
@ -679,7 +785,7 @@
///Очистить дерево ///Очистить дерево
mGlobal.ElementTree.fClear(); mGlobal.ElementTree.fClear();
///Прогрузить новое дерево ///Прогрузить новое дерево
mGlobal.ElementTree.fRender(lResponseJSON.Result,$(".openrpa-value-backend")[0].value); mGlobal.ElementTree.fRender(lResponseJSON.Result,$(".openrpa-value-backend")[0].value,"-");
///Показать ошибку, если таковая возникла ///Показать ошибку, если таковая возникла
if (lResponseJSON["ErrorFlag"]) { if (lResponseJSON["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lResponseJSON.ErrorMessage+" \nTraceback: "+lResponseJSON.ErrorTraceback); mGlobal.ShowModal("GUI Error",lResponseJSON.ErrorMessage+" \nTraceback: "+lResponseJSON.ErrorTraceback);

@ -78,12 +78,15 @@ def SessionRDPStart(inRDPFilePath):
[ [
[{"title": "Подключение к удаленному рабочему столу", "class_name": "#32770", "backend": "win32"}, [{"title": "Подключение к удаленному рабочему столу", "class_name": "#32770", "backend": "win32"},
{"title": "Боль&ше не выводить запрос о подключениях к этому компьютеру", "friendly_class_name": "CheckBox"}], {"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} — .*", [{"title_re": f"{lRDPFileName} — .*",
"class_name": "TscShellContainerClass", "backend": "win32"}] "class_name": "TscShellContainerClass", "backend": "win32"}]
], ],
60 30
) )
#Click if 0 is appear #Click if 0 is appear (RUS)
if 0 in lWaitResult: if 0 in lWaitResult:
#Check the box do not retry #Check the box do not retry
UIDesktop.UIOSelector_Get_UIO([{"title": "Подключение к удаленному рабочему столу", "backend": "win32"}, UIDesktop.UIOSelector_Get_UIO([{"title": "Подключение к удаленному рабочему столу", "backend": "win32"},
@ -96,7 +99,23 @@ def SessionRDPStart(inRDPFilePath):
[{"title_re": f"{lRDPFileName} — .*", [{"title_re": f"{lRDPFileName} — .*",
"class_name": "TscShellContainerClass", "backend": "win32"}] "class_name": "TscShellContainerClass", "backend": "win32"}]
], ],
60 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
) )
#Prepare little window #Prepare little window
SessionScreen100x550(lRDPFileName) SessionScreen100x550(lRDPFileName)

@ -1,17 +1,34 @@
from pyOpenRPA.Robot import UIDesktop from pyOpenRPA.Robot import UIDesktop
from . import Connector from . import Connector
import os
import pdb import pdb
#Check for session is closed. Reopen if detected. Always keep session is active #Check for session is closed. Reopen if detected. Always keep session is active
def Monitor(inGlobalDict, inListUpdateTimeout): def Monitor(inGlobalDict, inListUpdateTimeout):
while True: lFlagWhile = True
while lFlagWhile:
# UIOSelector list init # UIOSelector list init
lUIOSelectorList = [] lUIOSelectorList = []
for lItem in inGlobalDict["RDPList"]: for lItem in inGlobalDict["RDPList"]:
lUIOSelectorList.append([{"title_re": f"{lItem['SessionHex']} — .*", "backend": "win32"}]) lUIOSelectorList.append([{"title_re": f"{lItem['SessionHex']} — .*", "backend": "win32"}])
#Run wait command #Run wait command
lRDPDissappearList = UIDesktop.UIOSelectorsSecs_WaitDisappear_List(lUIOSelectorList, inListUpdateTimeout) lRDPDissappearList = UIDesktop.UIOSelectorsSecs_WaitDisappear_List(lUIOSelectorList, inListUpdateTimeout)
#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["FlagSessionIsActive"]=False
#Kill all RDP sessions
os.system('taskkill /F /im mstsc.exe')
#Return from function
return
for lItem in lRDPDissappearList: for lItem in lRDPDissappearList:
inGlobalDict["RDPList"][lItem]["FlagSessionIsActive"] = False # Set flag that session is disconnected
#pdb.set_trace() #pdb.set_trace()
#Session start #Session start
try:
Connector.Session(inGlobalDict["RDPList"][lItem]) Connector.Session(inGlobalDict["RDPList"][lItem])
except Exception:
pass
return None return None
#TODO Def garbage window cleaner (if connection was lost)

@ -1,22 +0,0 @@
#Robot RDPActive settings
def Settings():
mDict = {
"RDPList":
[
{
"Host": "77.77.22.22", # Host address
"Port": "7777", # RDP Port
"Login": "test", # Login
"Password": "test", # Password
"Screen": {
"Width": 1680, #Width of the remote desktop in pixels
"Height": 1050, #Height of the remote desktop in pixels
# "640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen
"FlagUseAllMonitors": False, # True or False
"DepthBit": "32" # "32" or "24" or "16" or "15"
},
"SessionHex":"" # Hex is created when robot runs
}
]
}
return mDict

@ -35,9 +35,15 @@ lCMDString = 'reg add "HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server C
os.system(lCMDString) os.system(lCMDString)
#time.sleep() #time.sleep()
for lConfigurationItem in mGlobalDict["RDPList"]: for lConfigurationItem in mGlobalDict["RDPList"]:
try:
Connector.Session(lConfigurationItem) Connector.Session(lConfigurationItem)
lConfigurationItem["FlagSessionIsActive"]=True #Flag that session is started
except Exception:
pass
#Run monitor #Run monitor
Monitor.Monitor(mGlobalDict, 1) Monitor.Monitor(mGlobalDict, 1)
#Enable certificate warning #Enable certificate warning
lCMDString = 'reg add "HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client" /v "AuthenticationLevelOverride" /t "REG_DWORD" /d 2 /f' lCMDString = 'reg add "HKEY_CURRENT_USER\\Software\\Microsoft\\Terminal Server Client" /v "AuthenticationLevelOverride" /t "REG_DWORD" /d 2 /f'
os.system(lCMDString) os.system(lCMDString)
#Close all thread from OrchestratorConnection
mGlobalDict["OrchestratorConnectorTerminateAll"]()

@ -3,7 +3,7 @@ r"""
The OpenRPA package (from UnicodeLabs) The OpenRPA package (from UnicodeLabs)
""" """
__version__ = 'v1.0.32' __version__ = 'v1.0.34'
__all__ = [] __all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>' __author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'
#from .Core import Robot #from .Core import Robot

@ -1,24 +1,35 @@
import logging import logging
import datetime #Robot settings
from pyOpenRPA.Robot import OrchestratorConnector from pyOpenRPA.Robot import OrchestratorConnector
import os
import logging
import datetime
#Definitions
lOrchestratorHost="localhost"
lOrchestratorPort=8081
lOrchestratorProtocol="http"
lOrchestratorAuthToken="1992-04-03-0643-ru-b4ff-openrpa52zzz"
#Robot settings #Robot settings
def Settings(): def Settings():
import os import os
mDict = { mDict = {
"Logger": logging.getLogger("Robot"),
"Storage": {
"Robot_R01_help": "Robot data storage in orchestrator env",
"Robot_R01": {}
},
"ProcessBitness": { "ProcessBitness": {
"Python32FullPath": None, #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe" "Python32FullPath": None, #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe"
"Python64FullPath": None, #Set from user "Python64FullPath": None, #Set from user
"Python32ProcessName": "OpenRPAUIDesktopX32.exe", #Config set once "Python32ProcessName": "OpenRPAUIDesktopX32.exe", #Config set once
"Python64ProcessName": "OpenRPAUIDesktopX64.exe" #Config set once "Python64ProcessName": "OpenRPAUIDesktopX64.exe" #Config set once
}, },
"Logger": logging.getLogger("Robot"),
"OrchestratorToRobotStorage": {
},
"OrchestratorToRobotResetStorage": {
"SafeTurnOff":False #Control from orchestrator to safety turn off robot
},
"OrchestratorConnector": { "OrchestratorConnector": {
#Fill below #Fill below
} },
"OrchestratorConnectorTerminateAll":OrchestratorConnector.IntervalTermimateAll #Call this function when program must be shutted down (to kill threads from OrchestratorConnector)
} }
###################### ######################
#OrchestratorConnector #OrchestratorConnector
@ -31,10 +42,10 @@ def Settings():
"RobotStorageKey": "R01_OrchestratorToRobot", "RobotStorageKey": "R01_OrchestratorToRobot",
"RobotResetValue": {"Test": "Test"}, "RobotResetValue": {"Test": "Test"},
"OrchestratorKeyList": ["Storage", "R01_OrchestratorToRobot"], "OrchestratorKeyList": ["Storage", "R01_OrchestratorToRobot"],
"OrchestratorProtocol": "http", "OrchestratorProtocol": lOrchestratorProtocol,
"OrchestratorHost": "localhost", "OrchestratorHost": lOrchestratorHost,
"OrchestratorPort": 8081, "OrchestratorPort": lOrchestratorPort,
"OrchestratorAuthToken": "1992-04-03-0643-ru-b4ff-openrpa52zzz" "OrchestratorAuthToken": lOrchestratorAuthToken
} }
] ]
} }

@ -1,4 +1,5 @@
cd %~dp0 cd %~dp0
RD /S /Q "__pycache__"
RD /S /Q "build" RD /S /Q "build"
RD /S /Q "dist" RD /S /Q "dist"
.\..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe setup.py sdist bdist_wheel .\..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe setup.py sdist bdist_wheel

@ -0,0 +1,5 @@
recursive-include pyOpenRPA\Resources *
recursive-include pyOpenRPA\Orchestrator\Web *
recursive-include pyOpenRPA\Studio\Web *
include pyOpenRPA\Tools\RobotRDPActive\Template.rdp
include pyOpenRPA\Tools\RobotScreenActive\ConsoleStart.bat

@ -1,3 +1,6 @@
cd %~dp0 cd %~dp0
RD /S /Q "__pycache__"
RD /S /Q "build"
RD /S /Q "dist"
.\..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe setup.py sdist bdist_wheel .\..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe setup.py sdist bdist_wheel
pause >nul pause >nul

@ -3,7 +3,7 @@ r"""
The OpenRPA package (from UnicodeLabs) The OpenRPA package (from UnicodeLabs)
""" """
__version__ = 'v1.0.32' __version__ = 'v1.0.34'
__all__ = [] __all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>' __author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'
#from .Core import Robot #from .Core import Robot

@ -46,5 +46,5 @@ setup(name='pyOpenRPA',
], ],
include_package_data=True, include_package_data=True,
#data_files = datafiles, #data_files = datafiles,
#package_data = {"": datafiles}, #package_data = {"pyOpenRPA": datafiles},
zip_safe=False) zip_safe=False)

@ -1,4 +1,4 @@
cd %~dp0\..\Sources cd %~dp0\..\Sources
copy /Y ..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe ..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_Studio.exe copy /Y ..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe ..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_Studio.exe
.\..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_Studio.exe -m pyOpenRPA.Studio "..\Studio\Settings.py" .\..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_Studio.exe -m pyOpenRPA.Studio "..\Studio\SettingsStudioExample.py"
pause >nul pause >nul

@ -38,7 +38,7 @@ def Settings():
"OrchestratorConnector": { "OrchestratorConnector": {
#Fill below #Fill below
}, },
"OrchestratorConnectorTerminateAll":OrchestratorConnector.IntervalTermimateAll "OrchestratorConnectorTerminateAll":OrchestratorConnector.IntervalTermimateAll #Call this function when program must be shutted down (to kill threads from OrchestratorConnector)
} }
###################### ######################
#OrchestratorConnector #OrchestratorConnector

@ -1,4 +1,4 @@
cd %~dp0..\..\Sources cd %~dp0..\..\Sources
copy /Y ..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe ..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_RobotRDPActive.exe copy /Y ..\Resources\WPy64-3720\python-3.7.2.amd64\python.exe ..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_RobotRDPActive.exe
..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_RobotRDPActive.exe -m pyOpenRPA.Tools.RobotRDPActive "C:\Abs\Archive\scopeSrcUL\OpenRPA_Creds\RobotRDPActive\SettingsVSK.py" ..\Resources\WPy64-3720\python-3.7.2.amd64\OpenRPA_RobotRDPActive.exe -m pyOpenRPA.Tools.RobotRDPActive "..\Utils\RobotRDPActive\SettingsRobotRDPActiveExample.py"
pause >nul pause >nul

@ -1,4 +1,6 @@
Beta before 1.0.1 (new way of OpenRPA with improovments. Sorry, but no backward compatibility)/ Backward compatibility will start from 1.0.1 Beta before 1.1.0 (new way of OpenRPA with improovments. Sorry, but no backward compatibility)/ Backward compatibility will start from 1.0.1
[1.0.33]
Manu changes - look git
[1.0.31] [1.0.31]
Orchestrator new engine - test 2 is ready. Go to PIP Orchestrator new engine - test 2 is ready. Go to PIP
[1.0.30] [1.0.30]

Loading…
Cancel
Save