dev-linux
Ivan Maslov 3 years ago
parent b2c0bcf07a
commit aeed68d692

@ -1,22 +1,4 @@
Лицензия-оферта
MIT License
pyOpenRPA License
Copyright (c) 2019 Ivan Maslov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,15 +1,17 @@
Metadata-Version: 2.1
Name: pyOpenRPA
Version: 1.2.6
Version: 1.2.7
Summary: First open source RPA platform for business
Home-page: https://gitlab.com/UnicodeLabs/OpenRPA
Home-page: https://pyopenrpa.ru/
Author: Ivan Maslov
Author-email: Ivan.Maslov@unicodelabs.ru
License: MIT
Keywords: OpenRPA RPA Robot Automation Robotization OpenSource
Author-email: Ivan.Maslov@pyopenrpa.ru
License: PYOPENRPA
Keywords: pyOpenRPA OpenRPA RPA Robot Automation Robotization OpenSource IT4Business
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: MIT License
Classifier: License :: Free For Educational Use
Classifier: License :: Free For Home Use
Classifier: License :: Free for non-commercial use
Classifier: Intended Audience :: Developers
Classifier: Environment :: Win32 (MS Windows)
Classifier: Environment :: X11 Applications
@ -25,6 +27,7 @@ Requires-Dist: pillow (>=6.0.0)
Requires-Dist: keyboard (>=0.13.3)
Requires-Dist: pyautogui (<=0.9.52)
Requires-Dist: crypto (>=1.4.1)
Requires-Dist: schedule (>=1.1.0)
Requires-Dist: pywinauto (>=0.6.8) ; platform_system == "win32" and python_version >= "3.0"
Requires-Dist: WMI (>=1.4.9) ; platform_system == "win32" and python_version >= "3.0"
Requires-Dist: pywin32 (>=224) ; platform_system == "win32" and python_version >= "3.0"

@ -1,9 +1,9 @@
pyOpenRPA-1.2.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.2.6.dist-info/METADATA,sha256=pU-EpQuvMPYjhD1o2BYjfpOfsruNrxm9s7mfWX9mF1M,3612
pyOpenRPA-1.2.6.dist-info/RECORD,,
pyOpenRPA-1.2.6.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA-1.2.6.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.2.6.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA-1.2.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.2.7.dist-info/METADATA,sha256=BzhjdELqdQkNJuXEIKiYjzPFg1-cNp2PHBfF9sVzBT4,3744
pyOpenRPA-1.2.7.dist-info/RECORD,,
pyOpenRPA-1.2.7.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA-1.2.7.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.2.7.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA/.idea/inspectionProfiles/profiles_settings.xml,sha256=YXLFmX7rPNGcnKK1uX1uKYPN0fpgskYNe7t0BV7cqkY,174
pyOpenRPA/.idea/misc.xml,sha256=V-fQnOz-bYEZULgfbFgm-8mURphZrKfXMSd0wKjeEyA,188
pyOpenRPA/.idea/modules.xml,sha256=Q__U1JIA2cjxbLRXAv-SfYY00fZA0TNlpkkbY4s3ncg,277
@ -11,9 +11,9 @@ pyOpenRPA/.idea/pyOpenRPA.iml,sha256=EXh41F8lqRiSBMVg-n2tKaEaHC6_3gGSuKkPJA12Na0
pyOpenRPA/.idea/vcs.xml,sha256=2HygA1oRAwc3VBf-irxHrX5JJG9DXuQwrN0BlubhoKY,191
pyOpenRPA/.idea/workspace.xml,sha256=6tJZehshdK4And6tEoUvkIB0KE7waL_NnTSkTYYAeFA,3802
pyOpenRPA/Agent/A2O.py,sha256=PlIZZCTnVrYF2i6DSAi_KbzZfc2gtcBPmOerrEZq68U,1718
pyOpenRPA/Agent/O2A.py,sha256=vu7UgiB0qY6-1i9qVWEBGyXWSi68TTNfkvnpMIZH7Vo,4458
pyOpenRPA/Agent/Processor.py,sha256=Co8nWpffgsnEE_TpG9WrpKxz3N0sDF7eFnKxDOk1sd8,4653
pyOpenRPA/Agent/__Agent__.py,sha256=JcMFvSC3_M94HEdZe8AK2IHuJOxeDJi4RpnY_LivWpM,10639
pyOpenRPA/Agent/O2A.py,sha256=XHl5nytUoUqfPvmYWh5auYo-s0GIThNmkOA9ON-JCis,5535
pyOpenRPA/Agent/Processor.py,sha256=xNZfQ_HcV-qm_x90tBLKYJqvnENiTqHSoUk2LhDfqWQ,6346
pyOpenRPA/Agent/__Agent__.py,sha256=RLy7YQyTm_IF9kjZ22k7hd5E7wRTBSau_zsxBtW17l0,12554
pyOpenRPA/Agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Agent/__pycache__/A2O.cpython-37.pyc,,
pyOpenRPA/Agent/__pycache__/O2A.cpython-37.pyc,,
@ -22,20 +22,28 @@ pyOpenRPA/Agent/__pycache__/__Agent__.cpython-37.pyc,,
pyOpenRPA/Agent/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Agent/readme.md,sha256=QF_Bnv204OK3t1JUEhjfICkxFmSdX6bvaRl_HI6lH9I,19
pyOpenRPA/Info.md,sha256=u4Nv-PjniSF0Zlbtr6jEJX2vblK3_1zhSLNUgOdtDaA,85
pyOpenRPA/Orchestrator/BackwardCompatibility.py,sha256=a2UZINDnHCKZVvHtOOPMyFZmDynzfcyQhFJCEEMhadY,34599
pyOpenRPA/Orchestrator/BackwardCompatibility.py,sha256=CpJtOc_WnV14AGIU7FKVRuemlf9bSr4Eo5_67wuyi_k,37506
pyOpenRPA/Orchestrator/ControlPanel.py,sha256=OzS8HjG__8OZgqhajr8L8owyugXPuSLWHLtXuKdEP78,103
pyOpenRPA/Orchestrator/Core.py,sha256=Kjphtu0g6iaS4D_fIWmzRaLLgBQ9fcwccpQJhOETTAc,521
pyOpenRPA/Orchestrator/Processor.py,sha256=Z1SglmX6ykTLifD3M1mzWEJQUgweWo6HjjCjHldjGyM,8594
pyOpenRPA/Orchestrator/Core.py,sha256=OHa3mSC3_wRAizqrWBVjlR6ln4-xVVvBpOSnWl6qVvY,529
pyOpenRPA/Orchestrator/Managers/ControlPanel.py,sha256=BgtLjb6PR6kTlOjPLCg2YGP458LS9JOaYEfNurhS0nk,16544
pyOpenRPA/Orchestrator/Managers/Git.py,sha256=dgXx2UzSwiEev4ov2hBbb-5MhXVhFKWZo2lmr19QSCQ,12582
pyOpenRPA/Orchestrator/Managers/Process.py,sha256=7T_qofdkRJHdPQbaiEsTDOboImSf2N6d_Ku513rURkw,41369
pyOpenRPA/Orchestrator/Managers/__init__.py,sha256=4my0XiwmI_QLRQVhOzNvWTggCosF3tb2yRxGkehOCq0,71
pyOpenRPA/Orchestrator/Managers/__pycache__/ControlPanel.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Managers/__pycache__/Git.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Managers/__pycache__/Process.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Managers/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Processor.py,sha256=FtNmdIsBStkLHLlOe6MDWzSmZv9m7ntlQs-NirA6OgQ,10264
pyOpenRPA/Orchestrator/ProcessorOld.py,sha256=Vh5zLRpWWf-vt9CCYI8nDY7oaefiufnu6Pnl4tp27pY,13749
pyOpenRPA/Orchestrator/RobotRDPActive/CMDStr.py,sha256=6otw1WnR2_evvQ5LGyOVh0BLk_nTdilViGub7p56fXQ,1531
pyOpenRPA/Orchestrator/RobotRDPActive/Clipboard.py,sha256=YB5HJL-Qf4IlVrFHyRv_ZMJ0Vo4vjyYqWKjvrTnf1k4,1564
pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py,sha256=Qwf194uO_wcO3kBe2hTI0py90ZC1ejDUGeh6UWEfavc,27789
pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py,sha256=_rTktGLcPaQoPUi482vnUWoeuB0zZcyS3k5kwEbvnM8,28021
pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py,sha256=wwH9JOoMFFxDKQ7IyNyh1OkFkZ23o1cD8Jm3n31ycII,657
pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=AQ_u9QVSLpce9hhSacm3UT98bErc636MXza4Q6mHsSc,12264
pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=bMahu6wRznmoLYsopgbNOLqufcQnEDanIepuGvXIsac,12405
pyOpenRPA/Orchestrator/RobotRDPActive/Recovery.py,sha256=jneD474V-ZBYnmQFxWoY_feGNMSL0lGaRK6TEfQ6gOc,2954
pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py,sha256=5FX48HlIn8NKfs7q_rp3lpumWtNcwdHq7J8ygnOwU_g,12284
pyOpenRPA/Orchestrator/RobotRDPActive/Scheduler.py,sha256=21N0ilFzWI1mj3X5S9tPMgwvG7BviuBxfTuqBY85Hy4,9144
pyOpenRPA/Orchestrator/RobotRDPActive/Template.rdp,sha256=JEMVYkEmNcfg_p8isdIyvj9E-2ZB5mj-R3MkcNMKxkA,2426
pyOpenRPA/Orchestrator/RobotRDPActive/Template.rdp,sha256=YjIxCXyIvDtZx-MPpyHPj3quT9dlUZPuuILiB21eRpU,2462
pyOpenRPA/Orchestrator/RobotRDPActive/Timer.py,sha256=y8--fUvg10qEFomecl_cmdWpdGjarZBlFpMbs_GvzoQ,1077
pyOpenRPA/Orchestrator/RobotRDPActive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Orchestrator/RobotRDPActive/__main__.py,sha256=z9PaUK4_nBiGd0YJdYVHV_rFx6VjZaxrrmKxSyoTFwY,2508
@ -51,7 +59,7 @@ pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Timer.cpython-37.pyc,,
pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Orchestrator/RobotScreenActive/ConsoleStart.bat,sha256=_HNadUKHOYI5y6foG3srh8wjSzhX33xaKNylFtDjOJk,114
pyOpenRPA/Orchestrator/RobotScreenActive/Monitor.py,sha256=TV-YisVqa_uGiyJLG9oK4u-5aDjGiFYZFh1dPjOgYc8,492
pyOpenRPA/Orchestrator/RobotScreenActive/Monitor.py,sha256=6gIiWFyacMvudv9t3D7jxz6uVHUt53b-SS3Ebqo2_lo,492
pyOpenRPA/Orchestrator/RobotScreenActive/Screen.py,sha256=VnYcvCVymrD35l2J4ln_tlVn7CilZhxE4Ggw9P-OhIw,606
pyOpenRPA/Orchestrator/RobotScreenActive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Orchestrator/RobotScreenActive/__main__.py,sha256=JASxDDVKWUU7DAbDkRrGTrPk-P7LZchTZFh8usp6b4U,593
@ -59,21 +67,21 @@ pyOpenRPA/Orchestrator/RobotScreenActive/__pycache__/Monitor.cpython-37.pyc,,
pyOpenRPA/Orchestrator/RobotScreenActive/__pycache__/Screen.cpython-37.pyc,,
pyOpenRPA/Orchestrator/RobotScreenActive/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Orchestrator/RobotScreenActive/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Server.py,sha256=Ke89zh5iZezhA_qyQ3sfWJmL9bfc1rBBYeq-WzznfsE,30432
pyOpenRPA/Orchestrator/ServerSettings.py,sha256=zVI-brV_58uKJ-MWESTZGYv89nN_0iW_-HfVNhip4jE,32890
pyOpenRPA/Orchestrator/SettingsTemplate.py,sha256=-LIyHRKVnbrALAyss6r6L56jBX_yOAdMEhnj8N2fN9A,20532
pyOpenRPA/Orchestrator/Server.py,sha256=DbvHZTTItOBbYiykn2GMjG2r6iUsXUqQZZjjnYPnZ8Q,32455
pyOpenRPA/Orchestrator/ServerSettings.py,sha256=YaZem-osX1bD8gnJyuYU0PWDOnhqkacmXjXXHYLqW3g,31731
pyOpenRPA/Orchestrator/SettingsTemplate.py,sha256=ij1quU5ENu43QjccHYsy8SwPCGibqJNGwcDaoF7cAPo,21340
pyOpenRPA/Orchestrator/Timer.py,sha256=HvYtEeH2Q5WVVjgds9XaBpWRmvZgwgBXurJDdVVq_T0,2097
pyOpenRPA/Orchestrator/Utils/LoggerHandlerDumpLogList.py,sha256=hD47TiOuKR-G8IWu9lJD2kG28qlH7YZV63i3qv1N5Dk,681
pyOpenRPA/Orchestrator/Utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Orchestrator/Utils/__pycache__/LoggerHandlerDumpLogList.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Utils/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Web/Basic.py,sha256=pPH55rPwZz1ktpzNIcC51jeV2MgZI10Zf0Q0DncihDw,7757
pyOpenRPA/Orchestrator/Web/Index.js,sha256=Blo3LHe_a3zrW7MqYo4BSIwoOx7nlO7Ko9LWxfeqU_o,39090
pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=a4N_reLA6_Zb2KXiL73a7cWtJwO0W0Dr5lZ-RpUwuI0,16428
pyOpenRPA/Orchestrator/Web/Index.js,sha256=YACiZAvjr6NmFlDhQu6urkJp49BX7L8WJU9p-MeIlCI,43508
pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=XGPCG-qaFsAcoaXnZe1mEjPEqwcVQZ3NVPjtKX8gV4c,19192
pyOpenRPA/Orchestrator/Web/__pycache__/Basic.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Web/favicon.ico,sha256=6S8XwSQ_3FXPpaX6zYkf8uUewVXO9bHnrrDHEoWrEgw,112922
pyOpenRPA/Orchestrator/__Orchestrator__.py,sha256=n-PrWqEDql1POF4bM-r9cTun9WZUqzIYRjxDEmV7xAM,119846
pyOpenRPA/Orchestrator/__init__.py,sha256=f1RFDzOkL3IVorCtqogjGdXYPtHH-P-y-5CqT7PGy7A,183
pyOpenRPA/Orchestrator/__Orchestrator__.py,sha256=wIRuMdoOwudlchdoMua0u2jO5AxCeATw0RSsQ9bKreo,150251
pyOpenRPA/Orchestrator/__init__.py,sha256=nJhjYtBXKOUNX_yNu1rRFk5y9cDz6AFiL0M6KgX_utQ,207
pyOpenRPA/Orchestrator/__main__.py,sha256=czJrc7_57WiO3EPIYfPeF_LG3pZsQVmuAYgbl_YXcVU,273
pyOpenRPA/Orchestrator/__pycache__/BackwardCompatibility.cpython-37.pyc,,
pyOpenRPA/Orchestrator/__pycache__/ControlPanel.cpython-37.pyc,,
@ -337,10 +345,10 @@ pyOpenRPA/Tools/SafeSource/__pycache__/Crypter.cpython-37.pyc,,
pyOpenRPA/Tools/SafeSource/__pycache__/DistrCreate.cpython-37.pyc,,
pyOpenRPA/Tools/SafeSource/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Tools/SafeSource/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/Terminator.py,sha256=VcjX3gFXiCGu3MMCidhrTNsmC9wsAqfjRJdTSU9fLnU,2178
pyOpenRPA/Tools/StopSafe.py,sha256=BNTtMmvsRE1Wtri3EkwhoBi6gGOjEPRQnJSV1C03c84,2176
pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/__pycache__/Terminator.cpython-37.pyc,,
pyOpenRPA/Tools/__pycache__/StopSafe.cpython-37.pyc,,
pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/__init__.py,sha256=fI-2Npv3ZqIEhm1omXoocfYZw7PY1Ccf_pHXi_bvI0w,174
pyOpenRPA/__init__.py,sha256=thBwsh1ouqe_mKoJCCECIcKbo7oF6WPz9ZV52uvuPQM,174
pyOpenRPA/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/test.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

@ -1,4 +1,5 @@
import requests, time, json
from . import Processor
# O2A - Data flow Orchestrator to Agent
# f"{lProtocolStr}://{lHostStr}:{lPortInt}/pyOpenRPA/Agent/O2A"
@ -20,6 +21,11 @@ def O2A_Loop(inGSettings):
while inGSettings["O2ADict"]["IsOnlineBool"]:
# Send request to the orchestrator server
lRequestBody = None
# ConnectionError - CE
lCEPhaseFastTimeLastGoodFloat = time.time()
lCEPhaseFastDurationSecFloat = inGSettings['O2ADict']['ConnectionTimeoutSecFloat']
lCEPhaseFastRetrySecFloat = inGSettings['O2ADict']['RetryTimeoutSecFloat']/5.0
lCEPhaseLongRetrySecFloat = inGSettings['O2ADict']['RetryTimeoutSecFloat']*12.0
try:
lProtocolStr= "https" if inGSettings["OrchestratorDict"]["IsHTTPSBool"] else "http"
lHostStr = inGSettings["OrchestratorDict"]["HostStr"]
@ -27,6 +33,7 @@ def O2A_Loop(inGSettings):
lURLStr=f"{lProtocolStr}://{lHostStr}:{lPortInt}/pyOpenRPA/Agent/O2A"
lDataDict = { "HostNameUpperStr": inGSettings["AgentDict"]["HostNameUpperStr"], "UserUpperStr": inGSettings["AgentDict"]["UserUpperStr"], "ActivityLastGUIDStr": lActivityLastGUIDStr}
lResponse = requests.post(url= lURLStr, cookies = {"AuthToken":inGSettings["OrchestratorDict"]["SuperTokenStr"]}, json=lDataDict, timeout=inGSettings["O2ADict"]["ConnectionTimeoutSecFloat"])
lCEPhaseFastTimeLastGoodFloat = time.time()
if lResponse.status_code != 200:
if lL: lL.warning(f"Agent can not connect to Orchestrator. Below the response from the orchestrator:{lResponse}")
time.sleep(inGSettings["O2ADict"]["RetryTimeoutSecFloat"])
@ -34,30 +41,39 @@ def O2A_Loop(inGSettings):
lRequestBody = lResponse.text
lBodyLenInt = len(lRequestBody)
if lBodyLenInt != 0: # CHeck if not empty result when close the connection from orch
lQueueItem = lResponse.json() # Try to get JSON
lQueueList = lResponse.json() # Try to get JSON
for lQueueItem in lQueueList:
# Append QUEUE item in ProcessorDict > ActivityList
lActivityLastGUIDStr = lQueueItem["GUIDStr"]
# Check if ActivityItem ["ThreadBool"] = False > go sync mode in processor queue; Else: New thread
if lQueueItem.get("ThreadBool",False) == False:
inGSettings["ProcessorDict"]["ActivityList"].append(lQueueItem)
else:
Processor.ProcessorRunAsync(inGSettings=inGSettings,inActivityList=[lQueueItem])
# Log full version if bytes size is less than limit . else short
lAgentLimitLogSizeBytesInt = 500
if lBodyLenInt <= lAgentLimitLogSizeBytesInt:
if lL: lL.info(f"ActivityItem was received from orchestrator: {lQueueItem}");
if lL: lL.info(f"ActivityItem from orchestrator: {lQueueItem}");
else:
if lL: lL.info(f"ActivityItem was received from orchestrator: Was supressed because of big size. Max is {lAgentLimitLogSizeBytesInt} bytes");
if lL: lL.info(f"ActivityItem from orchestrator: Supressed - big size. Size is {lBodyLenInt} bytes");
else:
if lL: lL.debug(f"Empty response from the orchestrator - loop when refresh the connection between Orc and Agent");
except requests.exceptions.ConnectionError as e:
if lL: lL.error(f"O2A Connection error - orchestrator is not available. Sleep for {inGSettings['A2ODict']['RetryTimeoutSecFloat']} s.")
time.sleep(inGSettings["O2ADict"]["RetryTimeoutSecFloat"])
if time.time() - lCEPhaseFastTimeLastGoodFloat <= lCEPhaseFastDurationSecFloat:
if lL: lL.error(f"O2A Connection error - orchestrator is not available. Sleep for {lCEPhaseFastRetrySecFloat} s.")
time.sleep(lCEPhaseFastRetrySecFloat)
else:
if lL: lL.error(f"O2A Connection error - orchestrator is not available. Sleep for {lCEPhaseLongRetrySecFloat} s.")
time.sleep(lCEPhaseLongRetrySecFloat)
except ConnectionResetError as e:
if lL: lL.error(f"O2A Connection reset error - orchestrator is not available. Sleep for {inGSettings['A2ODict']['RetryTimeoutSecFloat']} s.")
if lL: lL.error(f"O2A Connection reset error - orchestrator is not available. Sleep for {inGSettings['O2ADict']['RetryTimeoutSecFloat']} s.")
time.sleep(inGSettings["O2ADict"]["RetryTimeoutSecFloat"])
except json.decoder.JSONDecodeError as e:
if lL: lL.error(f"O2A JSON decode error - See body of the recieved content from the Orchestrator: {lRequestBody}")
time.sleep(inGSettings["O2ADict"]["RetryTimeoutSecFloat"])
except requests.exceptions.Timeout as e:
if lL: lL.exception(f"O2A requests timeout error (no response for long time). Sleep for {inGSettings['A2ODict']['RetryTimeoutSecFloat']} s.")
if lL: lL.exception(f"O2A requests timeout error (no response for long time). Sleep for {inGSettings['O2ADict']['RetryTimeoutSecFloat']} s.")
time.sleep(inGSettings["O2ADict"]["RetryTimeoutSecFloat"])
except Exception as e:
if lL: lL.exception(f"O2A Error handler. Sleep for {inGSettings['A2ODict']['RetryTimeoutSecFloat']} s.")
if lL: lL.exception(f"O2A Error handler. Sleep for {inGSettings['O2ADict']['RetryTimeoutSecFloat']} s.")
time.sleep(inGSettings["O2ADict"]["RetryTimeoutSecFloat"])

@ -13,6 +13,7 @@ def ProcessorRunSync(inGSettings):
# "ArgGSettings": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
# "ArgLogger": None, # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
# "GUIDStr": "sadasd-asdas-d-asdasd", # ActivityItem GUID which identify the Activity
# "ThreadBool": False
# },
],
"AliasDefDict": {}, # Storage for def with Str alias. To use it see pyOpenRPA.Orchestrator.ControlPanel
@ -36,6 +37,35 @@ def ProcessorRunSync(inGSettings):
else:
time.sleep(inGSettings["ProcessorDict"]["CheckIntervalSecFloat"]) # Sleep when list is empty
# Run processor Async
def ProcessorRunAsync(inGSettings, inActivityList):
"""
"inActivityList": [ # List of the activities
# {
# "Def":"DefAliasTest", # def link or def alias (look gSettings["Processor"]["AliasDefDict"])
# "ArgList":[1,2,3], # Args list
# "ArgDict":{"ttt":1,"222":2,"dsd":3}, # Args dictionary
# "ArgGSettings": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
# "ArgLogger": None, # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
# "GUIDStr": "sadasd-asdas-d-asdasd", # ActivityItem GUID which identify the Activity
# "ThreadBool": True
# },
"""
def __process__(inGSettings, inActivityList):
for lActivityItem in inActivityList:
lL = inGSettings["Logger"] # Logger alias
if lL: lL.debug(f'ActivityItem in new thread')
lResultList = ActivityListExecute(inGSettings = inGSettings, inActivityList = [lActivityItem]) # execute the activity item
#Some help code
if len(lResultList) == 0: lResultList= [None]
# Send result to Orc if we have GUIDStr
if "GUIDStr" in lActivityItem:
# Def to send to Orc
A2O.ActivityReturnDictSend(inGSettings=inGSettings, inActivityItemGUIDStr=lActivityItem["GUIDStr"],inReturn=lResultList[0])
# Start in new thread
lThread = threading.Thread(target=__process__,kwargs={"inGSettings": inGSettings, "inActivityList": inActivityList})
lThread.start()
# Execute ActivityItem list
# return the def result
def ActivityListExecute(inGSettings, inActivityList):

@ -2,6 +2,9 @@ import threading, socket, getpass, sys, uuid, subprocess, base64, psutil, getpas
from . import O2A, A2O # Data flow Orchestrator To Agent
from . import Processor # Processor Queue
from subprocess import CREATE_NEW_CONSOLE # Flag to create new process in another CMD
import os
gSettings = None
# Create binary file by the base64 string (safe for JSON transmition)
def OSFileBinaryDataBase64StrCreate(inFilePathStr, inFileDataBase64Str,inGSettings = None):
@ -58,16 +61,37 @@ def OSFileBinaryDataBase64StrReceive(inFilePathStr, inGSettings=None):
:param inGSettings: global settings of the Agent (singleton)
:return: File content in string base64 format (use base64.b64decode to decode data). Return None if file is not exist
"""
lL = inGSettings.get("Logger", None) if type(inGSettings) is dict else None
lFileDataBase64Str = None
if os.path.exists(inFilePathStr):
lFile = open(inFilePathStr, "rb")
lFileDataBytes = lFile.read()
lFile.close()
lFileDataBase64Str = base64.b64encode(lFileDataBytes).decode("utf-8")
lL = inGSettings.get("Logger", None) if type(inGSettings) is dict else None
lMessageStr = f"AGENT Binary file {inFilePathStr} has been read."
if lL: lL.info(lMessageStr)
A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
lMessageStr = f"OSFileBinaryDataBase64StrReceive: file {inFilePathStr} has been read"
if lL: lL.debug(lMessageStr)
#A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
else:
if lL: lL.debug(f"OSFileBinaryDataBase64StrReceive: file {inFilePathStr} is not exists - return None")
return lFileDataBase64Str
def OSFileMTimeGet(inFilePathStr: str) -> float or None:
"""
Read file modification time timestamp format (float)
:param inFilePathStr: File path to read
:return: timestamp (float) Return None if file is not exist
"""
global gSettings
lL = gSettings.get("Logger", None) if type(gSettings) is dict else None
lFileMTimeFloat = None
if os.path.exists(inFilePathStr):
lFileMTimeFloat = os.path.getmtime(inFilePathStr)
if lL: lL.debug(f"OSFileMTimeGet: file {inFilePathStr} has been read")
else:
if lL: lL.debug(f"OSFileMTimeGet: file {inFilePathStr} is not exists - return None")
return lFileMTimeFloat
def OSFileTextDataStrReceive(inFilePathStr, inEncodingStr="utf-8", inGSettings=None):
"""
Read text file in the agent GUI session
@ -77,17 +101,21 @@ def OSFileTextDataStrReceive(inFilePathStr, inEncodingStr="utf-8", inGSettings=N
:param inGSettings: global settings of the Agent (singleton)
:return: File text content in string format (use base64.b64decode to decode data). Return None if file is not exist
"""
lFileDataStr = None
lL = inGSettings.get("Logger", None) if type(inGSettings) is dict else None
if os.path.exists(inFilePathStr):
lFile = open(inFilePathStr, "r", encoding=inEncodingStr)
lFileDataStr = lFile.read()
lFile.close()
lL = inGSettings.get("Logger", None) if type(inGSettings) is dict else None
lMessageStr = f"AGENT Text file {inFilePathStr} has been read."
lMessageStr = f"OSFileTextDataStrReceive: file {inFilePathStr} has been read"
if lL: lL.info(lMessageStr)
A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
#A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
else:
if lL: lL.info(f"OSFileTextDataStrReceive: file {inFilePathStr} is not exists - return None")
return lFileDataStr
# Send CMD to OS. Result return to log + Orchestrator by the A2O connection
def OSCMD(inCMDStr, inRunAsyncBool=True, inGSettings = None, inSendOutputToOrchestratorLogsBool = True, inCMDEncodingStr = "cp1251"):
def OSCMD(inCMDStr, inRunAsyncBool=True, inGSettings = None, inSendOutputToOrchestratorLogsBool = True, inCMDEncodingStr = "cp1251", inCaptureBool = True):
"""
Execute CMD on the Agent daemonic process
@ -95,18 +123,21 @@ def OSCMD(inCMDStr, inRunAsyncBool=True, inGSettings = None, inSendOutputToOrche
:param inRunAsyncBool: True - Agent processor don't wait execution; False - Agent processor wait cmd execution
:param inGSettings: Agent global settings dict
:param inSendOutputToOrchestratorLogsBool: True - catch cmd execution output and send it to the Orchestrator logs; Flase - else case; Default True
!ATTENTION! If you need to start absolutely encapsulated app - set this flag as False. If you set True - the app output will come to Agent
:param inCMDEncodingStr: Set the encoding of the DOS window on the Agent server session. Windows is beautiful :) . Default is "cp1251" early was "cp866" - need test
:param inCaptureBool: !ATTENTION! If you need to start absolutely encapsulated app - set this flag as False. If you set True - the app output will come to Agent
:return:
"""
lResultStr = ""
# New feature
if inSendOutputToOrchestratorLogsBool == False and inCaptureBool == False:
inCMDStr = f"start {inCMDStr}"
# Subdef to listen OS result
def _CMDRunAndListenLogs(inCMDStr, inSendOutputToOrchestratorLogsBool, inCMDEncodingStr, inGSettings = None):
def _CMDRunAndListenLogs(inCMDStr, inSendOutputToOrchestratorLogsBool, inCMDEncodingStr, inGSettings = None, inCaptureBool = True):
lL = inGSettings.get("Logger",None) if type(inGSettings) is dict else None
lResultStr = ""
lOSCMDKeyStr = str(uuid.uuid4())[0:4].upper()
lCMDProcess = None
if inSendOutputToOrchestratorLogsBool == True:
if inCaptureBool == True:
lCMDProcess = subprocess.Popen(f'cmd /c {inCMDStr}', stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
else:
lCMDProcess = subprocess.Popen(f'cmd /c {inCMDStr}', stdout=None, stderr=None,
@ -114,12 +145,15 @@ def OSCMD(inCMDStr, inRunAsyncBool=True, inGSettings = None, inSendOutputToOrche
lListenBool = True
lMessageStr = f"{lOSCMDKeyStr}: # # # # AGENT CMD Process has been STARTED # # # # "
if lL: lL.info(lMessageStr)
if inSendOutputToOrchestratorLogsBool == True: # Capturing can be turned on!
A2O.LogListSend(inGSettings=inGSettings,inLogList=[lMessageStr])
lMessageStr = f"{lOSCMDKeyStr}: {inCMDStr}"
if lL: lL.info(lMessageStr)
if inSendOutputToOrchestratorLogsBool == True: # Capturing can be turned on!
A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
while lListenBool:
if inSendOutputToOrchestratorLogsBool == True: # Capturing can be turned on!
#if inSendOutputToOrchestratorLogsBool == True: # Capturing can be turned on!
if inCaptureBool == True: # Capturing can be turned on!
lOutputLineBytes = lCMDProcess.stdout.readline()
if lOutputLineBytes == b"":
lListenBool = False
@ -127,6 +161,7 @@ def OSCMD(inCMDStr, inRunAsyncBool=True, inGSettings = None, inSendOutputToOrche
if lStr.endswith("\n"): lStr = lStr[:-1]
lMessageStr = f"{lOSCMDKeyStr}: {lStr}"
if lL: lL.info(lMessageStr)
if inSendOutputToOrchestratorLogsBool == True: # Capturing can be turned on!
A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
lResultStr+=lStr
else: #Capturing is not turned on - wait until process will be closed
@ -137,15 +172,16 @@ def OSCMD(inCMDStr, inRunAsyncBool=True, inGSettings = None, inSendOutputToOrche
lListenBool = False
lMessageStr = f"{lOSCMDKeyStr}: # # # # AGENT CMD Process has been FINISHED # # # # "
if lL: lL.info(lMessageStr)
if inSendOutputToOrchestratorLogsBool == True: # Capturing can be turned on!
A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
return lResultStr
# New call
if inRunAsyncBool:
lThread = threading.Thread(target=_CMDRunAndListenLogs, kwargs={"inCMDStr":inCMDStr, "inGSettings":inGSettings, "inSendOutputToOrchestratorLogsBool":inSendOutputToOrchestratorLogsBool, "inCMDEncodingStr":inCMDEncodingStr })
lThread = threading.Thread(target=_CMDRunAndListenLogs, kwargs={"inCMDStr":inCMDStr, "inGSettings":inGSettings, "inSendOutputToOrchestratorLogsBool":inSendOutputToOrchestratorLogsBool, "inCMDEncodingStr":inCMDEncodingStr, "inCaptureBool": inCaptureBool })
lThread.start()
lResultStr="ActivityList has been started in async mode - no output is available here."
else:
lResultStr = _CMDRunAndListenLogs(inCMDStr=inCMDStr, inGSettings=inGSettings, inSendOutputToOrchestratorLogsBool = inSendOutputToOrchestratorLogsBool, inCMDEncodingStr = inCMDEncodingStr)
lResultStr = _CMDRunAndListenLogs(inCMDStr=inCMDStr, inGSettings=inGSettings, inSendOutputToOrchestratorLogsBool = inSendOutputToOrchestratorLogsBool, inCMDEncodingStr = inCMDEncodingStr, inCaptureBool=inCaptureBool)
#lCMDCode = "cmd /c " + inCMDStr
#subprocess.Popen(lCMDCode)
#lResultCMDRun = 1 # os.system(lCMDCode)
@ -180,7 +216,8 @@ def ProcessWOExeUpperUserListGet():
# Main def
def Agent(inGSettings):
lL = inGSettings["Logger"]
global gSettings
gSettings = inGSettings
# Append Orchestrator def to ProcessorDictAlias
lModule = sys.modules[__name__]
lModuleDefList = dir(lModule)

@ -2,7 +2,7 @@
# !!! ATTENTION: Backward compatibility has been started from v1.1.13 !!!
# So you can use config of the orchestrator 1.1.13 in new Orchestrator versions and all will be ok :) (hope it's true)
import win32security, json, datetime, time, copy
import schedule
# # # # # # # # # # # # # # # # # # #
# Backward compatibility Web defs up to v1.2.0
# # # # # # # # # # # # # # # # # # #
@ -489,3 +489,47 @@ def Update(inGSettings):
inGSettings["ServerDict"]["AgentLimitLogSizeBytesInt"] = 300
if lL: lL.warning(
f"Backward compatibility (v1.2.3 to v1.2.4): Add new key ServerDict > AgentLimitLogSizeBytesInt") # Log about compatibility
# Remove ControlPanelDict and CPDict > go to ServerDict > ControlPanelDict
if "ControlPanelDict" in inGSettings:
del inGSettings["ControlPanelDict"]
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Remove old key: ControlPanelDict") # Log about compatibility
if "CPDict" in inGSettings:
for lCPKeyStr in inGSettings["CPDict"]:
lCPItemDict = inGSettings["CPDict"][lCPKeyStr]
__Orchestrator__.WebCPUpdate(inCPKeyStr=lCPKeyStr,inHTMLRenderDef=lCPItemDict["HTMLRenderDef"],
inJSONGeneratorDef=lCPItemDict["JSONGeneratorDef"],
inJSInitGeneratorDef=lCPItemDict["JSInitGeneratorDef"])
del inGSettings["CPDict"]
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Remove old key: CPDict") # Log about compatibility
if "ControlPanelDict" not in inGSettings["ServerDict"]:
inGSettings["ServerDict"]["ControlPanelDict"]={}
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Create new key: ServerDict > ControlPanelDict") # Log about compatibility
# ManagersProcessDict
if "ManagersProcessDict" not in inGSettings:
inGSettings["ManagersProcessDict"]={}
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Create new key: ManagersProcessDict") # Log about compatibility
# Check "SchedulerDict": { "Schedule": schedule, # https://schedule.readthedocs.io/en/stable/examples.html
if inGSettings.get("SchedulerDict",{}).get("Schedule",None) is None:
inGSettings["SchedulerDict"]["Schedule"] = schedule
if lL: lL.warning(f"Backward compatibility (v1.2.4 to v1.2.7): Create new module schedule (schedule.readthedocs.io)") # Log about compatibility
# ManagersGitDict
if "ManagersGitDict" not in inGSettings:
inGSettings["ManagersGitDict"]={}
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Create new key: ManagersGitDict") # Log about compatibility
# ProcessorDict > ActivityItemNowDict
if "ActivityItemNowDict" not in inGSettings["ProcessorDict"]:
inGSettings["ProcessorDict"]["ActivityItemNowDict"]=None
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Create new key: ProcessorDict > ActivityItemNowDict") # Log about compatibility
# # "UACBool": True # True - check user access before do this URL item
for lURLItemDict in inGSettings["ServerDict"]["URLList"]:
if "UACBool" not in lURLItemDict:
lURLItemDict["UACBool"]=None
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): ServerDict > URLList > item: add UACBool = None") # Log about compatibility

@ -4,7 +4,7 @@ import threading
def IsProcessorThread(inGSettings):
return inGSettings["ProcessorDict"]["ThreadIdInt"] == threading.get_ident()
def IsOrchestratorInitialized(inGSettings):
def IsOrchestratorInitialized(inGSettings) -> bool:
"""
Check if Orchestrator will be successfully initialized

@ -0,0 +1,348 @@
from ... import Orchestrator
import jinja2
import os
from inspect import signature # For detect count of def args
from ..Web import Basic
import operator
import math
class ControlPanel():
"""
Manage your control panel on the orchestrator
Control panel has 3 events types:
- onRefreshHTML - run every n (see settings) second to detect changes in HTML control panel.
- onRefreshJSON - run every n (see settings) second to detect changes in JSON data container to client side.
- onInitJS - run when client reload the Orchestrator web page
.. code-block:: python
# Usage example:
lCPManager = Orchestrator.Managers.ControlPanel(inControlPanelNameStr="TestControlPanel",
inRefreshHTMLJinja2TemplatePathStr="ControlPanel\\test.html", inJinja2TemplateRefreshBool = True)
If you use Jinja2 you can use next data context:
StorageRobotDict: Orchestrator.StorageRobotGet(inRobotNameStr=self.mRobotNameStr),
ControlPanelInstance: self,
OrchestratorModule:Orchestrator,
RequestInstance: inRequest,
UserInfoDict: Orchestrator.WebUserInfoGet(inRequest=inRequest),
UserUACDict: Orchestrator.UACUserDictGet(inRequest=inRequest),
UserUACCheckDef: inRequest.UACClientCheck,
EnumerateDef: enumerate,
OperatorModule: operator,
MathModule: math
You can modify jinja context by use the function:
Jinja2DataUpdateDictSet
.. code-block:: html
Hello my control panel!
You can use any def from Orchestrator module here in Jinja2 HTML template:
Example: OrchestratorModule.OSCMD(inCMDStr="notepad")
{{MathModule.pi}}
{% if UserInfoDict['UserNameUpperStr']=="ND" %}
YES - IT IS ND
{% endif %}
"""
mControlPanelNameStr = None
# Jinja2 consolidated
mJinja2TemplateRefreshBool = None
mJinja2DataUpdateDict = None
# RefreshHTML block
mRefreshHTMLJinja2TemplatePathStr = None
mRefreshHTMLJinja2TemplateFileNameStr = None
mRefreshHTMLJinja2Loader = None
mRefreshHTMLJinja2Env = None
mRefreshHTMLJinja2Template = None
# InitJS block
mInitJSJinja2TemplatePathStr = None
mInitJSJinja2TemplateFileNameStr = None
mInitJSJinja2Loader = None
mInitJSJinja2Env = None
mInitJSJinja2Template = None
mBackwardCompatibilityHTMLDef = None
mBackwardCompatibilityJSDef = None
mBackwardCompatibilityJSONDef = None
mRobotNameStr = None
def __init__(self, inControlPanelNameStr, inRefreshHTMLJinja2TemplatePathStr = None, inJinja2TemplateRefreshBool = False, inRobotNameStr = None):
"""
Constructor of the control panel manager
:param inControlPanelNameStr:
:param inJinja2TemplatePathStr:
"""
# Connect self witch pyOpenRPA via ControlPanelNameStr
if inControlPanelNameStr in Orchestrator.GSettingsGet()["ServerDict"]["ControlPanelDict"]:
raise Exception(f"Another control panel with name {inControlPanelNameStr} is already exists. Please resolve the error and restart")
Orchestrator.GSettingsGet()["ServerDict"]["ControlPanelDict"][inControlPanelNameStr] = self
self.RefreshHTMLJinja2TemplatePathSet(inJinja2TemplatePathStr = inRefreshHTMLJinja2TemplatePathStr)
self.mJinja2TemplateRefreshBool = inJinja2TemplateRefreshBool
self.mControlPanelNameStr = inControlPanelNameStr # Set the name of the control panel
self.mRobotNameStr = inRobotNameStr # Set the robot name for robot it execute
def Jinja2DataUpdateDictSet(self, inJinja2DataUpdateDict):
"""
Set the data dict from the Jinja2 context (you can add some new params)
:param inJinja2DataUpdateDict: dict, which will be appended to main data context
:return: None
"""
self.mJinja2DataUpdateDict = inJinja2DataUpdateDict
def RefreshHTMLJinja2TemplatePathSet(self, inJinja2TemplatePathStr):
"""
Create Jinja2 env and load the template html
:param inJinja2TemplatePathStr:
:return:
"""
try:
if inJinja2TemplatePathStr is not None:
lSystemLoaderPathStr = "/".join(inJinja2TemplatePathStr.split("\\")[0:-1])
lTemplateFileNameStr = inJinja2TemplatePathStr.split("\\")[-1]
self.mRefreshHTMLJinja2TemplateFileNameStr = lTemplateFileNameStr
self.mRefreshHTMLJinja2Loader = jinja2.FileSystemLoader(lSystemLoaderPathStr)
self.mRefreshHTMLJinja2Env = jinja2.Environment(loader=self.mRefreshHTMLJinja2Loader, trim_blocks=True)
self.mRefreshHTMLJinja2Template = self.mRefreshHTMLJinja2Env.get_template(lTemplateFileNameStr)
except Exception as e:
Orchestrator.OrchestratorLoggerGet().exception("EXCEPTION WHEN INIT Jinja2")
def RefreshHTMLJinja2StrGenerate(self, inDataDict):
"""
Generate the HTML str from the Jinja2. Pass the context inDataDict
:param inDataDict:
:return:
"""
if self.mJinja2TemplateRefreshBool == True:
self.mRefreshHTMLJinja2Template = self.mRefreshHTMLJinja2Env.get_template(self.mRefreshHTMLJinja2TemplateFileNameStr)
lHTMLStr = self.mRefreshHTMLJinja2Template.render(**inDataDict) # Render the template into str
return lHTMLStr
def InitJSJinja2TemplatePathSet(self, inJinja2TemplatePathStr):
"""
Create Jinja2 env and load the template html
:param inJinja2TemplatePathStr:
:return:
"""
try:
if inJinja2TemplatePathStr is not None:
lSystemLoaderPathStr = "/".join(inJinja2TemplatePathStr.split("\\")[0:-1])
lTemplateFileNameStr = inJinja2TemplatePathStr.split("\\")[-1]
self.mInitJSJinja2TemplateFileNameStr = lTemplateFileNameStr
self.mInitJSJinja2Loader = jinja2.FileSystemLoader(lSystemLoaderPathStr)
self.mInitJSJinja2Env = jinja2.Environment(loader=self.mInitJSJinja2Loader, trim_blocks=True)
self.mInitJSJinja2Template = self.mInitJSJinja2Env.get_template(lTemplateFileNameStr)
except Exception as e:
Orchestrator.OrchestratorLoggerGet().exception("EXCEPTION WHEN INIT Jinja2")
def InitJSJinja2StrGenerate(self, inDataDict):
"""
Generate the HTML str from the Jinja2. Pass the context inDataDict
:param inDataDict:
:return:
"""
if self.mJinja2TemplateRefreshBool == True:
self.mInitJSJinja2Template = self.mInitJSJinja2Env.get_template(self.mInitJSJinja2TemplateFileNameStr)
lHTMLStr = self.mInitJSJinja2Template.render(**inDataDict) # Render the template into str
return lHTMLStr
def DataDictGenerate(self, inRequest):
"""
:param inRequest: request handler (from http.server import BaseHTTPRequestHandler)
:return:
"""
lData = {
"StorageRobotDict": None,
"ControlPanelInstance":self,
"OrchestratorModule":Orchestrator,
"RequestInstance": inRequest,
"UserInfoDict": Orchestrator.WebUserInfoGet(inRequest=inRequest),
"UserUACDict": Orchestrator.UACUserDictGet(inRequest=inRequest),
"UserUACCheckDef": inRequest.UACClientCheck,
"EnumerateDef": enumerate,
"OperatorModule": operator,
"MathModule": math
}
# Get the robot storage by the robot name (if you set robot name when init)
if self.mRobotNameStr is not None:
lData["StorageRobotDict"] = Orchestrator.StorageRobotGet(inRobotNameStr=self.mRobotNameStr)
# Checkj Jinja2DataUpdateDict
if self.mJinja2DataUpdateDict is not None:
lData.update(self.mJinja2DataUpdateDict)
return lData
def OnRefreshHTMLStr(self, inRequest):
"""
Event to generate HTML code of the control panel when refresh time is over.
Support backward compatibility for previous versions.
:param inRequest: request handler (from http.server import BaseHTTPRequestHandler)
:return:
"""
lHTMLStr = None
lL = Orchestrator.OrchestratorLoggerGet()
if self.mBackwardCompatibilityHTMLDef is None:
if self.mRefreshHTMLJinja2Template is not None or (self.mJinja2TemplateRefreshBool == True and self.mRefreshHTMLJinja2TemplateFileNameStr is not None):
lDataDict = self.OnRefreshHTMLDataDict(inRequest = inRequest)
# Jinja code
lHTMLStr = self.RefreshHTMLJinja2StrGenerate(inDataDict=lDataDict)
else:
lHTMLStr = self.BackwardAdapterHTMLDef(inRequest=inRequest)
# return the str
return lHTMLStr
def OnRefreshHTMLDataDict(self, inRequest):
"""
Event to prepare data context for the futher Jinja2 HTML generation. You can override this def if you want some thing more data
:param inRequest: request handler (from http.server import BaseHTTPRequestHandler)
:return: dict
"""
return self.DataDictGenerate(inRequest=inRequest)
def OnRefreshHTMLHashStr(self, inRequest):
"""
Generate the hash the result output HTML. You can override this function if you know how to optimize HTML rendering.
TODO NEED TO MODIFY ServerSettings to work with Hash because of all defs are need do use Hash
:param inRequest: request handler (from http.server import BaseHTTPRequestHandler)
:return: None - default, hash function is not determined. Str - hash function is working on!
"""
return None
def OnRefreshJSONDict(self, inRequest):
"""
Event to transmit some data from server side to the client side in JSON format. Call when page refresh is initialized
:param inRequest: request handler (from http.server import BaseHTTPRequestHandler)
:return: Dict type
"""
lResultDict = None
if self.mBackwardCompatibilityJSONDef is None:
pass
else:
lResultDict = self.BackwardAdapterJSONDef(inRequest=inRequest)
return lResultDict
def OnInitJSStr(self, inRequest):
"""
Event when orchestrator web page is init on the client side - you can transmit some java script code is str type to execute it once.
:param inRequest: request handler (from http.server import BaseHTTPRequestHandler)
:return: ""
"""
lJSStr = ""
if self.mBackwardCompatibilityJSDef is None:
if self.mInitJSJinja2Template is not None or (self.mJinja2TemplateRefreshBool == True and self.mInitJSJinja2TemplateFileNameStr is not None):
lDataDict = self.OnInitJSDataDict(inRequest = inRequest)
# Jinja code
lJSStr = self.InitJSJinja2StrGenerate(inDataDict=lDataDict)
else:
lJSStr = self.BackwardAdapterJSDef(inRequest=inRequest)
return lJSStr
def OnInitJSDataDict(self, inRequest):
"""
Event to prepare data context for the futher Jinja2 JS init generation. You can override this def if you want some thing more data
:param inRequest: request handler (from http.server import BaseHTTPRequestHandler)
:return: dict
"""
return self.DataDictGenerate(inRequest=inRequest)
def BackwardAdapterHTMLDef(self,inRequest):
lGS = Orchestrator.GSettingsGet()
lL = Orchestrator.OrchestratorLoggerGet()
# HTMLRenderDef
lItemHTMLRenderDef = self.mBackwardCompatibilityHTMLDef
lResultStr = ""
if lItemHTMLRenderDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings)
lHTMLResult = None
lDEFSignature = signature(lItemHTMLRenderDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lHTMLResult = lItemHTMLRenderDef(lGS)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lHTMLResult = lItemHTMLRenderDef(inRequest, lGS)
elif lDEFARGLen == 0: # def ()
lHTMLResult = lItemHTMLRenderDef()
# RunFunction
# Backward compatibility up to 1.2.0 - call HTML generator if result has no "HTMLStr"
if type(lHTMLResult) is str:
lResultStr = lHTMLResult
elif "HTMLStr" in lHTMLResult or "JSONDict" in lHTMLResult:
lResultStr = lHTMLResult["HTMLStr"]
else:
# Call backward compatibility HTML generator
lResultStr = Basic.HTMLControlPanelBC(inCPDict=lHTMLResult)
except Exception as e:
if lL: lL.exception(f"Error in control panel HTMLRenderDef. CP Key {self.mControlPanelNameStr}. Exception are below")
return lResultStr
def BackwardAdapterJSONDef(self,inRequest):
lGS = Orchestrator.GSettingsGet()
lL = Orchestrator.OrchestratorLoggerGet()
# HTMLRenderDef
lItemJSONGeneratorDef = self.mBackwardCompatibilityJSONDef
lResultDict = {}
if lItemJSONGeneratorDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings)
lJSONResult = None
lDEFSignature = signature(lItemJSONGeneratorDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lJSONResult = lItemJSONGeneratorDef(lGS)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lJSONResult = lItemJSONGeneratorDef(inRequest, lGS)
elif lDEFARGLen == 0: # def ()
lJSONResult = lItemJSONGeneratorDef()
# RunFunction
# Backward compatibility up to 1.2.0 - call HTML generator if result has no "HTMLStr"
lType = type(lJSONResult)
if lType is str or lJSONResult is None or lType is int or lType is list or lType is dict or lType is bool or lType is float:
lResultDict = lJSONResult
else:
if lL: lL.warning(f"JSONGenerator return bad type: {str(type(lJSONResult))}, CP Key {self.mControlPanelNameStr}")
except Exception as e:
if lL: lL.exception(
f"Error in control panel JSONGeneratorDef. CP Key {self.mControlPanelNameStr}. Exception are below")
return lResultDict
def BackwardAdapterJSDef(self,inRequest):
lGS = Orchestrator.GSettingsGet()
lL = Orchestrator.OrchestratorLoggerGet()
# HTMLRenderDef
lJSInitGeneratorDef = self.mBackwardCompatibilityJSDef
lResultStr = ""
if lJSInitGeneratorDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings)
lJSResult = ""
lDEFSignature = signature(lJSInitGeneratorDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lJSResult = lJSInitGeneratorDef(lGS)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lJSResult = lJSInitGeneratorDef(inRequest, lGS)
elif lDEFARGLen == 0: # def ()
lJSResult = lJSInitGeneratorDef()
if type(lJSResult) is str:
lResultStr = lJSResult # Add delimiter to some cases
else:
if lL: lL.warning(f"JSInitGenerator return bad type: {str(type(lJSResult))}, CP Key {self.mControlPanelNameStr}")
except Exception as e:
if lL: lL.exception(
f"Error in control panel JSInitGeneratorDef. CP Key {self.mControlPanelNameStr}. Exception are below")
return lResultStr

@ -0,0 +1,249 @@
import time
import os
from .. import __Orchestrator__
from . import Process
import threading
from typing import List
from typing import Tuple
from pyOpenRPA import Orchestrator
class Git():
mAgentHostNameStr = None
mAgentUserNameStr = None
mAbsPathStr = None
mProcessList: List[Tuple] = [] # List of the key turples of the Process instance
def __init__(self, inAgentHostNameStr=None, inAgentUserNameStr=None, inGitPathStr=""):
"""
Init the Git repo instance. It helps to detect new changes in repo and auto restart services
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process. If None - works with Orc session
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process. If None - works with Orc session
:param inGitPathStr: Relative (from the orchestrator working directory) or absolute. If "" - work with Orc repo
:return:
"""
lAbsPathStr = os.path.abspath(inGitPathStr)
lAbsPathUpperStr = lAbsPathStr.upper()
lGS = __Orchestrator__.GSettingsGet()
# Check if Process is not exists in GSettings
if (inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), lAbsPathUpperStr) not in lGS["ManagersGitDict"]:
self.mAbsPathStr = lAbsPathStr
self.mAbsPathUpperStr = lAbsPathUpperStr
self.mAgentHostNameStr = inAgentHostNameStr
self.mAgentUserNameStr = inAgentUserNameStr
lGS["ManagersGitDict"][(inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), lAbsPathUpperStr)]=self
else: raise Exception(f"Managers.Git ({inAgentHostNameStr}, {inAgentUserNameStr}, {lAbsPathUpperStr}): Can't init the Git instance because it already inited in early")
def ProcessConnect(self, inProcess: Process):
"""
Connect process to the Git instance. It will apply to stop safe process when upgrade the repo and than start it
:param inProcess: Process instance
:type inProcess: Process
"""
lProcessTurple = inProcess.KeyTurpleGet()
if lProcessTurple not in self.mProcessList:
self.mProcessList.append(lProcessTurple)
else:
raise Exception(f"Process with current key is already exists in Git process list.")
def ProcessListSaveStopSafe(self):
"""
Save the state and do the stop safe for the all processes
Will send safe stop in parallel mode but wait to the end of the safestop for the all processes. After that will continue
"""
lIntervalScheckSecFloat = 5.0
lThreadList:List[threading.Thread] = []
for lProcessItemTuple in self.mProcessList:
lProcessItem = Orchestrator.Managers.ProcessGet(*lProcessItemTuple)
lProcessItem.StatusSave()
lThread = threading.Thread(target=lProcessItem.StopSafe)
lThread.start()
lThreadList.append(lThread)
# Wait for all process will be safe stopped
lAllThreadStoppedBool = False
while not lAllThreadStoppedBool:
lAllThreadStoppedBool = True
for lThread in lThreadList:
if lThread.is_alive() == True:
lAllThreadStoppedBool = False
break
time.sleep(lIntervalScheckSecFloat)
def ProcessListRestore(self):
"""
Restore the process state for the all processes
"""
for lProcessItem in self.mProcessList:
lProcessItem.StatusRestore()
def __OSCMDShell__(self, inCMDStr):
"""
Detect the way of use and send the cmd. Wait for command execution!
:return: None is not exists
"""
if self.mAgentUserNameStr is not None and self.mAgentHostNameStr is not None: # Check if Agent specified
lActivityItemGUIDStr = __Orchestrator__.AgentOSCMD(inHostNameStr=self.mAgentHostNameStr,inUserStr=self.mAgentUserNameStr,inCMDStr=inCMDStr,inRunAsyncBool=False,inSendOutputToOrchestratorLogsBool=False)
lCMDResultStr = __Orchestrator__.AgentActivityItemReturnGet(inGUIDStr=lActivityItemGUIDStr)
else:
lCMDResultStr = __Orchestrator__.OSCMD(inCMDStr=inCMDStr, inRunAsyncBool=False)
return lCMDResultStr
def BranchRevGet(self, inBranchNameStr="HEAD"):
"""
Get the specified branch revision. Default return the current branch revision
.. code-block:: python
lGit.BranchRevGet(inBranchNameStr="dev") # Get revision of the local dev branch
lGit.BranchRevGet(inBranchNameStr="remotes/origin/dev") # Get revision of the remotes dev branch
lGit.BranchRevGet(inBranchNameStr="HEAD") # Get revision of the current HEAD branch
lGit.BranchRevGet() # Equal to the call inBranchNameStr="HEAD"
:param inBranchNameStr: The branch name where to get revision guid
:return: revision GUID
"""
lCMDStr = f"cd \"{self.mAbsPathUpperStr}\" && git rev-parse {inBranchNameStr}"
lCMDResultStr = self.__OSCMDShell__(inCMDStr=lCMDStr)
return lCMDResultStr
def BranchRevIsLast(self, inBranchLocalStr: str, inBranchRemoteStr: str) -> bool:
"""Get fetch and check if local branch revision is last (if check with remote)
:param inBranchLocalStr: _description_
:type inBranchLocalStr: str
:param inBranchRemoteStr: example: origin/prd
:type inBranchRemoteStr: str
:return: _description_
:rtype: bool
"""
lIsLastBool = False
self.Fetch()
lLocalBranchRevStr = self.BranchRevGet(inBranchNameStr=inBranchLocalStr)
lRemoteBranchRevStr = self.BranchRevGet(inBranchNameStr=inBranchRemoteStr)
if lLocalBranchRevStr == lRemoteBranchRevStr:
lIsLastBool = True
return lIsLastBool
def BranchRevLastGetInterval(self, inBranchLocalStr: str, inBranchRemoteStr: str, inPreviousBranchRestoreBool: bool = True, inIntervalSecFloat: float = 60.0):
"""Periodically check if revision is last
:param inBranchLocalStr: _description_
:type inBranchLocalStr: str
:param inBranchRemoteStr: example: origin/prd
:type inBranchRemoteStr: str
:param inPreviousBranchRestoreBool: _description_, defaults to True
:type inPreviousBranchRestoreBool: bool, optional
:param inIntervalSecFloat: _description_, defaults to 60.0
:type inIntervalSecFloat: float, optional
"""
#self.BranchRevLastGet(inBranchLocalStr, inBranchRemoteStr, inPreviousBranchRestoreBool)
Orchestrator.OrchestratorScheduleGet().every(inIntervalSecFloat).seconds.do(self.BranchRevLastGet, inBranchLocalStr, inBranchRemoteStr, inPreviousBranchRestoreBool)
def BranchRevLastGet(self, inBranchLocalStr: str, inBranchRemoteStr: str, inPreviousBranchRestoreBool: bool = True):
"""Do some action to get the last revision
:param inBranchLocalStr: [description]
:type inBranchLocalStr: str
:param inBranchRemoteStr: [description]
:type inBranchRemoteStr: str
"""
Orchestrator.OrchestratorLoggerGet().debug(f"Managers.Git ({self.mAbsPathStr}): self.BranchRevLastGet has been init")
# check if the correct revision
lCMDResultStr = None
if self.BranchRevIsLast(inBranchLocalStr=inBranchLocalStr, inBranchRemoteStr=inBranchRemoteStr) == False:
Orchestrator.OrchestratorLoggerGet().info(f"Managers.Git ({self.mAbsPathStr}): self.BranchRevLastGet, new rev (branch: {inBranchLocalStr}) has been detected - merge (branch: {inBranchRemoteStr})")
# Do the stop safe for the connected process
self.ProcessListSaveStopSafe()
lBranchNameCurrentStr = self.BranchNameGet()
# reset all changes in local folder
self.Clear()
# checkout
self.BranchCheckout(inBranchNameStr=inBranchLocalStr)
# merge
lCMDStr = f"cd \"{self.mAbsPathUpperStr}\" && git merge {inBranchRemoteStr}"
lCMDResultStr = self.__OSCMDShell__(inCMDStr=lCMDStr)
if inPreviousBranchRestoreBool == True:
# checkout to the source branch which was
self.BranchCheckout(inBranchNameStr=lBranchNameCurrentStr)
# do the orc restart
Orchestrator.OrchestratorLoggerGet().info(f"Managers.Git ({self.mAbsPathStr}): self.BranchRevLastGet, merge done, restart orc")
Orchestrator.OrchestratorRestart()
return lCMDResultStr
def BranchNameGet(self) -> str:
"""Get the current local branch name
:return: current local branch name
"""
#"git rev-parse --abbrev-ref HEAD"
lCMDStr = f"cd \"{self.mAbsPathUpperStr}\" && git rev-parse --abbrev-ref HEAD"
lCMDResultStr = self.__OSCMDShell__(inCMDStr=lCMDStr)
return lCMDResultStr
def BranchCheckout(self, inBranchNameStr):
self.Clear()
lCMDStr = f"cd \"{self.mAbsPathUpperStr}\" && git checkout {inBranchNameStr}"
lCMDResultStr = self.__OSCMDShell__(inCMDStr=lCMDStr)
return lCMDResultStr
def Clear(self):
"""Clear the all changes in the local folder. Get up to the current revision
"""
# f"git clean -f -d" # Очистить от лишних файлов
lCMDStr = f"cd \"{self.mAbsPathUpperStr}\" && git clean -f -d"
lCMDResultStr = self.__OSCMDShell__(inCMDStr=lCMDStr)
# f"git reset --hard" # Откатить файлы, которые отслеживаются Git и которые были изменены
lCMDStr = f"cd \"{self.mAbsPathUpperStr}\" && git reset --hard"
lCMDResultStr = self.__OSCMDShell__(inCMDStr=lCMDStr)
return lCMDResultStr
def Fetch(self):
"""
Get updates from the git server.
.. code-block:: python
lGit.Fetch() # get updates from the server
:return: None
"""
lCMDStr = f"cd \"{self.mAbsPathUpperStr}\" && git fetch"
lCMDResultStr = self.__OSCMDShell__(inCMDStr=lCMDStr)
return lCMDResultStr
def GitExists(inAgentHostNameStr: str, inAgentUserNameStr: str, inGitPathStr: str) -> bool:
"""
Check if the Git instance is exists in GSettings by the (inAgentHostNameStr: str, inAgentUserNameStr: str, inGitPathStr: str)
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inGitPathStr: Relative (from the orchestrator working directory) or absolute. If "" - work with Orc repo
:return: True - process exists in gsettings; False - else
"""
return (inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), inGitPathStr.upper()) in __Orchestrator__.GSettingsGet()["ManagersGitDict"]
def GitGet(inAgentHostNameStr: str, inAgentUserNameStr: str, inGitPathStr: str) -> Git:
"""
Return the Git instance by the (inAgentHostNameStr: str, inAgentUserNameStr: str, inGitPathStr: str)
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inGitPathStr: Relative (from the orchestrator working directory) or absolute. If "" - work with Orc repo
:return: Git instance (if exists) Else None
"""
lAbsPathUpperStr = os.path.abspath(inGitPathStr).upper()
return __Orchestrator__.GSettingsGet()["ManagersGitDict"].get((inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), lAbsPathUpperStr),None)
def GitBranchRevGet(inAgentHostNameStr: str, inAgentUserNameStr: str, inGitPathStr: str, inBranchNameStr: str="HEAD") -> str:
lGit = GitGet(inAgentHostNameStr = inAgentHostNameStr, inAgentUserNameStr = inAgentUserNameStr, inGitPathStr=inGitPathStr)
if lGit is not None: return lGit.BranchRevGet(inBranchNameStr=inBranchNameStr)
def GitFetch(inAgentHostNameStr: str, inAgentUserNameStr: str, inGitPathStr: str) -> None:
lGit = GitGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inGitPathStr=inGitPathStr)
if lGit is not None: lGit.Fetch()

@ -0,0 +1,692 @@
#from pyOpenRPA.Orchestrator import Managers
from .. import __Orchestrator__
import os
import time
from pyOpenRPA import Orchestrator
class Process():
"""
Manager process, which is need to be started / stopped / restarted
With Process instance you can automate your process activity. Use schedule package to set interval when process should be active and when not.
All defs in class are pickle safe! After orchestrator restart (if not the force stop of the orchestrator process) your instance with properties will be restored. But it not coverage the scheduler which is in __Orchestrator__ .
After orc restart you need to reinit all schedule rules: Orchestrator.OrchestratorScheduleGet
Process instance has the following statuses:
- 0_STOPPED
- 1_STOPPED_MANUAL
- 2_STOP_SAFE
- 3_STOP_SAFE_MANUAL
- 4_STARTED
- 5_STARTED_MANUAL
.. code-block:: python
# For the safe init class use ProcessInitSafe
lProcess = Orchestrator.Managers.ProcessInitSafe(inAgentHostNameStr="PCNAME",inAgentUserNameStr="USER",
inProcessNameWOExeStr="notepad",inStartCMDStr="notepad",inStopSafeTimeoutSecFloat=3)
# Async way to run job
lProcess.ScheduleStatusCheckEverySeconds(inIntervalSecondsInt=5)
Orchestrator.OrchestratorScheduleGet().every(5).seconds.do(Orchestrator.OrchestratorThreadStart,
lProcess.StartCheck)
# OR (sync mode)
Orchestrator.OrchestratorScheduleGet().every(5).seconds.do(lProcess.StartCheck)
How to use StopSafe on the robot side
.. code-block:: python
from pyOpenRPA.Tools import StopSafe
StopSafe.Init(inLogger=None)
StopSafe.IsSafeStop() # True - WM_CLOSE SIGNAL has come. taskkill /im someprocess.exe
"""
mAgentHostNameStr = None
mAgentUserNameStr = None
mStartPathStr = None
mStartCMDStr = None
mStartArgDict = None
mStatusCheckIntervalSecFloat = None
mProcessNameWOExeStr = None
mStopSafeTimeoutSecFloat = None
mStatusStr = None # 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
# MST - Manual Stop Trigger
mMSTdTSecFloat: float = None
mMSTdNInt = None
mMSTStartTimeList = []
mAgentMuteBool = False # Mute any sends to agent while some action is perfomed
mStatusSavedStr = None # Saved status to the further restore
def MuteWait(self):
"""
Internal def. Wait when class is apply to send new activities to the agent
:return:
"""
lIntervalSecFloat = 0.3
while self.mAgentMuteBool == True:
time.sleep(lIntervalSecFloat)
return None
def KeyTurpleGet(self):
"""
Get the key turple of the current process
"""
return (self.mAgentHostNameStr.upper(), self.mAgentUserNameStr.upper(), self.mProcessNameWOExeStr.upper())
def __init__(self, inAgentHostNameStr, inAgentUserNameStr, inProcessNameWOExeStr, inStartPathStr=None, inStartCMDStr = None, inStopSafeTimeoutSecFloat=300, inStartArgDict=None, inStatusCheckIntervalSecFloat=30):
"""
Init the class instance.
!ATTENTION! Function can raise exception if process with the same (inAgentHostNameStr, inAgentUserNameStr, inProcessNameWOExeStr) is already exists in GSettings (can be restored from previous Orchestrator session). See ProcessInitSafe to sefaty init the instance or restore previous
!ATTENTION! Schedule options you must
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:param inStartPathStr: Path to start process (.cmd/ .exe or something else). Path can be relative (from orc working directory) or absolute
:param inStartCMDStr: CMD script to start program (if no start file is exists)
:param inStopSafeTimeoutSecFloat: Time to wait for stop safe. After that do the stop force (if process is not stopped)
"""
lGS = __Orchestrator__.GSettingsGet()
# Check if Process is not exists in GSettings
if (inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), inProcessNameWOExeStr.upper()) not in lGS["ManagersProcessDict"]:
self.mStartArgDict = inStartArgDict
self.mAgentHostNameStr = inAgentHostNameStr
self.mAgentUserNameStr = inAgentUserNameStr
self.mStartPathStr = inStartPathStr
self.mStartCMDStr = inStartCMDStr
self.mProcessNameWOExeStr = inProcessNameWOExeStr
self.mStopSafeTimeoutSecFloat = inStopSafeTimeoutSecFloat
lGS["ManagersProcessDict"][(inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), inProcessNameWOExeStr.upper())]=self
lActivityDict = __Orchestrator__.ProcessorActivityItemCreate(inDef=self.StatusCheck,inArgList=[], inThreadBool=True)
__Orchestrator__.ProcessorActivityItemAppend(inActivityItemDict=lActivityDict)
if inStatusCheckIntervalSecFloat is not None: __Orchestrator__.OrchestratorScheduleGet().every(inStatusCheckIntervalSecFloat).seconds.do(Orchestrator.OrchestratorThreadStart,self.StatusCheck)
self.mStatusCheckIntervalSecFloat = inStatusCheckIntervalSecFloat
else: raise Exception(f"Managers.Process ({inAgentHostNameStr}, {inAgentUserNameStr}, {inProcessNameWOExeStr}): Can't init the Process instance because it already inited in early (see ProcessInitSafe)")
def ManualStopTriggerSet(self, inMSTdTSecFloat: float, inMSTdNInt: int) -> None:
"""
Set ManualStopTrigger (MST) to switch to STOPPED MANUAL if specified count of start fails will be catched in specified time period
:param inMSTdTSecFloat: Time perios in seconds
:param inMSTdNInt: Counts of the start tries
:return: None
"""
# MST - Manual Stop Trigger
self.mMSTdTSecFloat = inMSTdTSecFloat
self.mMSTdNInt = inMSTdNInt
def ManualStopTriggerNewStart(self):
"""
Log new start event. Check if it is applicable. Change status if ManualStop trigger criteria is applied
:return: # 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
if self.mMSTdTSecFloat is not None and self.mMSTdNInt is not None:
lTimeNowSecFloat = time.time()
self.mMSTStartTimeList.append(lTimeNowSecFloat) # Append current time to MST list
# Remove old items from list
lMSTStartTimeList = []
for lTimeItemSecFloat in self.mMSTStartTimeList:
ldTSecFloat = lTimeNowSecFloat - lTimeItemSecFloat
# Move to the new list if dT less
if ldTSecFloat < self.mMSTdTSecFloat: lMSTStartTimeList.append(lTimeItemSecFloat)
self.mMSTStartTimeList = lMSTStartTimeList # Set new list
# Check count in list
if len(lMSTStartTimeList) > self.mMSTdNInt:
self.mStatusStr = "1_STOPPED_MANUAL"
# Log info about process
lL = __Orchestrator__.OrchestratorLoggerGet()
lL.info(f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): ManualStopTrigger is activated. {self.mMSTdNInt} start tries in {self.mMSTdTSecFloat} sec.")
return self.mStatusStr
def ManualStopListClear(self) -> None:
"""
Clear the last start tries list.
:return: None
"""
self.mMSTStartTimeList=[]
def Manual2Auto(self) -> str:
"""
Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self):
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
lLogBool = False
if self.mStatusStr=="1_STOPPED_MANUAL": self.mStatusStr = "0_STOPPED"; lLogBool=True
if self.mStatusStr=="3_STOP_SAFE_MANUAL": self.mStatusStr = "2_STOP_SAFE"; lLogBool=True
if self.mStatusStr=="5_STARTED_MANUAL": self.mStatusStr = "4_STARTED"; lLogBool=True
# Log info about process
if lLogBool == True: self.StatusChangeLog()
return self.mStatusStr
def Start(self, inIsManualBool = True, inStartArgDict=None) -> str:
"""
Manual/Auto start. Manual start will block scheduling execution. To return schedule execution use def Manual2Auto.
Will not start if STOP SAFE is now and don't start auto is stopped manual now
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
if inIsManualBool == False: self.ManualStopTriggerNewStart() # Set the time
if self.mStatusStr is not None and (self.mStatusStr == "1_STOPPED_MANUAL" or "STOP_SAFE" in self.mStatusStr) and inIsManualBool == False:
lStr = f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Process will not start because of stopped manual or stop safe is now."
__Orchestrator__.OrchestratorLoggerGet().warning(lStr)
return self.mStatusStr
# Send activity item to agent - wait result
if self.mStartPathStr is not None: lCMDStr = os.path.abspath(self.mStartPathStr)
elif self.mStartCMDStr is not None: lCMDStr = self.mStartCMDStr
# Append args
if inStartArgDict is not None: self.mStartArgDict = inStartArgDict
if self.mStartArgDict is not None:
for lItemKeyStr in self.mStartArgDict:
lItemValueStr = self.mStartArgDict[lItemKeyStr]
lCMDStr = f"{lCMDStr} {lItemKeyStr} {lItemValueStr}"
#import pdb
#pdb.set_trace()
self.MuteWait()
self.mAgentMuteBool=True
lActivityItemStart = __Orchestrator__.ProcessorActivityItemCreate(inDef="OSCMD",
inArgDict={"inCMDStr":lCMDStr,"inSendOutputToOrchestratorLogsBool":False, "inCaptureBool":False},
inArgGSettingsStr="inGSettings")
lGUIDStr = __Orchestrator__.AgentActivityItemAdd(inHostNameStr=self.mAgentHostNameStr,
inUserStr=self.mAgentUserNameStr,
inActivityItemDict=lActivityItemStart)
lStartResult = __Orchestrator__.AgentActivityItemReturnGet(inGUIDStr=lGUIDStr)
if inIsManualBool==True:
self.mStatusStr = "5_STARTED_MANUAL"
else:
self.mStatusStr = "4_STARTED"
# Log info about process
self.StatusChangeLog()
self.mAgentMuteBool = False
return self.mStatusStr
def StartCheck(self) -> str:
"""
Start program if auto stopped (0_STOPPED).
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
self.MuteWait()
if self.mStatusStr == "0_STOPPED":
self.Start(inIsManualBool=False)
return self.mStatusStr
def StopSafe(self, inIsManualBool = True, inStopSafeTimeoutSecFloat = None) -> str:
"""
Manual/Auto stop safe. Stop safe is the operation which send signal to process to terminate own work (send term signal to process). Managers.Process wait for the mStopSafeTimeoutSecFloat seconds. After that, if process is not terminated - self will StopForce it.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:param inStopSafeTimeoutSecFloat: Default value goes from the instance. You can specify time is second to wait while safe stop. After that program will stop force
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
if inStopSafeTimeoutSecFloat is None: inStopSafeTimeoutSecFloat = self.mStopSafeTimeoutSecFloat
self.MuteWait()
self.mAgentMuteBool=True
# Send activity item to agent - wait result
lCMDStr = f'taskkill /im "{self.mProcessNameWOExeStr}.exe" /fi "username eq %USERNAME%"'
lActivityItemStart = __Orchestrator__.ProcessorActivityItemCreate(
inDef="OSCMD",inArgDict={"inCMDStr": lCMDStr,"inSendOutputToOrchestratorLogsBool":False, "inCaptureBool": False},inArgGSettingsStr="inGSettings")
lGUIDStr = __Orchestrator__.AgentActivityItemAdd(inHostNameStr=self.mAgentHostNameStr,
inUserStr=self.mAgentUserNameStr,
inActivityItemDict=lActivityItemStart)
lStartResult = __Orchestrator__.AgentActivityItemReturnGet(inGUIDStr=lGUIDStr)
if inIsManualBool==True:
self.mStatusStr = "3_STOP_SAFE_MANUAL"
else:
self.mStatusStr = "2_STOP_SAFE"
# Log info about process
self.StatusChangeLog()
# Interval check is stopped
lTimeStartFloat = time.time()
lIntervalCheckSafeStatusFLoat = 15.0
while "SAFE" in self.mStatusStr and (time.time() - lTimeStartFloat) < inStopSafeTimeoutSecFloat:
self.StatusCheck()
if "SAFE" not in self.mStatusStr: break
time.sleep(lIntervalCheckSafeStatusFLoat)
if "SAFE" in self.mStatusStr:
# Log info about process
lL = __Orchestrator__.OrchestratorLoggerGet()
lL.info(f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Safe stop has been wait for {inStopSafeTimeoutSecFloat} sec. Now do the force stop.")
self.StopForce(inIsManualBool=inIsManualBool,inMuteIgnoreBool=True)
# Log info about process
# self.StatusChangeLog() status check has already log status (see above)
self.mAgentMuteBool = False
return self.mStatusStr
def StopSafeCheck(self, inStopSafeTimeoutSecFloat = None) -> str:
"""
Stop safe program if auto started (4_STARTED).
:param inStopSafeTimeoutSecFloat: Default value goes from the instance. You can specify time is second to wait while safe stop. After that program will stop force
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
self.MuteWait()
if self.mStatusStr == "4_STARTED":
self.StopSafe(inIsManualBool=False, inStopSafeTimeoutSecFloat = inStopSafeTimeoutSecFloat)
return self.mStatusStr
def StopForce(self, inIsManualBool = True, inMuteIgnoreBool = False) -> str:
"""
Manual/Auto stop force. Force stop don't wait process termination - it just terminate process now.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
if inMuteIgnoreBool == False: self.MuteWait()
lMuteWorkBool = False
if self.mAgentMuteBool==False: self.mAgentMuteBool=True; lMuteWorkBool=True
# Send activity item to agent - wait result
lCMDStr = f'taskkill /F /im "{self.mProcessNameWOExeStr}.exe" /fi "username eq %USERNAME%"'
lActivityItemStart = __Orchestrator__.ProcessorActivityItemCreate(
inDef="OSCMD",inArgDict={"inCMDStr": lCMDStr,"inSendOutputToOrchestratorLogsBool":False, "inCaptureBool": False},inArgGSettingsStr="inGSettings")
lGUIDStr = __Orchestrator__.AgentActivityItemAdd(inHostNameStr=self.mAgentHostNameStr,
inUserStr=self.mAgentUserNameStr,
inActivityItemDict=lActivityItemStart)
lStartResult = __Orchestrator__.AgentActivityItemReturnGet(inGUIDStr=lGUIDStr)
if inIsManualBool==True:
self.mStatusStr = "1_STOPPED_MANUAL"
else:
self.mStatusStr = "0_STOPPED"
# Log info about process
self.StatusChangeLog()
if lMuteWorkBool == True:
self.mAgentMuteBool=False
return self.mStatusStr
def StopForceCheck(self) -> str:
"""
Stop force program if auto started (4_STARTED).
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
self.MuteWait()
if self.mStatusStr == "4_STARTED":
self.StopForce(inIsManualBool=False)
return self.mStatusStr
def RestartSafe(self, inIsManualBool = True):
"""
Manual/Auto restart safe. Restart safe is the operation which send signal to process to terminate own work (send term signal to process). Then it run process. Managers.Process wait for the mStopSafeTimeoutSecFloat seconds. After that, if process is not terminated - self will StopForce it.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
self.StopSafe(inIsManualBool=inIsManualBool)
return self.Start(inIsManualBool=inIsManualBool)
def RestartForce(self, inIsManualBool = True):
"""
Manual/Auto restart force. Force restart dont wait process termination - it just terminate process now ant then start it.
Manual restart will block scheduling execution. To return schedule execution use def Manual2Auto
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
self.StopForce(inIsManualBool=inIsManualBool)
return self.Start(inIsManualBool=inIsManualBool)
def StatusSave(self):
"""
Save current status of the process. After that you can restore process activity. Work when orchestrator is restarted. Don't save "STOP_SAFE" status > "STOPPED"
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
lWarnSafeBool = True
if self.mStatusStr == "2_STOP_SAFE": self.mStatusSavedStr = "0_STOPPED"
elif self.mStatusStr == "3_STOP_SAFE_MANUAL": self.mStatusSavedStr = "1_STOPPED_MANUAL"
else: self.mStatusSavedStr = self.mStatusStr; lWarnSafeBool = False
if lWarnSafeBool==True: __Orchestrator__.OrchestratorLoggerGet().warning(f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Safe status has been catched when safe > change saved status to stopped.")
return self.mStatusStr
def StatusCheckIntervalRestore(self):
"""Call from orchestrator when init
"""
if self.mStatusCheckIntervalSecFloat is not None:
__Orchestrator__.OrchestratorLoggerGet().info(f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Restore schedule to StatusCheck in interval of {self.mStatusCheckIntervalSecFloat} sec.")
__Orchestrator__.OrchestratorScheduleGet().every(self.mStatusCheckIntervalSecFloat).seconds.do(Orchestrator.OrchestratorThreadStart,self.StatusCheck)
def StatusRestore(self):
"""
Execute the StatusCheck, after that restore status to the saved state (see StatusSave). Work when orchestrator is restarted.
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
self.StatusCheck() # check current status
# Do some action
if self.mStatusSavedStr != self.mStatusStr and self.mStatusSavedStr is not None:
#lManualBool = False
#if "MANUAL" in self.mStatusSavedStr:
# lManualBool = True
if "STOPPED" in self.mStatusSavedStr and "STOPPED" not in self.mStatusStr:
self.StopSafe(inIsManualBool=True)
if "STARTED" in self.mStatusSavedStr and "STARTED" not in self.mStatusStr:
self.Start(inIsManualBool=True)
Orchestrator.OrchestratorLoggerGet().info(f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Status has been restored to {self.mStatusSavedStr}")
self.mStatusStr = self.mStatusSavedStr
self.mStatusSavedStr = None
return self.mStatusStr
def StatusChangeLog(self):
"""
Lof information about status change
:return:
"""
# Log info about process
lL = __Orchestrator__.OrchestratorLoggerGet()
lL.info(f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Status has been changed to {self.mStatusStr})")
def StatusCheck(self):
"""
Check if process is alive. The def will save the manual flag is exists. Don't wait mute but set mute if it is not set.
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
# Send activity item to agent - wait result
lLogBool = False
lActivityItemUserProcessList = __Orchestrator__.ProcessorActivityItemCreate(inDef="ProcessWOExeUpperUserListGet")
#self.MuteWait()
self.mAgentMuteBool=True
lGUIDStr = __Orchestrator__.AgentActivityItemAdd(inHostNameStr=self.mAgentHostNameStr,inUserStr=self.mAgentUserNameStr,inActivityItemDict=lActivityItemUserProcessList)
lUserProcessList = __Orchestrator__.AgentActivityItemReturnGet(inGUIDStr=lGUIDStr)
if self.mProcessNameWOExeStr.upper() in lUserProcessList:
if self.mStatusStr == "1_STOPPED_MANUAL": self.mStatusStr = "5_STARTED_MANUAL"; lLogBool=True
if self.mStatusStr == "0_STOPPED": self.mStatusStr = "4_STARTED"; lLogBool=True
if self.mStatusStr is None: self.mStatusStr = "4_STARTED"; lLogBool=True
else:
if self.mStatusStr == "2_STOP_SAFE": self.mStatusStr = "0_STOPPED"; lLogBool = True
if self.mStatusStr == "3_STOP_SAFE_MANUAL": self.mStatusStr = "1_STOPPED_MANUAL"; lLogBool = True
if self.mStatusStr == "5_STARTED_MANUAL": self.mStatusStr = "1_STOPPED_MANUAL"; lLogBool=True
if self.mStatusStr == "4_STARTED": self.mStatusStr = "0_STOPPED"; lLogBool=True
if self.mStatusStr is None: self.mStatusStr = "0_STOPPED"; lLogBool=True
# Log info about process
if lLogBool == True: self.StatusChangeLog()
self.mAgentMuteBool = False
return self.mStatusStr
def StatusCheckStart(self):
"""
Check process status and run it if auto stopped self.mStatusStr is "0_STOPPED"
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
lStatusStr = self.StatusCheck()
if lStatusStr == "0_STOPPED":
self.Start(inIsManualBool=False)
return self.mStatusStr
def StatusCheckStopForce(self):
"""
Check process status and auto stop force it if self.mStatusStr is 4_STARTED
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
lStatusStr = self.StatusCheck()
if lStatusStr == "4_STARTED":
self.StopForce(inIsManualBool=False)
return self.mStatusStr
def StatusCheckStopSafe(self):
"""
Check process status and auto stop safe it if self.mStatusStr is 4_STARTED
:return:
"""
lStatusStr = self.StatusCheck()
if lStatusStr == "4_STARTED":
self.StopSafe(inIsManualBool=False)
return self.mStatusStr
def ProcessInitSafe(inAgentHostNameStr, inAgentUserNameStr, inProcessNameWOExeStr, inStartPathStr=None, inStartCMDStr = None, inStopSafeTimeoutSecFloat=300) -> Process:
"""
Exception safe function. Check if process instance is not exists in GSettings (it can be after restart because Orchestrator restore objects from dump of the previous Orchestrator session)
Return existing instance (if exists) or create new instance and return it.
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:param inStartPathStr: Path to start process (.cmd/ .exe or something else). Path can be relative (from orc working directory) or absolute
:param inStartCMDStr: CMD script to start program (if no start file is exists)
:param inStopSafeTimeoutSecFloat: Time to wait for stop safe. After that do the stop force (if process is not stopped)
:return: Process instance
"""
lProcess = ProcessGet(inAgentHostNameStr = inAgentHostNameStr, inAgentUserNameStr = inAgentUserNameStr, inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: return lProcess
else: return Process(inAgentHostNameStr=inAgentHostNameStr,inAgentUserNameStr=inAgentUserNameStr,inProcessNameWOExeStr=inProcessNameWOExeStr,
inStartPathStr=inStartPathStr,inStartCMDStr=inStartCMDStr,inStopSafeTimeoutSecFloat=inStopSafeTimeoutSecFloat)
def ProcessExists(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str) -> bool:
"""
Check if the Process instance is exists in GSettings by the (inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:return: True - process exists in gsettings; False - else
"""
return (inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), inProcessNameWOExeStr.upper()) in __Orchestrator__.GSettingsGet()["ManagersProcessDict"]
def ProcessGet(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str) -> Process:
"""
Return the process instance by the inProcessNameWOExeStr
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:return: Process instance (if exists) Else None
"""
return __Orchestrator__.GSettingsGet()["ManagersProcessDict"].get((inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), inProcessNameWOExeStr.upper()),None)
def ProcessStatusStrGet(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str) -> str:
"""
Get the status of the Process instance.
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:return: Process status. See self.mStatusStr.
Process instance has the following statuses:
- 0_STOPPED
- 1_STOPPED_MANUAL
- 2_STOP_SAFE
- 3_STOP_SAFE_MANUAL
- 4_STARTED
- 5_STARTED_MANUAL
- None (if Process instance not exists)
"""
lProcess = ProcessGet(inAgentHostNameStr = inAgentHostNameStr, inAgentUserNameStr = inAgentUserNameStr, inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: return lProcess.mStatusStr
def ProcessStart(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inIsManualBool: bool = True) -> str:
"""
Manual/Auto start. Manual start will block scheduling execution. To return schedule execution use def Manual2Auto
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:return: Process status. See self.mStatusStr.
Process instance has the following statuses:
- 0_STOPPED
- 1_STOPPED_MANUAL
- 2_STOP_SAFE
- 3_STOP_SAFE_MANUAL
- 4_STARTED
- 5_STARTED_MANUAL
- None (if Process instance not exists)
"""
lProcess = ProcessGet(inAgentHostNameStr = inAgentHostNameStr, inAgentUserNameStr = inAgentUserNameStr, inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: return lProcess.Start(inIsManualBool=inIsManualBool)
def ProcessStopSafe(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inIsManualBool: bool = True, inStopSafeTimeoutSecFloat = None) -> str:
"""
Manual/Auto stop safe. Stop safe is the operation which send signal to process to terminate own work (send term signal to process). Managers.Process wait for the mStopSafeTimeoutSecFloat seconds. After that, if process is not terminated - self will StopForce it.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:param inStopSafeTimeoutSecFloat: Default value goes from the instance. You can specify time is second to wait while safe stop. After that program will stop force
:return: Process status. See self.mStatusStr.
Process instance has the following statuses:
- 0_STOPPED
- 1_STOPPED_MANUAL
- 2_STOP_SAFE
- 3_STOP_SAFE_MANUAL
- 4_STARTED
- 5_STARTED_MANUAL
- None (if Process instance not exists)
"""
lProcess = ProcessGet(inAgentHostNameStr = inAgentHostNameStr, inAgentUserNameStr = inAgentUserNameStr, inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: return lProcess.StopSafe(inIsManualBool=inIsManualBool)
def ProcessStopForce(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inIsManualBool: bool = True) -> str:
"""
Manual/Auto stop force. Force stop dont wait process termination - it just terminate process now.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:return: Process status. See self.mStatusStr.
Process instance has the following statuses:
- 0_STOPPED
- 1_STOPPED_MANUAL
- 2_STOP_SAFE
- 3_STOP_SAFE_MANUAL
- 4_STARTED
- 5_STARTED_MANUAL
- None (if Process instance not exists)
"""
lProcess = ProcessGet(inAgentHostNameStr = inAgentHostNameStr, inAgentUserNameStr = inAgentUserNameStr, inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: return lProcess.StopForce(inIsManualBool=inIsManualBool)
def ProcessStatusSave(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str):
"""
Save current status of the process. After that you can restore process activity. Work when orchestrator is restarted. Don't save "STOP_SAFE" status > "STOPPED"
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None:
lProcess.StatusSave()
return lProcess.mStatusStr
def ProcessStatusRestore(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str):
"""
Execute the StatusCheck, after that restore status to the saved state (see StatusSave). Work when orchestrator is restarted.
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None:
lProcess.StatusRestore()
return lProcess.mStatusStr
def ProcessStatusCheck(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str) -> str:
"""
Check if process is alive. The def will save the manual flag is exists.
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:return: Process status. See self.mStatusStr.
Process instance has the following statuses:
- 0_STOPPED
- 1_STOPPED_MANUAL
- 2_STOP_SAFE
- 3_STOP_SAFE_MANUAL
- 4_STARTED
- 5_STARTED_MANUAL
- None (if Process instance not exists)
"""
lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None:
lProcess.StatusCheck()
return lProcess.mStatusStr
def ProcessManual2Auto(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str) -> str:
"""
Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self):
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:return: Process status. See self.mStatusStr.
Process instance has the following statuses:
- 0_STOPPED
- 1_STOPPED_MANUAL
- 2_STOP_SAFE
- 3_STOP_SAFE_MANUAL
- 4_STARTED
- 5_STARTED_MANUAL
- None (if Process instance not exists)
"""
lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: return lProcess.Manual2Auto()
def ProcessManualStopTriggerSet(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inMSTdTSecFloat: float, inMSTdNInt: int) -> None:
"""
Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self):
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:param inMSTdTSecFloat: Time periods in seconds
:param inMSTdNInt: Counts of the start tries
:return: None
"""
lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: lProcess.ManualStopTriggerSet(inMSTdTSecFloat = inMSTdTSecFloat, inMSTdNInt = inMSTdNInt)
def ProcessManualStopListClear(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str) -> None:
"""
Clear the last start tries list.
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:return: None
"""
lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: lProcess.ManualStopListClear()
def ProcessScheduleStatusCheckEverySeconds(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str,inIntervalSecondsInt: int = 120):
"""
Run status check every interval in second you specify.
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:param inIntervalSecondsInt: Interval in seconds. Default is 120
:return: None
"""
lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inProcessNameWOExeStr=inProcessNameWOExeStr)
# Check job in threaded way
__Orchestrator__.OrchestratorScheduleGet().every(inIntervalSecondsInt).seconds.do(__Orchestrator__.OrchestratorThreadStart,lProcess.StatusCheck)

@ -0,0 +1,3 @@
from .ControlPanel import *
from .Process import *
from .Git import *

@ -27,14 +27,42 @@ def ProcessorRunSync(inGSettings, inRobotRDPThreadControlDict):
if len(lActivityList)>0:
if lL: lL.debug(f'Processor ActivityList len: {len(lActivityList)}')
lActivityItem = inGSettings["ProcessorDict"]["ActivityList"].pop(0) # Extract the first item from processor queue
if lActivityItem.get("ThreadBool", False) is False:
inRobotRDPThreadControlDict["ThreadExecuteBool"]=False # Stop the RobotRDPActive monitoring
inGSettings["ProcessorDict"]["ActivityItemNowDict"]=lActivityItem
ActivityListExecute(inGSettings = inGSettings, inActivityList = [lActivityItem]) # execute the activity item
inGSettings["ProcessorDict"]["ActivityItemNowDict"]=None
inRobotRDPThreadControlDict["ThreadExecuteBool"] = True # Continue the RobotRDPActive monitoring
else:
ProcessorRunAsync(inGSettings = inGSettings, inActivityList=[lActivityItem])
else:
time.sleep(inGSettings["ProcessorDict"]["CheckIntervalSecFloat"]) # Sleep when list is empty
except Exception as e:
if lL: lL.exception(f"Processor.ProcessorRunSync. Something goes very wrong in processor queue. See traceback")
# Run processor Async
def ProcessorRunAsync(inGSettings, inActivityList):
"""
"inActivityList": [ # List of the activities
# {
# "Def":"DefAliasTest", # def link or def alias (look gSettings["Processor"]["AliasDefDict"])
# "ArgList":[1,2,3], # Args list
# "ArgDict":{"ttt":1,"222":2,"dsd":3}, # Args dictionary
# "ArgGSettings": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
# "ArgLogger": None, # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
# "GUIDStr": "sadasd-asdas-d-asdasd", # ActivityItem GUID which identify the Activity
# "ThreadBool": True
# },
"""
def __process__(inGSettings, inActivityList):
for lActivityItem in inActivityList:
lL = inGSettings["Logger"] # Logger alias
if lL: lL.debug(f'ActivityItem in new thread')
lResultList = ActivityListExecute(inGSettings = inGSettings, inActivityList = [lActivityItem]) # execute the activity item
# Start in new thread
lThread = threading.Thread(target=__process__,kwargs={"inGSettings": inGSettings, "inActivityList": inActivityList})
lThread.start()
# Execute ActivityItem list
# return the def result
def ActivityListExecute(inGSettings, inActivityList):
@ -113,8 +141,8 @@ def ProcessorMonitorRunSync(inGSettings):
lActiveTimeStart = time.time()
try:
while True:
if len(inGSettings["ProcessorDict"]["ActivityList"])>0:
lItemDict = inGSettings["ProcessorDict"]["ActivityList"][0]
if inGSettings["ProcessorDict"]["ActivityItemNowDict"] is not None:
lItemDict = inGSettings["ProcessorDict"]["ActivityItemNowDict"]
if "GUIDStr" not in lItemDict:
lGUIDStr = str(uuid.uuid4()) # generate new GUID
lItemDict["GUIDStr"] = lGUIDStr

@ -79,13 +79,15 @@ def SessionConfigurationCreate(inConfiguration):
lDriveStoreDirectStr = ""
for lItem in inConfiguration['SharedDriveList']:
lDriveStoreDirectStr+=f"{lItem.upper()}:\\;" # Attention - all drives must be only in upper case!!!
#Replace {Width}, {Height}, {BitDepth}, {HostPort}, {Login}
#Replace {Width}, {Height}, {BitDepth}, {HostPort}, {Login} {redirectclipboard}
lRedirectClipboardStr = "1" if inConfiguration.get('RedirectClipboardBool',True) == True else "0"
lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{Width}", str(inConfiguration.get('Screen',{}).get("Width",1680)))
lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{Height}", str(inConfiguration.get('Screen',{}).get("Height",1050)))
lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{BitDepth}", inConfiguration.get('Screen',{}).get("DepthBit","32"))
lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{HostPort}", lHostPort)
lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{Login}", inConfiguration['Login'])
lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{SharedDriveList}", lDriveStoreDirectStr)
lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{redirectclipboard}", lRedirectClipboardStr)
#Save template to temp file
lRDPCurrentFileFullPath = os.path.join(tempfile.gettempdir(), f"{uuid.uuid4().hex}.rdp")
open(lRDPCurrentFileFullPath, "w", encoding="utf-16-le").write(lRDPTemplateFileContent)

@ -10,7 +10,7 @@ import psutil
gSettings = None # Gsettings will be initialized after the import module
# Create new RDPSession in RobotRDPActive
def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPasswordStr):
def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPasswordStr, inRedirectClipboardBool = True):
global gSettings
# ATTENTION - dont connect if RDP session is exist
if inRDPSessionKeyStr not in gSettings["RobotRDPActive"]["RDPList"]:
@ -27,6 +27,7 @@ def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPa
"DepthBit": "32" # "32" or "24" or "16" or "15", example "32"
},
"SharedDriveList": ["c"], # List of the Root sesion hard drives, example ["c"]
"RedirectClipboardBool": inRedirectClipboardBool, # True - share clipboard to RDP; False - else
###### Will updated in program ############
"SessionHex": "77777sdfsdf77777dsfdfsf77777777", # Hex is created when robot runs, example ""
"SessionIsWindowExistBool": False, # Flag if the RDP window is exist, old name "FlagSessionIsActive". Check every n seconds , example False

@ -8,7 +8,7 @@ def CheckScreen(inIntervalSeconds=1):
#Send os command to create console version (base screen)
Screen.ConsoleScreenBase()
#Delay to create console screen
time.sleep(2)
time.sleep(5)
#Delay
time.sleep(inIntervalSeconds)
return None

@ -11,6 +11,7 @@ from socketserver import ThreadingMixIn
import threading
import json
from threading import Thread
import inspect
from . import Processor # Add new processor
from . import ProcessorOld # Support old processor - deprecated defs only for backward compatibility
import urllib.parse # decode URL in string
@ -45,6 +46,13 @@ def __ComplexDictMerge2to1__(in1Dict, in2Dict):
# Tool to merge complex dictionaries - no exceptions, just overwrite dict 2 in dict 1
def __ComplexDictMerge2to1Overwrite__(in1Dict, in2Dict):
"""
Merge in2Dict in in1Dict. In conflict override and get value from dict 2
:param in1Dict: Source dict. Save the link (structure)
:param in2Dict: New data dict
:return: Merged dict 1
"""
lPathList=None
if lPathList is None: lPathList = []
for lKeyStr in in2Dict:
@ -253,7 +261,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
#Tech def
#return {"headers":[],"body":"","statuscode":111}
def URLItemCheckDo(self, inURLItem, inMethod):
def URLItemCheckDo(self, inURLItem, inMethod, inOnlyFlagUACBool = False):
###############################
#Tech sub def - do item
################################
@ -273,7 +281,14 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
lFileObject.close()
#If function is set
if "ResponseDefRequestGlobal" in inURLItem:
lDef = inURLItem["ResponseDefRequestGlobal"]
lDefSignature = inspect.signature(lDef)
if len(lDefSignature.parameters) == 2:
inURLItem["ResponseDefRequestGlobal"](inRequest, inGlobalDict)
elif len(lDefSignature.parameters) == 1:
inURLItem["ResponseDefRequestGlobal"](inRequest)
else:
inURLItem["ResponseDefRequestGlobal"]()
if "ResponseFolderPath" in inURLItem:
#lRequestPath = inRequest.path
lRequestPath = urllib.parse.unquote(inRequest.path)
@ -290,6 +305,9 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# Закрыть файловый объект
lFileObject.close()
##############################################
# UAC Check
if inOnlyFlagUACBool == True and inURLItem.get("UACBool",None) in [None, True]:
return False
if inURLItem["Method"].upper() == inMethod.upper():
# check Match type variant: BeginWith
if inURLItem["MatchType"].upper() == "BEGINWITH":
@ -348,10 +366,12 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
self.end_headers()
# Write content as utf-8 data
self.wfile.write(inResponseDict["Body"])
except ConnectionResetError as e:
if lL: lL.warning(f"An existing connection was forcibly closed by the remote host - OK for the network interactions (ConnectionResetError: [WinError 10054])")
except (ConnectionResetError, ConnectionAbortedError) as e:
if lL: lL.warning(f"SERVER: Connection was forcibly closed by the client side - OK for the network interactions (ConnectionResetError: [WinError 10054] or ConnectionAbortedError: [WinError 10053])")
def do_GET(self):
try:
threading.current_thread().request = self
self.OpenRPA = {}
self.OpenRPA["AuthToken"] = None
self.OpenRPA["Domain"] = None
@ -361,6 +381,16 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# Prepare result dict
lResponseDict = {"Headers": {}, "SetCookies": {}, "Body": b"", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict
############################
#First - all with Flag UACBool
############################
for lURLItem in gSettingsDict["ServerDict"]["URLList"]:
#Check if all condition are applied
lFlagURLIsApplied=False
lFlagURLIsApplied=self.URLItemCheckDo(inURLItem=lURLItem, inMethod="GET", inOnlyFlagUACBool=True)
if lFlagURLIsApplied:
self.ResponseDictSend()
return
#####################################
#Do authentication
#Check if authentication is turned on
@ -425,6 +455,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# POST
def do_POST(self):
try:
threading.current_thread().request = self
lL = gSettingsDict["Logger"]
self.OpenRPA = {}
self.OpenRPA["AuthToken"] = None
@ -436,6 +467,16 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
#pdb.set_trace()
lResponseDict = {"Headers": {}, "SetCookies":{}, "Body": b"", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict
############################
#First - all with Flag UACBool
############################
for lURLItem in gSettingsDict["ServerDict"]["URLList"]:
#Check if all condition are applied
lFlagURLIsApplied=False
lFlagURLIsApplied=self.URLItemCheckDo(inURLItem=lURLItem, inMethod="POST", inOnlyFlagUACBool=True)
if lFlagURLIsApplied:
self.ResponseDictSend()
return
#####################################
#Do authentication
#Check if authentication is turned on

@ -1,6 +1,5 @@
import json, os
import copy
from inspect import signature # For detect count of def args
from . import __Orchestrator__
#ControlPanelDict
from desktopmagic.screengrab_win32 import (
@ -15,6 +14,7 @@ from .Web import Basic
from . import BackwardCompatibility # Support old up to 1.2.0 defs
from . import Processor
from . import SettingsTemplate
# # # # # # # # # # # #
# v 1.2.0 Functionallity
# # # # # # # # # # # #
@ -24,31 +24,14 @@ def HiddenJSInitGenerate(inRequest, inGSettings):
lUACCPTemplateKeyList=["pyOpenRPADict","CPKeyDict"]
lL = inGSettings["Logger"] # Alias for logger
lJSInitResultStr = ""
lRenderFunctionsRobotDict = inGSettings["CPDict"]
lRenderFunctionsRobotDict = inGSettings["ServerDict"]["ControlPanelDict"]
for lItemKeyStr in lRenderFunctionsRobotDict:
lItemDict = lRenderFunctionsRobotDict[lItemKeyStr]
lJSInitGeneratorDef = lItemDict.get("JSInitGeneratorDef",None)
lUACBool = dUAC(inRoleKeyList=lUACCPTemplateKeyList+[lItemKeyStr]) # Check if render function is applicable User Access Rights (UAC)
if lItemKeyStr=="VersionCheck": lUACBool=True # For backward compatibility for the old fron version which not reload page when new orch version is comming
if lUACBool: # Run function if UAC is TRUE
# JSONGeneratorDef
if lJSInitGeneratorDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings)
lJSResult = None
lDEFSignature = signature(lJSInitGeneratorDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lJSResult = lJSInitGeneratorDef(inGSettings)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lJSResult = lJSInitGeneratorDef(inRequest, inGSettings)
elif lDEFARGLen == 0: # def ()
lJSResult = lJSInitGeneratorDef()
if type(lJSResult) is str:
lJSInitResultStr += "; "+lJSResult # Add delimiter to some cases
else:
if lL: lL.warning(f"JSInitGenerator return bad type: {str(type(lJSResult))}, CP Key {lItemKeyStr}")
except Exception as e:
if lL: lL.exception(f"Error in control panel JSInitGeneratorDef. CP Key {lItemKeyStr}. Exception are below")
lJSInitResultStr = lJSInitResultStr + ";" + lItemDict.OnInitJSStr(inRequest=inRequest)
return lJSInitResultStr
# Generate CP HTML + JSON
@ -59,59 +42,20 @@ def HiddenCPDictGenerate(inRequest, inGSettings):
lL = inGSettings["Logger"] # Alias for logger
# Create result JSON
lCPDict = {}
lRenderFunctionsRobotDict = inGSettings["CPDict"]
lRenderFunctionsRobotDict = inGSettings["ServerDict"]["ControlPanelDict"]
for lItemKeyStr in lRenderFunctionsRobotDict:
lItemDict = lRenderFunctionsRobotDict[lItemKeyStr]
lItemHTMLRenderDef = lItemDict.get("HTMLRenderDef",None)
lItemJSONGeneratorDef = lItemDict.get("JSONGeneratorDef",None)
lUACBool = dUAC(inRoleKeyList=lUACCPTemplateKeyList+[lItemKeyStr]) # Check if render function is applicable User Access Rights (UAC)
if lItemKeyStr=="VersionCheck": lUACBool=True # For backward compatibility for the old fron version which not reload page when new orch version is comming
if lUACBool: # Run function if UAC is TRUE
lCPItemDict = {"HTMLStr": None, "JSONDict":None}
# HTMLRenderDef
if lItemHTMLRenderDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings)
lHTMLResult = None
lDEFSignature = signature(lItemHTMLRenderDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lHTMLResult = lItemHTMLRenderDef(inGSettings)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lHTMLResult = lItemHTMLRenderDef(inRequest, inGSettings)
elif lDEFARGLen == 0: # def ()
lHTMLResult = lItemHTMLRenderDef()
# RunFunction
# Backward compatibility up to 1.2.0 - call HTML generator if result has no "HTMLStr"
if type(lHTMLResult) is str:
lCPItemDict["HTMLStr"] = lHTMLResult
elif "HTMLStr" in lHTMLResult or "JSONDict" in lHTMLResult:
lCPItemDict = lHTMLResult # new version
else:
# Call backward compatibility HTML generator
lCPItemDict["HTMLStr"] = Basic.HTMLControlPanelBC(inCPDict=lHTMLResult)
except Exception as e:
if lL: lL.exception(f"Error in control panel HTMLRenderDef. CP Key {lItemKeyStr}. Exception are below")
# HTML Render
lCPItemDict["HTMLStr"] = lItemDict.OnRefreshHTMLStr(inRequest=inRequest)
# JSONGeneratorDef
if lItemJSONGeneratorDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings)
lJSONResult = None
lDEFSignature = signature(lItemJSONGeneratorDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lJSONResult = lItemJSONGeneratorDef(inGSettings)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lJSONResult = lItemJSONGeneratorDef(inRequest, inGSettings)
elif lDEFARGLen == 0: # def ()
lJSONResult = lItemJSONGeneratorDef()
# RunFunction
# Backward compatibility up to 1.2.0 - call HTML generator if result has no "HTMLStr"
lType = type(lJSONResult)
if lType is str or lJSONResult is None or lType is int or lType is list or lType is dict or lType is bool or lType is float:
lCPItemDict["JSONDict"] = lJSONResult
else:
if lL: lL.warning(f"JSONGenerator return bad type: {str(type(lJSONResult))}, CP Key {lItemKeyStr}")
lCPItemDict["JSONDict"] = lItemDict.OnRefreshJSONDict(inRequest=inRequest)
except Exception as e:
if lL: lL.exception(f"Error in control panel JSONGeneratorDef. CP Key {lItemKeyStr}. Exception are below")
lL.exception(f"EXCEPTION WHEN HTML/ JSON RENDER")
# Insert CPItemDict in result CPDict
lCPDict[lItemKeyStr]=lCPItemDict
return lCPDict
@ -207,6 +151,8 @@ def pyOpenRPA_ServerData(inRequest,inGSettings):
def pyOpenRPA_ServerJSInit(inRequest,inGSettings):
lResultStr = HiddenJSInitGenerate(inRequest=inRequest, inGSettings=inGSettings)
inResponseDict = inRequest.OpenRPAResponseDict
if lResultStr is None:
lResultStr = ""
# Write content as utf-8 data
inResponseDict["Body"] = bytes(lResultStr, "utf8")
@ -281,8 +227,22 @@ def pyOpenRPA_Processor(inRequest, inGSettings):
lActivityTypeListStr = "Has some error with Activity Type read"
lWebAuditMessageStr = __Orchestrator__.WebAuditMessageCreate(inRequest=inRequest,inOperationCodeStr=lActivityTypeListStr, inMessageStr="pyOpenRPA_Processor")
if lL: lL.info(lWebAuditMessageStr)
# Append in list
inGSettings["ProcessorDict"]["ActivityList"]+=lInput
# Separate into 2 lists - sync and async
lSyncActvityList = []
lAsyncActivityList = []
for lActivityItem in lInput:
if lInput.get("ThreadBool", False) == False:
lSyncActvityList.append(lActivityItem)
else:
lAsyncActivityList.append(lActivityItem)
# Sync: Append in list
inGSettings["ProcessorDict"]["ActivityList"]+=lSyncActvityList
# Async: go to run
if len(lAsyncActivityList)>0:
for lActivityItem in lAsyncActivityList:
lActivityItemArgsDict = {"inGSettings":inGSettings,"inActivityList":[lActivityItem]}
lThread = threading.Thread(target=Processor.ActivityListExecute, kwargs=lActivityItemArgsDict)
lThread.start()
else:
# Logging info about processor activity if not SuperToken ()
if not __Orchestrator__.WebUserIsSuperToken(inRequest=inRequest, inGSettings=inGSettings):
@ -293,8 +253,13 @@ def pyOpenRPA_Processor(inRequest, inGSettings):
lActivityTypeListStr = "Has some error with Activity Type read"
lWebAuditMessageStr = __Orchestrator__.WebAuditMessageCreate(inRequest=inRequest,inOperationCodeStr=lActivityTypeListStr, inMessageStr="pyOpenRPA_Processor")
if lL: lL.info(lWebAuditMessageStr)
if lInput.get("ThreadBool",False) == False:
# Append in list
inGSettings["ProcessorDict"]["ActivityList"].append(lInput)
else:
lActivityItemArgsDict = {"inGSettings": inGSettings, "inActivityList": [lInput]}
lThread = threading.Thread(target=Processor.ActivityListExecute, kwargs=lActivityItemArgsDict)
lThread.start()
# Execute activity list
def pyOpenRPA_ActivityListExecute(inRequest, inGSettings):
# Recieve the data
@ -369,7 +334,6 @@ def pyOpenRPA_Agent_O2A(inRequest, inGSettings):
lThisAgentDict["IsListenBool"] = True # Set is online
lQueueList = lThisAgentDict["ActivityList"]
if len(lQueueList)>0:# Do some operations if has queue items
if lL: lL.debug(f'O2A: ConnectionCountInt: {lThisAgentDict["ConnectionCountInt"]};ConnectionFirstQueueItemCountInt {lThisAgentDict["ConnectionFirstQueueItemCountInt"]}')
# check if delta datetime is < than ActivityLifeTimeSecFloat
lActivityItem = lThisAgentDict["ActivityList"][0]
lActivityLifetimeSecFloat = (datetime.datetime.now() - lActivityItem["CreatedByDatetime"]).total_seconds()
@ -377,36 +341,35 @@ def pyOpenRPA_Agent_O2A(inRequest, inGSettings):
if lActivityLifetimeSecFloat > lActivityItemLifetimeLimitSecFloat:
lActivityItem = lThisAgentDict["ActivityList"].pop(0)
else:
lReturnActivityItemList = []
lReturnActivityItemDict = None
# If lInput['ActivityLastGUIDStr'] is '' > return 0 element for send in Agent
if lInput['ActivityLastGUIDStr'] == "":
lReturnActivityItemDict = lThisAgentDict["ActivityList"][0]
lReturnActivityItemList=lQueueList # 2022 02 21 - Maslov Return list - not one item
else:
# go from the end - search element with GUIDStr
lForTriggerGetNextItem = False
for lForActivityItemDict in lQueueList:
if lForTriggerGetNextItem == True:
lReturnActivityItemDict = lForActivityItemDict
break
lReturnActivityItemList.append(lReturnActivityItemDict) # 2022 02 21 - Maslov Return list - not one item
#break
if lForActivityItemDict['GUIDStr'] == lInput['ActivityLastGUIDStr']: lForTriggerGetNextItem = True
# CASE if GUID is not detected - return 0 element
if lReturnActivityItemDict == None and lForTriggerGetNextItem == False:
lReturnActivityItemDict = lThisAgentDict["ActivityList"][0]
if (len(lQueueList)==1 and lQueueList[0]['GUIDStr'] != lInput['ActivityLastGUIDStr']):
#lReturnActivityItemDict = lThisAgentDict["ActivityList"][0]
lReturnActivityItemList=lQueueList # 2022 02 21 - Maslov Return list - not one item
# Send QUEUE ITEM
if lReturnActivityItemDict is not None:
lReturnActivityItemDict = copy.deepcopy(lReturnActivityItemDict)
if "CreatedByDatetime" in lReturnActivityItemDict:
del lReturnActivityItemDict["CreatedByDatetime"]
inRequest.OpenRPAResponseDict["Body"] = bytes(json.dumps(lReturnActivityItemDict), "utf8")
if len(lReturnActivityItemList) > 0:
lReturnActivityItemList = copy.deepcopy(lReturnActivityItemList)
for lItemDict in lReturnActivityItemList:
if "CreatedByDatetime" in lItemDict:
del lItemDict["CreatedByDatetime"]
inRequest.OpenRPAResponseDict["Body"] = bytes(json.dumps(lReturnActivityItemList), "utf8")
# Log full version if bytes size is less than limit . else short
lBodyLenInt = len(inRequest.OpenRPAResponseDict["Body"])
lAgentLimitLogSizeBytesInt = inGSettings["ServerDict"]["AgentLimitLogSizeBytesInt"]
if lBodyLenInt <= lAgentLimitLogSizeBytesInt:
if lL: lL.info(f"Activity item to agent Hostname {lInput['HostNameUpperStr']}, User {lInput['UserUpperStr']}. Activity item: {lReturnActivityItemDict}")
else:
if lL: lL.info(
f"Activity item to agent Hostname {lInput['HostNameUpperStr']}, User {lInput['UserUpperStr']}. "
f"Activity item: Was suppressed because of body size of {lBodyLenInt} bytes. Max is {lAgentLimitLogSizeBytesInt}")
if lL: lL.debug(f"ActivityItem to Agent ({lInput['HostNameUpperStr']}, {lInput['UserUpperStr']}): Item count: {len(lReturnActivityItemList)}, bytes size: {lBodyLenInt}")
lDoLoopBool = False # CLose the connection
else: # Nothing to send - sleep for the next iteration
time.sleep(lAgentLoopSleepSecFloat)
@ -415,6 +378,32 @@ def pyOpenRPA_Agent_O2A(inRequest, inGSettings):
except Exception as e:
if lL: lL.exception("pyOpenRPA_Agent_O2A Exception!")
lThisAgentDict["ConnectionCountInt"] -= 1 # Connection go to be closed - decrement the connection count
def pyOpenRPA_Debugging_HelperDefList(inRequest, inGSettings):
# Parse query
lResultDict = {
"success": True,
"results": []
}
# Get the path
lPathSplitList = __Orchestrator__.WebRequestParsePath(inRequest=inRequest).split('/')
lQueryStr = None
if "HelperDefList" != lPathSplitList[-1] and "" != lPathSplitList[-1]: lQueryStr = lPathSplitList[-1]
if lQueryStr != "" and lQueryStr is not None:
lDefList = __Orchestrator__.ActivityItemHelperDefList(inDefQueryStr=lQueryStr)
for lDefStr in lDefList:
lResultDict["results"].append({"name": lDefStr, "value": lDefStr, "text": lDefStr})
__Orchestrator__.WebRequestResponseSend(inRequest=inRequest, inResponeStr=json.dumps(lResultDict))
def pyOpenRPA_Debugging_HelperDefAutofill(inRequest, inGSettings):
# Parse query
# Get the path
lPathSplitList = __Orchestrator__.WebRequestParsePath(inRequest=inRequest).split('/')
lQueryStr = None
if "HelperDefAutofill" != lPathSplitList[-1] and "" != lPathSplitList[-1]: lQueryStr = lPathSplitList[-1]
lResultDict = __Orchestrator__.ActivityItemHelperDefAutofill(inDef = lQueryStr)
__Orchestrator__.WebRequestResponseSend(inRequest=inRequest, inResponeStr=json.dumps(lResultDict))
# See docs in Agent (pyOpenRPA.Agent.A2O)
def pyOpenRPA_Agent_A2O(inRequest, inGSettings):
lL = inGSettings["Logger"]
@ -434,7 +423,13 @@ def pyOpenRPA_Agent_A2O(inRequest, inGSettings):
lActivityReturnItemValue = lInput["ActivityReturnDict"][lActivityReturnItemKeyStr]
# Create item in gSettings
inGSettings["AgentActivityReturnDict"][lActivityReturnItemKeyStr]=SettingsTemplate.__AgentActivityReturnDictItemCreate__(inReturn=lActivityReturnItemValue)
if lL: lL.debug(f"SERVER: pyOpenRPA_Agent_A2O:: Has recieved result of the activity items from agent! ActivityItem GUID Str: {lActivityReturnItemKeyStr}; Return value: {lActivityReturnItemValue}")
lLogStr = "x bytes"
try:
if lActivityReturnItemValue is not None:
lLogStr = f"{len(lActivityReturnItemValue)} bytes"
except Exception as e:
pass
if lL: lL.debug(f"SERVER: pyOpenRPA_Agent_A2O:: Has recieved result of the activity items from agent! ActivityItem GUID Str: {lActivityReturnItemKeyStr}; Return value len: {lLogStr}")
# Delete the source activity item from AgentDict
if lAgentDictItemKeyTurple in inGSettings["AgentDict"]:
lAgentDictActivityListNew = []
@ -484,6 +479,8 @@ def SettingsUpdate(inGlobalConfiguration):
{"Method": "POST", "URL": "/pyOpenRPA/ActivityListExecute", "MatchType": "Equal","ResponseDefRequestGlobal": pyOpenRPA_ActivityListExecute, "ResponseContentType": "application/json"},
{"Method": "POST", "URL": "/pyOpenRPA/Agent/O2A", "MatchType": "Equal","ResponseDefRequestGlobal": pyOpenRPA_Agent_O2A, "ResponseContentType": "application/json"},
{"Method": "POST", "URL": "/pyOpenRPA/Agent/A2O", "MatchType": "Equal","ResponseDefRequestGlobal": pyOpenRPA_Agent_A2O, "ResponseContentType": "application/json"},
{"Method": "GET", "URL": "/pyOpenRPA/Debugging/HelperDefList/", "MatchType": "BeginWith","ResponseDefRequestGlobal": pyOpenRPA_Debugging_HelperDefList, "ResponseContentType": "application/json"},
{"Method": "GET", "URL": "/pyOpenRPA/Debugging/HelperDefAutofill/", "MatchType": "BeginWith","ResponseDefRequestGlobal": pyOpenRPA_Debugging_HelperDefAutofill, "ResponseContentType": "application/json"},
]
inGlobalConfiguration["ServerDict"]["URLList"]=inGlobalConfiguration["ServerDict"]["URLList"]+lURLList
return inGlobalConfiguration

@ -1,4 +1,5 @@
import os, logging, datetime, sys
import schedule # https://schedule.readthedocs.io/en/stable/examples.html
# Technical def - return GSettings structure with examples
def __Create__():
@ -39,6 +40,9 @@ def __Create__():
# # # # # # # # # # # # # # # # # #
},
"ServerDict": {
"ControlPanelDict": {
# "CPKey": <Managers.ControlPanel instance>
},
"AgentLimitLogSizeBytesInt": 300, # Don't show body if json body of transmition is more than
"ServerThread": None, # Server thread is there
"AgentActivityLifetimeSecFloat": 1200.0, # Time in seconds to life for activity for the agent
@ -105,18 +109,20 @@ def __Create__():
# "ResponseFilePath": "", #Absolute or relative path
# "ResponseFolderPath": "", #Absolute or relative path
# "ResponseContentType": "", #HTTP Content-type
# "ResponseDefRequestGlobal": None #Function with str result
# "ResponseDefRequestGlobal": None ,#Function with str result
# "UACBool": True # True - check user access before do this URL item. None - get Server flag if ask user
# }
#{
# "Method": "GET",
# "URL": "/test/", # URL of the request
# "MatchType": "BeginWith", # "BeginWith|Contains|Equal|EqualCase",
# # "ResponseFilePath": "", #Absolute or relative path
# "ResponseFolderPath": "C:\Abs\Archive\scopeSrcUL\OpenRPA\Orchestrator\Settings",
# # Absolute or relative path
# # "ResponseContentType": "", #HTTP Content-type
# # "ResponseDefRequestGlobal": None #Function with str result
# # "UACBool": True # True - check user access before do this URL item
#}
{
"Method": "GET",
"URL": "/test/", # URL of the request
"MatchType": "BeginWith", # "BeginWith|Contains|Equal|EqualCase",
# "ResponseFilePath": "", #Absolute or relative path
"ResponseFolderPath": "C:\Abs\Archive\scopeSrcUL\OpenRPA\Orchestrator\Settings",
# Absolute or relative path
# "ResponseContentType": "", #HTTP Content-type
# "ResponseDefRequestGlobal": None #Function with str result
}
],
},
@ -126,6 +132,7 @@ def __Create__():
"ActivityList": []
},
"SchedulerDict": {
"Schedule": schedule, # https://schedule.readthedocs.io/en/stable/examples.html
"CheckIntervalSecFloat": 5.0, # Check interval in seconds
"ActivityTimeList": [
# {
@ -145,6 +152,8 @@ def __Create__():
# },
],
},
"ManagersProcessDict":{}, # The key of the Process is (mAgentHostNameStr.upper(), mAgentUserNameStr.upper(), mProcessNameWOExeStr.upper())
"ManagersGitDict":{}, # The key of the Git instance is (mAgentHostNameStr.upper(), mAgentUserNameStr.upper(), mAbsPathUpperStr.upper())
"ProcessorDict": { # Has been changed. New general processor (one threaded) v.1.2.0
"ActivityList": [ # List of the activities
# {
@ -156,24 +165,13 @@ def __Create__():
# "GUIDStr": ..., # GUID of the activity
# },
],
"ActivityItemNowDict": None, # Activity Item which is executing now
"AliasDefDict": {}, # Storage for def with Str alias. To use it see pyOpenRPA.Orchestrator.ControlPanel
"CheckIntervalSecFloat": 1.0, # Interval for check gSettings in ProcessorDict > ActivityList
"ExecuteBool": True, # Flag to execute thread processor
"ThreadIdInt": None, # Technical field - will be setup when processor init
"WarningExecutionMoreThanSecFloat": 60.0 # Push warning if execution more than n seconds
},
"ControlPanelDict": { # Old structure > CPDict
"RefreshSeconds": 5, # deprecated parameter
"RobotList": [
#{
# "RenderFunction": RenderRobotR01,
# "KeyStr": "TestControlPanelKey"
#}
]
},
"CPDict": {
# "CPKey": {"HTMLRenderDef":None, "JSONGeneratorDef":None, "JSInitGeneratorDef":None}
},
# # # # # # # # # # # # # #
"RobotRDPActive": {
"RecoveryDict": {
@ -294,7 +292,8 @@ def __UACClientAdminCreate__():
"RestartOrchestratorBool": True, # Restart orchestrator activity
"RestartOrchestratorGITPullBool": True, # Turn off (RDP remember) orc + git pull + Turn on (rdp remember)
"RestartPCBool": True, # Send CMD to restart pc
"NothingBool":True # USe option if you dont want to give some access to the RDP controls
"NothingBool":True, # USe option if you dont want to give some access to the RDP controls
"Debugging":True # Debugging tool
},
"ActivityDict": { # Empty dict - all access
"ActivityListExecuteBool": True, # Execute activity at the current thread
@ -324,7 +323,7 @@ def LoggerDumpLogHandlerAdd(inLogger, inGSettingsClientDict):
# inModeStr:
# "BASIC" - create standart configuration
from pyOpenRPA.Orchestrator.Utils import LoggerHandlerDumpLogList
def Create(inModeStr="BASIC"):
def Create(inModeStr="BASIC", inLoggerLevel = None):
if inModeStr=="BASIC":
lResult = __Create__() # Create settings
# Создать файл логирования
@ -334,21 +333,23 @@ def Create(inModeStr="BASIC"):
##########################
# Подготовка логгера Robot
#########################
mRobotLogger = lResult["Logger"]
mRobotLogger.setLevel(logging.INFO)
if inLoggerLevel is None: inLoggerLevel=logging.INFO
lL = lResult["Logger"]
if len(lL.handlers) == 0:
lL.setLevel(logging.INFO)
# create the logging file handler
mRobotLoggerFH = logging.FileHandler(
"Reports\\" + datetime.datetime.now().strftime("%Y_%m_%d") + ".log")
mRobotLoggerFormatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
mRobotLoggerFH.setFormatter(mRobotLoggerFormatter)
# add handler to logger object
mRobotLogger.addHandler(mRobotLoggerFH)
lL.addHandler(mRobotLoggerFH)
####################Add console output
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(mRobotLoggerFormatter)
mRobotLogger.addHandler(handler)
lL.addHandler(handler)
############################################
LoggerDumpLogHandlerAdd(inLogger=mRobotLogger, inGSettingsClientDict=lResult["Client"])
LoggerDumpLogHandlerAdd(inLogger=lL, inGSettingsClientDict=lResult["Client"])
#mHandlerDumpLogList = LoggerHandlerDumpLogList.LoggerHandlerDumpLogList(inDict=lResult["Client"],
# inKeyStr="DumpLogList",
# inHashKeyStr="DumpLogListHashStr",
@ -356,4 +357,6 @@ def Create(inModeStr="BASIC"):
# "DumpLogListCountInt"])
#mHandlerDumpLogList.setFormatter(mRobotLoggerFormatter)
#mRobotLogger.addHandler(mHandlerDumpLogList)
else:
if lL: lL.warning("Pay attention! Your code has been call SettingsTemplate.Create - since pyOpenRPA v1.2.7 GSettings is creating automatically")
return lResult # return the result dict

@ -883,14 +883,110 @@ $(document).ready(function() {
if (lUACAsk(["pyOpenRPADict","AdminDict","RestartOrchestratorBool"])) { $(".UACClient-pyOpenRPADict-AdminDict-RestartOrchestratorBool").show(); }
if (lUACAsk(["pyOpenRPADict","AdminDict","RestartOrchestratorGITPullBool"])) { $(".UACClient-pyOpenRPADict-AdminDict-RestartOrchestratorGITPullBool").show(); }
if (lUACAsk(["pyOpenRPADict","AdminDict","RestartPCBool"])) { $(".UACClient-pyOpenRPADict-AdminDict-RestartPCBool").show(); }
if (lUACAsk(["pyOpenRPADict","AdminDict","Debugging"])) { $(".UACClient-pyOpenRPADict-AdminDict-Debugging").show(); }
}
/// v1.2.0 pyOpenRPA Init defs
mGlobal.pyOpenRPA.ServerJSInitDef(); // Recieve JS from server (if exist) and then call anothe url ServerData
mGlobal.pyOpenRPA.ServerDataRefreshDef(); // Init the refresh data def from server side
mGlobal.pyOpenRPA.ServerLogListRefreshDef(); // Init the refresh data def from the log window
mGlobal.pyOpenRPA.ServerLogListDoRenderTrue(); // Init button to freeze/unfreeze textare with logs
mGlobal.pyOpenRPA.ServerJSInitDef(); // Recieve JS from server (if exist) and then call anothe url ServerData
//$('.ui.dropdown').dropdown();
////////////////////////////////////////////
// 1.2.7 Debugging
/// Execute ActivityItem
// Debugging onchange def autofill init
var lDropdownOnChange = function(inEvent){
//lValueStr = inEvent.target.value
lValueStr = inEvent
$.ajax({
type: "GET",
url: '/pyOpenRPA/Debugging/HelperDefAutofill/'+lValueStr,
data: null,
success:
function(lData,l2,l3)
{
var lResponseJSON=JSON.parse(lData)
console.log("HelperDefAutofill:")
console.log(lResponseJSON)
//ArgDict merge
var lArgDictTargetDict = lResponseJSON["ArgDict"]
var lArgDictStr = $(".mGlobal-pyOpenRPA-Debugging-ArgDict")[0].value
if (lArgDictStr !="" && lArgDictStr !=null) {
lArgDictLastDict = JSON.parse(lArgDictStr)
lArgDictTargetDict = mGlobal.pyOpenRPA.DebuggingAutofillMerge(lArgDictTargetDict, lArgDictLastDict)
}
$(".mGlobal-pyOpenRPA-Debugging-ArgList")[0].value = JSON.stringify(lResponseJSON["ArgList"])
$(".mGlobal-pyOpenRPA-Debugging-ArgDict")[0].value = JSON.stringify(lArgDictTargetDict)
$(".mGlobal-pyOpenRPA-Debugging-ArgGSettingsStr")[0].value = JSON.stringify(lResponseJSON["ArgGSettingsStr"])
$(".mGlobal-pyOpenRPA-Debugging-ArgLoggerStr")[0].value = JSON.stringify(lResponseJSON["ArgLoggerStr"])
},
dataType: "text"
});
}
//$('.ui.dropdown.mGlobal-pyOpenRPA-Debugging-Def-Dropdown')[0].onchange=lDropdownOnChange
$('.ui.dropdown').dropdown();
mGlobal.pyOpenRPA.DebuggingExecute=function() {
///EXAMPLE
// {
// "Def":"OSCMD", // def link or def alias (look gSettings["Processor"]["AliasDefDict"])
// "ArgList":[], // Args list
// "ArgDict":{"inCMDStr":lCMDCode,"inRunAsyncBool":false}, // Args dictionary
// "ArgGSettings": null, // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
// "ArgLogger": "inLogger" // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
// }
///Подготовить конфигурацию
lArgListStr = $(".mGlobal-pyOpenRPA-Debugging-ArgList")[0].value
lArgDictStr = $(".mGlobal-pyOpenRPA-Debugging-ArgDict")[0].value
lArgGSettingsStr = $(".mGlobal-pyOpenRPA-Debugging-ArgGSettingsStr")[0].value
lArgLoggerStr = $(".mGlobal-pyOpenRPA-Debugging-ArgLoggerStr")[0].value
lActivityItem = {
"Def":$(".mGlobal-pyOpenRPA-Debugging-Def")[0].value, // def link or def alias (look gSettings["Processor"]["AliasDefDict"])
"ArgList":(lArgListStr == "" ? [] : JSON.parse(lArgListStr)), // Args list
"ArgDict":(lArgDictStr == "" ? {} : JSON.parse(lArgDictStr)), // Args dictionary
"ArgGSettingsStr": (lArgGSettingsStr == "" ? null : lArgGSettingsStr), // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
"ArgLoggerStr": (lArgLoggerStr == "" ? null : lArgLoggerStr) // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
}
lData = [lActivityItem]
$.ajax({
type: "POST",
url: '/pyOpenRPA/ActivityListExecute',
data: JSON.stringify(lData),
success:
function(lData,l2,l3)
{
var lResponseJSON=JSON.parse(lData)
console.log(lResponseJSON)
$(".mGlobal-pyOpenRPA-Debugging-Output")[0].value = JSON.stringify(lResponseJSON[0])
},
dataType: "text"
});
}
mGlobal.pyOpenRPA.DebuggingAutofillMerge=function(inTargetDict, inLastDict) {
// Merge 2 dict (get values from Last dict if key exists in new dict
for (const [lKeyStr, lValue] of Object.entries(inTargetDict)) {
//Check if key exists in LastDict
if (lKeyStr in inLastDict) {
inTargetDict[lKeyStr] = inLastDict[lKeyStr]
}
}
return inTargetDict
}
// 1.2.7 Debugging toolbox init
$('.ui.dropdown.mGlobal-pyOpenRPA-Debugging-Def-Dropdown')
.dropdown({
apiSettings: {
// this url parses query server side and returns filtered results
url: '/pyOpenRPA/Debugging/HelperDefList/{query}'
},
onChange: lDropdownOnChange
})
;
});

@ -45,6 +45,16 @@
margin: 5em 0em 0em;
padding: 5em 0em;
}
.ui.search.dropdown>input.search {
width:100%;
font-family:monospace;
font-weight: bold;
}
.ui.search.dropdown>.text {
width:100%;
font-family:monospace;
font-weight: bold;
}
</style>
</head>
<body>
@ -298,6 +308,57 @@
</div>
</div>
</div>
<div class="row UACClient-pyOpenRPADict-AdminDict-Debugging" style= "display:none;">
<div class="twelve wide column">
<h4 class="ui horizontal divider header" >
<i class="bug icon"></i>
Debugging - Send
</h4>
<div class="ui labeled input">
<div class="ui label">Def</div>
</div>
<div class="ui fluid search selection dropdown mGlobal-pyOpenRPA-Debugging-Def-Dropdown" style="margin-bottom:10px;">
<input class="mGlobal-pyOpenRPA-Debugging-Def" type="hidden" name="country" style="width:100%; font-family:monospace; font-weight: bold;">
<i class="dropdown icon"></i>
<div class="default text">Def</div>
<div class="menu">
<div class="item" data-value="eh">pyOpenRPA... sys.. os.. </div>
</div>
</div>
<div class="ui fluid labeled input" style="margin-bottom:10px;">
<div class="ui label">
ArgList
</div>
<input type="text" placeholder="[1,2,3]" class="mGlobal-pyOpenRPA-Debugging-ArgList" style="width:100%; font-family:monospace; font-weight: bold;">
</div>
<div class="ui fluid labeled input" style="margin-bottom:10px;">
<div class="ui label">
ArgDict
</div>
<input type="text" placeholder="{&quot;Key1&quot;:&quot;Value1&quot;}" class="mGlobal-pyOpenRPA-Debugging-ArgDict" style="width:100%; font-family:monospace; font-weight: bold;">
</div>
<div class="ui fluid labeled input" style="margin-bottom:10px;">
<div class="ui label">
ArgGSettingsStr
</div>
<input type="text" placeholder="inGSettings" class="mGlobal-pyOpenRPA-Debugging-ArgGSettingsStr" style="width:100%; font-family:monospace; font-weight: bold;">
</div>
<div class="ui fluid labeled input" style="margin-bottom:10px;">
<div class="ui label">
ArgLoggerStr
</div>
<input type="text" placeholder="inLogger" class="mGlobal-pyOpenRPA-Debugging-ArgLoggerStr" style="width:100%; font-family:monospace; font-weight: bold;">
</div>
<div class="ui fluid button" onclick="mGlobal.pyOpenRPA.DebuggingExecute();">Execute</div>
</div>
<div class="four wide column">
<h4 class="ui horizontal divider header" >
<i class="bug icon"></i>
Debugging - Output
</h4>
<p><textarea class="mGlobal-pyOpenRPA-Debugging-Output" readonly="readonly" style="width:100%; font-family:monospace; font-weight: bold;" rows="16" cols="60"></textarea></p>
</div>
</div>
<h4 class="ui horizontal divider header">
<i class="clipboard list icon"></i>

@ -5,5 +5,6 @@ The pyOpenRPA package (from UnicodeLabs)
"""
from .Web import Basic
from .__Orchestrator__ import *
from . import Managers
__all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'

@ -1,8 +1,10 @@
"""
# How to use
# from pyOpenRPA.Tools import Terminator
# Terminator.Init(inLogger=None)
# Terminator.IsSignalClose() # True - WM_CLOSE SIGNAL has come
# Terminator.SessionLogoff() # Logoff the session
# from pyOpenRPA.Tools import StopSafe
# StopSafe.Init(inLogger=None)
# StopSafe.IsSafeStop() # True - WM_CLOSE SIGNAL has come. taskkill /im someprocess.exe
"""
import win32con
import win32gui
@ -12,33 +14,35 @@ gLogger = None
gWindowTitleStr = "PythonTerminator" # Title of the phantom window
gWindowDescriptionStr = "pyOpenRPA library for safe turn off the program (by send the WM_CLOSE signal from task kill)" # Description of the phantom window
# Init the terminator
def Init(inLogger=None):
"""
Init the StopSafe module. After that you can use def IsStopSafe() to check if close signal has come.
:param inLogger: Logger to log messages about StopSafe
:return:
"""
global gLogger
global gIsSignalCloseBool
gIsSignalCloseBool = False # Init default
gLogger = inLogger
#import sys
#import time
#import atexit
import threading
#atexit.register(print, 'PYTHON SPAM APP: SHUTDOWN')
shutdown_thread = threading.Thread(target=shutdown_monitor)
if gLogger: gLogger.info(f"StopSafe: Init termination catch thread")
shutdown_thread = threading.Thread(target=_shutdown_monitor)
shutdown_thread.start()
#shutdown_thread.join()
#shutdown_monitor()
# Terminator.IsSignalClose() # True - WM_CLOSE SIGNAL has come
def IsSignalClose():
def IsStopSafe():
"""
Check if stop signal has come.
:return:
"""
global gIsSignalCloseBool # Init the global variable
return gIsSignalCloseBool # Return the result
# Terminator.SessionLogoff() # Logoff the session
def SessionLogoff():
os.system("shutdown /l")
# Technical function
def shutdown_monitor():
def _shutdown_monitor():
global gIsSignalCloseBool # Init the global variable
global gLogger
def wndproc(hwnd, msg, wparam, lparam):
@ -58,5 +62,5 @@ def shutdown_monitor():
win32gui.PumpMessages()
gIsSignalCloseBool = True # WM_CLOSE message has come
if gLogger:
gLogger.info(f"Terminator: Program has recieve the close signal - safe exit")
gLogger.info(f"StopSafe: Program has catch VM_CLOSE signal - do safe exit")

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

@ -0,0 +1,35 @@
Thanks to all the wonderful folks who have contributed to schedule over the years:
- mattss <https://github.com/mattss>
- mrhwick <https://github.com/mrhwick>
- cfrco <https://github.com/cfrco>
- matrixise <https://github.com/matrixise>
- abultman <https://github.com/abultman>
- mplewis <https://github.com/mplewis>
- WoLfulus <https://github.com/WoLfulus>
- dylwhich <https://github.com/dylwhich>
- fkromer <https://github.com/fkromer>
- alaingilbert <https://github.com/alaingilbert>
- Zerrossetto <https://github.com/Zerrossetto>
- yetingsky <https://github.com/yetingsky>
- schnepp <https://github.com/schnepp> <https://bitbucket.org/saschaschnepp>
- grampajoe <https://github.com/grampajoe>
- gilbsgilbs <https://github.com/gilbsgilbs>
- Nathan Wailes <https://github.com/NathanWailes>
- Connor Skees <https://github.com/ConnorSkees>
- qmorek <https://github.com/qmorek>
- aisk <https://github.com/aisk>
- MichaelCorleoneLi <https://github.com/MichaelCorleoneLi>
- sijmenhuizenga <https://github.com/SijmenHuizenga>
- eladbi <https://github.com/eladbi>
- chankeypathak <https://github.com/chankeypathak>
- vubon <https://github.com/vubon>
- gaguirregabiria <https://github.com/gaguirregabiria>
- rhagenaars <https://github.com/RHagenaars>
- Skenvy <https://github.com/skenvy>
- zcking <https://github.com/zcking>
- Martin Thoma <https://github.com/MartinThoma>
- ebllg <https://github.com/ebllg>
- fredthomsen <https://github.com/fredthomsen>
- biggerfisch <https://github.com/biggerfisch>
- sosolidkk <https://github.com/sosolidkk>

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2013 Daniel Bader (http://dbader.org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

@ -0,0 +1,91 @@
Metadata-Version: 2.1
Name: schedule
Version: 1.1.0
Summary: Job scheduling for humans.
Home-page: https://github.com/dbader/schedule
Author: Daniel Bader
Author-email: mail@dbader.org
License: MIT
Download-URL: https://github.com/dbader/schedule/tarball/1.1.0
Keywords: schedule,periodic,jobs,scheduling,clockwork,cron,scheduler,job scheduling
Platform: UNKNOWN
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Development Status :: 5 - Production/Stable
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Natural Language :: English
Requires-Python: >=3.6
`schedule <https://schedule.readthedocs.io/>`__
===============================================
.. image:: https://github.com/dbader/schedule/workflows/Tests/badge.svg
:target: https://github.com/dbader/schedule/actions?query=workflow%3ATests+branch%3Amaster
.. image:: https://coveralls.io/repos/dbader/schedule/badge.svg?branch=master
:target: https://coveralls.io/r/dbader/schedule
.. image:: https://img.shields.io/pypi/v/schedule.svg
:target: https://pypi.python.org/pypi/schedule
Python job scheduling for humans. Run Python functions (or any other callable) periodically using a friendly syntax.
- A simple to use API for scheduling jobs, made for humans.
- In-process scheduler for periodic jobs. No extra processes needed!
- Very lightweight and no external dependencies.
- Excellent test coverage.
- Tested on Python and 3.6, 3.7, 3.8, 3.9
Usage
-----
.. code-block:: bash
$ pip install schedule
.. code-block:: python
import schedule
import time
def job():
print("I'm working...")
schedule.every(10).seconds.do(job)
schedule.every(10).minutes.do(job)
schedule.every().hour.do(job)
schedule.every().day.at("10:30").do(job)
schedule.every(5).to(10).minutes.do(job)
schedule.every().monday.do(job)
schedule.every().wednesday.at("13:15").do(job)
schedule.every().minute.at(":17").do(job)
while True:
schedule.run_pending()
time.sleep(1)
Documentation
-------------
Schedule's documentation lives at `schedule.readthedocs.io <https://schedule.readthedocs.io/>`_.
Meta
----
Daniel Bader - `@dbader_org <https://twitter.com/dbader_org>`_ - mail@dbader.org
Inspired by `Adam Wiggins' <https://github.com/adamwiggins>`_ article `"Rethinking Cron" <https://adam.herokuapp.com/past/2010/4/13/rethinking_cron/>`_ and the `clockwork <https://github.com/Rykian/clockwork>`_ Ruby module.
Distributed under the MIT license. See `LICENSE.txt <https://github.com/dbader/schedule/blob/master/LICENSE.txt>`_ for more information.
https://github.com/dbader/schedule

@ -0,0 +1,9 @@
schedule-1.1.0.dist-info/AUTHORS.rst,sha256=kdTW4zMQMcIf50TZeSRgSd9Xt-GgBWmNBU7T-L42w4Y,1539
schedule-1.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
schedule-1.1.0.dist-info/LICENSE.txt,sha256=MKg1LDGM4bZFrN4CmWlzQtQ4DtJjfXyhiorSVmHjtBs,1099
schedule-1.1.0.dist-info/METADATA,sha256=PqtfjpOzw6RLQBETDHUTpy3--PbtzxBFsqerANEqRGE,2996
schedule-1.1.0.dist-info/RECORD,,
schedule-1.1.0.dist-info/WHEEL,sha256=Z-nyYpwrcSqxfdux5Mbn_DQ525iP7J2DG3JgGvOYyTQ,110
schedule-1.1.0.dist-info/top_level.txt,sha256=gFq0D6Oy7pGyXL4X3ITQVefZHZ6ScWCUk8Z3C1ub7SE,9
schedule/__init__.py,sha256=t_wUVwkVvmyOeFy0vm8lZLRwkt6AbqbjFbc4jMsUk8w,28680
schedule/__pycache__/__init__.cpython-37.pyc,,

@ -0,0 +1,6 @@
Wheel-Version: 1.0
Generator: bdist_wheel (0.36.2)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any

@ -0,0 +1,839 @@
"""
Python job scheduling for humans.
github.com/dbader/schedule
An in-process scheduler for periodic jobs that uses the builder pattern
for configuration. Schedule lets you run Python functions (or any other
callable) periodically at pre-determined intervals using a simple,
human-friendly syntax.
Inspired by Addam Wiggins' article "Rethinking Cron" [1] and the
"clockwork" Ruby module [2][3].
Features:
- A simple to use API for scheduling jobs.
- Very lightweight and no external dependencies.
- Excellent test coverage.
- Tested on Python 3.6, 3.7, 3.8, 3.9
Usage:
>>> import schedule
>>> import time
>>> def job(message='stuff'):
>>> print("I'm working on:", message)
>>> schedule.every(10).minutes.do(job)
>>> schedule.every(5).to(10).days.do(job)
>>> schedule.every().hour.do(job, message='things')
>>> schedule.every().day.at("10:30").do(job)
>>> while True:
>>> schedule.run_pending()
>>> time.sleep(1)
[1] https://adam.herokuapp.com/past/2010/4/13/rethinking_cron/
[2] https://github.com/Rykian/clockwork
[3] https://adam.herokuapp.com/past/2010/6/30/replace_cron_with_clockwork/
"""
from collections.abc import Hashable
import datetime
import functools
import logging
import random
import re
import time
from typing import Set, List, Optional, Callable, Union
logger = logging.getLogger("schedule")
class ScheduleError(Exception):
"""Base schedule exception"""
pass
class ScheduleValueError(ScheduleError):
"""Base schedule value error"""
pass
class IntervalError(ScheduleValueError):
"""An improper interval was used"""
pass
class CancelJob(object):
"""
Can be returned from a job to unschedule itself.
"""
pass
class Scheduler(object):
"""
Objects instantiated by the :class:`Scheduler <Scheduler>` are
factories to create jobs, keep record of scheduled jobs and
handle their execution.
"""
def __init__(self) -> None:
self.jobs: List[Job] = []
def run_pending(self) -> None:
"""
Run all jobs that are scheduled to run.
Please note that it is *intended behavior that run_pending()
does not run missed jobs*. For example, if you've registered a job
that should run every minute and you only call run_pending()
in one hour increments then your job won't be run 60 times in
between but only once.
"""
runnable_jobs = (job for job in self.jobs if job.should_run)
for job in sorted(runnable_jobs):
self._run_job(job)
def run_all(self, delay_seconds: int = 0) -> None:
"""
Run all jobs regardless if they are scheduled to run or not.
A delay of `delay` seconds is added between each job. This helps
distribute system load generated by the jobs more evenly
over time.
:param delay_seconds: A delay added between every executed job
"""
logger.debug(
"Running *all* %i jobs with %is delay in between",
len(self.jobs),
delay_seconds,
)
for job in self.jobs[:]:
self._run_job(job)
time.sleep(delay_seconds)
def get_jobs(self, tag: Optional[Hashable] = None) -> List["Job"]:
"""
Gets scheduled jobs marked with the given tag, or all jobs
if tag is omitted.
:param tag: An identifier used to identify a subset of
jobs to retrieve
"""
if tag is None:
return self.jobs[:]
else:
return [job for job in self.jobs if tag in job.tags]
def clear(self, tag: Optional[Hashable] = None) -> None:
"""
Deletes scheduled jobs marked with the given tag, or all jobs
if tag is omitted.
:param tag: An identifier used to identify a subset of
jobs to delete
"""
if tag is None:
logger.debug("Deleting *all* jobs")
del self.jobs[:]
else:
logger.debug('Deleting all jobs tagged "%s"', tag)
self.jobs[:] = (job for job in self.jobs if tag not in job.tags)
def cancel_job(self, job: "Job") -> None:
"""
Delete a scheduled job.
:param job: The job to be unscheduled
"""
try:
logger.debug('Cancelling job "%s"', str(job))
self.jobs.remove(job)
except ValueError:
logger.debug('Cancelling not-scheduled job "%s"', str(job))
def every(self, interval: int = 1) -> "Job":
"""
Schedule a new periodic job.
:param interval: A quantity of a certain time unit
:return: An unconfigured :class:`Job <Job>`
"""
job = Job(interval, self)
return job
def _run_job(self, job: "Job") -> None:
ret = job.run()
if isinstance(ret, CancelJob) or ret is CancelJob:
self.cancel_job(job)
@property
def next_run(self) -> Optional[datetime.datetime]:
"""
Datetime when the next job should run.
:return: A :class:`~datetime.datetime` object
or None if no jobs scheduled
"""
if not self.jobs:
return None
return min(self.jobs).next_run
@property
def idle_seconds(self) -> Optional[float]:
"""
:return: Number of seconds until
:meth:`next_run <Scheduler.next_run>`
or None if no jobs are scheduled
"""
if not self.next_run:
return None
return (self.next_run - datetime.datetime.now()).total_seconds()
class Job(object):
"""
A periodic job as used by :class:`Scheduler`.
:param interval: A quantity of a certain time unit
:param scheduler: The :class:`Scheduler <Scheduler>` instance that
this job will register itself with once it has
been fully configured in :meth:`Job.do()`.
Every job runs at a given fixed time interval that is defined by:
* a :meth:`time unit <Job.second>`
* a quantity of `time units` defined by `interval`
A job is usually created and returned by :meth:`Scheduler.every`
method, which also defines its `interval`.
"""
def __init__(self, interval: int, scheduler: Scheduler = None):
self.interval: int = interval # pause interval * unit between runs
self.latest: Optional[int] = None # upper limit to the interval
self.job_func: Optional[functools.partial] = None # the job job_func to run
# time units, e.g. 'minutes', 'hours', ...
self.unit: Optional[str] = None
# optional time at which this job runs
self.at_time: Optional[datetime.time] = None
# datetime of the last run
self.last_run: Optional[datetime.datetime] = None
# datetime of the next run
self.next_run: Optional[datetime.datetime] = None
# timedelta between runs, only valid for
self.period: Optional[datetime.timedelta] = None
# Specific day of the week to start on
self.start_day: Optional[str] = None
# optional time of final run
self.cancel_after: Optional[datetime.datetime] = None
self.tags: Set[Hashable] = set() # unique set of tags for the job
self.scheduler: Optional[Scheduler] = scheduler # scheduler to register with
def __lt__(self, other) -> bool:
"""
PeriodicJobs are sortable based on the scheduled time they
run next.
"""
return self.next_run < other.next_run
def __str__(self) -> str:
if hasattr(self.job_func, "__name__"):
job_func_name = self.job_func.__name__ # type: ignore
else:
job_func_name = repr(self.job_func)
return ("Job(interval={}, unit={}, do={}, args={}, kwargs={})").format(
self.interval,
self.unit,
job_func_name,
"()" if self.job_func is None else self.job_func.args,
"{}" if self.job_func is None else self.job_func.keywords,
)
def __repr__(self):
def format_time(t):
return t.strftime("%Y-%m-%d %H:%M:%S") if t else "[never]"
def is_repr(j):
return not isinstance(j, Job)
timestats = "(last run: %s, next run: %s)" % (
format_time(self.last_run),
format_time(self.next_run),
)
if hasattr(self.job_func, "__name__"):
job_func_name = self.job_func.__name__
else:
job_func_name = repr(self.job_func)
args = [repr(x) if is_repr(x) else str(x) for x in self.job_func.args]
kwargs = ["%s=%s" % (k, repr(v)) for k, v in self.job_func.keywords.items()]
call_repr = job_func_name + "(" + ", ".join(args + kwargs) + ")"
if self.at_time is not None:
return "Every %s %s at %s do %s %s" % (
self.interval,
self.unit[:-1] if self.interval == 1 else self.unit,
self.at_time,
call_repr,
timestats,
)
else:
fmt = (
"Every %(interval)s "
+ ("to %(latest)s " if self.latest is not None else "")
+ "%(unit)s do %(call_repr)s %(timestats)s"
)
return fmt % dict(
interval=self.interval,
latest=self.latest,
unit=(self.unit[:-1] if self.interval == 1 else self.unit),
call_repr=call_repr,
timestats=timestats,
)
@property
def second(self):
if self.interval != 1:
raise IntervalError("Use seconds instead of second")
return self.seconds
@property
def seconds(self):
self.unit = "seconds"
return self
@property
def minute(self):
if self.interval != 1:
raise IntervalError("Use minutes instead of minute")
return self.minutes
@property
def minutes(self):
self.unit = "minutes"
return self
@property
def hour(self):
if self.interval != 1:
raise IntervalError("Use hours instead of hour")
return self.hours
@property
def hours(self):
self.unit = "hours"
return self
@property
def day(self):
if self.interval != 1:
raise IntervalError("Use days instead of day")
return self.days
@property
def days(self):
self.unit = "days"
return self
@property
def week(self):
if self.interval != 1:
raise IntervalError("Use weeks instead of week")
return self.weeks
@property
def weeks(self):
self.unit = "weeks"
return self
@property
def monday(self):
if self.interval != 1:
raise IntervalError(
"Scheduling .monday() jobs is only allowed for weekly jobs. "
"Using .monday() on a job scheduled to run every 2 or more weeks "
"is not supported."
)
self.start_day = "monday"
return self.weeks
@property
def tuesday(self):
if self.interval != 1:
raise IntervalError(
"Scheduling .tuesday() jobs is only allowed for weekly jobs. "
"Using .tuesday() on a job scheduled to run every 2 or more weeks "
"is not supported."
)
self.start_day = "tuesday"
return self.weeks
@property
def wednesday(self):
if self.interval != 1:
raise IntervalError(
"Scheduling .wednesday() jobs is only allowed for weekly jobs. "
"Using .wednesday() on a job scheduled to run every 2 or more weeks "
"is not supported."
)
self.start_day = "wednesday"
return self.weeks
@property
def thursday(self):
if self.interval != 1:
raise IntervalError(
"Scheduling .thursday() jobs is only allowed for weekly jobs. "
"Using .thursday() on a job scheduled to run every 2 or more weeks "
"is not supported."
)
self.start_day = "thursday"
return self.weeks
@property
def friday(self):
if self.interval != 1:
raise IntervalError(
"Scheduling .friday() jobs is only allowed for weekly jobs. "
"Using .friday() on a job scheduled to run every 2 or more weeks "
"is not supported."
)
self.start_day = "friday"
return self.weeks
@property
def saturday(self):
if self.interval != 1:
raise IntervalError(
"Scheduling .saturday() jobs is only allowed for weekly jobs. "
"Using .saturday() on a job scheduled to run every 2 or more weeks "
"is not supported."
)
self.start_day = "saturday"
return self.weeks
@property
def sunday(self):
if self.interval != 1:
raise IntervalError(
"Scheduling .sunday() jobs is only allowed for weekly jobs. "
"Using .sunday() on a job scheduled to run every 2 or more weeks "
"is not supported."
)
self.start_day = "sunday"
return self.weeks
def tag(self, *tags: Hashable):
"""
Tags the job with one or more unique identifiers.
Tags must be hashable. Duplicate tags are discarded.
:param tags: A unique list of ``Hashable`` tags.
:return: The invoked job instance
"""
if not all(isinstance(tag, Hashable) for tag in tags):
raise TypeError("Tags must be hashable")
self.tags.update(tags)
return self
def at(self, time_str):
"""
Specify a particular time that the job should be run at.
:param time_str: A string in one of the following formats:
- For daily jobs -> `HH:MM:SS` or `HH:MM`
- For hourly jobs -> `MM:SS` or `:MM`
- For minute jobs -> `:SS`
The format must make sense given how often the job is
repeating; for example, a job that repeats every minute
should not be given a string in the form `HH:MM:SS`. The
difference between `:MM` and :SS` is inferred from the
selected time-unit (e.g. `every().hour.at(':30')` vs.
`every().minute.at(':30')`).
:return: The invoked job instance
"""
if self.unit not in ("days", "hours", "minutes") and not self.start_day:
raise ScheduleValueError(
"Invalid unit (valid units are `days`, `hours`, and `minutes`)"
)
if not isinstance(time_str, str):
raise TypeError("at() should be passed a string")
if self.unit == "days" or self.start_day:
if not re.match(r"^([0-2]\d:)?[0-5]\d:[0-5]\d$", time_str):
raise ScheduleValueError(
"Invalid time format for a daily job (valid format is HH:MM(:SS)?)"
)
if self.unit == "hours":
if not re.match(r"^([0-5]\d)?:[0-5]\d$", time_str):
raise ScheduleValueError(
"Invalid time format for an hourly job (valid format is (MM)?:SS)"
)
if self.unit == "minutes":
if not re.match(r"^:[0-5]\d$", time_str):
raise ScheduleValueError(
"Invalid time format for a minutely job (valid format is :SS)"
)
time_values = time_str.split(":")
hour: Union[str, int]
minute: Union[str, int]
second: Union[str, int]
if len(time_values) == 3:
hour, minute, second = time_values
elif len(time_values) == 2 and self.unit == "minutes":
hour = 0
minute = 0
_, second = time_values
elif len(time_values) == 2 and self.unit == "hours" and len(time_values[0]):
hour = 0
minute, second = time_values
else:
hour, minute = time_values
second = 0
if self.unit == "days" or self.start_day:
hour = int(hour)
if not (0 <= hour <= 23):
raise ScheduleValueError(
"Invalid number of hours ({} is not between 0 and 23)"
)
elif self.unit == "hours":
hour = 0
elif self.unit == "minutes":
hour = 0
minute = 0
minute = int(minute)
second = int(second)
self.at_time = datetime.time(hour, minute, second)
return self
def to(self, latest: int):
"""
Schedule the job to run at an irregular (randomized) interval.
The job's interval will randomly vary from the value given
to `every` to `latest`. The range defined is inclusive on
both ends. For example, `every(A).to(B).seconds` executes
the job function every N seconds such that A <= N <= B.
:param latest: Maximum interval between randomized job runs
:return: The invoked job instance
"""
self.latest = latest
return self
def until(
self,
until_time: Union[datetime.datetime, datetime.timedelta, datetime.time, str],
):
"""
Schedule job to run until the specified moment.
The job is canceled whenever the next run is calculated and it turns out the
next run is after the until_time. The job is also canceled right before it runs,
if the current time is after until_time. This latter case can happen when the
the job was scheduled to run before until_time, but runs after until_time.
If until_time is a moment in the past, ScheduleValueError is thrown.
:param until_time: A moment in the future representing the latest time a job can
be run. If only a time is supplied, the date is set to today.
The following formats are accepted:
- datetime.datetime
- datetime.timedelta
- datetime.time
- String in one of the following formats: "%Y-%m-%d %H:%M:%S",
"%Y-%m-%d %H:%M", "%Y-%m-%d", "%H:%M:%S", "%H:%M"
as defined by strptime() behaviour. If an invalid string format is passed,
ScheduleValueError is thrown.
:return: The invoked job instance
"""
if isinstance(until_time, datetime.datetime):
self.cancel_after = until_time
elif isinstance(until_time, datetime.timedelta):
self.cancel_after = datetime.datetime.now() + until_time
elif isinstance(until_time, datetime.time):
self.cancel_after = datetime.datetime.combine(
datetime.datetime.now(), until_time
)
elif isinstance(until_time, str):
cancel_after = self._decode_datetimestr(
until_time,
[
"%Y-%m-%d %H:%M:%S",
"%Y-%m-%d %H:%M",
"%Y-%m-%d",
"%H:%M:%S",
"%H:%M",
],
)
if cancel_after is None:
raise ScheduleValueError("Invalid string format for until()")
if "-" not in until_time:
# the until_time is a time-only format. Set the date to today
now = datetime.datetime.now()
cancel_after = cancel_after.replace(
year=now.year, month=now.month, day=now.day
)
self.cancel_after = cancel_after
else:
raise TypeError(
"until() takes a string, datetime.datetime, datetime.timedelta, "
"datetime.time parameter"
)
if self.cancel_after < datetime.datetime.now():
raise ScheduleValueError(
"Cannot schedule a job to run until a time in the past"
)
return self
def do(self, job_func: Callable, *args, **kwargs):
"""
Specifies the job_func that should be called every time the
job runs.
Any additional arguments are passed on to job_func when
the job runs.
:param job_func: The function to be scheduled
:return: The invoked job instance
"""
self.job_func = functools.partial(job_func, *args, **kwargs)
functools.update_wrapper(self.job_func, job_func)
self._schedule_next_run()
if self.scheduler is None:
raise ScheduleError(
"Unable to a add job to schedule. "
"Job is not associated with an scheduler"
)
self.scheduler.jobs.append(self)
return self
@property
def should_run(self) -> bool:
"""
:return: ``True`` if the job should be run now.
"""
assert self.next_run is not None, "must run _schedule_next_run before"
return datetime.datetime.now() >= self.next_run
def run(self):
"""
Run the job and immediately reschedule it.
If the job's deadline is reached (configured using .until()), the job is not
run and CancelJob is returned immediately. If the next scheduled run exceeds
the job's deadline, CancelJob is returned after the execution. In this latter
case CancelJob takes priority over any other returned value.
:return: The return value returned by the `job_func`, or CancelJob if the job's
deadline is reached.
"""
if self._is_overdue(datetime.datetime.now()):
logger.debug("Cancelling job %s", self)
return CancelJob
logger.debug("Running job %s", self)
ret = self.job_func()
self.last_run = datetime.datetime.now()
self._schedule_next_run()
if self._is_overdue(self.next_run):
logger.debug("Cancelling job %s", self)
return CancelJob
return ret
def _schedule_next_run(self) -> None:
"""
Compute the instant when this job should run next.
"""
if self.unit not in ("seconds", "minutes", "hours", "days", "weeks"):
raise ScheduleValueError(
"Invalid unit (valid units are `seconds`, `minutes`, `hours`, "
"`days`, and `weeks`)"
)
if self.latest is not None:
if not (self.latest >= self.interval):
raise ScheduleError("`latest` is greater than `interval`")
interval = random.randint(self.interval, self.latest)
else:
interval = self.interval
self.period = datetime.timedelta(**{self.unit: interval})
self.next_run = datetime.datetime.now() + self.period
if self.start_day is not None:
if self.unit != "weeks":
raise ScheduleValueError("`unit` should be 'weeks'")
weekdays = (
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday",
)
if self.start_day not in weekdays:
raise ScheduleValueError(
"Invalid start day (valid start days are {})".format(weekdays)
)
weekday = weekdays.index(self.start_day)
days_ahead = weekday - self.next_run.weekday()
if days_ahead <= 0: # Target day already happened this week
days_ahead += 7
self.next_run += datetime.timedelta(days_ahead) - self.period
if self.at_time is not None:
if self.unit not in ("days", "hours", "minutes") and self.start_day is None:
raise ScheduleValueError("Invalid unit without specifying start day")
kwargs = {"second": self.at_time.second, "microsecond": 0}
if self.unit == "days" or self.start_day is not None:
kwargs["hour"] = self.at_time.hour
if self.unit in ["days", "hours"] or self.start_day is not None:
kwargs["minute"] = self.at_time.minute
self.next_run = self.next_run.replace(**kwargs) # type: ignore
# Make sure we run at the specified time *today* (or *this hour*)
# as well. This accounts for when a job takes so long it finished
# in the next period.
if not self.last_run or (self.next_run - self.last_run) > self.period:
now = datetime.datetime.now()
if (
self.unit == "days"
and self.at_time > now.time()
and self.interval == 1
):
self.next_run = self.next_run - datetime.timedelta(days=1)
elif self.unit == "hours" and (
self.at_time.minute > now.minute
or (
self.at_time.minute == now.minute
and self.at_time.second > now.second
)
):
self.next_run = self.next_run - datetime.timedelta(hours=1)
elif self.unit == "minutes" and self.at_time.second > now.second:
self.next_run = self.next_run - datetime.timedelta(minutes=1)
if self.start_day is not None and self.at_time is not None:
# Let's see if we will still make that time we specified today
if (self.next_run - datetime.datetime.now()).days >= 7:
self.next_run -= self.period
def _is_overdue(self, when: datetime.datetime):
return self.cancel_after is not None and when > self.cancel_after
def _decode_datetimestr(
self, datetime_str: str, formats: List[str]
) -> Optional[datetime.datetime]:
for f in formats:
try:
return datetime.datetime.strptime(datetime_str, f)
except ValueError:
pass
return None
# The following methods are shortcuts for not having to
# create a Scheduler instance:
#: Default :class:`Scheduler <Scheduler>` object
default_scheduler = Scheduler()
#: Default :class:`Jobs <Job>` list
jobs = default_scheduler.jobs # todo: should this be a copy, e.g. jobs()?
def every(interval: int = 1) -> Job:
"""Calls :meth:`every <Scheduler.every>` on the
:data:`default scheduler instance <default_scheduler>`.
"""
return default_scheduler.every(interval)
def run_pending() -> None:
"""Calls :meth:`run_pending <Scheduler.run_pending>` on the
:data:`default scheduler instance <default_scheduler>`.
"""
default_scheduler.run_pending()
def run_all(delay_seconds: int = 0) -> None:
"""Calls :meth:`run_all <Scheduler.run_all>` on the
:data:`default scheduler instance <default_scheduler>`.
"""
default_scheduler.run_all(delay_seconds=delay_seconds)
def get_jobs(tag: Optional[Hashable] = None) -> List[Job]:
"""Calls :meth:`get_jobs <Scheduler.get_jobs>` on the
:data:`default scheduler instance <default_scheduler>`.
"""
return default_scheduler.get_jobs(tag)
def clear(tag: Optional[Hashable] = None) -> None:
"""Calls :meth:`clear <Scheduler.clear>` on the
:data:`default scheduler instance <default_scheduler>`.
"""
default_scheduler.clear(tag)
def cancel_job(job: Job) -> None:
"""Calls :meth:`cancel_job <Scheduler.cancel_job>` on the
:data:`default scheduler instance <default_scheduler>`.
"""
default_scheduler.cancel_job(job)
def next_run() -> Optional[datetime.datetime]:
"""Calls :meth:`next_run <Scheduler.next_run>` on the
:data:`default scheduler instance <default_scheduler>`.
"""
return default_scheduler.next_run
def idle_seconds() -> Optional[float]:
"""Calls :meth:`idle_seconds <Scheduler.idle_seconds>` on the
:data:`default scheduler instance <default_scheduler>`.
"""
return default_scheduler.idle_seconds
def repeat(job, *args, **kwargs):
"""
Decorator to schedule a new periodic job.
Any additional arguments are passed on to the decorated function
when the job runs.
:param job: a :class:`Jobs <Job>`
"""
def _schedule_decorator(decorated_function):
job.do(decorated_function, *args, **kwargs)
return decorated_function
return _schedule_decorator

@ -1,15 +1,17 @@
Metadata-Version: 2.1
Name: pyOpenRPA
Version: 1.2.6
Version: 1.2.7
Summary: First open source RPA platform for business
Home-page: https://gitlab.com/UnicodeLabs/OpenRPA
Home-page: https://pyopenrpa.ru/
Author: Ivan Maslov
Author-email: Ivan.Maslov@unicodelabs.ru
License: MIT
Keywords: OpenRPA RPA Robot Automation Robotization OpenSource
Author-email: Ivan.Maslov@pyopenrpa.ru
License: PYOPENRPA
Keywords: pyOpenRPA OpenRPA RPA Robot Automation Robotization OpenSource IT4Business
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: MIT License
Classifier: License :: Free For Educational Use
Classifier: License :: Free For Home Use
Classifier: License :: Free for non-commercial use
Classifier: Intended Audience :: Developers
Classifier: Environment :: Win32 (MS Windows)
Classifier: Environment :: X11 Applications
@ -25,6 +27,7 @@ Requires-Dist: pillow (>=6.0.0)
Requires-Dist: keyboard (>=0.13.3)
Requires-Dist: pyautogui (<=0.9.52)
Requires-Dist: crypto (>=1.4.1)
Requires-Dist: schedule (>=1.1.0)
Requires-Dist: pywinauto (>=0.6.8) ; platform_system == "win32" and python_version >= "3.0"
Requires-Dist: WMI (>=1.4.9) ; platform_system == "win32" and python_version >= "3.0"
Requires-Dist: pywin32 (>=224) ; platform_system == "win32" and python_version >= "3.0"

@ -1,9 +1,9 @@
pyOpenRPA-1.2.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.2.6.dist-info/METADATA,sha256=pU-EpQuvMPYjhD1o2BYjfpOfsruNrxm9s7mfWX9mF1M,3612
pyOpenRPA-1.2.6.dist-info/RECORD,,
pyOpenRPA-1.2.6.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA-1.2.6.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.2.6.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA-1.2.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
pyOpenRPA-1.2.7.dist-info/METADATA,sha256=BzhjdELqdQkNJuXEIKiYjzPFg1-cNp2PHBfF9sVzBT4,3744
pyOpenRPA-1.2.7.dist-info/RECORD,,
pyOpenRPA-1.2.7.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA-1.2.7.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97
pyOpenRPA-1.2.7.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10
pyOpenRPA/.idea/inspectionProfiles/profiles_settings.xml,sha256=YXLFmX7rPNGcnKK1uX1uKYPN0fpgskYNe7t0BV7cqkY,174
pyOpenRPA/.idea/misc.xml,sha256=V-fQnOz-bYEZULgfbFgm-8mURphZrKfXMSd0wKjeEyA,188
pyOpenRPA/.idea/modules.xml,sha256=Q__U1JIA2cjxbLRXAv-SfYY00fZA0TNlpkkbY4s3ncg,277
@ -11,9 +11,9 @@ pyOpenRPA/.idea/pyOpenRPA.iml,sha256=EXh41F8lqRiSBMVg-n2tKaEaHC6_3gGSuKkPJA12Na0
pyOpenRPA/.idea/vcs.xml,sha256=2HygA1oRAwc3VBf-irxHrX5JJG9DXuQwrN0BlubhoKY,191
pyOpenRPA/.idea/workspace.xml,sha256=6tJZehshdK4And6tEoUvkIB0KE7waL_NnTSkTYYAeFA,3802
pyOpenRPA/Agent/A2O.py,sha256=PlIZZCTnVrYF2i6DSAi_KbzZfc2gtcBPmOerrEZq68U,1718
pyOpenRPA/Agent/O2A.py,sha256=vu7UgiB0qY6-1i9qVWEBGyXWSi68TTNfkvnpMIZH7Vo,4458
pyOpenRPA/Agent/Processor.py,sha256=Co8nWpffgsnEE_TpG9WrpKxz3N0sDF7eFnKxDOk1sd8,4653
pyOpenRPA/Agent/__Agent__.py,sha256=JcMFvSC3_M94HEdZe8AK2IHuJOxeDJi4RpnY_LivWpM,10639
pyOpenRPA/Agent/O2A.py,sha256=XHl5nytUoUqfPvmYWh5auYo-s0GIThNmkOA9ON-JCis,5535
pyOpenRPA/Agent/Processor.py,sha256=xNZfQ_HcV-qm_x90tBLKYJqvnENiTqHSoUk2LhDfqWQ,6346
pyOpenRPA/Agent/__Agent__.py,sha256=RLy7YQyTm_IF9kjZ22k7hd5E7wRTBSau_zsxBtW17l0,12554
pyOpenRPA/Agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Agent/__pycache__/A2O.cpython-37.pyc,,
pyOpenRPA/Agent/__pycache__/O2A.cpython-37.pyc,,
@ -22,20 +22,28 @@ pyOpenRPA/Agent/__pycache__/__Agent__.cpython-37.pyc,,
pyOpenRPA/Agent/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Agent/readme.md,sha256=QF_Bnv204OK3t1JUEhjfICkxFmSdX6bvaRl_HI6lH9I,19
pyOpenRPA/Info.md,sha256=u4Nv-PjniSF0Zlbtr6jEJX2vblK3_1zhSLNUgOdtDaA,85
pyOpenRPA/Orchestrator/BackwardCompatibility.py,sha256=a2UZINDnHCKZVvHtOOPMyFZmDynzfcyQhFJCEEMhadY,34599
pyOpenRPA/Orchestrator/BackwardCompatibility.py,sha256=CpJtOc_WnV14AGIU7FKVRuemlf9bSr4Eo5_67wuyi_k,37506
pyOpenRPA/Orchestrator/ControlPanel.py,sha256=OzS8HjG__8OZgqhajr8L8owyugXPuSLWHLtXuKdEP78,103
pyOpenRPA/Orchestrator/Core.py,sha256=Kjphtu0g6iaS4D_fIWmzRaLLgBQ9fcwccpQJhOETTAc,521
pyOpenRPA/Orchestrator/Processor.py,sha256=Z1SglmX6ykTLifD3M1mzWEJQUgweWo6HjjCjHldjGyM,8594
pyOpenRPA/Orchestrator/Core.py,sha256=OHa3mSC3_wRAizqrWBVjlR6ln4-xVVvBpOSnWl6qVvY,529
pyOpenRPA/Orchestrator/Managers/ControlPanel.py,sha256=BgtLjb6PR6kTlOjPLCg2YGP458LS9JOaYEfNurhS0nk,16544
pyOpenRPA/Orchestrator/Managers/Git.py,sha256=dgXx2UzSwiEev4ov2hBbb-5MhXVhFKWZo2lmr19QSCQ,12582
pyOpenRPA/Orchestrator/Managers/Process.py,sha256=7T_qofdkRJHdPQbaiEsTDOboImSf2N6d_Ku513rURkw,41369
pyOpenRPA/Orchestrator/Managers/__init__.py,sha256=4my0XiwmI_QLRQVhOzNvWTggCosF3tb2yRxGkehOCq0,71
pyOpenRPA/Orchestrator/Managers/__pycache__/ControlPanel.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Managers/__pycache__/Git.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Managers/__pycache__/Process.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Managers/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Processor.py,sha256=FtNmdIsBStkLHLlOe6MDWzSmZv9m7ntlQs-NirA6OgQ,10264
pyOpenRPA/Orchestrator/ProcessorOld.py,sha256=Vh5zLRpWWf-vt9CCYI8nDY7oaefiufnu6Pnl4tp27pY,13749
pyOpenRPA/Orchestrator/RobotRDPActive/CMDStr.py,sha256=6otw1WnR2_evvQ5LGyOVh0BLk_nTdilViGub7p56fXQ,1531
pyOpenRPA/Orchestrator/RobotRDPActive/Clipboard.py,sha256=YB5HJL-Qf4IlVrFHyRv_ZMJ0Vo4vjyYqWKjvrTnf1k4,1564
pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py,sha256=Qwf194uO_wcO3kBe2hTI0py90ZC1ejDUGeh6UWEfavc,27789
pyOpenRPA/Orchestrator/RobotRDPActive/Connector.py,sha256=_rTktGLcPaQoPUi482vnUWoeuB0zZcyS3k5kwEbvnM8,28021
pyOpenRPA/Orchestrator/RobotRDPActive/ConnectorExceptions.py,sha256=wwH9JOoMFFxDKQ7IyNyh1OkFkZ23o1cD8Jm3n31ycII,657
pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=AQ_u9QVSLpce9hhSacm3UT98bErc636MXza4Q6mHsSc,12264
pyOpenRPA/Orchestrator/RobotRDPActive/Processor.py,sha256=bMahu6wRznmoLYsopgbNOLqufcQnEDanIepuGvXIsac,12405
pyOpenRPA/Orchestrator/RobotRDPActive/Recovery.py,sha256=jneD474V-ZBYnmQFxWoY_feGNMSL0lGaRK6TEfQ6gOc,2954
pyOpenRPA/Orchestrator/RobotRDPActive/RobotRDPActive.py,sha256=5FX48HlIn8NKfs7q_rp3lpumWtNcwdHq7J8ygnOwU_g,12284
pyOpenRPA/Orchestrator/RobotRDPActive/Scheduler.py,sha256=21N0ilFzWI1mj3X5S9tPMgwvG7BviuBxfTuqBY85Hy4,9144
pyOpenRPA/Orchestrator/RobotRDPActive/Template.rdp,sha256=JEMVYkEmNcfg_p8isdIyvj9E-2ZB5mj-R3MkcNMKxkA,2426
pyOpenRPA/Orchestrator/RobotRDPActive/Template.rdp,sha256=YjIxCXyIvDtZx-MPpyHPj3quT9dlUZPuuILiB21eRpU,2462
pyOpenRPA/Orchestrator/RobotRDPActive/Timer.py,sha256=y8--fUvg10qEFomecl_cmdWpdGjarZBlFpMbs_GvzoQ,1077
pyOpenRPA/Orchestrator/RobotRDPActive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Orchestrator/RobotRDPActive/__main__.py,sha256=z9PaUK4_nBiGd0YJdYVHV_rFx6VjZaxrrmKxSyoTFwY,2508
@ -51,7 +59,7 @@ pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/Timer.cpython-37.pyc,,
pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Orchestrator/RobotRDPActive/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Orchestrator/RobotScreenActive/ConsoleStart.bat,sha256=_HNadUKHOYI5y6foG3srh8wjSzhX33xaKNylFtDjOJk,114
pyOpenRPA/Orchestrator/RobotScreenActive/Monitor.py,sha256=TV-YisVqa_uGiyJLG9oK4u-5aDjGiFYZFh1dPjOgYc8,492
pyOpenRPA/Orchestrator/RobotScreenActive/Monitor.py,sha256=6gIiWFyacMvudv9t3D7jxz6uVHUt53b-SS3Ebqo2_lo,492
pyOpenRPA/Orchestrator/RobotScreenActive/Screen.py,sha256=VnYcvCVymrD35l2J4ln_tlVn7CilZhxE4Ggw9P-OhIw,606
pyOpenRPA/Orchestrator/RobotScreenActive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Orchestrator/RobotScreenActive/__main__.py,sha256=JASxDDVKWUU7DAbDkRrGTrPk-P7LZchTZFh8usp6b4U,593
@ -59,21 +67,21 @@ pyOpenRPA/Orchestrator/RobotScreenActive/__pycache__/Monitor.cpython-37.pyc,,
pyOpenRPA/Orchestrator/RobotScreenActive/__pycache__/Screen.cpython-37.pyc,,
pyOpenRPA/Orchestrator/RobotScreenActive/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Orchestrator/RobotScreenActive/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Server.py,sha256=Ke89zh5iZezhA_qyQ3sfWJmL9bfc1rBBYeq-WzznfsE,30432
pyOpenRPA/Orchestrator/ServerSettings.py,sha256=zVI-brV_58uKJ-MWESTZGYv89nN_0iW_-HfVNhip4jE,32890
pyOpenRPA/Orchestrator/SettingsTemplate.py,sha256=-LIyHRKVnbrALAyss6r6L56jBX_yOAdMEhnj8N2fN9A,20532
pyOpenRPA/Orchestrator/Server.py,sha256=DbvHZTTItOBbYiykn2GMjG2r6iUsXUqQZZjjnYPnZ8Q,32455
pyOpenRPA/Orchestrator/ServerSettings.py,sha256=YaZem-osX1bD8gnJyuYU0PWDOnhqkacmXjXXHYLqW3g,31731
pyOpenRPA/Orchestrator/SettingsTemplate.py,sha256=ij1quU5ENu43QjccHYsy8SwPCGibqJNGwcDaoF7cAPo,21340
pyOpenRPA/Orchestrator/Timer.py,sha256=HvYtEeH2Q5WVVjgds9XaBpWRmvZgwgBXurJDdVVq_T0,2097
pyOpenRPA/Orchestrator/Utils/LoggerHandlerDumpLogList.py,sha256=hD47TiOuKR-G8IWu9lJD2kG28qlH7YZV63i3qv1N5Dk,681
pyOpenRPA/Orchestrator/Utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Orchestrator/Utils/__pycache__/LoggerHandlerDumpLogList.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Utils/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Web/Basic.py,sha256=pPH55rPwZz1ktpzNIcC51jeV2MgZI10Zf0Q0DncihDw,7757
pyOpenRPA/Orchestrator/Web/Index.js,sha256=Blo3LHe_a3zrW7MqYo4BSIwoOx7nlO7Ko9LWxfeqU_o,39090
pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=a4N_reLA6_Zb2KXiL73a7cWtJwO0W0Dr5lZ-RpUwuI0,16428
pyOpenRPA/Orchestrator/Web/Index.js,sha256=YACiZAvjr6NmFlDhQu6urkJp49BX7L8WJU9p-MeIlCI,43508
pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=XGPCG-qaFsAcoaXnZe1mEjPEqwcVQZ3NVPjtKX8gV4c,19192
pyOpenRPA/Orchestrator/Web/__pycache__/Basic.cpython-37.pyc,,
pyOpenRPA/Orchestrator/Web/favicon.ico,sha256=6S8XwSQ_3FXPpaX6zYkf8uUewVXO9bHnrrDHEoWrEgw,112922
pyOpenRPA/Orchestrator/__Orchestrator__.py,sha256=n-PrWqEDql1POF4bM-r9cTun9WZUqzIYRjxDEmV7xAM,119846
pyOpenRPA/Orchestrator/__init__.py,sha256=f1RFDzOkL3IVorCtqogjGdXYPtHH-P-y-5CqT7PGy7A,183
pyOpenRPA/Orchestrator/__Orchestrator__.py,sha256=wIRuMdoOwudlchdoMua0u2jO5AxCeATw0RSsQ9bKreo,150251
pyOpenRPA/Orchestrator/__init__.py,sha256=nJhjYtBXKOUNX_yNu1rRFk5y9cDz6AFiL0M6KgX_utQ,207
pyOpenRPA/Orchestrator/__main__.py,sha256=czJrc7_57WiO3EPIYfPeF_LG3pZsQVmuAYgbl_YXcVU,273
pyOpenRPA/Orchestrator/__pycache__/BackwardCompatibility.cpython-37.pyc,,
pyOpenRPA/Orchestrator/__pycache__/ControlPanel.cpython-37.pyc,,
@ -337,10 +345,10 @@ pyOpenRPA/Tools/SafeSource/__pycache__/Crypter.cpython-37.pyc,,
pyOpenRPA/Tools/SafeSource/__pycache__/DistrCreate.cpython-37.pyc,,
pyOpenRPA/Tools/SafeSource/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/Tools/SafeSource/__pycache__/__main__.cpython-37.pyc,,
pyOpenRPA/Tools/Terminator.py,sha256=VcjX3gFXiCGu3MMCidhrTNsmC9wsAqfjRJdTSU9fLnU,2178
pyOpenRPA/Tools/StopSafe.py,sha256=BNTtMmvsRE1Wtri3EkwhoBi6gGOjEPRQnJSV1C03c84,2176
pyOpenRPA/Tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
pyOpenRPA/Tools/__pycache__/Terminator.cpython-37.pyc,,
pyOpenRPA/Tools/__pycache__/StopSafe.cpython-37.pyc,,
pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/__init__.py,sha256=fI-2Npv3ZqIEhm1omXoocfYZw7PY1Ccf_pHXi_bvI0w,174
pyOpenRPA/__init__.py,sha256=thBwsh1ouqe_mKoJCCECIcKbo7oF6WPz9ZV52uvuPQM,174
pyOpenRPA/__pycache__/__init__.cpython-37.pyc,,
pyOpenRPA/test.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

@ -1,4 +1,5 @@
import requests, time, json
from . import Processor
# O2A - Data flow Orchestrator to Agent
# f"{lProtocolStr}://{lHostStr}:{lPortInt}/pyOpenRPA/Agent/O2A"
@ -20,6 +21,11 @@ def O2A_Loop(inGSettings):
while inGSettings["O2ADict"]["IsOnlineBool"]:
# Send request to the orchestrator server
lRequestBody = None
# ConnectionError - CE
lCEPhaseFastTimeLastGoodFloat = time.time()
lCEPhaseFastDurationSecFloat = inGSettings['O2ADict']['ConnectionTimeoutSecFloat']
lCEPhaseFastRetrySecFloat = inGSettings['O2ADict']['RetryTimeoutSecFloat']/5.0
lCEPhaseLongRetrySecFloat = inGSettings['O2ADict']['RetryTimeoutSecFloat']*12.0
try:
lProtocolStr= "https" if inGSettings["OrchestratorDict"]["IsHTTPSBool"] else "http"
lHostStr = inGSettings["OrchestratorDict"]["HostStr"]
@ -27,6 +33,7 @@ def O2A_Loop(inGSettings):
lURLStr=f"{lProtocolStr}://{lHostStr}:{lPortInt}/pyOpenRPA/Agent/O2A"
lDataDict = { "HostNameUpperStr": inGSettings["AgentDict"]["HostNameUpperStr"], "UserUpperStr": inGSettings["AgentDict"]["UserUpperStr"], "ActivityLastGUIDStr": lActivityLastGUIDStr}
lResponse = requests.post(url= lURLStr, cookies = {"AuthToken":inGSettings["OrchestratorDict"]["SuperTokenStr"]}, json=lDataDict, timeout=inGSettings["O2ADict"]["ConnectionTimeoutSecFloat"])
lCEPhaseFastTimeLastGoodFloat = time.time()
if lResponse.status_code != 200:
if lL: lL.warning(f"Agent can not connect to Orchestrator. Below the response from the orchestrator:{lResponse}")
time.sleep(inGSettings["O2ADict"]["RetryTimeoutSecFloat"])
@ -34,30 +41,39 @@ def O2A_Loop(inGSettings):
lRequestBody = lResponse.text
lBodyLenInt = len(lRequestBody)
if lBodyLenInt != 0: # CHeck if not empty result when close the connection from orch
lQueueItem = lResponse.json() # Try to get JSON
lQueueList = lResponse.json() # Try to get JSON
for lQueueItem in lQueueList:
# Append QUEUE item in ProcessorDict > ActivityList
lActivityLastGUIDStr = lQueueItem["GUIDStr"]
# Check if ActivityItem ["ThreadBool"] = False > go sync mode in processor queue; Else: New thread
if lQueueItem.get("ThreadBool",False) == False:
inGSettings["ProcessorDict"]["ActivityList"].append(lQueueItem)
else:
Processor.ProcessorRunAsync(inGSettings=inGSettings,inActivityList=[lQueueItem])
# Log full version if bytes size is less than limit . else short
lAgentLimitLogSizeBytesInt = 500
if lBodyLenInt <= lAgentLimitLogSizeBytesInt:
if lL: lL.info(f"ActivityItem was received from orchestrator: {lQueueItem}");
if lL: lL.info(f"ActivityItem from orchestrator: {lQueueItem}");
else:
if lL: lL.info(f"ActivityItem was received from orchestrator: Was supressed because of big size. Max is {lAgentLimitLogSizeBytesInt} bytes");
if lL: lL.info(f"ActivityItem from orchestrator: Supressed - big size. Size is {lBodyLenInt} bytes");
else:
if lL: lL.debug(f"Empty response from the orchestrator - loop when refresh the connection between Orc and Agent");
except requests.exceptions.ConnectionError as e:
if lL: lL.error(f"O2A Connection error - orchestrator is not available. Sleep for {inGSettings['A2ODict']['RetryTimeoutSecFloat']} s.")
time.sleep(inGSettings["O2ADict"]["RetryTimeoutSecFloat"])
if time.time() - lCEPhaseFastTimeLastGoodFloat <= lCEPhaseFastDurationSecFloat:
if lL: lL.error(f"O2A Connection error - orchestrator is not available. Sleep for {lCEPhaseFastRetrySecFloat} s.")
time.sleep(lCEPhaseFastRetrySecFloat)
else:
if lL: lL.error(f"O2A Connection error - orchestrator is not available. Sleep for {lCEPhaseLongRetrySecFloat} s.")
time.sleep(lCEPhaseLongRetrySecFloat)
except ConnectionResetError as e:
if lL: lL.error(f"O2A Connection reset error - orchestrator is not available. Sleep for {inGSettings['A2ODict']['RetryTimeoutSecFloat']} s.")
if lL: lL.error(f"O2A Connection reset error - orchestrator is not available. Sleep for {inGSettings['O2ADict']['RetryTimeoutSecFloat']} s.")
time.sleep(inGSettings["O2ADict"]["RetryTimeoutSecFloat"])
except json.decoder.JSONDecodeError as e:
if lL: lL.error(f"O2A JSON decode error - See body of the recieved content from the Orchestrator: {lRequestBody}")
time.sleep(inGSettings["O2ADict"]["RetryTimeoutSecFloat"])
except requests.exceptions.Timeout as e:
if lL: lL.exception(f"O2A requests timeout error (no response for long time). Sleep for {inGSettings['A2ODict']['RetryTimeoutSecFloat']} s.")
if lL: lL.exception(f"O2A requests timeout error (no response for long time). Sleep for {inGSettings['O2ADict']['RetryTimeoutSecFloat']} s.")
time.sleep(inGSettings["O2ADict"]["RetryTimeoutSecFloat"])
except Exception as e:
if lL: lL.exception(f"O2A Error handler. Sleep for {inGSettings['A2ODict']['RetryTimeoutSecFloat']} s.")
if lL: lL.exception(f"O2A Error handler. Sleep for {inGSettings['O2ADict']['RetryTimeoutSecFloat']} s.")
time.sleep(inGSettings["O2ADict"]["RetryTimeoutSecFloat"])

@ -13,6 +13,7 @@ def ProcessorRunSync(inGSettings):
# "ArgGSettings": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
# "ArgLogger": None, # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
# "GUIDStr": "sadasd-asdas-d-asdasd", # ActivityItem GUID which identify the Activity
# "ThreadBool": False
# },
],
"AliasDefDict": {}, # Storage for def with Str alias. To use it see pyOpenRPA.Orchestrator.ControlPanel
@ -36,6 +37,35 @@ def ProcessorRunSync(inGSettings):
else:
time.sleep(inGSettings["ProcessorDict"]["CheckIntervalSecFloat"]) # Sleep when list is empty
# Run processor Async
def ProcessorRunAsync(inGSettings, inActivityList):
"""
"inActivityList": [ # List of the activities
# {
# "Def":"DefAliasTest", # def link or def alias (look gSettings["Processor"]["AliasDefDict"])
# "ArgList":[1,2,3], # Args list
# "ArgDict":{"ttt":1,"222":2,"dsd":3}, # Args dictionary
# "ArgGSettings": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
# "ArgLogger": None, # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
# "GUIDStr": "sadasd-asdas-d-asdasd", # ActivityItem GUID which identify the Activity
# "ThreadBool": True
# },
"""
def __process__(inGSettings, inActivityList):
for lActivityItem in inActivityList:
lL = inGSettings["Logger"] # Logger alias
if lL: lL.debug(f'ActivityItem in new thread')
lResultList = ActivityListExecute(inGSettings = inGSettings, inActivityList = [lActivityItem]) # execute the activity item
#Some help code
if len(lResultList) == 0: lResultList= [None]
# Send result to Orc if we have GUIDStr
if "GUIDStr" in lActivityItem:
# Def to send to Orc
A2O.ActivityReturnDictSend(inGSettings=inGSettings, inActivityItemGUIDStr=lActivityItem["GUIDStr"],inReturn=lResultList[0])
# Start in new thread
lThread = threading.Thread(target=__process__,kwargs={"inGSettings": inGSettings, "inActivityList": inActivityList})
lThread.start()
# Execute ActivityItem list
# return the def result
def ActivityListExecute(inGSettings, inActivityList):

@ -2,6 +2,9 @@ import threading, socket, getpass, sys, uuid, subprocess, base64, psutil, getpas
from . import O2A, A2O # Data flow Orchestrator To Agent
from . import Processor # Processor Queue
from subprocess import CREATE_NEW_CONSOLE # Flag to create new process in another CMD
import os
gSettings = None
# Create binary file by the base64 string (safe for JSON transmition)
def OSFileBinaryDataBase64StrCreate(inFilePathStr, inFileDataBase64Str,inGSettings = None):
@ -58,16 +61,37 @@ def OSFileBinaryDataBase64StrReceive(inFilePathStr, inGSettings=None):
:param inGSettings: global settings of the Agent (singleton)
:return: File content in string base64 format (use base64.b64decode to decode data). Return None if file is not exist
"""
lL = inGSettings.get("Logger", None) if type(inGSettings) is dict else None
lFileDataBase64Str = None
if os.path.exists(inFilePathStr):
lFile = open(inFilePathStr, "rb")
lFileDataBytes = lFile.read()
lFile.close()
lFileDataBase64Str = base64.b64encode(lFileDataBytes).decode("utf-8")
lL = inGSettings.get("Logger", None) if type(inGSettings) is dict else None
lMessageStr = f"AGENT Binary file {inFilePathStr} has been read."
if lL: lL.info(lMessageStr)
A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
lMessageStr = f"OSFileBinaryDataBase64StrReceive: file {inFilePathStr} has been read"
if lL: lL.debug(lMessageStr)
#A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
else:
if lL: lL.debug(f"OSFileBinaryDataBase64StrReceive: file {inFilePathStr} is not exists - return None")
return lFileDataBase64Str
def OSFileMTimeGet(inFilePathStr: str) -> float or None:
"""
Read file modification time timestamp format (float)
:param inFilePathStr: File path to read
:return: timestamp (float) Return None if file is not exist
"""
global gSettings
lL = gSettings.get("Logger", None) if type(gSettings) is dict else None
lFileMTimeFloat = None
if os.path.exists(inFilePathStr):
lFileMTimeFloat = os.path.getmtime(inFilePathStr)
if lL: lL.debug(f"OSFileMTimeGet: file {inFilePathStr} has been read")
else:
if lL: lL.debug(f"OSFileMTimeGet: file {inFilePathStr} is not exists - return None")
return lFileMTimeFloat
def OSFileTextDataStrReceive(inFilePathStr, inEncodingStr="utf-8", inGSettings=None):
"""
Read text file in the agent GUI session
@ -77,17 +101,21 @@ def OSFileTextDataStrReceive(inFilePathStr, inEncodingStr="utf-8", inGSettings=N
:param inGSettings: global settings of the Agent (singleton)
:return: File text content in string format (use base64.b64decode to decode data). Return None if file is not exist
"""
lFileDataStr = None
lL = inGSettings.get("Logger", None) if type(inGSettings) is dict else None
if os.path.exists(inFilePathStr):
lFile = open(inFilePathStr, "r", encoding=inEncodingStr)
lFileDataStr = lFile.read()
lFile.close()
lL = inGSettings.get("Logger", None) if type(inGSettings) is dict else None
lMessageStr = f"AGENT Text file {inFilePathStr} has been read."
lMessageStr = f"OSFileTextDataStrReceive: file {inFilePathStr} has been read"
if lL: lL.info(lMessageStr)
A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
#A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
else:
if lL: lL.info(f"OSFileTextDataStrReceive: file {inFilePathStr} is not exists - return None")
return lFileDataStr
# Send CMD to OS. Result return to log + Orchestrator by the A2O connection
def OSCMD(inCMDStr, inRunAsyncBool=True, inGSettings = None, inSendOutputToOrchestratorLogsBool = True, inCMDEncodingStr = "cp1251"):
def OSCMD(inCMDStr, inRunAsyncBool=True, inGSettings = None, inSendOutputToOrchestratorLogsBool = True, inCMDEncodingStr = "cp1251", inCaptureBool = True):
"""
Execute CMD on the Agent daemonic process
@ -95,18 +123,21 @@ def OSCMD(inCMDStr, inRunAsyncBool=True, inGSettings = None, inSendOutputToOrche
:param inRunAsyncBool: True - Agent processor don't wait execution; False - Agent processor wait cmd execution
:param inGSettings: Agent global settings dict
:param inSendOutputToOrchestratorLogsBool: True - catch cmd execution output and send it to the Orchestrator logs; Flase - else case; Default True
!ATTENTION! If you need to start absolutely encapsulated app - set this flag as False. If you set True - the app output will come to Agent
:param inCMDEncodingStr: Set the encoding of the DOS window on the Agent server session. Windows is beautiful :) . Default is "cp1251" early was "cp866" - need test
:param inCaptureBool: !ATTENTION! If you need to start absolutely encapsulated app - set this flag as False. If you set True - the app output will come to Agent
:return:
"""
lResultStr = ""
# New feature
if inSendOutputToOrchestratorLogsBool == False and inCaptureBool == False:
inCMDStr = f"start {inCMDStr}"
# Subdef to listen OS result
def _CMDRunAndListenLogs(inCMDStr, inSendOutputToOrchestratorLogsBool, inCMDEncodingStr, inGSettings = None):
def _CMDRunAndListenLogs(inCMDStr, inSendOutputToOrchestratorLogsBool, inCMDEncodingStr, inGSettings = None, inCaptureBool = True):
lL = inGSettings.get("Logger",None) if type(inGSettings) is dict else None
lResultStr = ""
lOSCMDKeyStr = str(uuid.uuid4())[0:4].upper()
lCMDProcess = None
if inSendOutputToOrchestratorLogsBool == True:
if inCaptureBool == True:
lCMDProcess = subprocess.Popen(f'cmd /c {inCMDStr}', stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
else:
lCMDProcess = subprocess.Popen(f'cmd /c {inCMDStr}', stdout=None, stderr=None,
@ -114,12 +145,15 @@ def OSCMD(inCMDStr, inRunAsyncBool=True, inGSettings = None, inSendOutputToOrche
lListenBool = True
lMessageStr = f"{lOSCMDKeyStr}: # # # # AGENT CMD Process has been STARTED # # # # "
if lL: lL.info(lMessageStr)
if inSendOutputToOrchestratorLogsBool == True: # Capturing can be turned on!
A2O.LogListSend(inGSettings=inGSettings,inLogList=[lMessageStr])
lMessageStr = f"{lOSCMDKeyStr}: {inCMDStr}"
if lL: lL.info(lMessageStr)
if inSendOutputToOrchestratorLogsBool == True: # Capturing can be turned on!
A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
while lListenBool:
if inSendOutputToOrchestratorLogsBool == True: # Capturing can be turned on!
#if inSendOutputToOrchestratorLogsBool == True: # Capturing can be turned on!
if inCaptureBool == True: # Capturing can be turned on!
lOutputLineBytes = lCMDProcess.stdout.readline()
if lOutputLineBytes == b"":
lListenBool = False
@ -127,6 +161,7 @@ def OSCMD(inCMDStr, inRunAsyncBool=True, inGSettings = None, inSendOutputToOrche
if lStr.endswith("\n"): lStr = lStr[:-1]
lMessageStr = f"{lOSCMDKeyStr}: {lStr}"
if lL: lL.info(lMessageStr)
if inSendOutputToOrchestratorLogsBool == True: # Capturing can be turned on!
A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
lResultStr+=lStr
else: #Capturing is not turned on - wait until process will be closed
@ -137,15 +172,16 @@ def OSCMD(inCMDStr, inRunAsyncBool=True, inGSettings = None, inSendOutputToOrche
lListenBool = False
lMessageStr = f"{lOSCMDKeyStr}: # # # # AGENT CMD Process has been FINISHED # # # # "
if lL: lL.info(lMessageStr)
if inSendOutputToOrchestratorLogsBool == True: # Capturing can be turned on!
A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])
return lResultStr
# New call
if inRunAsyncBool:
lThread = threading.Thread(target=_CMDRunAndListenLogs, kwargs={"inCMDStr":inCMDStr, "inGSettings":inGSettings, "inSendOutputToOrchestratorLogsBool":inSendOutputToOrchestratorLogsBool, "inCMDEncodingStr":inCMDEncodingStr })
lThread = threading.Thread(target=_CMDRunAndListenLogs, kwargs={"inCMDStr":inCMDStr, "inGSettings":inGSettings, "inSendOutputToOrchestratorLogsBool":inSendOutputToOrchestratorLogsBool, "inCMDEncodingStr":inCMDEncodingStr, "inCaptureBool": inCaptureBool })
lThread.start()
lResultStr="ActivityList has been started in async mode - no output is available here."
else:
lResultStr = _CMDRunAndListenLogs(inCMDStr=inCMDStr, inGSettings=inGSettings, inSendOutputToOrchestratorLogsBool = inSendOutputToOrchestratorLogsBool, inCMDEncodingStr = inCMDEncodingStr)
lResultStr = _CMDRunAndListenLogs(inCMDStr=inCMDStr, inGSettings=inGSettings, inSendOutputToOrchestratorLogsBool = inSendOutputToOrchestratorLogsBool, inCMDEncodingStr = inCMDEncodingStr, inCaptureBool=inCaptureBool)
#lCMDCode = "cmd /c " + inCMDStr
#subprocess.Popen(lCMDCode)
#lResultCMDRun = 1 # os.system(lCMDCode)
@ -180,7 +216,8 @@ def ProcessWOExeUpperUserListGet():
# Main def
def Agent(inGSettings):
lL = inGSettings["Logger"]
global gSettings
gSettings = inGSettings
# Append Orchestrator def to ProcessorDictAlias
lModule = sys.modules[__name__]
lModuleDefList = dir(lModule)

@ -2,7 +2,7 @@
# !!! ATTENTION: Backward compatibility has been started from v1.1.13 !!!
# So you can use config of the orchestrator 1.1.13 in new Orchestrator versions and all will be ok :) (hope it's true)
import win32security, json, datetime, time, copy
import schedule
# # # # # # # # # # # # # # # # # # #
# Backward compatibility Web defs up to v1.2.0
# # # # # # # # # # # # # # # # # # #
@ -489,3 +489,47 @@ def Update(inGSettings):
inGSettings["ServerDict"]["AgentLimitLogSizeBytesInt"] = 300
if lL: lL.warning(
f"Backward compatibility (v1.2.3 to v1.2.4): Add new key ServerDict > AgentLimitLogSizeBytesInt") # Log about compatibility
# Remove ControlPanelDict and CPDict > go to ServerDict > ControlPanelDict
if "ControlPanelDict" in inGSettings:
del inGSettings["ControlPanelDict"]
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Remove old key: ControlPanelDict") # Log about compatibility
if "CPDict" in inGSettings:
for lCPKeyStr in inGSettings["CPDict"]:
lCPItemDict = inGSettings["CPDict"][lCPKeyStr]
__Orchestrator__.WebCPUpdate(inCPKeyStr=lCPKeyStr,inHTMLRenderDef=lCPItemDict["HTMLRenderDef"],
inJSONGeneratorDef=lCPItemDict["JSONGeneratorDef"],
inJSInitGeneratorDef=lCPItemDict["JSInitGeneratorDef"])
del inGSettings["CPDict"]
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Remove old key: CPDict") # Log about compatibility
if "ControlPanelDict" not in inGSettings["ServerDict"]:
inGSettings["ServerDict"]["ControlPanelDict"]={}
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Create new key: ServerDict > ControlPanelDict") # Log about compatibility
# ManagersProcessDict
if "ManagersProcessDict" not in inGSettings:
inGSettings["ManagersProcessDict"]={}
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Create new key: ManagersProcessDict") # Log about compatibility
# Check "SchedulerDict": { "Schedule": schedule, # https://schedule.readthedocs.io/en/stable/examples.html
if inGSettings.get("SchedulerDict",{}).get("Schedule",None) is None:
inGSettings["SchedulerDict"]["Schedule"] = schedule
if lL: lL.warning(f"Backward compatibility (v1.2.4 to v1.2.7): Create new module schedule (schedule.readthedocs.io)") # Log about compatibility
# ManagersGitDict
if "ManagersGitDict" not in inGSettings:
inGSettings["ManagersGitDict"]={}
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Create new key: ManagersGitDict") # Log about compatibility
# ProcessorDict > ActivityItemNowDict
if "ActivityItemNowDict" not in inGSettings["ProcessorDict"]:
inGSettings["ProcessorDict"]["ActivityItemNowDict"]=None
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Create new key: ProcessorDict > ActivityItemNowDict") # Log about compatibility
# # "UACBool": True # True - check user access before do this URL item
for lURLItemDict in inGSettings["ServerDict"]["URLList"]:
if "UACBool" not in lURLItemDict:
lURLItemDict["UACBool"]=None
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): ServerDict > URLList > item: add UACBool = None") # Log about compatibility

@ -4,7 +4,7 @@ import threading
def IsProcessorThread(inGSettings):
return inGSettings["ProcessorDict"]["ThreadIdInt"] == threading.get_ident()
def IsOrchestratorInitialized(inGSettings):
def IsOrchestratorInitialized(inGSettings) -> bool:
"""
Check if Orchestrator will be successfully initialized

@ -0,0 +1,348 @@
from ... import Orchestrator
import jinja2
import os
from inspect import signature # For detect count of def args
from ..Web import Basic
import operator
import math
class ControlPanel():
"""
Manage your control panel on the orchestrator
Control panel has 3 events types:
- onRefreshHTML - run every n (see settings) second to detect changes in HTML control panel.
- onRefreshJSON - run every n (see settings) second to detect changes in JSON data container to client side.
- onInitJS - run when client reload the Orchestrator web page
.. code-block:: python
# Usage example:
lCPManager = Orchestrator.Managers.ControlPanel(inControlPanelNameStr="TestControlPanel",
inRefreshHTMLJinja2TemplatePathStr="ControlPanel\\test.html", inJinja2TemplateRefreshBool = True)
If you use Jinja2 you can use next data context:
StorageRobotDict: Orchestrator.StorageRobotGet(inRobotNameStr=self.mRobotNameStr),
ControlPanelInstance: self,
OrchestratorModule:Orchestrator,
RequestInstance: inRequest,
UserInfoDict: Orchestrator.WebUserInfoGet(inRequest=inRequest),
UserUACDict: Orchestrator.UACUserDictGet(inRequest=inRequest),
UserUACCheckDef: inRequest.UACClientCheck,
EnumerateDef: enumerate,
OperatorModule: operator,
MathModule: math
You can modify jinja context by use the function:
Jinja2DataUpdateDictSet
.. code-block:: html
Hello my control panel!
You can use any def from Orchestrator module here in Jinja2 HTML template:
Example: OrchestratorModule.OSCMD(inCMDStr="notepad")
{{MathModule.pi}}
{% if UserInfoDict['UserNameUpperStr']=="ND" %}
YES - IT IS ND
{% endif %}
"""
mControlPanelNameStr = None
# Jinja2 consolidated
mJinja2TemplateRefreshBool = None
mJinja2DataUpdateDict = None
# RefreshHTML block
mRefreshHTMLJinja2TemplatePathStr = None
mRefreshHTMLJinja2TemplateFileNameStr = None
mRefreshHTMLJinja2Loader = None
mRefreshHTMLJinja2Env = None
mRefreshHTMLJinja2Template = None
# InitJS block
mInitJSJinja2TemplatePathStr = None
mInitJSJinja2TemplateFileNameStr = None
mInitJSJinja2Loader = None
mInitJSJinja2Env = None
mInitJSJinja2Template = None
mBackwardCompatibilityHTMLDef = None
mBackwardCompatibilityJSDef = None
mBackwardCompatibilityJSONDef = None
mRobotNameStr = None
def __init__(self, inControlPanelNameStr, inRefreshHTMLJinja2TemplatePathStr = None, inJinja2TemplateRefreshBool = False, inRobotNameStr = None):
"""
Constructor of the control panel manager
:param inControlPanelNameStr:
:param inJinja2TemplatePathStr:
"""
# Connect self witch pyOpenRPA via ControlPanelNameStr
if inControlPanelNameStr in Orchestrator.GSettingsGet()["ServerDict"]["ControlPanelDict"]:
raise Exception(f"Another control panel with name {inControlPanelNameStr} is already exists. Please resolve the error and restart")
Orchestrator.GSettingsGet()["ServerDict"]["ControlPanelDict"][inControlPanelNameStr] = self
self.RefreshHTMLJinja2TemplatePathSet(inJinja2TemplatePathStr = inRefreshHTMLJinja2TemplatePathStr)
self.mJinja2TemplateRefreshBool = inJinja2TemplateRefreshBool
self.mControlPanelNameStr = inControlPanelNameStr # Set the name of the control panel
self.mRobotNameStr = inRobotNameStr # Set the robot name for robot it execute
def Jinja2DataUpdateDictSet(self, inJinja2DataUpdateDict):
"""
Set the data dict from the Jinja2 context (you can add some new params)
:param inJinja2DataUpdateDict: dict, which will be appended to main data context
:return: None
"""
self.mJinja2DataUpdateDict = inJinja2DataUpdateDict
def RefreshHTMLJinja2TemplatePathSet(self, inJinja2TemplatePathStr):
"""
Create Jinja2 env and load the template html
:param inJinja2TemplatePathStr:
:return:
"""
try:
if inJinja2TemplatePathStr is not None:
lSystemLoaderPathStr = "/".join(inJinja2TemplatePathStr.split("\\")[0:-1])
lTemplateFileNameStr = inJinja2TemplatePathStr.split("\\")[-1]
self.mRefreshHTMLJinja2TemplateFileNameStr = lTemplateFileNameStr
self.mRefreshHTMLJinja2Loader = jinja2.FileSystemLoader(lSystemLoaderPathStr)
self.mRefreshHTMLJinja2Env = jinja2.Environment(loader=self.mRefreshHTMLJinja2Loader, trim_blocks=True)
self.mRefreshHTMLJinja2Template = self.mRefreshHTMLJinja2Env.get_template(lTemplateFileNameStr)
except Exception as e:
Orchestrator.OrchestratorLoggerGet().exception("EXCEPTION WHEN INIT Jinja2")
def RefreshHTMLJinja2StrGenerate(self, inDataDict):
"""
Generate the HTML str from the Jinja2. Pass the context inDataDict
:param inDataDict:
:return:
"""
if self.mJinja2TemplateRefreshBool == True:
self.mRefreshHTMLJinja2Template = self.mRefreshHTMLJinja2Env.get_template(self.mRefreshHTMLJinja2TemplateFileNameStr)
lHTMLStr = self.mRefreshHTMLJinja2Template.render(**inDataDict) # Render the template into str
return lHTMLStr
def InitJSJinja2TemplatePathSet(self, inJinja2TemplatePathStr):
"""
Create Jinja2 env and load the template html
:param inJinja2TemplatePathStr:
:return:
"""
try:
if inJinja2TemplatePathStr is not None:
lSystemLoaderPathStr = "/".join(inJinja2TemplatePathStr.split("\\")[0:-1])
lTemplateFileNameStr = inJinja2TemplatePathStr.split("\\")[-1]
self.mInitJSJinja2TemplateFileNameStr = lTemplateFileNameStr
self.mInitJSJinja2Loader = jinja2.FileSystemLoader(lSystemLoaderPathStr)
self.mInitJSJinja2Env = jinja2.Environment(loader=self.mInitJSJinja2Loader, trim_blocks=True)
self.mInitJSJinja2Template = self.mInitJSJinja2Env.get_template(lTemplateFileNameStr)
except Exception as e:
Orchestrator.OrchestratorLoggerGet().exception("EXCEPTION WHEN INIT Jinja2")
def InitJSJinja2StrGenerate(self, inDataDict):
"""
Generate the HTML str from the Jinja2. Pass the context inDataDict
:param inDataDict:
:return:
"""
if self.mJinja2TemplateRefreshBool == True:
self.mInitJSJinja2Template = self.mInitJSJinja2Env.get_template(self.mInitJSJinja2TemplateFileNameStr)
lHTMLStr = self.mInitJSJinja2Template.render(**inDataDict) # Render the template into str
return lHTMLStr
def DataDictGenerate(self, inRequest):
"""
:param inRequest: request handler (from http.server import BaseHTTPRequestHandler)
:return:
"""
lData = {
"StorageRobotDict": None,
"ControlPanelInstance":self,
"OrchestratorModule":Orchestrator,
"RequestInstance": inRequest,
"UserInfoDict": Orchestrator.WebUserInfoGet(inRequest=inRequest),
"UserUACDict": Orchestrator.UACUserDictGet(inRequest=inRequest),
"UserUACCheckDef": inRequest.UACClientCheck,
"EnumerateDef": enumerate,
"OperatorModule": operator,
"MathModule": math
}
# Get the robot storage by the robot name (if you set robot name when init)
if self.mRobotNameStr is not None:
lData["StorageRobotDict"] = Orchestrator.StorageRobotGet(inRobotNameStr=self.mRobotNameStr)
# Checkj Jinja2DataUpdateDict
if self.mJinja2DataUpdateDict is not None:
lData.update(self.mJinja2DataUpdateDict)
return lData
def OnRefreshHTMLStr(self, inRequest):
"""
Event to generate HTML code of the control panel when refresh time is over.
Support backward compatibility for previous versions.
:param inRequest: request handler (from http.server import BaseHTTPRequestHandler)
:return:
"""
lHTMLStr = None
lL = Orchestrator.OrchestratorLoggerGet()
if self.mBackwardCompatibilityHTMLDef is None:
if self.mRefreshHTMLJinja2Template is not None or (self.mJinja2TemplateRefreshBool == True and self.mRefreshHTMLJinja2TemplateFileNameStr is not None):
lDataDict = self.OnRefreshHTMLDataDict(inRequest = inRequest)
# Jinja code
lHTMLStr = self.RefreshHTMLJinja2StrGenerate(inDataDict=lDataDict)
else:
lHTMLStr = self.BackwardAdapterHTMLDef(inRequest=inRequest)
# return the str
return lHTMLStr
def OnRefreshHTMLDataDict(self, inRequest):
"""
Event to prepare data context for the futher Jinja2 HTML generation. You can override this def if you want some thing more data
:param inRequest: request handler (from http.server import BaseHTTPRequestHandler)
:return: dict
"""
return self.DataDictGenerate(inRequest=inRequest)
def OnRefreshHTMLHashStr(self, inRequest):
"""
Generate the hash the result output HTML. You can override this function if you know how to optimize HTML rendering.
TODO NEED TO MODIFY ServerSettings to work with Hash because of all defs are need do use Hash
:param inRequest: request handler (from http.server import BaseHTTPRequestHandler)
:return: None - default, hash function is not determined. Str - hash function is working on!
"""
return None
def OnRefreshJSONDict(self, inRequest):
"""
Event to transmit some data from server side to the client side in JSON format. Call when page refresh is initialized
:param inRequest: request handler (from http.server import BaseHTTPRequestHandler)
:return: Dict type
"""
lResultDict = None
if self.mBackwardCompatibilityJSONDef is None:
pass
else:
lResultDict = self.BackwardAdapterJSONDef(inRequest=inRequest)
return lResultDict
def OnInitJSStr(self, inRequest):
"""
Event when orchestrator web page is init on the client side - you can transmit some java script code is str type to execute it once.
:param inRequest: request handler (from http.server import BaseHTTPRequestHandler)
:return: ""
"""
lJSStr = ""
if self.mBackwardCompatibilityJSDef is None:
if self.mInitJSJinja2Template is not None or (self.mJinja2TemplateRefreshBool == True and self.mInitJSJinja2TemplateFileNameStr is not None):
lDataDict = self.OnInitJSDataDict(inRequest = inRequest)
# Jinja code
lJSStr = self.InitJSJinja2StrGenerate(inDataDict=lDataDict)
else:
lJSStr = self.BackwardAdapterJSDef(inRequest=inRequest)
return lJSStr
def OnInitJSDataDict(self, inRequest):
"""
Event to prepare data context for the futher Jinja2 JS init generation. You can override this def if you want some thing more data
:param inRequest: request handler (from http.server import BaseHTTPRequestHandler)
:return: dict
"""
return self.DataDictGenerate(inRequest=inRequest)
def BackwardAdapterHTMLDef(self,inRequest):
lGS = Orchestrator.GSettingsGet()
lL = Orchestrator.OrchestratorLoggerGet()
# HTMLRenderDef
lItemHTMLRenderDef = self.mBackwardCompatibilityHTMLDef
lResultStr = ""
if lItemHTMLRenderDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings)
lHTMLResult = None
lDEFSignature = signature(lItemHTMLRenderDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lHTMLResult = lItemHTMLRenderDef(lGS)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lHTMLResult = lItemHTMLRenderDef(inRequest, lGS)
elif lDEFARGLen == 0: # def ()
lHTMLResult = lItemHTMLRenderDef()
# RunFunction
# Backward compatibility up to 1.2.0 - call HTML generator if result has no "HTMLStr"
if type(lHTMLResult) is str:
lResultStr = lHTMLResult
elif "HTMLStr" in lHTMLResult or "JSONDict" in lHTMLResult:
lResultStr = lHTMLResult["HTMLStr"]
else:
# Call backward compatibility HTML generator
lResultStr = Basic.HTMLControlPanelBC(inCPDict=lHTMLResult)
except Exception as e:
if lL: lL.exception(f"Error in control panel HTMLRenderDef. CP Key {self.mControlPanelNameStr}. Exception are below")
return lResultStr
def BackwardAdapterJSONDef(self,inRequest):
lGS = Orchestrator.GSettingsGet()
lL = Orchestrator.OrchestratorLoggerGet()
# HTMLRenderDef
lItemJSONGeneratorDef = self.mBackwardCompatibilityJSONDef
lResultDict = {}
if lItemJSONGeneratorDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings)
lJSONResult = None
lDEFSignature = signature(lItemJSONGeneratorDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lJSONResult = lItemJSONGeneratorDef(lGS)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lJSONResult = lItemJSONGeneratorDef(inRequest, lGS)
elif lDEFARGLen == 0: # def ()
lJSONResult = lItemJSONGeneratorDef()
# RunFunction
# Backward compatibility up to 1.2.0 - call HTML generator if result has no "HTMLStr"
lType = type(lJSONResult)
if lType is str or lJSONResult is None or lType is int or lType is list or lType is dict or lType is bool or lType is float:
lResultDict = lJSONResult
else:
if lL: lL.warning(f"JSONGenerator return bad type: {str(type(lJSONResult))}, CP Key {self.mControlPanelNameStr}")
except Exception as e:
if lL: lL.exception(
f"Error in control panel JSONGeneratorDef. CP Key {self.mControlPanelNameStr}. Exception are below")
return lResultDict
def BackwardAdapterJSDef(self,inRequest):
lGS = Orchestrator.GSettingsGet()
lL = Orchestrator.OrchestratorLoggerGet()
# HTMLRenderDef
lJSInitGeneratorDef = self.mBackwardCompatibilityJSDef
lResultStr = ""
if lJSInitGeneratorDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings)
lJSResult = ""
lDEFSignature = signature(lJSInitGeneratorDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lJSResult = lJSInitGeneratorDef(lGS)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lJSResult = lJSInitGeneratorDef(inRequest, lGS)
elif lDEFARGLen == 0: # def ()
lJSResult = lJSInitGeneratorDef()
if type(lJSResult) is str:
lResultStr = lJSResult # Add delimiter to some cases
else:
if lL: lL.warning(f"JSInitGenerator return bad type: {str(type(lJSResult))}, CP Key {self.mControlPanelNameStr}")
except Exception as e:
if lL: lL.exception(
f"Error in control panel JSInitGeneratorDef. CP Key {self.mControlPanelNameStr}. Exception are below")
return lResultStr

@ -0,0 +1,249 @@
import time
import os
from .. import __Orchestrator__
from . import Process
import threading
from typing import List
from typing import Tuple
from pyOpenRPA import Orchestrator
class Git():
mAgentHostNameStr = None
mAgentUserNameStr = None
mAbsPathStr = None
mProcessList: List[Tuple] = [] # List of the key turples of the Process instance
def __init__(self, inAgentHostNameStr=None, inAgentUserNameStr=None, inGitPathStr=""):
"""
Init the Git repo instance. It helps to detect new changes in repo and auto restart services
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process. If None - works with Orc session
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process. If None - works with Orc session
:param inGitPathStr: Relative (from the orchestrator working directory) or absolute. If "" - work with Orc repo
:return:
"""
lAbsPathStr = os.path.abspath(inGitPathStr)
lAbsPathUpperStr = lAbsPathStr.upper()
lGS = __Orchestrator__.GSettingsGet()
# Check if Process is not exists in GSettings
if (inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), lAbsPathUpperStr) not in lGS["ManagersGitDict"]:
self.mAbsPathStr = lAbsPathStr
self.mAbsPathUpperStr = lAbsPathUpperStr
self.mAgentHostNameStr = inAgentHostNameStr
self.mAgentUserNameStr = inAgentUserNameStr
lGS["ManagersGitDict"][(inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), lAbsPathUpperStr)]=self
else: raise Exception(f"Managers.Git ({inAgentHostNameStr}, {inAgentUserNameStr}, {lAbsPathUpperStr}): Can't init the Git instance because it already inited in early")
def ProcessConnect(self, inProcess: Process):
"""
Connect process to the Git instance. It will apply to stop safe process when upgrade the repo and than start it
:param inProcess: Process instance
:type inProcess: Process
"""
lProcessTurple = inProcess.KeyTurpleGet()
if lProcessTurple not in self.mProcessList:
self.mProcessList.append(lProcessTurple)
else:
raise Exception(f"Process with current key is already exists in Git process list.")
def ProcessListSaveStopSafe(self):
"""
Save the state and do the stop safe for the all processes
Will send safe stop in parallel mode but wait to the end of the safestop for the all processes. After that will continue
"""
lIntervalScheckSecFloat = 5.0
lThreadList:List[threading.Thread] = []
for lProcessItemTuple in self.mProcessList:
lProcessItem = Orchestrator.Managers.ProcessGet(*lProcessItemTuple)
lProcessItem.StatusSave()
lThread = threading.Thread(target=lProcessItem.StopSafe)
lThread.start()
lThreadList.append(lThread)
# Wait for all process will be safe stopped
lAllThreadStoppedBool = False
while not lAllThreadStoppedBool:
lAllThreadStoppedBool = True
for lThread in lThreadList:
if lThread.is_alive() == True:
lAllThreadStoppedBool = False
break
time.sleep(lIntervalScheckSecFloat)
def ProcessListRestore(self):
"""
Restore the process state for the all processes
"""
for lProcessItem in self.mProcessList:
lProcessItem.StatusRestore()
def __OSCMDShell__(self, inCMDStr):
"""
Detect the way of use and send the cmd. Wait for command execution!
:return: None is not exists
"""
if self.mAgentUserNameStr is not None and self.mAgentHostNameStr is not None: # Check if Agent specified
lActivityItemGUIDStr = __Orchestrator__.AgentOSCMD(inHostNameStr=self.mAgentHostNameStr,inUserStr=self.mAgentUserNameStr,inCMDStr=inCMDStr,inRunAsyncBool=False,inSendOutputToOrchestratorLogsBool=False)
lCMDResultStr = __Orchestrator__.AgentActivityItemReturnGet(inGUIDStr=lActivityItemGUIDStr)
else:
lCMDResultStr = __Orchestrator__.OSCMD(inCMDStr=inCMDStr, inRunAsyncBool=False)
return lCMDResultStr
def BranchRevGet(self, inBranchNameStr="HEAD"):
"""
Get the specified branch revision. Default return the current branch revision
.. code-block:: python
lGit.BranchRevGet(inBranchNameStr="dev") # Get revision of the local dev branch
lGit.BranchRevGet(inBranchNameStr="remotes/origin/dev") # Get revision of the remotes dev branch
lGit.BranchRevGet(inBranchNameStr="HEAD") # Get revision of the current HEAD branch
lGit.BranchRevGet() # Equal to the call inBranchNameStr="HEAD"
:param inBranchNameStr: The branch name where to get revision guid
:return: revision GUID
"""
lCMDStr = f"cd \"{self.mAbsPathUpperStr}\" && git rev-parse {inBranchNameStr}"
lCMDResultStr = self.__OSCMDShell__(inCMDStr=lCMDStr)
return lCMDResultStr
def BranchRevIsLast(self, inBranchLocalStr: str, inBranchRemoteStr: str) -> bool:
"""Get fetch and check if local branch revision is last (if check with remote)
:param inBranchLocalStr: _description_
:type inBranchLocalStr: str
:param inBranchRemoteStr: example: origin/prd
:type inBranchRemoteStr: str
:return: _description_
:rtype: bool
"""
lIsLastBool = False
self.Fetch()
lLocalBranchRevStr = self.BranchRevGet(inBranchNameStr=inBranchLocalStr)
lRemoteBranchRevStr = self.BranchRevGet(inBranchNameStr=inBranchRemoteStr)
if lLocalBranchRevStr == lRemoteBranchRevStr:
lIsLastBool = True
return lIsLastBool
def BranchRevLastGetInterval(self, inBranchLocalStr: str, inBranchRemoteStr: str, inPreviousBranchRestoreBool: bool = True, inIntervalSecFloat: float = 60.0):
"""Periodically check if revision is last
:param inBranchLocalStr: _description_
:type inBranchLocalStr: str
:param inBranchRemoteStr: example: origin/prd
:type inBranchRemoteStr: str
:param inPreviousBranchRestoreBool: _description_, defaults to True
:type inPreviousBranchRestoreBool: bool, optional
:param inIntervalSecFloat: _description_, defaults to 60.0
:type inIntervalSecFloat: float, optional
"""
#self.BranchRevLastGet(inBranchLocalStr, inBranchRemoteStr, inPreviousBranchRestoreBool)
Orchestrator.OrchestratorScheduleGet().every(inIntervalSecFloat).seconds.do(self.BranchRevLastGet, inBranchLocalStr, inBranchRemoteStr, inPreviousBranchRestoreBool)
def BranchRevLastGet(self, inBranchLocalStr: str, inBranchRemoteStr: str, inPreviousBranchRestoreBool: bool = True):
"""Do some action to get the last revision
:param inBranchLocalStr: [description]
:type inBranchLocalStr: str
:param inBranchRemoteStr: [description]
:type inBranchRemoteStr: str
"""
Orchestrator.OrchestratorLoggerGet().debug(f"Managers.Git ({self.mAbsPathStr}): self.BranchRevLastGet has been init")
# check if the correct revision
lCMDResultStr = None
if self.BranchRevIsLast(inBranchLocalStr=inBranchLocalStr, inBranchRemoteStr=inBranchRemoteStr) == False:
Orchestrator.OrchestratorLoggerGet().info(f"Managers.Git ({self.mAbsPathStr}): self.BranchRevLastGet, new rev (branch: {inBranchLocalStr}) has been detected - merge (branch: {inBranchRemoteStr})")
# Do the stop safe for the connected process
self.ProcessListSaveStopSafe()
lBranchNameCurrentStr = self.BranchNameGet()
# reset all changes in local folder
self.Clear()
# checkout
self.BranchCheckout(inBranchNameStr=inBranchLocalStr)
# merge
lCMDStr = f"cd \"{self.mAbsPathUpperStr}\" && git merge {inBranchRemoteStr}"
lCMDResultStr = self.__OSCMDShell__(inCMDStr=lCMDStr)
if inPreviousBranchRestoreBool == True:
# checkout to the source branch which was
self.BranchCheckout(inBranchNameStr=lBranchNameCurrentStr)
# do the orc restart
Orchestrator.OrchestratorLoggerGet().info(f"Managers.Git ({self.mAbsPathStr}): self.BranchRevLastGet, merge done, restart orc")
Orchestrator.OrchestratorRestart()
return lCMDResultStr
def BranchNameGet(self) -> str:
"""Get the current local branch name
:return: current local branch name
"""
#"git rev-parse --abbrev-ref HEAD"
lCMDStr = f"cd \"{self.mAbsPathUpperStr}\" && git rev-parse --abbrev-ref HEAD"
lCMDResultStr = self.__OSCMDShell__(inCMDStr=lCMDStr)
return lCMDResultStr
def BranchCheckout(self, inBranchNameStr):
self.Clear()
lCMDStr = f"cd \"{self.mAbsPathUpperStr}\" && git checkout {inBranchNameStr}"
lCMDResultStr = self.__OSCMDShell__(inCMDStr=lCMDStr)
return lCMDResultStr
def Clear(self):
"""Clear the all changes in the local folder. Get up to the current revision
"""
# f"git clean -f -d" # Очистить от лишних файлов
lCMDStr = f"cd \"{self.mAbsPathUpperStr}\" && git clean -f -d"
lCMDResultStr = self.__OSCMDShell__(inCMDStr=lCMDStr)
# f"git reset --hard" # Откатить файлы, которые отслеживаются Git и которые были изменены
lCMDStr = f"cd \"{self.mAbsPathUpperStr}\" && git reset --hard"
lCMDResultStr = self.__OSCMDShell__(inCMDStr=lCMDStr)
return lCMDResultStr
def Fetch(self):
"""
Get updates from the git server.
.. code-block:: python
lGit.Fetch() # get updates from the server
:return: None
"""
lCMDStr = f"cd \"{self.mAbsPathUpperStr}\" && git fetch"
lCMDResultStr = self.__OSCMDShell__(inCMDStr=lCMDStr)
return lCMDResultStr
def GitExists(inAgentHostNameStr: str, inAgentUserNameStr: str, inGitPathStr: str) -> bool:
"""
Check if the Git instance is exists in GSettings by the (inAgentHostNameStr: str, inAgentUserNameStr: str, inGitPathStr: str)
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inGitPathStr: Relative (from the orchestrator working directory) or absolute. If "" - work with Orc repo
:return: True - process exists in gsettings; False - else
"""
return (inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), inGitPathStr.upper()) in __Orchestrator__.GSettingsGet()["ManagersGitDict"]
def GitGet(inAgentHostNameStr: str, inAgentUserNameStr: str, inGitPathStr: str) -> Git:
"""
Return the Git instance by the (inAgentHostNameStr: str, inAgentUserNameStr: str, inGitPathStr: str)
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inGitPathStr: Relative (from the orchestrator working directory) or absolute. If "" - work with Orc repo
:return: Git instance (if exists) Else None
"""
lAbsPathUpperStr = os.path.abspath(inGitPathStr).upper()
return __Orchestrator__.GSettingsGet()["ManagersGitDict"].get((inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), lAbsPathUpperStr),None)
def GitBranchRevGet(inAgentHostNameStr: str, inAgentUserNameStr: str, inGitPathStr: str, inBranchNameStr: str="HEAD") -> str:
lGit = GitGet(inAgentHostNameStr = inAgentHostNameStr, inAgentUserNameStr = inAgentUserNameStr, inGitPathStr=inGitPathStr)
if lGit is not None: return lGit.BranchRevGet(inBranchNameStr=inBranchNameStr)
def GitFetch(inAgentHostNameStr: str, inAgentUserNameStr: str, inGitPathStr: str) -> None:
lGit = GitGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inGitPathStr=inGitPathStr)
if lGit is not None: lGit.Fetch()

@ -0,0 +1,692 @@
#from pyOpenRPA.Orchestrator import Managers
from .. import __Orchestrator__
import os
import time
from pyOpenRPA import Orchestrator
class Process():
"""
Manager process, which is need to be started / stopped / restarted
With Process instance you can automate your process activity. Use schedule package to set interval when process should be active and when not.
All defs in class are pickle safe! After orchestrator restart (if not the force stop of the orchestrator process) your instance with properties will be restored. But it not coverage the scheduler which is in __Orchestrator__ .
After orc restart you need to reinit all schedule rules: Orchestrator.OrchestratorScheduleGet
Process instance has the following statuses:
- 0_STOPPED
- 1_STOPPED_MANUAL
- 2_STOP_SAFE
- 3_STOP_SAFE_MANUAL
- 4_STARTED
- 5_STARTED_MANUAL
.. code-block:: python
# For the safe init class use ProcessInitSafe
lProcess = Orchestrator.Managers.ProcessInitSafe(inAgentHostNameStr="PCNAME",inAgentUserNameStr="USER",
inProcessNameWOExeStr="notepad",inStartCMDStr="notepad",inStopSafeTimeoutSecFloat=3)
# Async way to run job
lProcess.ScheduleStatusCheckEverySeconds(inIntervalSecondsInt=5)
Orchestrator.OrchestratorScheduleGet().every(5).seconds.do(Orchestrator.OrchestratorThreadStart,
lProcess.StartCheck)
# OR (sync mode)
Orchestrator.OrchestratorScheduleGet().every(5).seconds.do(lProcess.StartCheck)
How to use StopSafe on the robot side
.. code-block:: python
from pyOpenRPA.Tools import StopSafe
StopSafe.Init(inLogger=None)
StopSafe.IsSafeStop() # True - WM_CLOSE SIGNAL has come. taskkill /im someprocess.exe
"""
mAgentHostNameStr = None
mAgentUserNameStr = None
mStartPathStr = None
mStartCMDStr = None
mStartArgDict = None
mStatusCheckIntervalSecFloat = None
mProcessNameWOExeStr = None
mStopSafeTimeoutSecFloat = None
mStatusStr = None # 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
# MST - Manual Stop Trigger
mMSTdTSecFloat: float = None
mMSTdNInt = None
mMSTStartTimeList = []
mAgentMuteBool = False # Mute any sends to agent while some action is perfomed
mStatusSavedStr = None # Saved status to the further restore
def MuteWait(self):
"""
Internal def. Wait when class is apply to send new activities to the agent
:return:
"""
lIntervalSecFloat = 0.3
while self.mAgentMuteBool == True:
time.sleep(lIntervalSecFloat)
return None
def KeyTurpleGet(self):
"""
Get the key turple of the current process
"""
return (self.mAgentHostNameStr.upper(), self.mAgentUserNameStr.upper(), self.mProcessNameWOExeStr.upper())
def __init__(self, inAgentHostNameStr, inAgentUserNameStr, inProcessNameWOExeStr, inStartPathStr=None, inStartCMDStr = None, inStopSafeTimeoutSecFloat=300, inStartArgDict=None, inStatusCheckIntervalSecFloat=30):
"""
Init the class instance.
!ATTENTION! Function can raise exception if process with the same (inAgentHostNameStr, inAgentUserNameStr, inProcessNameWOExeStr) is already exists in GSettings (can be restored from previous Orchestrator session). See ProcessInitSafe to sefaty init the instance or restore previous
!ATTENTION! Schedule options you must
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:param inStartPathStr: Path to start process (.cmd/ .exe or something else). Path can be relative (from orc working directory) or absolute
:param inStartCMDStr: CMD script to start program (if no start file is exists)
:param inStopSafeTimeoutSecFloat: Time to wait for stop safe. After that do the stop force (if process is not stopped)
"""
lGS = __Orchestrator__.GSettingsGet()
# Check if Process is not exists in GSettings
if (inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), inProcessNameWOExeStr.upper()) not in lGS["ManagersProcessDict"]:
self.mStartArgDict = inStartArgDict
self.mAgentHostNameStr = inAgentHostNameStr
self.mAgentUserNameStr = inAgentUserNameStr
self.mStartPathStr = inStartPathStr
self.mStartCMDStr = inStartCMDStr
self.mProcessNameWOExeStr = inProcessNameWOExeStr
self.mStopSafeTimeoutSecFloat = inStopSafeTimeoutSecFloat
lGS["ManagersProcessDict"][(inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), inProcessNameWOExeStr.upper())]=self
lActivityDict = __Orchestrator__.ProcessorActivityItemCreate(inDef=self.StatusCheck,inArgList=[], inThreadBool=True)
__Orchestrator__.ProcessorActivityItemAppend(inActivityItemDict=lActivityDict)
if inStatusCheckIntervalSecFloat is not None: __Orchestrator__.OrchestratorScheduleGet().every(inStatusCheckIntervalSecFloat).seconds.do(Orchestrator.OrchestratorThreadStart,self.StatusCheck)
self.mStatusCheckIntervalSecFloat = inStatusCheckIntervalSecFloat
else: raise Exception(f"Managers.Process ({inAgentHostNameStr}, {inAgentUserNameStr}, {inProcessNameWOExeStr}): Can't init the Process instance because it already inited in early (see ProcessInitSafe)")
def ManualStopTriggerSet(self, inMSTdTSecFloat: float, inMSTdNInt: int) -> None:
"""
Set ManualStopTrigger (MST) to switch to STOPPED MANUAL if specified count of start fails will be catched in specified time period
:param inMSTdTSecFloat: Time perios in seconds
:param inMSTdNInt: Counts of the start tries
:return: None
"""
# MST - Manual Stop Trigger
self.mMSTdTSecFloat = inMSTdTSecFloat
self.mMSTdNInt = inMSTdNInt
def ManualStopTriggerNewStart(self):
"""
Log new start event. Check if it is applicable. Change status if ManualStop trigger criteria is applied
:return: # 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
if self.mMSTdTSecFloat is not None and self.mMSTdNInt is not None:
lTimeNowSecFloat = time.time()
self.mMSTStartTimeList.append(lTimeNowSecFloat) # Append current time to MST list
# Remove old items from list
lMSTStartTimeList = []
for lTimeItemSecFloat in self.mMSTStartTimeList:
ldTSecFloat = lTimeNowSecFloat - lTimeItemSecFloat
# Move to the new list if dT less
if ldTSecFloat < self.mMSTdTSecFloat: lMSTStartTimeList.append(lTimeItemSecFloat)
self.mMSTStartTimeList = lMSTStartTimeList # Set new list
# Check count in list
if len(lMSTStartTimeList) > self.mMSTdNInt:
self.mStatusStr = "1_STOPPED_MANUAL"
# Log info about process
lL = __Orchestrator__.OrchestratorLoggerGet()
lL.info(f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): ManualStopTrigger is activated. {self.mMSTdNInt} start tries in {self.mMSTdTSecFloat} sec.")
return self.mStatusStr
def ManualStopListClear(self) -> None:
"""
Clear the last start tries list.
:return: None
"""
self.mMSTStartTimeList=[]
def Manual2Auto(self) -> str:
"""
Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self):
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
lLogBool = False
if self.mStatusStr=="1_STOPPED_MANUAL": self.mStatusStr = "0_STOPPED"; lLogBool=True
if self.mStatusStr=="3_STOP_SAFE_MANUAL": self.mStatusStr = "2_STOP_SAFE"; lLogBool=True
if self.mStatusStr=="5_STARTED_MANUAL": self.mStatusStr = "4_STARTED"; lLogBool=True
# Log info about process
if lLogBool == True: self.StatusChangeLog()
return self.mStatusStr
def Start(self, inIsManualBool = True, inStartArgDict=None) -> str:
"""
Manual/Auto start. Manual start will block scheduling execution. To return schedule execution use def Manual2Auto.
Will not start if STOP SAFE is now and don't start auto is stopped manual now
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
if inIsManualBool == False: self.ManualStopTriggerNewStart() # Set the time
if self.mStatusStr is not None and (self.mStatusStr == "1_STOPPED_MANUAL" or "STOP_SAFE" in self.mStatusStr) and inIsManualBool == False:
lStr = f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Process will not start because of stopped manual or stop safe is now."
__Orchestrator__.OrchestratorLoggerGet().warning(lStr)
return self.mStatusStr
# Send activity item to agent - wait result
if self.mStartPathStr is not None: lCMDStr = os.path.abspath(self.mStartPathStr)
elif self.mStartCMDStr is not None: lCMDStr = self.mStartCMDStr
# Append args
if inStartArgDict is not None: self.mStartArgDict = inStartArgDict
if self.mStartArgDict is not None:
for lItemKeyStr in self.mStartArgDict:
lItemValueStr = self.mStartArgDict[lItemKeyStr]
lCMDStr = f"{lCMDStr} {lItemKeyStr} {lItemValueStr}"
#import pdb
#pdb.set_trace()
self.MuteWait()
self.mAgentMuteBool=True
lActivityItemStart = __Orchestrator__.ProcessorActivityItemCreate(inDef="OSCMD",
inArgDict={"inCMDStr":lCMDStr,"inSendOutputToOrchestratorLogsBool":False, "inCaptureBool":False},
inArgGSettingsStr="inGSettings")
lGUIDStr = __Orchestrator__.AgentActivityItemAdd(inHostNameStr=self.mAgentHostNameStr,
inUserStr=self.mAgentUserNameStr,
inActivityItemDict=lActivityItemStart)
lStartResult = __Orchestrator__.AgentActivityItemReturnGet(inGUIDStr=lGUIDStr)
if inIsManualBool==True:
self.mStatusStr = "5_STARTED_MANUAL"
else:
self.mStatusStr = "4_STARTED"
# Log info about process
self.StatusChangeLog()
self.mAgentMuteBool = False
return self.mStatusStr
def StartCheck(self) -> str:
"""
Start program if auto stopped (0_STOPPED).
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
self.MuteWait()
if self.mStatusStr == "0_STOPPED":
self.Start(inIsManualBool=False)
return self.mStatusStr
def StopSafe(self, inIsManualBool = True, inStopSafeTimeoutSecFloat = None) -> str:
"""
Manual/Auto stop safe. Stop safe is the operation which send signal to process to terminate own work (send term signal to process). Managers.Process wait for the mStopSafeTimeoutSecFloat seconds. After that, if process is not terminated - self will StopForce it.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:param inStopSafeTimeoutSecFloat: Default value goes from the instance. You can specify time is second to wait while safe stop. After that program will stop force
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
if inStopSafeTimeoutSecFloat is None: inStopSafeTimeoutSecFloat = self.mStopSafeTimeoutSecFloat
self.MuteWait()
self.mAgentMuteBool=True
# Send activity item to agent - wait result
lCMDStr = f'taskkill /im "{self.mProcessNameWOExeStr}.exe" /fi "username eq %USERNAME%"'
lActivityItemStart = __Orchestrator__.ProcessorActivityItemCreate(
inDef="OSCMD",inArgDict={"inCMDStr": lCMDStr,"inSendOutputToOrchestratorLogsBool":False, "inCaptureBool": False},inArgGSettingsStr="inGSettings")
lGUIDStr = __Orchestrator__.AgentActivityItemAdd(inHostNameStr=self.mAgentHostNameStr,
inUserStr=self.mAgentUserNameStr,
inActivityItemDict=lActivityItemStart)
lStartResult = __Orchestrator__.AgentActivityItemReturnGet(inGUIDStr=lGUIDStr)
if inIsManualBool==True:
self.mStatusStr = "3_STOP_SAFE_MANUAL"
else:
self.mStatusStr = "2_STOP_SAFE"
# Log info about process
self.StatusChangeLog()
# Interval check is stopped
lTimeStartFloat = time.time()
lIntervalCheckSafeStatusFLoat = 15.0
while "SAFE" in self.mStatusStr and (time.time() - lTimeStartFloat) < inStopSafeTimeoutSecFloat:
self.StatusCheck()
if "SAFE" not in self.mStatusStr: break
time.sleep(lIntervalCheckSafeStatusFLoat)
if "SAFE" in self.mStatusStr:
# Log info about process
lL = __Orchestrator__.OrchestratorLoggerGet()
lL.info(f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Safe stop has been wait for {inStopSafeTimeoutSecFloat} sec. Now do the force stop.")
self.StopForce(inIsManualBool=inIsManualBool,inMuteIgnoreBool=True)
# Log info about process
# self.StatusChangeLog() status check has already log status (see above)
self.mAgentMuteBool = False
return self.mStatusStr
def StopSafeCheck(self, inStopSafeTimeoutSecFloat = None) -> str:
"""
Stop safe program if auto started (4_STARTED).
:param inStopSafeTimeoutSecFloat: Default value goes from the instance. You can specify time is second to wait while safe stop. After that program will stop force
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
self.MuteWait()
if self.mStatusStr == "4_STARTED":
self.StopSafe(inIsManualBool=False, inStopSafeTimeoutSecFloat = inStopSafeTimeoutSecFloat)
return self.mStatusStr
def StopForce(self, inIsManualBool = True, inMuteIgnoreBool = False) -> str:
"""
Manual/Auto stop force. Force stop don't wait process termination - it just terminate process now.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
if inMuteIgnoreBool == False: self.MuteWait()
lMuteWorkBool = False
if self.mAgentMuteBool==False: self.mAgentMuteBool=True; lMuteWorkBool=True
# Send activity item to agent - wait result
lCMDStr = f'taskkill /F /im "{self.mProcessNameWOExeStr}.exe" /fi "username eq %USERNAME%"'
lActivityItemStart = __Orchestrator__.ProcessorActivityItemCreate(
inDef="OSCMD",inArgDict={"inCMDStr": lCMDStr,"inSendOutputToOrchestratorLogsBool":False, "inCaptureBool": False},inArgGSettingsStr="inGSettings")
lGUIDStr = __Orchestrator__.AgentActivityItemAdd(inHostNameStr=self.mAgentHostNameStr,
inUserStr=self.mAgentUserNameStr,
inActivityItemDict=lActivityItemStart)
lStartResult = __Orchestrator__.AgentActivityItemReturnGet(inGUIDStr=lGUIDStr)
if inIsManualBool==True:
self.mStatusStr = "1_STOPPED_MANUAL"
else:
self.mStatusStr = "0_STOPPED"
# Log info about process
self.StatusChangeLog()
if lMuteWorkBool == True:
self.mAgentMuteBool=False
return self.mStatusStr
def StopForceCheck(self) -> str:
"""
Stop force program if auto started (4_STARTED).
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
self.MuteWait()
if self.mStatusStr == "4_STARTED":
self.StopForce(inIsManualBool=False)
return self.mStatusStr
def RestartSafe(self, inIsManualBool = True):
"""
Manual/Auto restart safe. Restart safe is the operation which send signal to process to terminate own work (send term signal to process). Then it run process. Managers.Process wait for the mStopSafeTimeoutSecFloat seconds. After that, if process is not terminated - self will StopForce it.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
self.StopSafe(inIsManualBool=inIsManualBool)
return self.Start(inIsManualBool=inIsManualBool)
def RestartForce(self, inIsManualBool = True):
"""
Manual/Auto restart force. Force restart dont wait process termination - it just terminate process now ant then start it.
Manual restart will block scheduling execution. To return schedule execution use def Manual2Auto
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
self.StopForce(inIsManualBool=inIsManualBool)
return self.Start(inIsManualBool=inIsManualBool)
def StatusSave(self):
"""
Save current status of the process. After that you can restore process activity. Work when orchestrator is restarted. Don't save "STOP_SAFE" status > "STOPPED"
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
lWarnSafeBool = True
if self.mStatusStr == "2_STOP_SAFE": self.mStatusSavedStr = "0_STOPPED"
elif self.mStatusStr == "3_STOP_SAFE_MANUAL": self.mStatusSavedStr = "1_STOPPED_MANUAL"
else: self.mStatusSavedStr = self.mStatusStr; lWarnSafeBool = False
if lWarnSafeBool==True: __Orchestrator__.OrchestratorLoggerGet().warning(f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Safe status has been catched when safe > change saved status to stopped.")
return self.mStatusStr
def StatusCheckIntervalRestore(self):
"""Call from orchestrator when init
"""
if self.mStatusCheckIntervalSecFloat is not None:
__Orchestrator__.OrchestratorLoggerGet().info(f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Restore schedule to StatusCheck in interval of {self.mStatusCheckIntervalSecFloat} sec.")
__Orchestrator__.OrchestratorScheduleGet().every(self.mStatusCheckIntervalSecFloat).seconds.do(Orchestrator.OrchestratorThreadStart,self.StatusCheck)
def StatusRestore(self):
"""
Execute the StatusCheck, after that restore status to the saved state (see StatusSave). Work when orchestrator is restarted.
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
self.StatusCheck() # check current status
# Do some action
if self.mStatusSavedStr != self.mStatusStr and self.mStatusSavedStr is not None:
#lManualBool = False
#if "MANUAL" in self.mStatusSavedStr:
# lManualBool = True
if "STOPPED" in self.mStatusSavedStr and "STOPPED" not in self.mStatusStr:
self.StopSafe(inIsManualBool=True)
if "STARTED" in self.mStatusSavedStr and "STARTED" not in self.mStatusStr:
self.Start(inIsManualBool=True)
Orchestrator.OrchestratorLoggerGet().info(f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Status has been restored to {self.mStatusSavedStr}")
self.mStatusStr = self.mStatusSavedStr
self.mStatusSavedStr = None
return self.mStatusStr
def StatusChangeLog(self):
"""
Lof information about status change
:return:
"""
# Log info about process
lL = __Orchestrator__.OrchestratorLoggerGet()
lL.info(f"Managers.Process ({self.mAgentHostNameStr}, {self.mAgentUserNameStr}, {self.mProcessNameWOExeStr}): Status has been changed to {self.mStatusStr})")
def StatusCheck(self):
"""
Check if process is alive. The def will save the manual flag is exists. Don't wait mute but set mute if it is not set.
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
# Send activity item to agent - wait result
lLogBool = False
lActivityItemUserProcessList = __Orchestrator__.ProcessorActivityItemCreate(inDef="ProcessWOExeUpperUserListGet")
#self.MuteWait()
self.mAgentMuteBool=True
lGUIDStr = __Orchestrator__.AgentActivityItemAdd(inHostNameStr=self.mAgentHostNameStr,inUserStr=self.mAgentUserNameStr,inActivityItemDict=lActivityItemUserProcessList)
lUserProcessList = __Orchestrator__.AgentActivityItemReturnGet(inGUIDStr=lGUIDStr)
if self.mProcessNameWOExeStr.upper() in lUserProcessList:
if self.mStatusStr == "1_STOPPED_MANUAL": self.mStatusStr = "5_STARTED_MANUAL"; lLogBool=True
if self.mStatusStr == "0_STOPPED": self.mStatusStr = "4_STARTED"; lLogBool=True
if self.mStatusStr is None: self.mStatusStr = "4_STARTED"; lLogBool=True
else:
if self.mStatusStr == "2_STOP_SAFE": self.mStatusStr = "0_STOPPED"; lLogBool = True
if self.mStatusStr == "3_STOP_SAFE_MANUAL": self.mStatusStr = "1_STOPPED_MANUAL"; lLogBool = True
if self.mStatusStr == "5_STARTED_MANUAL": self.mStatusStr = "1_STOPPED_MANUAL"; lLogBool=True
if self.mStatusStr == "4_STARTED": self.mStatusStr = "0_STOPPED"; lLogBool=True
if self.mStatusStr is None: self.mStatusStr = "0_STOPPED"; lLogBool=True
# Log info about process
if lLogBool == True: self.StatusChangeLog()
self.mAgentMuteBool = False
return self.mStatusStr
def StatusCheckStart(self):
"""
Check process status and run it if auto stopped self.mStatusStr is "0_STOPPED"
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
lStatusStr = self.StatusCheck()
if lStatusStr == "0_STOPPED":
self.Start(inIsManualBool=False)
return self.mStatusStr
def StatusCheckStopForce(self):
"""
Check process status and auto stop force it if self.mStatusStr is 4_STARTED
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
lStatusStr = self.StatusCheck()
if lStatusStr == "4_STARTED":
self.StopForce(inIsManualBool=False)
return self.mStatusStr
def StatusCheckStopSafe(self):
"""
Check process status and auto stop safe it if self.mStatusStr is 4_STARTED
:return:
"""
lStatusStr = self.StatusCheck()
if lStatusStr == "4_STARTED":
self.StopSafe(inIsManualBool=False)
return self.mStatusStr
def ProcessInitSafe(inAgentHostNameStr, inAgentUserNameStr, inProcessNameWOExeStr, inStartPathStr=None, inStartCMDStr = None, inStopSafeTimeoutSecFloat=300) -> Process:
"""
Exception safe function. Check if process instance is not exists in GSettings (it can be after restart because Orchestrator restore objects from dump of the previous Orchestrator session)
Return existing instance (if exists) or create new instance and return it.
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:param inStartPathStr: Path to start process (.cmd/ .exe or something else). Path can be relative (from orc working directory) or absolute
:param inStartCMDStr: CMD script to start program (if no start file is exists)
:param inStopSafeTimeoutSecFloat: Time to wait for stop safe. After that do the stop force (if process is not stopped)
:return: Process instance
"""
lProcess = ProcessGet(inAgentHostNameStr = inAgentHostNameStr, inAgentUserNameStr = inAgentUserNameStr, inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: return lProcess
else: return Process(inAgentHostNameStr=inAgentHostNameStr,inAgentUserNameStr=inAgentUserNameStr,inProcessNameWOExeStr=inProcessNameWOExeStr,
inStartPathStr=inStartPathStr,inStartCMDStr=inStartCMDStr,inStopSafeTimeoutSecFloat=inStopSafeTimeoutSecFloat)
def ProcessExists(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str) -> bool:
"""
Check if the Process instance is exists in GSettings by the (inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:return: True - process exists in gsettings; False - else
"""
return (inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), inProcessNameWOExeStr.upper()) in __Orchestrator__.GSettingsGet()["ManagersProcessDict"]
def ProcessGet(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str) -> Process:
"""
Return the process instance by the inProcessNameWOExeStr
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:return: Process instance (if exists) Else None
"""
return __Orchestrator__.GSettingsGet()["ManagersProcessDict"].get((inAgentHostNameStr.upper(), inAgentUserNameStr.upper(), inProcessNameWOExeStr.upper()),None)
def ProcessStatusStrGet(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str) -> str:
"""
Get the status of the Process instance.
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:return: Process status. See self.mStatusStr.
Process instance has the following statuses:
- 0_STOPPED
- 1_STOPPED_MANUAL
- 2_STOP_SAFE
- 3_STOP_SAFE_MANUAL
- 4_STARTED
- 5_STARTED_MANUAL
- None (if Process instance not exists)
"""
lProcess = ProcessGet(inAgentHostNameStr = inAgentHostNameStr, inAgentUserNameStr = inAgentUserNameStr, inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: return lProcess.mStatusStr
def ProcessStart(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inIsManualBool: bool = True) -> str:
"""
Manual/Auto start. Manual start will block scheduling execution. To return schedule execution use def Manual2Auto
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:return: Process status. See self.mStatusStr.
Process instance has the following statuses:
- 0_STOPPED
- 1_STOPPED_MANUAL
- 2_STOP_SAFE
- 3_STOP_SAFE_MANUAL
- 4_STARTED
- 5_STARTED_MANUAL
- None (if Process instance not exists)
"""
lProcess = ProcessGet(inAgentHostNameStr = inAgentHostNameStr, inAgentUserNameStr = inAgentUserNameStr, inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: return lProcess.Start(inIsManualBool=inIsManualBool)
def ProcessStopSafe(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inIsManualBool: bool = True, inStopSafeTimeoutSecFloat = None) -> str:
"""
Manual/Auto stop safe. Stop safe is the operation which send signal to process to terminate own work (send term signal to process). Managers.Process wait for the mStopSafeTimeoutSecFloat seconds. After that, if process is not terminated - self will StopForce it.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:param inStopSafeTimeoutSecFloat: Default value goes from the instance. You can specify time is second to wait while safe stop. After that program will stop force
:return: Process status. See self.mStatusStr.
Process instance has the following statuses:
- 0_STOPPED
- 1_STOPPED_MANUAL
- 2_STOP_SAFE
- 3_STOP_SAFE_MANUAL
- 4_STARTED
- 5_STARTED_MANUAL
- None (if Process instance not exists)
"""
lProcess = ProcessGet(inAgentHostNameStr = inAgentHostNameStr, inAgentUserNameStr = inAgentUserNameStr, inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: return lProcess.StopSafe(inIsManualBool=inIsManualBool)
def ProcessStopForce(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inIsManualBool: bool = True) -> str:
"""
Manual/Auto stop force. Force stop dont wait process termination - it just terminate process now.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
:return: Process status. See self.mStatusStr.
Process instance has the following statuses:
- 0_STOPPED
- 1_STOPPED_MANUAL
- 2_STOP_SAFE
- 3_STOP_SAFE_MANUAL
- 4_STARTED
- 5_STARTED_MANUAL
- None (if Process instance not exists)
"""
lProcess = ProcessGet(inAgentHostNameStr = inAgentHostNameStr, inAgentUserNameStr = inAgentUserNameStr, inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: return lProcess.StopForce(inIsManualBool=inIsManualBool)
def ProcessStatusSave(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str):
"""
Save current status of the process. After that you can restore process activity. Work when orchestrator is restarted. Don't save "STOP_SAFE" status > "STOPPED"
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None:
lProcess.StatusSave()
return lProcess.mStatusStr
def ProcessStatusRestore(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str):
"""
Execute the StatusCheck, after that restore status to the saved state (see StatusSave). Work when orchestrator is restarted.
:return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
"""
lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None:
lProcess.StatusRestore()
return lProcess.mStatusStr
def ProcessStatusCheck(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str) -> str:
"""
Check if process is alive. The def will save the manual flag is exists.
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:return: Process status. See self.mStatusStr.
Process instance has the following statuses:
- 0_STOPPED
- 1_STOPPED_MANUAL
- 2_STOP_SAFE
- 3_STOP_SAFE_MANUAL
- 4_STARTED
- 5_STARTED_MANUAL
- None (if Process instance not exists)
"""
lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None:
lProcess.StatusCheck()
return lProcess.mStatusStr
def ProcessManual2Auto(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str) -> str:
"""
Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self):
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:return: Process status. See self.mStatusStr.
Process instance has the following statuses:
- 0_STOPPED
- 1_STOPPED_MANUAL
- 2_STOP_SAFE
- 3_STOP_SAFE_MANUAL
- 4_STARTED
- 5_STARTED_MANUAL
- None (if Process instance not exists)
"""
lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: return lProcess.Manual2Auto()
def ProcessManualStopTriggerSet(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inMSTdTSecFloat: float, inMSTdNInt: int) -> None:
"""
Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self):
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:param inMSTdTSecFloat: Time periods in seconds
:param inMSTdNInt: Counts of the start tries
:return: None
"""
lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: lProcess.ManualStopTriggerSet(inMSTdTSecFloat = inMSTdTSecFloat, inMSTdNInt = inMSTdNInt)
def ProcessManualStopListClear(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str) -> None:
"""
Clear the last start tries list.
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:return: None
"""
lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inProcessNameWOExeStr=inProcessNameWOExeStr)
if lProcess is not None: lProcess.ManualStopListClear()
def ProcessScheduleStatusCheckEverySeconds(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str,inIntervalSecondsInt: int = 120):
"""
Run status check every interval in second you specify.
:param inAgentHostNameStr: Agent hostname in any case. Required to identify Process
:param inAgentUserNameStr: Agent user name in any case. Required to identify Process
:param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
:param inIntervalSecondsInt: Interval in seconds. Default is 120
:return: None
"""
lProcess = ProcessGet(inAgentHostNameStr=inAgentHostNameStr, inAgentUserNameStr=inAgentUserNameStr,
inProcessNameWOExeStr=inProcessNameWOExeStr)
# Check job in threaded way
__Orchestrator__.OrchestratorScheduleGet().every(inIntervalSecondsInt).seconds.do(__Orchestrator__.OrchestratorThreadStart,lProcess.StatusCheck)

@ -0,0 +1,3 @@
from .ControlPanel import *
from .Process import *
from .Git import *

@ -27,14 +27,42 @@ def ProcessorRunSync(inGSettings, inRobotRDPThreadControlDict):
if len(lActivityList)>0:
if lL: lL.debug(f'Processor ActivityList len: {len(lActivityList)}')
lActivityItem = inGSettings["ProcessorDict"]["ActivityList"].pop(0) # Extract the first item from processor queue
if lActivityItem.get("ThreadBool", False) is False:
inRobotRDPThreadControlDict["ThreadExecuteBool"]=False # Stop the RobotRDPActive monitoring
inGSettings["ProcessorDict"]["ActivityItemNowDict"]=lActivityItem
ActivityListExecute(inGSettings = inGSettings, inActivityList = [lActivityItem]) # execute the activity item
inGSettings["ProcessorDict"]["ActivityItemNowDict"]=None
inRobotRDPThreadControlDict["ThreadExecuteBool"] = True # Continue the RobotRDPActive monitoring
else:
ProcessorRunAsync(inGSettings = inGSettings, inActivityList=[lActivityItem])
else:
time.sleep(inGSettings["ProcessorDict"]["CheckIntervalSecFloat"]) # Sleep when list is empty
except Exception as e:
if lL: lL.exception(f"Processor.ProcessorRunSync. Something goes very wrong in processor queue. See traceback")
# Run processor Async
def ProcessorRunAsync(inGSettings, inActivityList):
"""
"inActivityList": [ # List of the activities
# {
# "Def":"DefAliasTest", # def link or def alias (look gSettings["Processor"]["AliasDefDict"])
# "ArgList":[1,2,3], # Args list
# "ArgDict":{"ttt":1,"222":2,"dsd":3}, # Args dictionary
# "ArgGSettings": None # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
# "ArgLogger": None, # Name of GSettings attribute: str (ArgDict) or index (for ArgList)
# "GUIDStr": "sadasd-asdas-d-asdasd", # ActivityItem GUID which identify the Activity
# "ThreadBool": True
# },
"""
def __process__(inGSettings, inActivityList):
for lActivityItem in inActivityList:
lL = inGSettings["Logger"] # Logger alias
if lL: lL.debug(f'ActivityItem in new thread')
lResultList = ActivityListExecute(inGSettings = inGSettings, inActivityList = [lActivityItem]) # execute the activity item
# Start in new thread
lThread = threading.Thread(target=__process__,kwargs={"inGSettings": inGSettings, "inActivityList": inActivityList})
lThread.start()
# Execute ActivityItem list
# return the def result
def ActivityListExecute(inGSettings, inActivityList):
@ -113,8 +141,8 @@ def ProcessorMonitorRunSync(inGSettings):
lActiveTimeStart = time.time()
try:
while True:
if len(inGSettings["ProcessorDict"]["ActivityList"])>0:
lItemDict = inGSettings["ProcessorDict"]["ActivityList"][0]
if inGSettings["ProcessorDict"]["ActivityItemNowDict"] is not None:
lItemDict = inGSettings["ProcessorDict"]["ActivityItemNowDict"]
if "GUIDStr" not in lItemDict:
lGUIDStr = str(uuid.uuid4()) # generate new GUID
lItemDict["GUIDStr"] = lGUIDStr

@ -79,13 +79,15 @@ def SessionConfigurationCreate(inConfiguration):
lDriveStoreDirectStr = ""
for lItem in inConfiguration['SharedDriveList']:
lDriveStoreDirectStr+=f"{lItem.upper()}:\\;" # Attention - all drives must be only in upper case!!!
#Replace {Width}, {Height}, {BitDepth}, {HostPort}, {Login}
#Replace {Width}, {Height}, {BitDepth}, {HostPort}, {Login} {redirectclipboard}
lRedirectClipboardStr = "1" if inConfiguration.get('RedirectClipboardBool',True) == True else "0"
lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{Width}", str(inConfiguration.get('Screen',{}).get("Width",1680)))
lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{Height}", str(inConfiguration.get('Screen',{}).get("Height",1050)))
lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{BitDepth}", inConfiguration.get('Screen',{}).get("DepthBit","32"))
lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{HostPort}", lHostPort)
lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{Login}", inConfiguration['Login'])
lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{SharedDriveList}", lDriveStoreDirectStr)
lRDPTemplateFileContent = lRDPTemplateFileContent.replace("{redirectclipboard}", lRedirectClipboardStr)
#Save template to temp file
lRDPCurrentFileFullPath = os.path.join(tempfile.gettempdir(), f"{uuid.uuid4().hex}.rdp")
open(lRDPCurrentFileFullPath, "w", encoding="utf-16-le").write(lRDPTemplateFileContent)

@ -10,7 +10,7 @@ import psutil
gSettings = None # Gsettings will be initialized after the import module
# Create new RDPSession in RobotRDPActive
def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPasswordStr):
def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPasswordStr, inRedirectClipboardBool = True):
global gSettings
# ATTENTION - dont connect if RDP session is exist
if inRDPSessionKeyStr not in gSettings["RobotRDPActive"]["RDPList"]:
@ -27,6 +27,7 @@ def RDPSessionConnect(inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPa
"DepthBit": "32" # "32" or "24" or "16" or "15", example "32"
},
"SharedDriveList": ["c"], # List of the Root sesion hard drives, example ["c"]
"RedirectClipboardBool": inRedirectClipboardBool, # True - share clipboard to RDP; False - else
###### Will updated in program ############
"SessionHex": "77777sdfsdf77777dsfdfsf77777777", # Hex is created when robot runs, example ""
"SessionIsWindowExistBool": False, # Flag if the RDP window is exist, old name "FlagSessionIsActive". Check every n seconds , example False

@ -8,7 +8,7 @@ def CheckScreen(inIntervalSeconds=1):
#Send os command to create console version (base screen)
Screen.ConsoleScreenBase()
#Delay to create console screen
time.sleep(2)
time.sleep(5)
#Delay
time.sleep(inIntervalSeconds)
return None

@ -11,6 +11,7 @@ from socketserver import ThreadingMixIn
import threading
import json
from threading import Thread
import inspect
from . import Processor # Add new processor
from . import ProcessorOld # Support old processor - deprecated defs only for backward compatibility
import urllib.parse # decode URL in string
@ -45,6 +46,13 @@ def __ComplexDictMerge2to1__(in1Dict, in2Dict):
# Tool to merge complex dictionaries - no exceptions, just overwrite dict 2 in dict 1
def __ComplexDictMerge2to1Overwrite__(in1Dict, in2Dict):
"""
Merge in2Dict in in1Dict. In conflict override and get value from dict 2
:param in1Dict: Source dict. Save the link (structure)
:param in2Dict: New data dict
:return: Merged dict 1
"""
lPathList=None
if lPathList is None: lPathList = []
for lKeyStr in in2Dict:
@ -253,7 +261,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
#Tech def
#return {"headers":[],"body":"","statuscode":111}
def URLItemCheckDo(self, inURLItem, inMethod):
def URLItemCheckDo(self, inURLItem, inMethod, inOnlyFlagUACBool = False):
###############################
#Tech sub def - do item
################################
@ -273,7 +281,14 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
lFileObject.close()
#If function is set
if "ResponseDefRequestGlobal" in inURLItem:
lDef = inURLItem["ResponseDefRequestGlobal"]
lDefSignature = inspect.signature(lDef)
if len(lDefSignature.parameters) == 2:
inURLItem["ResponseDefRequestGlobal"](inRequest, inGlobalDict)
elif len(lDefSignature.parameters) == 1:
inURLItem["ResponseDefRequestGlobal"](inRequest)
else:
inURLItem["ResponseDefRequestGlobal"]()
if "ResponseFolderPath" in inURLItem:
#lRequestPath = inRequest.path
lRequestPath = urllib.parse.unquote(inRequest.path)
@ -290,6 +305,9 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# Закрыть файловый объект
lFileObject.close()
##############################################
# UAC Check
if inOnlyFlagUACBool == True and inURLItem.get("UACBool",None) in [None, True]:
return False
if inURLItem["Method"].upper() == inMethod.upper():
# check Match type variant: BeginWith
if inURLItem["MatchType"].upper() == "BEGINWITH":
@ -348,10 +366,12 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
self.end_headers()
# Write content as utf-8 data
self.wfile.write(inResponseDict["Body"])
except ConnectionResetError as e:
if lL: lL.warning(f"An existing connection was forcibly closed by the remote host - OK for the network interactions (ConnectionResetError: [WinError 10054])")
except (ConnectionResetError, ConnectionAbortedError) as e:
if lL: lL.warning(f"SERVER: Connection was forcibly closed by the client side - OK for the network interactions (ConnectionResetError: [WinError 10054] or ConnectionAbortedError: [WinError 10053])")
def do_GET(self):
try:
threading.current_thread().request = self
self.OpenRPA = {}
self.OpenRPA["AuthToken"] = None
self.OpenRPA["Domain"] = None
@ -361,6 +381,16 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# Prepare result dict
lResponseDict = {"Headers": {}, "SetCookies": {}, "Body": b"", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict
############################
#First - all with Flag UACBool
############################
for lURLItem in gSettingsDict["ServerDict"]["URLList"]:
#Check if all condition are applied
lFlagURLIsApplied=False
lFlagURLIsApplied=self.URLItemCheckDo(inURLItem=lURLItem, inMethod="GET", inOnlyFlagUACBool=True)
if lFlagURLIsApplied:
self.ResponseDictSend()
return
#####################################
#Do authentication
#Check if authentication is turned on
@ -425,6 +455,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# POST
def do_POST(self):
try:
threading.current_thread().request = self
lL = gSettingsDict["Logger"]
self.OpenRPA = {}
self.OpenRPA["AuthToken"] = None
@ -436,6 +467,16 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
#pdb.set_trace()
lResponseDict = {"Headers": {}, "SetCookies":{}, "Body": b"", "StatusCode": None}
self.OpenRPAResponseDict = lResponseDict
############################
#First - all with Flag UACBool
############################
for lURLItem in gSettingsDict["ServerDict"]["URLList"]:
#Check if all condition are applied
lFlagURLIsApplied=False
lFlagURLIsApplied=self.URLItemCheckDo(inURLItem=lURLItem, inMethod="POST", inOnlyFlagUACBool=True)
if lFlagURLIsApplied:
self.ResponseDictSend()
return
#####################################
#Do authentication
#Check if authentication is turned on

@ -1,6 +1,5 @@
import json, os
import copy
from inspect import signature # For detect count of def args
from . import __Orchestrator__
#ControlPanelDict
from desktopmagic.screengrab_win32 import (
@ -15,6 +14,7 @@ from .Web import Basic
from . import BackwardCompatibility # Support old up to 1.2.0 defs
from . import Processor
from . import SettingsTemplate
# # # # # # # # # # # #
# v 1.2.0 Functionallity
# # # # # # # # # # # #
@ -24,31 +24,14 @@ def HiddenJSInitGenerate(inRequest, inGSettings):
lUACCPTemplateKeyList=["pyOpenRPADict","CPKeyDict"]
lL = inGSettings["Logger"] # Alias for logger
lJSInitResultStr = ""
lRenderFunctionsRobotDict = inGSettings["CPDict"]
lRenderFunctionsRobotDict = inGSettings["ServerDict"]["ControlPanelDict"]
for lItemKeyStr in lRenderFunctionsRobotDict:
lItemDict = lRenderFunctionsRobotDict[lItemKeyStr]
lJSInitGeneratorDef = lItemDict.get("JSInitGeneratorDef",None)
lUACBool = dUAC(inRoleKeyList=lUACCPTemplateKeyList+[lItemKeyStr]) # Check if render function is applicable User Access Rights (UAC)
if lItemKeyStr=="VersionCheck": lUACBool=True # For backward compatibility for the old fron version which not reload page when new orch version is comming
if lUACBool: # Run function if UAC is TRUE
# JSONGeneratorDef
if lJSInitGeneratorDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings)
lJSResult = None
lDEFSignature = signature(lJSInitGeneratorDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lJSResult = lJSInitGeneratorDef(inGSettings)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lJSResult = lJSInitGeneratorDef(inRequest, inGSettings)
elif lDEFARGLen == 0: # def ()
lJSResult = lJSInitGeneratorDef()
if type(lJSResult) is str:
lJSInitResultStr += "; "+lJSResult # Add delimiter to some cases
else:
if lL: lL.warning(f"JSInitGenerator return bad type: {str(type(lJSResult))}, CP Key {lItemKeyStr}")
except Exception as e:
if lL: lL.exception(f"Error in control panel JSInitGeneratorDef. CP Key {lItemKeyStr}. Exception are below")
lJSInitResultStr = lJSInitResultStr + ";" + lItemDict.OnInitJSStr(inRequest=inRequest)
return lJSInitResultStr
# Generate CP HTML + JSON
@ -59,59 +42,20 @@ def HiddenCPDictGenerate(inRequest, inGSettings):
lL = inGSettings["Logger"] # Alias for logger
# Create result JSON
lCPDict = {}
lRenderFunctionsRobotDict = inGSettings["CPDict"]
lRenderFunctionsRobotDict = inGSettings["ServerDict"]["ControlPanelDict"]
for lItemKeyStr in lRenderFunctionsRobotDict:
lItemDict = lRenderFunctionsRobotDict[lItemKeyStr]
lItemHTMLRenderDef = lItemDict.get("HTMLRenderDef",None)
lItemJSONGeneratorDef = lItemDict.get("JSONGeneratorDef",None)
lUACBool = dUAC(inRoleKeyList=lUACCPTemplateKeyList+[lItemKeyStr]) # Check if render function is applicable User Access Rights (UAC)
if lItemKeyStr=="VersionCheck": lUACBool=True # For backward compatibility for the old fron version which not reload page when new orch version is comming
if lUACBool: # Run function if UAC is TRUE
lCPItemDict = {"HTMLStr": None, "JSONDict":None}
# HTMLRenderDef
if lItemHTMLRenderDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings)
lHTMLResult = None
lDEFSignature = signature(lItemHTMLRenderDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lHTMLResult = lItemHTMLRenderDef(inGSettings)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lHTMLResult = lItemHTMLRenderDef(inRequest, inGSettings)
elif lDEFARGLen == 0: # def ()
lHTMLResult = lItemHTMLRenderDef()
# RunFunction
# Backward compatibility up to 1.2.0 - call HTML generator if result has no "HTMLStr"
if type(lHTMLResult) is str:
lCPItemDict["HTMLStr"] = lHTMLResult
elif "HTMLStr" in lHTMLResult or "JSONDict" in lHTMLResult:
lCPItemDict = lHTMLResult # new version
else:
# Call backward compatibility HTML generator
lCPItemDict["HTMLStr"] = Basic.HTMLControlPanelBC(inCPDict=lHTMLResult)
except Exception as e:
if lL: lL.exception(f"Error in control panel HTMLRenderDef. CP Key {lItemKeyStr}. Exception are below")
# HTML Render
lCPItemDict["HTMLStr"] = lItemDict.OnRefreshHTMLStr(inRequest=inRequest)
# JSONGeneratorDef
if lItemJSONGeneratorDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings)
lJSONResult = None
lDEFSignature = signature(lItemJSONGeneratorDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lJSONResult = lItemJSONGeneratorDef(inGSettings)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lJSONResult = lItemJSONGeneratorDef(inRequest, inGSettings)
elif lDEFARGLen == 0: # def ()
lJSONResult = lItemJSONGeneratorDef()
# RunFunction
# Backward compatibility up to 1.2.0 - call HTML generator if result has no "HTMLStr"
lType = type(lJSONResult)
if lType is str or lJSONResult is None or lType is int or lType is list or lType is dict or lType is bool or lType is float:
lCPItemDict["JSONDict"] = lJSONResult
else:
if lL: lL.warning(f"JSONGenerator return bad type: {str(type(lJSONResult))}, CP Key {lItemKeyStr}")
lCPItemDict["JSONDict"] = lItemDict.OnRefreshJSONDict(inRequest=inRequest)
except Exception as e:
if lL: lL.exception(f"Error in control panel JSONGeneratorDef. CP Key {lItemKeyStr}. Exception are below")
lL.exception(f"EXCEPTION WHEN HTML/ JSON RENDER")
# Insert CPItemDict in result CPDict
lCPDict[lItemKeyStr]=lCPItemDict
return lCPDict
@ -207,6 +151,8 @@ def pyOpenRPA_ServerData(inRequest,inGSettings):
def pyOpenRPA_ServerJSInit(inRequest,inGSettings):
lResultStr = HiddenJSInitGenerate(inRequest=inRequest, inGSettings=inGSettings)
inResponseDict = inRequest.OpenRPAResponseDict
if lResultStr is None:
lResultStr = ""
# Write content as utf-8 data
inResponseDict["Body"] = bytes(lResultStr, "utf8")
@ -281,8 +227,22 @@ def pyOpenRPA_Processor(inRequest, inGSettings):
lActivityTypeListStr = "Has some error with Activity Type read"
lWebAuditMessageStr = __Orchestrator__.WebAuditMessageCreate(inRequest=inRequest,inOperationCodeStr=lActivityTypeListStr, inMessageStr="pyOpenRPA_Processor")
if lL: lL.info(lWebAuditMessageStr)
# Append in list
inGSettings["ProcessorDict"]["ActivityList"]+=lInput
# Separate into 2 lists - sync and async
lSyncActvityList = []
lAsyncActivityList = []
for lActivityItem in lInput:
if lInput.get("ThreadBool", False) == False:
lSyncActvityList.append(lActivityItem)
else:
lAsyncActivityList.append(lActivityItem)
# Sync: Append in list
inGSettings["ProcessorDict"]["ActivityList"]+=lSyncActvityList
# Async: go to run
if len(lAsyncActivityList)>0:
for lActivityItem in lAsyncActivityList:
lActivityItemArgsDict = {"inGSettings":inGSettings,"inActivityList":[lActivityItem]}
lThread = threading.Thread(target=Processor.ActivityListExecute, kwargs=lActivityItemArgsDict)
lThread.start()
else:
# Logging info about processor activity if not SuperToken ()
if not __Orchestrator__.WebUserIsSuperToken(inRequest=inRequest, inGSettings=inGSettings):
@ -293,8 +253,13 @@ def pyOpenRPA_Processor(inRequest, inGSettings):
lActivityTypeListStr = "Has some error with Activity Type read"
lWebAuditMessageStr = __Orchestrator__.WebAuditMessageCreate(inRequest=inRequest,inOperationCodeStr=lActivityTypeListStr, inMessageStr="pyOpenRPA_Processor")
if lL: lL.info(lWebAuditMessageStr)
if lInput.get("ThreadBool",False) == False:
# Append in list
inGSettings["ProcessorDict"]["ActivityList"].append(lInput)
else:
lActivityItemArgsDict = {"inGSettings": inGSettings, "inActivityList": [lInput]}
lThread = threading.Thread(target=Processor.ActivityListExecute, kwargs=lActivityItemArgsDict)
lThread.start()
# Execute activity list
def pyOpenRPA_ActivityListExecute(inRequest, inGSettings):
# Recieve the data
@ -369,7 +334,6 @@ def pyOpenRPA_Agent_O2A(inRequest, inGSettings):
lThisAgentDict["IsListenBool"] = True # Set is online
lQueueList = lThisAgentDict["ActivityList"]
if len(lQueueList)>0:# Do some operations if has queue items
if lL: lL.debug(f'O2A: ConnectionCountInt: {lThisAgentDict["ConnectionCountInt"]};ConnectionFirstQueueItemCountInt {lThisAgentDict["ConnectionFirstQueueItemCountInt"]}')
# check if delta datetime is < than ActivityLifeTimeSecFloat
lActivityItem = lThisAgentDict["ActivityList"][0]
lActivityLifetimeSecFloat = (datetime.datetime.now() - lActivityItem["CreatedByDatetime"]).total_seconds()
@ -377,36 +341,35 @@ def pyOpenRPA_Agent_O2A(inRequest, inGSettings):
if lActivityLifetimeSecFloat > lActivityItemLifetimeLimitSecFloat:
lActivityItem = lThisAgentDict["ActivityList"].pop(0)
else:
lReturnActivityItemList = []
lReturnActivityItemDict = None
# If lInput['ActivityLastGUIDStr'] is '' > return 0 element for send in Agent
if lInput['ActivityLastGUIDStr'] == "":
lReturnActivityItemDict = lThisAgentDict["ActivityList"][0]
lReturnActivityItemList=lQueueList # 2022 02 21 - Maslov Return list - not one item
else:
# go from the end - search element with GUIDStr
lForTriggerGetNextItem = False
for lForActivityItemDict in lQueueList:
if lForTriggerGetNextItem == True:
lReturnActivityItemDict = lForActivityItemDict
break
lReturnActivityItemList.append(lReturnActivityItemDict) # 2022 02 21 - Maslov Return list - not one item
#break
if lForActivityItemDict['GUIDStr'] == lInput['ActivityLastGUIDStr']: lForTriggerGetNextItem = True
# CASE if GUID is not detected - return 0 element
if lReturnActivityItemDict == None and lForTriggerGetNextItem == False:
lReturnActivityItemDict = lThisAgentDict["ActivityList"][0]
if (len(lQueueList)==1 and lQueueList[0]['GUIDStr'] != lInput['ActivityLastGUIDStr']):
#lReturnActivityItemDict = lThisAgentDict["ActivityList"][0]
lReturnActivityItemList=lQueueList # 2022 02 21 - Maslov Return list - not one item
# Send QUEUE ITEM
if lReturnActivityItemDict is not None:
lReturnActivityItemDict = copy.deepcopy(lReturnActivityItemDict)
if "CreatedByDatetime" in lReturnActivityItemDict:
del lReturnActivityItemDict["CreatedByDatetime"]
inRequest.OpenRPAResponseDict["Body"] = bytes(json.dumps(lReturnActivityItemDict), "utf8")
if len(lReturnActivityItemList) > 0:
lReturnActivityItemList = copy.deepcopy(lReturnActivityItemList)
for lItemDict in lReturnActivityItemList:
if "CreatedByDatetime" in lItemDict:
del lItemDict["CreatedByDatetime"]
inRequest.OpenRPAResponseDict["Body"] = bytes(json.dumps(lReturnActivityItemList), "utf8")
# Log full version if bytes size is less than limit . else short
lBodyLenInt = len(inRequest.OpenRPAResponseDict["Body"])
lAgentLimitLogSizeBytesInt = inGSettings["ServerDict"]["AgentLimitLogSizeBytesInt"]
if lBodyLenInt <= lAgentLimitLogSizeBytesInt:
if lL: lL.info(f"Activity item to agent Hostname {lInput['HostNameUpperStr']}, User {lInput['UserUpperStr']}. Activity item: {lReturnActivityItemDict}")
else:
if lL: lL.info(
f"Activity item to agent Hostname {lInput['HostNameUpperStr']}, User {lInput['UserUpperStr']}. "
f"Activity item: Was suppressed because of body size of {lBodyLenInt} bytes. Max is {lAgentLimitLogSizeBytesInt}")
if lL: lL.debug(f"ActivityItem to Agent ({lInput['HostNameUpperStr']}, {lInput['UserUpperStr']}): Item count: {len(lReturnActivityItemList)}, bytes size: {lBodyLenInt}")
lDoLoopBool = False # CLose the connection
else: # Nothing to send - sleep for the next iteration
time.sleep(lAgentLoopSleepSecFloat)
@ -415,6 +378,32 @@ def pyOpenRPA_Agent_O2A(inRequest, inGSettings):
except Exception as e:
if lL: lL.exception("pyOpenRPA_Agent_O2A Exception!")
lThisAgentDict["ConnectionCountInt"] -= 1 # Connection go to be closed - decrement the connection count
def pyOpenRPA_Debugging_HelperDefList(inRequest, inGSettings):
# Parse query
lResultDict = {
"success": True,
"results": []
}
# Get the path
lPathSplitList = __Orchestrator__.WebRequestParsePath(inRequest=inRequest).split('/')
lQueryStr = None
if "HelperDefList" != lPathSplitList[-1] and "" != lPathSplitList[-1]: lQueryStr = lPathSplitList[-1]
if lQueryStr != "" and lQueryStr is not None:
lDefList = __Orchestrator__.ActivityItemHelperDefList(inDefQueryStr=lQueryStr)
for lDefStr in lDefList:
lResultDict["results"].append({"name": lDefStr, "value": lDefStr, "text": lDefStr})
__Orchestrator__.WebRequestResponseSend(inRequest=inRequest, inResponeStr=json.dumps(lResultDict))
def pyOpenRPA_Debugging_HelperDefAutofill(inRequest, inGSettings):
# Parse query
# Get the path
lPathSplitList = __Orchestrator__.WebRequestParsePath(inRequest=inRequest).split('/')
lQueryStr = None
if "HelperDefAutofill" != lPathSplitList[-1] and "" != lPathSplitList[-1]: lQueryStr = lPathSplitList[-1]
lResultDict = __Orchestrator__.ActivityItemHelperDefAutofill(inDef = lQueryStr)
__Orchestrator__.WebRequestResponseSend(inRequest=inRequest, inResponeStr=json.dumps(lResultDict))
# See docs in Agent (pyOpenRPA.Agent.A2O)
def pyOpenRPA_Agent_A2O(inRequest, inGSettings):
lL = inGSettings["Logger"]
@ -434,7 +423,13 @@ def pyOpenRPA_Agent_A2O(inRequest, inGSettings):
lActivityReturnItemValue = lInput["ActivityReturnDict"][lActivityReturnItemKeyStr]
# Create item in gSettings
inGSettings["AgentActivityReturnDict"][lActivityReturnItemKeyStr]=SettingsTemplate.__AgentActivityReturnDictItemCreate__(inReturn=lActivityReturnItemValue)
if lL: lL.debug(f"SERVER: pyOpenRPA_Agent_A2O:: Has recieved result of the activity items from agent! ActivityItem GUID Str: {lActivityReturnItemKeyStr}; Return value: {lActivityReturnItemValue}")
lLogStr = "x bytes"
try:
if lActivityReturnItemValue is not None:
lLogStr = f"{len(lActivityReturnItemValue)} bytes"
except Exception as e:
pass
if lL: lL.debug(f"SERVER: pyOpenRPA_Agent_A2O:: Has recieved result of the activity items from agent! ActivityItem GUID Str: {lActivityReturnItemKeyStr}; Return value len: {lLogStr}")
# Delete the source activity item from AgentDict
if lAgentDictItemKeyTurple in inGSettings["AgentDict"]:
lAgentDictActivityListNew = []
@ -484,6 +479,8 @@ def SettingsUpdate(inGlobalConfiguration):
{"Method": "POST", "URL": "/pyOpenRPA/ActivityListExecute", "MatchType": "Equal","ResponseDefRequestGlobal": pyOpenRPA_ActivityListExecute, "ResponseContentType": "application/json"},
{"Method": "POST", "URL": "/pyOpenRPA/Agent/O2A", "MatchType": "Equal","ResponseDefRequestGlobal": pyOpenRPA_Agent_O2A, "ResponseContentType": "application/json"},
{"Method": "POST", "URL": "/pyOpenRPA/Agent/A2O", "MatchType": "Equal","ResponseDefRequestGlobal": pyOpenRPA_Agent_A2O, "ResponseContentType": "application/json"},
{"Method": "GET", "URL": "/pyOpenRPA/Debugging/HelperDefList/", "MatchType": "BeginWith","ResponseDefRequestGlobal": pyOpenRPA_Debugging_HelperDefList, "ResponseContentType": "application/json"},
{"Method": "GET", "URL": "/pyOpenRPA/Debugging/HelperDefAutofill/", "MatchType": "BeginWith","ResponseDefRequestGlobal": pyOpenRPA_Debugging_HelperDefAutofill, "ResponseContentType": "application/json"},
]
inGlobalConfiguration["ServerDict"]["URLList"]=inGlobalConfiguration["ServerDict"]["URLList"]+lURLList
return inGlobalConfiguration

@ -1,4 +1,5 @@
import os, logging, datetime, sys
import schedule # https://schedule.readthedocs.io/en/stable/examples.html
# Technical def - return GSettings structure with examples
def __Create__():
@ -39,6 +40,9 @@ def __Create__():
# # # # # # # # # # # # # # # # # #
},
"ServerDict": {
"ControlPanelDict": {
# "CPKey": <Managers.ControlPanel instance>
},
"AgentLimitLogSizeBytesInt": 300, # Don't show body if json body of transmition is more than
"ServerThread": None, # Server thread is there
"AgentActivityLifetimeSecFloat": 1200.0, # Time in seconds to life for activity for the agent
@ -105,18 +109,20 @@ def __Create__():
# "ResponseFilePath": "", #Absolute or relative path
# "ResponseFolderPath": "", #Absolute or relative path
# "ResponseContentType": "", #HTTP Content-type
# "ResponseDefRequestGlobal": None #Function with str result
# "ResponseDefRequestGlobal": None ,#Function with str result
# "UACBool": True # True - check user access before do this URL item. None - get Server flag if ask user
# }
#{
# "Method": "GET",
# "URL": "/test/", # URL of the request
# "MatchType": "BeginWith", # "BeginWith|Contains|Equal|EqualCase",
# # "ResponseFilePath": "", #Absolute or relative path
# "ResponseFolderPath": "C:\Abs\Archive\scopeSrcUL\OpenRPA\Orchestrator\Settings",
# # Absolute or relative path
# # "ResponseContentType": "", #HTTP Content-type
# # "ResponseDefRequestGlobal": None #Function with str result
# # "UACBool": True # True - check user access before do this URL item
#}
{
"Method": "GET",
"URL": "/test/", # URL of the request
"MatchType": "BeginWith", # "BeginWith|Contains|Equal|EqualCase",
# "ResponseFilePath": "", #Absolute or relative path
"ResponseFolderPath": "C:\Abs\Archive\scopeSrcUL\OpenRPA\Orchestrator\Settings",
# Absolute or relative path
# "ResponseContentType": "", #HTTP Content-type
# "ResponseDefRequestGlobal": None #Function with str result
}
],
},
@ -126,6 +132,7 @@ def __Create__():
"ActivityList": []
},
"SchedulerDict": {
"Schedule": schedule, # https://schedule.readthedocs.io/en/stable/examples.html
"CheckIntervalSecFloat": 5.0, # Check interval in seconds
"ActivityTimeList": [
# {
@ -145,6 +152,8 @@ def __Create__():
# },
],
},
"ManagersProcessDict":{}, # The key of the Process is (mAgentHostNameStr.upper(), mAgentUserNameStr.upper(), mProcessNameWOExeStr.upper())
"ManagersGitDict":{}, # The key of the Git instance is (mAgentHostNameStr.upper(), mAgentUserNameStr.upper(), mAbsPathUpperStr.upper())
"ProcessorDict": { # Has been changed. New general processor (one threaded) v.1.2.0
"ActivityList": [ # List of the activities
# {
@ -156,24 +165,13 @@ def __Create__():
# "GUIDStr": ..., # GUID of the activity
# },
],
"ActivityItemNowDict": None, # Activity Item which is executing now
"AliasDefDict": {}, # Storage for def with Str alias. To use it see pyOpenRPA.Orchestrator.ControlPanel
"CheckIntervalSecFloat": 1.0, # Interval for check gSettings in ProcessorDict > ActivityList
"ExecuteBool": True, # Flag to execute thread processor
"ThreadIdInt": None, # Technical field - will be setup when processor init
"WarningExecutionMoreThanSecFloat": 60.0 # Push warning if execution more than n seconds
},
"ControlPanelDict": { # Old structure > CPDict
"RefreshSeconds": 5, # deprecated parameter
"RobotList": [
#{
# "RenderFunction": RenderRobotR01,
# "KeyStr": "TestControlPanelKey"
#}
]
},
"CPDict": {
# "CPKey": {"HTMLRenderDef":None, "JSONGeneratorDef":None, "JSInitGeneratorDef":None}
},
# # # # # # # # # # # # # #
"RobotRDPActive": {
"RecoveryDict": {
@ -294,7 +292,8 @@ def __UACClientAdminCreate__():
"RestartOrchestratorBool": True, # Restart orchestrator activity
"RestartOrchestratorGITPullBool": True, # Turn off (RDP remember) orc + git pull + Turn on (rdp remember)
"RestartPCBool": True, # Send CMD to restart pc
"NothingBool":True # USe option if you dont want to give some access to the RDP controls
"NothingBool":True, # USe option if you dont want to give some access to the RDP controls
"Debugging":True # Debugging tool
},
"ActivityDict": { # Empty dict - all access
"ActivityListExecuteBool": True, # Execute activity at the current thread
@ -324,7 +323,7 @@ def LoggerDumpLogHandlerAdd(inLogger, inGSettingsClientDict):
# inModeStr:
# "BASIC" - create standart configuration
from pyOpenRPA.Orchestrator.Utils import LoggerHandlerDumpLogList
def Create(inModeStr="BASIC"):
def Create(inModeStr="BASIC", inLoggerLevel = None):
if inModeStr=="BASIC":
lResult = __Create__() # Create settings
# Создать файл логирования
@ -334,21 +333,23 @@ def Create(inModeStr="BASIC"):
##########################
# Подготовка логгера Robot
#########################
mRobotLogger = lResult["Logger"]
mRobotLogger.setLevel(logging.INFO)
if inLoggerLevel is None: inLoggerLevel=logging.INFO
lL = lResult["Logger"]
if len(lL.handlers) == 0:
lL.setLevel(logging.INFO)
# create the logging file handler
mRobotLoggerFH = logging.FileHandler(
"Reports\\" + datetime.datetime.now().strftime("%Y_%m_%d") + ".log")
mRobotLoggerFormatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
mRobotLoggerFH.setFormatter(mRobotLoggerFormatter)
# add handler to logger object
mRobotLogger.addHandler(mRobotLoggerFH)
lL.addHandler(mRobotLoggerFH)
####################Add console output
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(mRobotLoggerFormatter)
mRobotLogger.addHandler(handler)
lL.addHandler(handler)
############################################
LoggerDumpLogHandlerAdd(inLogger=mRobotLogger, inGSettingsClientDict=lResult["Client"])
LoggerDumpLogHandlerAdd(inLogger=lL, inGSettingsClientDict=lResult["Client"])
#mHandlerDumpLogList = LoggerHandlerDumpLogList.LoggerHandlerDumpLogList(inDict=lResult["Client"],
# inKeyStr="DumpLogList",
# inHashKeyStr="DumpLogListHashStr",
@ -356,4 +357,6 @@ def Create(inModeStr="BASIC"):
# "DumpLogListCountInt"])
#mHandlerDumpLogList.setFormatter(mRobotLoggerFormatter)
#mRobotLogger.addHandler(mHandlerDumpLogList)
else:
if lL: lL.warning("Pay attention! Your code has been call SettingsTemplate.Create - since pyOpenRPA v1.2.7 GSettings is creating automatically")
return lResult # return the result dict

@ -883,14 +883,110 @@ $(document).ready(function() {
if (lUACAsk(["pyOpenRPADict","AdminDict","RestartOrchestratorBool"])) { $(".UACClient-pyOpenRPADict-AdminDict-RestartOrchestratorBool").show(); }
if (lUACAsk(["pyOpenRPADict","AdminDict","RestartOrchestratorGITPullBool"])) { $(".UACClient-pyOpenRPADict-AdminDict-RestartOrchestratorGITPullBool").show(); }
if (lUACAsk(["pyOpenRPADict","AdminDict","RestartPCBool"])) { $(".UACClient-pyOpenRPADict-AdminDict-RestartPCBool").show(); }
if (lUACAsk(["pyOpenRPADict","AdminDict","Debugging"])) { $(".UACClient-pyOpenRPADict-AdminDict-Debugging").show(); }
}
/// v1.2.0 pyOpenRPA Init defs
mGlobal.pyOpenRPA.ServerJSInitDef(); // Recieve JS from server (if exist) and then call anothe url ServerData
mGlobal.pyOpenRPA.ServerDataRefreshDef(); // Init the refresh data def from server side
mGlobal.pyOpenRPA.ServerLogListRefreshDef(); // Init the refresh data def from the log window
mGlobal.pyOpenRPA.ServerLogListDoRenderTrue(); // Init button to freeze/unfreeze textare with logs
mGlobal.pyOpenRPA.ServerJSInitDef(); // Recieve JS from server (if exist) and then call anothe url ServerData
//$('.ui.dropdown').dropdown();
////////////////////////////////////////////
// 1.2.7 Debugging
/// Execute ActivityItem
// Debugging onchange def autofill init
var lDropdownOnChange = function(inEvent){
//lValueStr = inEvent.target.value
lValueStr = inEvent
$.ajax({
type: "GET",
url: '/pyOpenRPA/Debugging/HelperDefAutofill/'+lValueStr,
data: null,
success:
function(lData,l2,l3)
{
var lResponseJSON=JSON.parse(lData)
console.log("HelperDefAutofill:")
console.log(lResponseJSON)
//ArgDict merge
var lArgDictTargetDict = lResponseJSON["ArgDict"]
var lArgDictStr = $(".mGlobal-pyOpenRPA-Debugging-ArgDict")[0].value
if (lArgDictStr !="" && lArgDictStr !=null) {
lArgDictLastDict = JSON.parse(lArgDictStr)
lArgDictTargetDict = mGlobal.pyOpenRPA.DebuggingAutofillMerge(lArgDictTargetDict, lArgDictLastDict)
}
$(".mGlobal-pyOpenRPA-Debugging-ArgList")[0].value = JSON.stringify(lResponseJSON["ArgList"])
$(".mGlobal-pyOpenRPA-Debugging-ArgDict")[0].value = JSON.stringify(lArgDictTargetDict)
$(".mGlobal-pyOpenRPA-Debugging-ArgGSettingsStr")[0].value = JSON.stringify(lResponseJSON["ArgGSettingsStr"])
$(".mGlobal-pyOpenRPA-Debugging-ArgLoggerStr")[0].value = JSON.stringify(lResponseJSON["ArgLoggerStr"])
},
dataType: "text"
});
}
//$('.ui.dropdown.mGlobal-pyOpenRPA-Debugging-Def-Dropdown')[0].onchange=lDropdownOnChange
$('.ui.dropdown').dropdown();
mGlobal.pyOpenRPA.DebuggingExecute=function() {
///EXAMPLE
// {
// "Def":"OSCMD", // def link or def alias (look gSettings["Processor"]["AliasDefDict"])
// "ArgList":[], // Args list
// "ArgDict":{"inCMDStr":lCMDCode,"inRunAsyncBool":false}, // Args dictionary
// "ArgGSettings": null, // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
// "ArgLogger": "inLogger" // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
// }
///Подготовить конфигурацию
lArgListStr = $(".mGlobal-pyOpenRPA-Debugging-ArgList")[0].value
lArgDictStr = $(".mGlobal-pyOpenRPA-Debugging-ArgDict")[0].value
lArgGSettingsStr = $(".mGlobal-pyOpenRPA-Debugging-ArgGSettingsStr")[0].value
lArgLoggerStr = $(".mGlobal-pyOpenRPA-Debugging-ArgLoggerStr")[0].value
lActivityItem = {
"Def":$(".mGlobal-pyOpenRPA-Debugging-Def")[0].value, // def link or def alias (look gSettings["Processor"]["AliasDefDict"])
"ArgList":(lArgListStr == "" ? [] : JSON.parse(lArgListStr)), // Args list
"ArgDict":(lArgDictStr == "" ? {} : JSON.parse(lArgDictStr)), // Args dictionary
"ArgGSettingsStr": (lArgGSettingsStr == "" ? null : lArgGSettingsStr), // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
"ArgLoggerStr": (lArgLoggerStr == "" ? null : lArgLoggerStr) // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
}
lData = [lActivityItem]
$.ajax({
type: "POST",
url: '/pyOpenRPA/ActivityListExecute',
data: JSON.stringify(lData),
success:
function(lData,l2,l3)
{
var lResponseJSON=JSON.parse(lData)
console.log(lResponseJSON)
$(".mGlobal-pyOpenRPA-Debugging-Output")[0].value = JSON.stringify(lResponseJSON[0])
},
dataType: "text"
});
}
mGlobal.pyOpenRPA.DebuggingAutofillMerge=function(inTargetDict, inLastDict) {
// Merge 2 dict (get values from Last dict if key exists in new dict
for (const [lKeyStr, lValue] of Object.entries(inTargetDict)) {
//Check if key exists in LastDict
if (lKeyStr in inLastDict) {
inTargetDict[lKeyStr] = inLastDict[lKeyStr]
}
}
return inTargetDict
}
// 1.2.7 Debugging toolbox init
$('.ui.dropdown.mGlobal-pyOpenRPA-Debugging-Def-Dropdown')
.dropdown({
apiSettings: {
// this url parses query server side and returns filtered results
url: '/pyOpenRPA/Debugging/HelperDefList/{query}'
},
onChange: lDropdownOnChange
})
;
});

@ -45,6 +45,16 @@
margin: 5em 0em 0em;
padding: 5em 0em;
}
.ui.search.dropdown>input.search {
width:100%;
font-family:monospace;
font-weight: bold;
}
.ui.search.dropdown>.text {
width:100%;
font-family:monospace;
font-weight: bold;
}
</style>
</head>
<body>
@ -298,6 +308,57 @@
</div>
</div>
</div>
<div class="row UACClient-pyOpenRPADict-AdminDict-Debugging" style= "display:none;">
<div class="twelve wide column">
<h4 class="ui horizontal divider header" >
<i class="bug icon"></i>
Debugging - Send
</h4>
<div class="ui labeled input">
<div class="ui label">Def</div>
</div>
<div class="ui fluid search selection dropdown mGlobal-pyOpenRPA-Debugging-Def-Dropdown" style="margin-bottom:10px;">
<input class="mGlobal-pyOpenRPA-Debugging-Def" type="hidden" name="country" style="width:100%; font-family:monospace; font-weight: bold;">
<i class="dropdown icon"></i>
<div class="default text">Def</div>
<div class="menu">
<div class="item" data-value="eh">pyOpenRPA... sys.. os.. </div>
</div>
</div>
<div class="ui fluid labeled input" style="margin-bottom:10px;">
<div class="ui label">
ArgList
</div>
<input type="text" placeholder="[1,2,3]" class="mGlobal-pyOpenRPA-Debugging-ArgList" style="width:100%; font-family:monospace; font-weight: bold;">
</div>
<div class="ui fluid labeled input" style="margin-bottom:10px;">
<div class="ui label">
ArgDict
</div>
<input type="text" placeholder="{&quot;Key1&quot;:&quot;Value1&quot;}" class="mGlobal-pyOpenRPA-Debugging-ArgDict" style="width:100%; font-family:monospace; font-weight: bold;">
</div>
<div class="ui fluid labeled input" style="margin-bottom:10px;">
<div class="ui label">
ArgGSettingsStr
</div>
<input type="text" placeholder="inGSettings" class="mGlobal-pyOpenRPA-Debugging-ArgGSettingsStr" style="width:100%; font-family:monospace; font-weight: bold;">
</div>
<div class="ui fluid labeled input" style="margin-bottom:10px;">
<div class="ui label">
ArgLoggerStr
</div>
<input type="text" placeholder="inLogger" class="mGlobal-pyOpenRPA-Debugging-ArgLoggerStr" style="width:100%; font-family:monospace; font-weight: bold;">
</div>
<div class="ui fluid button" onclick="mGlobal.pyOpenRPA.DebuggingExecute();">Execute</div>
</div>
<div class="four wide column">
<h4 class="ui horizontal divider header" >
<i class="bug icon"></i>
Debugging - Output
</h4>
<p><textarea class="mGlobal-pyOpenRPA-Debugging-Output" readonly="readonly" style="width:100%; font-family:monospace; font-weight: bold;" rows="16" cols="60"></textarea></p>
</div>
</div>
<h4 class="ui horizontal divider header">
<i class="clipboard list icon"></i>

@ -5,5 +5,6 @@ The pyOpenRPA package (from UnicodeLabs)
"""
from .Web import Basic
from .__Orchestrator__ import *
from . import Managers
__all__ = []
__author__ = 'Ivan Maslov <ivan.maslov@unicodelabs.ru>'

@ -1,8 +1,10 @@
"""
# How to use
# from pyOpenRPA.Tools import Terminator
# Terminator.Init(inLogger=None)
# Terminator.IsSignalClose() # True - WM_CLOSE SIGNAL has come
# Terminator.SessionLogoff() # Logoff the session
# from pyOpenRPA.Tools import StopSafe
# StopSafe.Init(inLogger=None)
# StopSafe.IsSafeStop() # True - WM_CLOSE SIGNAL has come. taskkill /im someprocess.exe
"""
import win32con
import win32gui
@ -12,33 +14,35 @@ gLogger = None
gWindowTitleStr = "PythonTerminator" # Title of the phantom window
gWindowDescriptionStr = "pyOpenRPA library for safe turn off the program (by send the WM_CLOSE signal from task kill)" # Description of the phantom window
# Init the terminator
def Init(inLogger=None):
"""
Init the StopSafe module. After that you can use def IsStopSafe() to check if close signal has come.
:param inLogger: Logger to log messages about StopSafe
:return:
"""
global gLogger
global gIsSignalCloseBool
gIsSignalCloseBool = False # Init default
gLogger = inLogger
#import sys
#import time
#import atexit
import threading
#atexit.register(print, 'PYTHON SPAM APP: SHUTDOWN')
shutdown_thread = threading.Thread(target=shutdown_monitor)
if gLogger: gLogger.info(f"StopSafe: Init termination catch thread")
shutdown_thread = threading.Thread(target=_shutdown_monitor)
shutdown_thread.start()
#shutdown_thread.join()
#shutdown_monitor()
# Terminator.IsSignalClose() # True - WM_CLOSE SIGNAL has come
def IsSignalClose():
def IsStopSafe():
"""
Check if stop signal has come.
:return:
"""
global gIsSignalCloseBool # Init the global variable
return gIsSignalCloseBool # Return the result
# Terminator.SessionLogoff() # Logoff the session
def SessionLogoff():
os.system("shutdown /l")
# Technical function
def shutdown_monitor():
def _shutdown_monitor():
global gIsSignalCloseBool # Init the global variable
global gLogger
def wndproc(hwnd, msg, wparam, lparam):
@ -58,5 +62,5 @@ def shutdown_monitor():
win32gui.PumpMessages()
gIsSignalCloseBool = True # WM_CLOSE message has come
if gLogger:
gLogger.info(f"Terminator: Program has recieve the close signal - safe exit")
gLogger.info(f"StopSafe: Program has catch VM_CLOSE signal - do safe exit")

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

@ -5,7 +5,7 @@
####################################
pyOpenRPA is created by Ivan Maslov (Russia).
Use it absolutely for free!
Hosted by PYOPENRPA LLC (Russia)
My purpose is to create #IT4Business models in the companies.
I can help you to create the new #IT4Business in your company.

@ -14,25 +14,19 @@ Welcome to pyOpenRPA's wiki
! ATTENTION ! pyOpenRPA works only on MS Windows 7+/Server 2008+. Guys from Unix/Mac - sorry. We will come to you soon :)
**************************************************
Donate
**************************************************
pyOpenRPA is absolutely non-commercial project.
Please donate some $ if pyOpenRPA project is actual for you. Link to online donations.
https://yoomoney.ru/to/4100115560661986
**************************************************
About
**************************************************
Dear RPA-tors. Let me congratulate you with great change in the RPA world. Since 2019 the first enterprise level open source RPA platform is here!
pyOpenRPA is absolutely open source commercial project. Hosted by LLC PYOPENRPA (RUSSIA)
The pyOpenRPA - free, fast and reliable
Powerful OpenSource RPA tool for business (based on python 3). Best performance and absolutely free!
The pyOpenRPA is based on Python and using well known OpenSource solutions such as Selenium, OpenCV, Win32, UI automation and others. Thanks to it we were able to create consolidated platform with all possible features.
The pyOpenRPA is distributed under the MIT license which allows you to use it in any way you want and any time you need without any restrictions.
The pyOpenRPA is distributed under the PYOPENRPA license.
At the time of this writing the pyOpenRPA is successfully using in several big Russian companies. Companies in which it was decided to develop own RPA division with no dependencies on expensive licenses.
**************************************************

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

@ -32,7 +32,9 @@ setup(name='pyOpenRPA',
long_description_content_type='text/markdown',
classifiers=[
'Development Status :: 5 - Production/Stable',
'License :: OSI Approved :: MIT License',
'License :: Free For Educational Use',
'License :: Free For Home Use',
'License :: Free for non-commercial use',
'Intended Audience :: Developers',
'Environment :: Win32 (MS Windows)',
'Environment :: X11 Applications',
@ -44,11 +46,11 @@ setup(name='pyOpenRPA',
'Topic :: Software Development :: Quality Assurance',
'Topic :: Home Automation'
],
keywords='OpenRPA RPA Robot Automation Robotization OpenSource',
url='https://gitlab.com/UnicodeLabs/OpenRPA',
keywords='pyOpenRPA OpenRPA RPA Robot Automation Robotization OpenSource IT4Business',
url='https://pyopenrpa.ru/',
author='Ivan Maslov',
author_email='Ivan.Maslov@unicodelabs.ru',
license='MIT',
author_email='Ivan.Maslov@pyopenrpa.ru',
license='PYOPENRPA',
packages=find_packages(),
install_requires=[
'pywinauto>=0.6.8;platform_system=="win32" and python_version>="3.0"',

@ -194,7 +194,7 @@
<div class="section" id="copyrights-contacts">
<span id="id1"></span><h1>3. Copyrights &amp; Contacts<a class="headerlink" href="#copyrights-contacts" title="Permalink to this headline"></a></h1>
<p>pyOpenRPA is created by Ivan Maslov (Russia).
Use it absolutely for free!</p>
Hosted by PYOPENRPA LLC (Russia)</p>
<p>My purpose is to create #IT4Business models in the companies.
I can help you to create the new #IT4Business in your company.
#IT4Business homepage - <a class="reference external" href="https://www.facebook.com/RU.IT4Business">https://www.facebook.com/RU.IT4Business</a>

@ -214,20 +214,23 @@
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Agent.__Agent__.OSFileBinaryDataBase64StrReceive" title="pyOpenRPA.Agent.__Agent__.OSFileBinaryDataBase64StrReceive"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OSFileBinaryDataBase64StrReceive</span></code></a>(inFilePathStr)</p></td>
<td><p>Read binary file and encode in base64 to transmit (safe for JSON transmition)</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Agent.__Agent__.OSFileTextDataStrCreate" title="pyOpenRPA.Agent.__Agent__.OSFileTextDataStrCreate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OSFileTextDataStrCreate</span></code></a>(inFilePathStr, …)</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Agent.__Agent__.OSFileMTimeGet" title="pyOpenRPA.Agent.__Agent__.OSFileMTimeGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OSFileMTimeGet</span></code></a>(inFilePathStr)</p></td>
<td><p>Read file modification time timestamp format (float)</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Agent.__Agent__.OSFileTextDataStrCreate" title="pyOpenRPA.Agent.__Agent__.OSFileTextDataStrCreate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OSFileTextDataStrCreate</span></code></a>(inFilePathStr, …)</p></td>
<td><p>Create text file in the agent GUI session</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Agent.__Agent__.OSFileTextDataStrReceive" title="pyOpenRPA.Agent.__Agent__.OSFileTextDataStrReceive"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OSFileTextDataStrReceive</span></code></a>(inFilePathStr[, …])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Agent.__Agent__.OSFileTextDataStrReceive" title="pyOpenRPA.Agent.__Agent__.OSFileTextDataStrReceive"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OSFileTextDataStrReceive</span></code></a>(inFilePathStr[, …])</p></td>
<td><p>Read text file in the agent GUI session</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Agent.__Agent__.ProcessWOExeUpperUserListGet" title="pyOpenRPA.Agent.__Agent__.ProcessWOExeUpperUserListGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessWOExeUpperUserListGet</span></code></a>()</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Agent.__Agent__.ProcessWOExeUpperUserListGet" title="pyOpenRPA.Agent.__Agent__.ProcessWOExeUpperUserListGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessWOExeUpperUserListGet</span></code></a>()</p></td>
<td><p>Return the process list only for the current user (where Agent is running) without .EXE in upper case.</p></td>
</tr>
</tbody>
</table>
<dl class="py function">
<dt id="pyOpenRPA.Agent.__Agent__.OSCMD">
<code class="sig-prename descclassname">pyOpenRPA.Agent.__Agent__.</code><code class="sig-name descname">OSCMD</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inCMDStr</span></em>, <em class="sig-param"><span class="n">inRunAsyncBool</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inSendOutputToOrchestratorLogsBool</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">inCMDEncodingStr</span><span class="o">=</span><span class="default_value">'cp1251'</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Agent/__Agent__.html#OSCMD"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Agent.__Agent__.OSCMD" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Agent.__Agent__.</code><code class="sig-name descname">OSCMD</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inCMDStr</span></em>, <em class="sig-param"><span class="n">inRunAsyncBool</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inSendOutputToOrchestratorLogsBool</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">inCMDEncodingStr</span><span class="o">=</span><span class="default_value">'cp1251'</span></em>, <em class="sig-param"><span class="n">inCaptureBool</span><span class="o">=</span><span class="default_value">True</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Agent/__Agent__.html#OSCMD"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Agent.__Agent__.OSCMD" title="Permalink to this definition"></a></dt>
<dd><p>Execute CMD on the Agent daemonic process</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
@ -236,12 +239,14 @@
<li><p><strong>inRunAsyncBool</strong> True - Agent processor dont wait execution; False - Agent processor wait cmd execution</p></li>
<li><p><strong>inGSettings</strong> Agent global settings dict</p></li>
<li><p><strong>inSendOutputToOrchestratorLogsBool</strong> True - catch cmd execution output and send it to the Orchestrator logs; Flase - else case; Default True</p></li>
<li><p><strong>inCMDEncodingStr</strong> Set the encoding of the DOS window on the Agent server session. Windows is beautiful :) . Default is “cp1251” early was “cp866” - need test</p></li>
<li><p><strong>inCaptureBool</strong> !ATTENTION! If you need to start absolutely encapsulated app - set this flag as False. If you set True - the app output will come to Agent</p></li>
</ul>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p></p>
</dd>
</dl>
<p>!ATTENTION! If you need to start absolutely encapsulated app - set this flag as False. If you set True - the app output will come to Agent
:param inCMDEncodingStr: Set the encoding of the DOS window on the Agent server session. Windows is beautiful :) . Default is “cp1251” early was “cp866” - need test
:return:</p>
</dd></dl>
<dl class="py function">
@ -273,6 +278,20 @@
</dl>
</dd></dl>
<dl class="py function">
<dt id="pyOpenRPA.Agent.__Agent__.OSFileMTimeGet">
<code class="sig-prename descclassname">pyOpenRPA.Agent.__Agent__.</code><code class="sig-name descname">OSFileMTimeGet</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inFilePathStr</span><span class="p">:</span> <span class="n">str</span></em><span class="sig-paren">)</span> &#x2192; float<a class="reference internal" href="../_modules/pyOpenRPA/Agent/__Agent__.html#OSFileMTimeGet"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Agent.__Agent__.OSFileMTimeGet" title="Permalink to this definition"></a></dt>
<dd><p>Read file modification time timestamp format (float)</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>inFilePathStr</strong> File path to read</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p>timestamp (float) Return None if file is not exist</p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt id="pyOpenRPA.Agent.__Agent__.OSFileTextDataStrCreate">
<code class="sig-prename descclassname">pyOpenRPA.Agent.__Agent__.</code><code class="sig-name descname">OSFileTextDataStrCreate</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inFilePathStr</span></em>, <em class="sig-param"><span class="n">inFileDataStr</span></em>, <em class="sig-param"><span class="n">inEncodingStr</span><span class="o">=</span><span class="default_value">'utf-8'</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Agent/__Agent__.html#OSFileTextDataStrCreate"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Agent.__Agent__.OSFileTextDataStrCreate" title="Permalink to this definition"></a></dt>

@ -313,200 +313,212 @@
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileBinaryDataBytesCreate" title="pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileBinaryDataBytesCreate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">AgentOSFileBinaryDataBytesCreate</span></code></a>(…[, …])</p></td>
<td><p>Create binary file by the base64 string by the pyOpenRPA.Agent daemon process (safe for JSON transmition)</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileSend" title="pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileSend"><code class="xref py py-obj docutils literal notranslate"><span class="pre">AgentOSFileSend</span></code></a>(inHostNameStr, inUserStr, …)</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileBinaryDataReceive" title="pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileBinaryDataReceive"><code class="xref py py-obj docutils literal notranslate"><span class="pre">AgentOSFileBinaryDataReceive</span></code></a>(inHostNameStr, …)</p></td>
<td><p>Read binary file from agent (synchronious)</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileSend" title="pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileSend"><code class="xref py py-obj docutils literal notranslate"><span class="pre">AgentOSFileSend</span></code></a>(inHostNameStr, inUserStr, …)</p></td>
<td><p>Send the file from the Orchestrator to Agent (synchroniously) pyOpenRPA.Agent daemon process (safe for JSON transmition).</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileTextDataStrCreate" title="pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileTextDataStrCreate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">AgentOSFileTextDataStrCreate</span></code></a>(inHostNameStr, …)</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileTextDataStrCreate" title="pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileTextDataStrCreate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">AgentOSFileTextDataStrCreate</span></code></a>(inHostNameStr, …)</p></td>
<td><p>Create text file by the string by the pyOpenRPA.Agent daemon process</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileTextDataStrReceive" title="pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileTextDataStrReceive"><code class="xref py py-obj docutils literal notranslate"><span class="pre">AgentOSFileTextDataStrReceive</span></code></a>(inHostNameStr, …)</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileTextDataStrReceive" title="pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileTextDataStrReceive"><code class="xref py py-obj docutils literal notranslate"><span class="pre">AgentOSFileTextDataStrReceive</span></code></a>(inHostNameStr, …)</p></td>
<td><p>Read text file in the agent GUI session</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSLogoff" title="pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSLogoff"><code class="xref py py-obj docutils literal notranslate"><span class="pre">AgentOSLogoff</span></code></a>(inHostNameStr, inUserStr)</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSLogoff" title="pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSLogoff"><code class="xref py py-obj docutils literal notranslate"><span class="pre">AgentOSLogoff</span></code></a>(inHostNameStr, inUserStr)</p></td>
<td><p>Logoff the agent user session</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentProcessWOExeUpperUserListGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.AgentProcessWOExeUpperUserListGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">AgentProcessWOExeUpperUserListGet</span></code></a>(…[, …])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentProcessWOExeUpperUserListGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.AgentProcessWOExeUpperUserListGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">AgentProcessWOExeUpperUserListGet</span></code></a>(…[, …])</p></td>
<td><p>Return the process list only for the current user (where Agent is running) without .EXE in upper case.</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsAutocleaner" title="pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsAutocleaner"><code class="xref py py-obj docutils literal notranslate"><span class="pre">GSettingsAutocleaner</span></code></a>([inGSettings])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsAutocleaner" title="pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsAutocleaner"><code class="xref py py-obj docutils literal notranslate"><span class="pre">GSettingsAutocleaner</span></code></a>([inGSettings])</p></td>
<td><p>HIDDEN Interval gSettings auto cleaner def to clear some garbage.</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">GSettingsGet</span></code></a>([inGSettings])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">GSettingsGet</span></code></a>([inGSettings])</p></td>
<td><p>Get the GSettings from the singleton module.</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueAppend" title="pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueAppend"><code class="xref py py-obj docutils literal notranslate"><span class="pre">GSettingsKeyListValueAppend</span></code></a>(inValue[, …])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueAppend" title="pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueAppend"><code class="xref py py-obj docutils literal notranslate"><span class="pre">GSettingsKeyListValueAppend</span></code></a>(inValue[, …])</p></td>
<td><p>Append value in GSettings by the key list</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">GSettingsKeyListValueGet</span></code></a>([inKeyList, …])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">GSettingsKeyListValueGet</span></code></a>([inKeyList, …])</p></td>
<td><p>Get the value from the GSettings by the key list</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueOperatorPlus" title="pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueOperatorPlus"><code class="xref py py-obj docutils literal notranslate"><span class="pre">GSettingsKeyListValueOperatorPlus</span></code></a>(inValue[, …])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueOperatorPlus" title="pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueOperatorPlus"><code class="xref py py-obj docutils literal notranslate"><span class="pre">GSettingsKeyListValueOperatorPlus</span></code></a>(inValue[, …])</p></td>
<td><p>Execute plus operation between 2 lists (1:inValue and 2:gSettings by the inKeyList)</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueSet" title="pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueSet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">GSettingsKeyListValueSet</span></code></a>(inValue[, …])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueSet" title="pyOpenRPA.Orchestrator.__Orchestrator__.GSettingsKeyListValueSet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">GSettingsKeyListValueSet</span></code></a>(inValue[, …])</p></td>
<td><p>Set value in GSettings by the key list</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OSCMD" title="pyOpenRPA.Orchestrator.__Orchestrator__.OSCMD"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OSCMD</span></code></a>(inCMDStr[, inRunAsyncBool, inLogger])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OSCMD" title="pyOpenRPA.Orchestrator.__Orchestrator__.OSCMD"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OSCMD</span></code></a>(inCMDStr[, inRunAsyncBool, inLogger])</p></td>
<td><p>OS send command in shell locally</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OSCredentialsVerify" title="pyOpenRPA.Orchestrator.__Orchestrator__.OSCredentialsVerify"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OSCredentialsVerify</span></code></a>(inUserStr, inPasswordStr)</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OSCredentialsVerify" title="pyOpenRPA.Orchestrator.__Orchestrator__.OSCredentialsVerify"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OSCredentialsVerify</span></code></a>(inUserStr, inPasswordStr)</p></td>
<td><p>Verify user credentials in windows.</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OSLogoff" title="pyOpenRPA.Orchestrator.__Orchestrator__.OSLogoff"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OSLogoff</span></code></a>()</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OSLogoff" title="pyOpenRPA.Orchestrator.__Orchestrator__.OSLogoff"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OSLogoff</span></code></a>()</p></td>
<td><p>Logoff the current orchestrator session :return:</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OSRemotePCRestart" title="pyOpenRPA.Orchestrator.__Orchestrator__.OSRemotePCRestart"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OSRemotePCRestart</span></code></a>(inHostStr[, inForceBool, …])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OSRemotePCRestart" title="pyOpenRPA.Orchestrator.__Orchestrator__.OSRemotePCRestart"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OSRemotePCRestart</span></code></a>(inHostStr[, inForceBool, …])</p></td>
<td><p>Send signal via power shell to restart remote PC ATTENTION: Orchestrator user need to have restart right on the Remote machine to restart PC.</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.Orchestrator" title="pyOpenRPA.Orchestrator.__Orchestrator__.Orchestrator"><code class="xref py py-obj docutils literal notranslate"><span class="pre">Orchestrator</span></code></a>([inGSettings, …])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.Orchestrator" title="pyOpenRPA.Orchestrator.__Orchestrator__.Orchestrator"><code class="xref py py-obj docutils literal notranslate"><span class="pre">Orchestrator</span></code></a>([inGSettings, …])</p></td>
<td><p>Main def to start orchestrator</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorInitWait" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorInitWait"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorInitWait</span></code></a>()</p></td>
<td><p>Wait thread while orc will process initial action.</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorIsAdmin" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorIsAdmin"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorIsAdmin</span></code></a>()</p></td>
<td><p>Check if Orchestrator process is running as administrator</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorLoggerGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorLoggerGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorLoggerGet</span></code></a>()</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorIsInited" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorIsInited"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorIsInited</span></code></a>()</p></td>
<td><p>Check if Orchestrator initial actions were processed</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorLoggerGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorLoggerGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorLoggerGet</span></code></a>()</p></td>
<td><p>Get the logger from the Orchestrator</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorPySearchInit" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorPySearchInit"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorPySearchInit</span></code></a>(inGlobPatternStr[, …])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorPySearchInit" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorPySearchInit"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorPySearchInit</span></code></a>(inGlobPatternStr[, …])</p></td>
<td><p>Search the py files by the glob and do the safe init (in try except).</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorRerunAsAdmin" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorRerunAsAdmin"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorRerunAsAdmin</span></code></a>()</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorRerunAsAdmin" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorRerunAsAdmin"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorRerunAsAdmin</span></code></a>()</p></td>
<td><p>Check if not admin - then rerun orchestrator as administrator</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorRestart" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorRestart"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorRestart</span></code></a>([inGSettings])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorRestart" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorRestart"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorRestart</span></code></a>([inGSettings])</p></td>
<td><p>Orchestrator restart</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorScheduleGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorScheduleGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorScheduleGet</span></code></a>()</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorScheduleGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorScheduleGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorScheduleGet</span></code></a>()</p></td>
<td><p>Get the schedule (schedule.readthedocs.io) from the Orchestrator</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionRestore" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionRestore"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorSessionRestore</span></code></a>([inGSettings])</p></td>
<td><p>Check _SessionLast_RDPList.json and _SessionLast_StorageDict.pickle in working directory. if exist - load into gsettings # _SessionLast_StorageDict.pickle (binary) _SessionLast_RDPList.json (encoding = “utf-8”) _SessionLast_StorageDict.pickle (binary).</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionRestore" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionRestore"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorSessionRestore</span></code></a>([inGSettings])</p></td>
<td><p>Check _SessioLast… files in working directory. if exist - load into gsettings (from version 1.2.7) _SessionLast_GSettings.pickle (binary).</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionSave" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionSave"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorSessionSave</span></code></a>([inGSettings])</p></td>
<td><p>Orchestrator session save in file</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionSave" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionSave"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorSessionSave</span></code></a>([inGSettings])</p></td>
<td><p>Orchestrator session save in file (from version 1.2.7) _SessionLast_GSettings.pickle (binary)</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorThreadStart" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorThreadStart"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorThreadStart</span></code></a>(inDef, *inArgList, …)</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorThreadStart" title="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorThreadStart"><code class="xref py py-obj docutils literal notranslate"><span class="pre">OrchestratorThreadStart</span></code></a>(inDef, *inArgList, …)</p></td>
<td><p>Execute def in new thread and pass some args with list and dict types</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessDefIntervalCall" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessDefIntervalCall"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessDefIntervalCall</span></code></a>(inDef, inIntervalSecFloat)</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessDefIntervalCall" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessDefIntervalCall"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessDefIntervalCall</span></code></a>(inDef, inIntervalSecFloat)</p></td>
<td><p>Use this procedure if you need to run periodically some def.</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessIsStarted" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessIsStarted"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessIsStarted</span></code></a>(inProcessNameWOExeStr)</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessIsStarted" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessIsStarted"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessIsStarted</span></code></a>(inProcessNameWOExeStr)</p></td>
<td><p>Check if there is any running process that contains the given name processName.</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessListGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessListGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessListGet</span></code></a>([inProcessNameWOExeList])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessListGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessListGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessListGet</span></code></a>([inProcessNameWOExeList])</p></td>
<td><p>Return process list on the orchestrator machine sorted by Memory Usage.</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessStart" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessStart"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessStart</span></code></a>(inPathStr, inArgList[, …])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessStart" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessStart"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessStart</span></code></a>(inPathStr, inArgList[, …])</p></td>
<td><p>Start process locally.</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessStop" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessStop"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessStop</span></code></a>(inProcessNameWOExeStr, …[, …])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessStop" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessStop"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessStop</span></code></a>(inProcessNameWOExeStr, …[, …])</p></td>
<td><p>Stop process on the orchestrator machine.</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorActivityItemAppend" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorActivityItemAppend"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessorActivityItemAppend</span></code></a>([inGSettings, …])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorActivityItemAppend" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorActivityItemAppend"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessorActivityItemAppend</span></code></a>([inGSettings, …])</p></td>
<td><p>Create and add activity item in processor queue.</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorActivityItemCreate" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorActivityItemCreate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessorActivityItemCreate</span></code></a>(inDef[, …])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorActivityItemCreate" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorActivityItemCreate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessorActivityItemCreate</span></code></a>(inDef[, …])</p></td>
<td><p>Create activity item.</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorAliasDefCreate" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorAliasDefCreate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessorAliasDefCreate</span></code></a>(inDef[, inAliasStr, …])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorAliasDefCreate" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorAliasDefCreate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessorAliasDefCreate</span></code></a>(inDef[, inAliasStr, …])</p></td>
<td><p>Create alias for def (can be used in ActivityItem in field Def) !WHEN DEF ALIAS IS REQUIRED! - Def alias is required when you try to call Python def from the Orchestrator WEB side (because you cant transmit Python def object out of the Python environment) Deprecated.</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorAliasDefUpdate" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorAliasDefUpdate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessorAliasDefUpdate</span></code></a>(inDef, inAliasStr[, …])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorAliasDefUpdate" title="pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorAliasDefUpdate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">ProcessorAliasDefUpdate</span></code></a>(inDef, inAliasStr[, …])</p></td>
<td><p>Update alias for def (can be used in ActivityItem in field Def).</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.PythonStart" title="pyOpenRPA.Orchestrator.__Orchestrator__.PythonStart"><code class="xref py py-obj docutils literal notranslate"><span class="pre">PythonStart</span></code></a>(inModulePathStr, inDefNameStr[, …])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.PythonStart" title="pyOpenRPA.Orchestrator.__Orchestrator__.PythonStart"><code class="xref py py-obj docutils literal notranslate"><span class="pre">PythonStart</span></code></a>(inModulePathStr, inDefNameStr[, …])</p></td>
<td><p>Import module and run def in the Orchestrator process.</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionCMDRun" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionCMDRun"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionCMDRun</span></code></a>(inRDPSessionKeyStr, inCMDStr)</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionCMDRun" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionCMDRun"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionCMDRun</span></code></a>(inRDPSessionKeyStr, inCMDStr)</p></td>
<td><p>Send CMD command to the RDP session “RUN” window</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionConnect" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionConnect"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionConnect</span></code></a>(inRDPSessionKeyStr[, …])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionConnect" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionConnect"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionConnect</span></code></a>(inRDPSessionKeyStr[, …])</p></td>
<td><p>Create new RDPSession in RobotRDPActive. Attention - activity will be ignored if RDP key is already exists</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionDisconnect" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionDisconnect"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionDisconnect</span></code></a>(inRDPSessionKeyStr[, …])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionDisconnect" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionDisconnect"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionDisconnect</span></code></a>(inRDPSessionKeyStr[, …])</p></td>
<td><p>Disconnect the RDP session and stop monitoring it.</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionDublicatesResolve" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionDublicatesResolve"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionDublicatesResolve</span></code></a>(inGSettings)</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionDublicatesResolve" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionDublicatesResolve"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionDublicatesResolve</span></code></a>(inGSettings)</p></td>
<td><p>DEVELOPING Search duplicates in GSettings RDPlist !def is developing!</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionFileStoredRecieve" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionFileStoredRecieve"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionFileStoredRecieve</span></code></a>(…[, inGSettings])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionFileStoredRecieve" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionFileStoredRecieve"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionFileStoredRecieve</span></code></a>(…[, inGSettings])</p></td>
<td><p>Recieve file from RDP session to the Orchestrator session using shared drive in RDP (see RDP Configuration Dict, Shared drive)</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionFileStoredSend" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionFileStoredSend"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionFileStoredSend</span></code></a>(inRDPSessionKeyStr, …)</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionFileStoredSend" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionFileStoredSend"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionFileStoredSend</span></code></a>(inRDPSessionKeyStr, …)</p></td>
<td><p>Send file from Orchestrator session to the RDP session using shared drive in RDP (see RDP Configuration Dict, Shared drive)</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionLogoff" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionLogoff"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionLogoff</span></code></a>(inRDPSessionKeyStr[, …])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionLogoff" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionLogoff"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionLogoff</span></code></a>(inRDPSessionKeyStr[, …])</p></td>
<td><p>Logoff the RDP session from the Orchestrator process (close all apps in session when logoff)</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionMonitorStop" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionMonitorStop"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionMonitorStop</span></code></a>(inRDPSessionKeyStr[, …])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionMonitorStop" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionMonitorStop"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionMonitorStop</span></code></a>(inRDPSessionKeyStr[, …])</p></td>
<td><p>Stop monitoring the RDP session by the Orchestrator process.</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionProcessStartIfNotRunning" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionProcessStartIfNotRunning"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionProcessStartIfNotRunning</span></code></a>(…[, …])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionProcessStartIfNotRunning" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionProcessStartIfNotRunning"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionProcessStartIfNotRunning</span></code></a>(…[, …])</p></td>
<td><p>Start process in RDP if it is not running (check by the arg inProcessNameWEXEStr)</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionProcessStop" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionProcessStop"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionProcessStop</span></code></a>(inRDPSessionKeyStr, …)</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionProcessStop" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionProcessStop"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionProcessStop</span></code></a>(inRDPSessionKeyStr, …)</p></td>
<td><p>Send CMD command to the RDP session “RUN” window.</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionReconnect" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionReconnect"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionReconnect</span></code></a>(inRDPSessionKeyStr[, …])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionReconnect" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionReconnect"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionReconnect</span></code></a>(inRDPSessionKeyStr[, …])</p></td>
<td><p>Reconnect the RDP session</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionResponsibilityCheck" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionResponsibilityCheck"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionResponsibilityCheck</span></code></a>(inRDPSessionKeyStr)</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionResponsibilityCheck" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionResponsibilityCheck"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPSessionResponsibilityCheck</span></code></a>(inRDPSessionKeyStr)</p></td>
<td><p>DEVELOPING, MAYBE NOT USEFUL Check RDP Session responsibility TODO NEED DEV + TEST</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPTemplateCreate" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPTemplateCreate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPTemplateCreate</span></code></a>(inLoginStr, inPasswordStr)</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPTemplateCreate" title="pyOpenRPA.Orchestrator.__Orchestrator__.RDPTemplateCreate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">RDPTemplateCreate</span></code></a>(inLoginStr, inPasswordStr)</p></td>
<td><p>Create RDP connect dict item/ Use it connect/reconnect (Orchestrator.RDPSessionConnect)</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.SchedulerActivityTimeAddWeekly" title="pyOpenRPA.Orchestrator.__Orchestrator__.SchedulerActivityTimeAddWeekly"><code class="xref py py-obj docutils literal notranslate"><span class="pre">SchedulerActivityTimeAddWeekly</span></code></a>([…])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.SchedulerActivityTimeAddWeekly" title="pyOpenRPA.Orchestrator.__Orchestrator__.SchedulerActivityTimeAddWeekly"><code class="xref py py-obj docutils literal notranslate"><span class="pre">SchedulerActivityTimeAddWeekly</span></code></a>([…])</p></td>
<td><p>Add activity item list in scheduler.</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.Start" title="pyOpenRPA.Orchestrator.__Orchestrator__.Start"><code class="xref py py-obj docutils literal notranslate"><span class="pre">Start</span></code></a>([inDumpRestoreBool, …])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.Start" title="pyOpenRPA.Orchestrator.__Orchestrator__.Start"><code class="xref py py-obj docutils literal notranslate"><span class="pre">Start</span></code></a>([inDumpRestoreBool, …])</p></td>
<td><p>Start the orchestrator threads execution</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.StorageRobotExists" title="pyOpenRPA.Orchestrator.__Orchestrator__.StorageRobotExists"><code class="xref py py-obj docutils literal notranslate"><span class="pre">StorageRobotExists</span></code></a>(inRobotNameStr)</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.StorageRobotExists" title="pyOpenRPA.Orchestrator.__Orchestrator__.StorageRobotExists"><code class="xref py py-obj docutils literal notranslate"><span class="pre">StorageRobotExists</span></code></a>(inRobotNameStr)</p></td>
<td><p>Check if robot storage exists</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.StorageRobotGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.StorageRobotGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">StorageRobotGet</span></code></a>(inRobotNameStr)</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.StorageRobotGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.StorageRobotGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">StorageRobotGet</span></code></a>(inRobotNameStr)</p></td>
<td><p>Get the robot storage by the robot name.</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.UACKeyListCheck" title="pyOpenRPA.Orchestrator.__Orchestrator__.UACKeyListCheck"><code class="xref py py-obj docutils literal notranslate"><span class="pre">UACKeyListCheck</span></code></a>(inRequest, inRoleKeyList)</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.UACKeyListCheck" title="pyOpenRPA.Orchestrator.__Orchestrator__.UACKeyListCheck"><code class="xref py py-obj docutils literal notranslate"><span class="pre">UACKeyListCheck</span></code></a>(inRequest, inRoleKeyList)</p></td>
<td><p>Check is client is has access for the key list</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.UACSuperTokenUpdate" title="pyOpenRPA.Orchestrator.__Orchestrator__.UACSuperTokenUpdate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">UACSuperTokenUpdate</span></code></a>(inSuperTokenStr[, …])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.UACSuperTokenUpdate" title="pyOpenRPA.Orchestrator.__Orchestrator__.UACSuperTokenUpdate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">UACSuperTokenUpdate</span></code></a>(inSuperTokenStr[, …])</p></td>
<td><p>Add supertoken for the all access (it is need for the robot communication without human)</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.UACUpdate" title="pyOpenRPA.Orchestrator.__Orchestrator__.UACUpdate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">UACUpdate</span></code></a>(inADLoginStr[, inADStr, …])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.UACUpdate" title="pyOpenRPA.Orchestrator.__Orchestrator__.UACUpdate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">UACUpdate</span></code></a>(inADLoginStr[, inADStr, …])</p></td>
<td><p>Update user access (UAC)</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.UACUserDictGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.UACUserDictGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">UACUserDictGet</span></code></a>(inRequest)</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.UACUserDictGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.UACUserDictGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">UACUserDictGet</span></code></a>(inRequest)</p></td>
<td><p>Return user UAC hierarchy dict of the inRequest object.</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebAuditMessageCreate" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebAuditMessageCreate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebAuditMessageCreate</span></code></a>(inRequest[, …])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebAuditMessageCreate" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebAuditMessageCreate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebAuditMessageCreate</span></code></a>([inRequest, …])</p></td>
<td><p>Create message string with request user details (IP, Login etc…).</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebCPUpdate" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebCPUpdate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebCPUpdate</span></code></a>(inCPKeyStr[, inHTMLRenderDef, …])</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebCPUpdate" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebCPUpdate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebCPUpdate</span></code></a>(inCPKeyStr[, inHTMLRenderDef, …])</p></td>
<td><p>Add control panel HTML, JSON generator or JS when page init</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebListenCreate" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebListenCreate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebListenCreate</span></code></a>([inServerKeyStr, …])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebListenCreate" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebListenCreate"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebListenCreate</span></code></a>([inServerKeyStr, …])</p></td>
<td><p>Create listen interface for the web server</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyBytes" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyBytes"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebRequestParseBodyBytes</span></code></a>(inRequest)</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebRequestGet</span></code></a>()</p></td>
<td><p>Return the web request instance if current thread was created by web request from client.</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyBytes" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyBytes"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebRequestParseBodyBytes</span></code></a>([inRequest])</p></td>
<td><p>Extract the body in bytes from the request</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyJSON" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyJSON"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebRequestParseBodyJSON</span></code></a>(inRequest)</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyJSON" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyJSON"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebRequestParseBodyJSON</span></code></a>([inRequest])</p></td>
<td><p>Extract the body in dict/list from the request</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyStr" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyStr"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebRequestParseBodyStr</span></code></a>(inRequest)</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyStr" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyStr"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebRequestParseBodyStr</span></code></a>([inRequest])</p></td>
<td><p>Extract the body in str from the request</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseFile" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseFile"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebRequestParseFile</span></code></a>(inRequest)</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseFile" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseFile"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebRequestParseFile</span></code></a>([inRequest])</p></td>
<td><p>Parse the request - extract the file (name, body in bytes)</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParsePath" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParsePath"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebRequestParsePath</span></code></a>(inRequest)</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParsePath" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParsePath"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebRequestParsePath</span></code></a>([inRequest])</p></td>
<td><p>Parse the request - extract the url.</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestResponseSend" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestResponseSend"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebRequestResponseSend</span></code></a>(inRequest, inResponeStr)</p></td>
<td><p>Send response for the request :return:</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestResponseSend" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestResponseSend"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebRequestResponseSend</span></code></a>(inResponeStr[, inRequest])</p></td>
<td><p>Send response for the request</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectDef" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectDef"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebURLConnectDef</span></code></a>(inMethodStr, inURLStr, …)</p></td>
<td><p>Connect URL to DEF</p></td>
@ -517,13 +529,13 @@
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFolder" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFolder"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebURLConnectFolder</span></code></a>(inMethodStr, inURLStr, …)</p></td>
<td><p>Connect URL to Folder</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserInfoGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebUserInfoGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebUserInfoGet</span></code></a>(inRequest)</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserInfoGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebUserInfoGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebUserInfoGet</span></code></a>([inRequest])</p></td>
<td><p>Return User info about request</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserIsSuperToken" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebUserIsSuperToken"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebUserIsSuperToken</span></code></a>(inRequest[, inGSettings])</p></td>
<tr class="row-odd"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserIsSuperToken" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebUserIsSuperToken"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebUserIsSuperToken</span></code></a>([inRequest, inGSettings])</p></td>
<td><p>Return bool if request is authentificated with supetoken (token which is never expires)</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserUACHierarchyGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebUserUACHierarchyGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebUserUACHierarchyGet</span></code></a>(inRequest)</p></td>
<tr class="row-even"><td><p><a class="reference internal" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserUACHierarchyGet" title="pyOpenRPA.Orchestrator.__Orchestrator__.WebUserUACHierarchyGet"><code class="xref py py-obj docutils literal notranslate"><span class="pre">WebUserUACHierarchyGet</span></code></a>([inRequest])</p></td>
<td><p>Return User UAC Hierarchy DICT Return {…}</p></td>
</tr>
</tbody>
@ -771,7 +783,7 @@
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSCMD">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">AgentOSCMD</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inHostNameStr</span></em>, <em class="sig-param"><span class="n">inUserStr</span></em>, <em class="sig-param"><span class="n">inCMDStr</span></em>, <em class="sig-param"><span class="n">inRunAsyncBool</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">inSendOutputToOrchestratorLogsBool</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">inCMDEncodingStr</span><span class="o">=</span><span class="default_value">'cp1251'</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#AgentOSCMD"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSCMD" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">AgentOSCMD</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inHostNameStr</span></em>, <em class="sig-param"><span class="n">inUserStr</span></em>, <em class="sig-param"><span class="n">inCMDStr</span></em>, <em class="sig-param"><span class="n">inRunAsyncBool</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">inSendOutputToOrchestratorLogsBool</span><span class="o">=</span><span class="default_value">True</span></em>, <em class="sig-param"><span class="n">inCMDEncodingStr</span><span class="o">=</span><span class="default_value">'cp1251'</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inCaptureBool</span><span class="o">=</span><span class="default_value">True</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#AgentOSCMD"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSCMD" title="Permalink to this definition"></a></dt>
<dd><p>Send CMD to OS thought the pyOpenRPA.Agent daemon. Result return to log + Orchestrator by the A2O connection</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
@ -783,6 +795,7 @@
<li><p><strong>inRunAsyncBool</strong> True - Agent processor dont wait execution; False - Agent processor wait cmd execution</p></li>
<li><p><strong>inSendOutputToOrchestratorLogsBool</strong> True - catch cmd execution output and send it to the Orchestrator logs; Flase - else case; Default True</p></li>
<li><p><strong>inCMDEncodingStr</strong> Set the encoding of the DOS window on the Agent server session. Windows is beautiful :) . Default is “cp1251” early was “cp866” - need test</p></li>
<li><p><strong>inCaptureBool</strong> !ATTENTION! If you need to start absolutely encapsulated app - set this flag as False. If you set True - the app output will come to Agent</p></li>
</ul>
</dd>
<dt class="field-even">Returns</dt>
@ -870,6 +883,25 @@
</dl>
</dd></dl>
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileBinaryDataReceive">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">AgentOSFileBinaryDataReceive</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inHostNameStr</span></em>, <em class="sig-param"><span class="n">inUserStr</span></em>, <em class="sig-param"><span class="n">inFilePathStr</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#AgentOSFileBinaryDataReceive"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileBinaryDataReceive" title="Permalink to this definition"></a></dt>
<dd><p>Read binary file from agent (synchronious)</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>inGSettings</strong> Global settings dict (singleton)</p></li>
<li><p><strong>inHostNameStr</strong> </p></li>
<li><p><strong>inUserStr</strong> </p></li>
<li><p><strong>inFilePathStr</strong> File path to read</p></li>
</ul>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p>file data bytes</p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileSend">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">AgentOSFileSend</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inHostNameStr</span></em>, <em class="sig-param"><span class="n">inUserStr</span></em>, <em class="sig-param"><span class="n">inOrchestratorFilePathStr</span></em>, <em class="sig-param"><span class="n">inAgentFilePathStr</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#AgentOSFileSend"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileSend" title="Permalink to this definition"></a></dt>
@ -1182,6 +1214,13 @@ ATTENTION: Orchestrator user need to have restart right on the Remote machine to
</dl>
</dd></dl>
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorInitWait">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">OrchestratorInitWait</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; None<a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#OrchestratorInitWait"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorInitWait" title="Permalink to this definition"></a></dt>
<dd><p>Wait thread while orc will process initial action.
ATTENTION: DO NOT CALL THIS DEF IN THREAD WHERE ORCHESTRATOR MUST BE INITIALIZED - INFINITE LOOP</p>
</dd></dl>
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorIsAdmin">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">OrchestratorIsAdmin</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#OrchestratorIsAdmin"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorIsAdmin" title="Permalink to this definition"></a></dt>
@ -1193,9 +1232,23 @@ ATTENTION: Orchestrator user need to have restart right on the Remote machine to
</dl>
</dd></dl>
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorIsInited">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">OrchestratorIsInited</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; bool<a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#OrchestratorIsInited"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorIsInited" title="Permalink to this definition"></a></dt>
<dd><p>Check if Orchestrator initial actions were processed</p>
<dl class="field-list simple">
<dt class="field-odd">Returns</dt>
<dd class="field-odd"><p>True - orc is already inited; False - else</p>
</dd>
<dt class="field-even">Return type</dt>
<dd class="field-even"><p>bool</p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorLoggerGet">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">OrchestratorLoggerGet</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#OrchestratorLoggerGet"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorLoggerGet" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">OrchestratorLoggerGet</code><span class="sig-paren">(</span><span class="sig-paren">)</span> &#x2192; logging.Logger<a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#OrchestratorLoggerGet"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorLoggerGet" title="Permalink to this definition"></a></dt>
<dd><p>Get the logger from the Orchestrator</p>
<dl class="field-list simple">
<dt class="field-odd">Returns</dt>
@ -1206,32 +1259,37 @@ ATTENTION: Orchestrator user need to have restart right on the Remote machine to
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorPySearchInit">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">OrchestratorPySearchInit</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inGlobPatternStr</span></em>, <em class="sig-param"><span class="n">inDefStr</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inDefArgNameGSettingsStr</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#OrchestratorPySearchInit"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorPySearchInit" title="Permalink to this definition"></a></dt>
<dd><p>Search the py files by the glob and do the safe init (in try except). Also add inited module in sys.modules as imported (module name = file name without extension).</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># USAGE VAR 1 (without the def auto call)</span>
<span class="c1"># Autoinit control panels starts with CP_</span>
<span class="n">Orchestrator</span><span class="o">.</span><span class="n">OrchestratorPySearchInit</span><span class="p">(</span><span class="n">inGlobPatternStr</span><span class="o">=</span><span class="s2">&quot;ControlPanel\CP_*.py&quot;</span><span class="p">)</span>
<span class="c1"># USAGE VAR 2 (with the def auto call) - for the backward compatibility CP for the Orchestrator ver. &lt; 1.2.7</span>
<span class="c1"># Autoinit control panels starts with CP_</span>
<span class="n">Orchestrator</span><span class="o">.</span><span class="n">OrchestratorPySearchInit</span><span class="p">(</span><span class="n">inGlobPatternStr</span><span class="o">=</span><span class="s2">&quot;ControlPanel\CP_*.py&quot;</span><span class="p">,</span> <span class="n">inDefStr</span><span class="o">=</span><span class="s2">&quot;SettingsUpdate&quot;</span><span class="p">,</span> <span class="n">inDefArgNameGSettingsStr</span><span class="o">=</span><span class="s2">&quot;inGSettings&quot;</span><span class="p">)</span>
<span class="c1"># INFO: The code above will replace the code below</span>
<span class="c1">## !!! For Relative import !!! CP Version Check</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;&quot;</span><span class="p">)))</span>
<span class="kn">from</span> <span class="nn">ControlPanel</span> <span class="kn">import</span> <span class="n">CP_VersionCheck</span>
<span class="n">CP_VersionCheck</span><span class="o">.</span><span class="n">SettingsUpdate</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">gSettings</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="n">gSettings</span><span class="p">[</span><span class="s2">&quot;Logger&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">exception</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Exception when init CP. See below.&quot;</span><span class="p">)</span>
</pre></div>
</div>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">OrchestratorPySearchInit</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inGlobPatternStr</span></em>, <em class="sig-param"><span class="n">inDefStr</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inDefArgNameGSettingsStr</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inAsyncInitBool</span><span class="o">=</span><span class="default_value">False</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#OrchestratorPySearchInit"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorPySearchInit" title="Permalink to this definition"></a></dt>
<dd><p>Search the py files by the glob and do the safe init (in try except). Also add inited module in sys.modules as imported (module name = file name without extension).
You can init CP in async way!
.. code-block:: python</p>
<blockquote>
<div><p># USAGE VAR 1 (without the def auto call)
# Autoinit control panels starts with <a href="#id3"><span class="problematic" id="id4">CP_</span></a>
Orchestrator.OrchestratorPySearchInit(inGlobPatternStr=”ControlPanelCP_*.py”)</p>
<p># USAGE VAR 2 (with the def auto call) - for the backward compatibility CP for the Orchestrator ver. &lt; 1.2.7
# Autoinit control panels starts with <a href="#id5"><span class="problematic" id="id6">CP_</span></a>
Orchestrator.OrchestratorPySearchInit(inGlobPatternStr=”ControlPanelCP_*.py”, inDefStr=”SettingsUpdate”, inDefArgNameGSettingsStr=”inGSettings”)</p>
<p># INFO: The code above will replace the code below
## !!! For Relative import !!! CP Version Check
try:</p>
<blockquote>
<div><p>sys.path.insert(0,os.path.abspath(os.path.join(r””)))
from ControlPanel import CP_VersionCheck
CP_VersionCheck.SettingsUpdate(inGSettings=gSettings)</p>
</div></blockquote>
<dl class="simple">
<dt>except Exception as e:</dt><dd><p>gSettings[“Logger”].exception(f”Exception when init CP. See below.”)</p>
</dd>
</dl>
</div></blockquote>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>inGlobPatternStr</strong> example”..***X64*.cmd”</p></li>
<li><p><strong>inDefStr</strong> OPTIONAL The string name of the def. For backward compatibility if you need to auto call some def from initialized module</p></li>
<li><p><strong>inDefArgNameGSettingsStr</strong> OPTIONAL The name of the GSettings argument in def (if exists)</p></li>
<li><p><strong>inAsyncInitBool</strong> OPTIONAL True - init py modules in many threads - parallel execution. False (default) - sequence execution</p></li>
</ul>
</dd>
<dt class="field-even">Returns</dt>
@ -1277,12 +1335,16 @@ ATTENTION: Orchestrator user need to have restart right on the Remote machine to
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionRestore">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">OrchestratorSessionRestore</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#OrchestratorSessionRestore"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionRestore" title="Permalink to this definition"></a></dt>
<dd><p>Check _SessionLast_RDPList.json and _SessionLast_StorageDict.pickle in working directory. if exist - load into gsettings
# _SessionLast_StorageDict.pickle (binary)</p>
<dd><p>Check _SessioLast… files in working directory. if exist - load into gsettings
(from version 1.2.7)</p>
<blockquote>
<div><p>_SessionLast_RDPList.json (encoding = “utf-8”)
_SessionLast_StorageDict.pickle (binary)</p>
<div><p>_SessionLast_GSettings.pickle (binary)</p>
</div></blockquote>
<dl class="simple">
<dt>(above the version 1.2.7)</dt><dd><p>_SessionLast_RDPList.json (encoding = “utf-8”)
_SessionLast_StorageDict.pickle (binary)</p>
</dd>
</dl>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>inGSettings</strong> Global settings dict (singleton)</p>
@ -1296,8 +1358,13 @@ _SessionLast_StorageDict.pickle (binary)</p>
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionSave">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">OrchestratorSessionSave</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#OrchestratorSessionSave"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionSave" title="Permalink to this definition"></a></dt>
<dd><dl class="simple">
<dt>Orchestrator session save in file</dt><dd><p>_SessionLast_RDPList.json (encoding = “utf-8”)
<dd><p>Orchestrator session save in file
(from version 1.2.7)</p>
<blockquote>
<div><p>_SessionLast_GSettings.pickle (binary)</p>
</div></blockquote>
<dl class="simple">
<dt>(above the version 1.2.7)</dt><dd><p>_SessionLast_RDPList.json (encoding = “utf-8”)
_SessionLast_StorageDict.pickle (binary)</p>
</dd>
</dl>
@ -1737,7 +1804,7 @@ Deprecated. See ActivityItemDefAliasUpdate</p>
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionConnect">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">RDPSessionConnect</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRDPSessionKeyStr</span></em>, <em class="sig-param"><span class="n">inRDPTemplateDict</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inHostStr</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inPortStr</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inLoginStr</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inPasswordStr</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#RDPSessionConnect"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionConnect" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">RDPSessionConnect</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRDPSessionKeyStr</span></em>, <em class="sig-param"><span class="n">inRDPTemplateDict</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inHostStr</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inPortStr</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inLoginStr</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inPasswordStr</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inRedirectClipboardBool</span><span class="o">=</span><span class="default_value">True</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#RDPSessionConnect"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionConnect" title="Permalink to this definition"></a></dt>
<dd><dl class="simple">
<dt>Create new RDPSession in RobotRDPActive. Attention - activity will be ignored if RDP key is already exists</dt><dd><p>2 way of the use</p>
</dd>
@ -2047,7 +2114,7 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.RDPTemplateCreate">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">RDPTemplateCreate</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inLoginStr</span></em>, <em class="sig-param"><span class="n">inPasswordStr</span></em>, <em class="sig-param"><span class="n">inHostStr</span><span class="o">=</span><span class="default_value">'127.0.0.1'</span></em>, <em class="sig-param"><span class="n">inPortInt</span><span class="o">=</span><span class="default_value">3389</span></em>, <em class="sig-param"><span class="n">inWidthPXInt</span><span class="o">=</span><span class="default_value">1680</span></em>, <em class="sig-param"><span class="n">inHeightPXInt</span><span class="o">=</span><span class="default_value">1050</span></em>, <em class="sig-param"><span class="n">inUseBothMonitorBool</span><span class="o">=</span><span class="default_value">False</span></em>, <em class="sig-param"><span class="n">inDepthBitInt</span><span class="o">=</span><span class="default_value">32</span></em>, <em class="sig-param"><span class="n">inSharedDriveList</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#RDPTemplateCreate"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPTemplateCreate" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">RDPTemplateCreate</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inLoginStr</span></em>, <em class="sig-param"><span class="n">inPasswordStr</span></em>, <em class="sig-param"><span class="n">inHostStr</span><span class="o">=</span><span class="default_value">'127.0.0.1'</span></em>, <em class="sig-param"><span class="n">inPortInt</span><span class="o">=</span><span class="default_value">3389</span></em>, <em class="sig-param"><span class="n">inWidthPXInt</span><span class="o">=</span><span class="default_value">1680</span></em>, <em class="sig-param"><span class="n">inHeightPXInt</span><span class="o">=</span><span class="default_value">1050</span></em>, <em class="sig-param"><span class="n">inUseBothMonitorBool</span><span class="o">=</span><span class="default_value">False</span></em>, <em class="sig-param"><span class="n">inDepthBitInt</span><span class="o">=</span><span class="default_value">32</span></em>, <em class="sig-param"><span class="n">inSharedDriveList</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inRedirectClipboardBool</span><span class="o">=</span><span class="default_value">True</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#RDPTemplateCreate"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.RDPTemplateCreate" title="Permalink to this definition"></a></dt>
<dd><p>Create RDP connect dict item/ Use it connect/reconnect (Orchestrator.RDPSessionConnect)</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># USAGE</span>
<span class="kn">from</span> <span class="nn">pyOpenRPA</span> <span class="kn">import</span> <span class="n">Orchestrator</span>
@ -2066,6 +2133,7 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<span class="c1"># &quot;Host&quot;: &quot;127.0.0.1&quot;, &quot;Port&quot;: &quot;3389&quot;, &quot;Login&quot;: &quot;USER_99&quot;, &quot;Password&quot;: &quot;USER_PASS_HERE&quot;,</span>
<span class="c1"># &quot;Screen&quot;: { &quot;Width&quot;: 1680, &quot;Height&quot;: 1050, &quot;FlagUseAllMonitors&quot;: False, &quot;DepthBit&quot;: &quot;32&quot; },</span>
<span class="c1"># &quot;SharedDriveList&quot;: [&quot;c&quot;],</span>
<span class="c1"># &quot;RedirectClipboardBool&quot;: True, # True - share clipboard to RDP; False - else</span>
<span class="c1"># ###### Will updated in program ############</span>
<span class="c1"># &quot;SessionHex&quot;: &quot;77777sdfsdf77777dsfdfsf77777777&quot;, # Hex is created when robot runs, example &quot;&quot;</span>
<span class="c1"># &quot;SessionIsWindowExistBool&quot;: False, &quot;SessionIsWindowResponsibleBool&quot;: False, &quot;SessionIsIgnoredBool&quot;: False</span>
@ -2084,6 +2152,7 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<li><p><strong>inUseBothMonitorBool</strong> True - connect to the RDP with both monitors. False - else case</p></li>
<li><p><strong>inDepthBitInt</strong> Remote desktop bitness. Available: 32 or 24 or 16 or 15, example 32</p></li>
<li><p><strong>inSharedDriveList</strong> Host local disc to connect to the RDP session. Example: [“c”, “d”]</p></li>
<li><p><strong>inRedirectClipboardBool</strong> # True - share clipboard to RDP; False - else</p></li>
</ul>
</dd>
<dt class="field-even">Returns</dt>
@ -2102,6 +2171,7 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
</div></blockquote>
<p>},
“SharedDriveList”: inSharedDriveList, # List of the Root sesion hard drives, example [“c”]
“RedirectClipboardBool”: True, # True - share clipboard to RDP; False - else
###### Will updated in program ############
“SessionHex”: “77777sdfsdf77777dsfdfsf77777777”, # Hex is created when robot runs, example “”
“SessionIsWindowExistBool”: False,
@ -2266,7 +2336,7 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.WebAuditMessageCreate">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebAuditMessageCreate</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span></em>, <em class="sig-param"><span class="n">inOperationCodeStr</span><span class="o">=</span><span class="default_value">'-'</span></em>, <em class="sig-param"><span class="n">inMessageStr</span><span class="o">=</span><span class="default_value">'-'</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebAuditMessageCreate"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebAuditMessageCreate" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebAuditMessageCreate</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inOperationCodeStr</span><span class="o">=</span><span class="default_value">'-'</span></em>, <em class="sig-param"><span class="n">inMessageStr</span><span class="o">=</span><span class="default_value">'-'</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebAuditMessageCreate"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebAuditMessageCreate" title="Permalink to this definition"></a></dt>
<dd><p>Create message string with request user details (IP, Login etc…). Very actual for IT security in big company.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># USAGE</span>
<span class="kn">from</span> <span class="nn">pyOpenRPA</span> <span class="kn">import</span> <span class="n">Orchestrator</span>
@ -2283,7 +2353,7 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>inRequest</strong> HTTP request handler</p></li>
<li><p><strong>inRequest</strong> HTTP request handler. Optional if call def from request thread</p></li>
<li><p><strong>inOperationCodeStr</strong> operation code in string format (actual for IT audit in control panels)</p></li>
<li><p><strong>inMessageStr</strong> additional message after</p></li>
</ul>
@ -2331,13 +2401,19 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
</dl>
</dd></dl>
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestGet">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebRequestGet</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebRequestGet"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestGet" title="Permalink to this definition"></a></dt>
<dd><p>Return the web request instance if current thread was created by web request from client. else return None</p>
</dd></dl>
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyBytes">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebRequestParseBodyBytes</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebRequestParseBodyBytes"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyBytes" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebRequestParseBodyBytes</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebRequestParseBodyBytes"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyBytes" title="Permalink to this definition"></a></dt>
<dd><p>Extract the body in bytes from the request</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>inRequest</strong> inRequest from the server</p>
<dd class="field-odd"><p><strong>inRequest</strong> inRequest from the server. Optional if call def from request thread</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p>Bytes or None</p>
@ -2347,11 +2423,11 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyJSON">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebRequestParseBodyJSON</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebRequestParseBodyJSON"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyJSON" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebRequestParseBodyJSON</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebRequestParseBodyJSON"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyJSON" title="Permalink to this definition"></a></dt>
<dd><p>Extract the body in dict/list from the request</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>inRequest</strong> </p>
<dd class="field-odd"><p><strong>inRequest</strong> inRequest from the server. Optional if call def from request thread</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p>dict or list</p>
@ -2361,11 +2437,11 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyStr">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebRequestParseBodyStr</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebRequestParseBodyStr"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyStr" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebRequestParseBodyStr</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebRequestParseBodyStr"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyStr" title="Permalink to this definition"></a></dt>
<dd><p>Extract the body in str from the request</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>inRequest</strong> inRequest from the server</p>
<dd class="field-odd"><p><strong>inRequest</strong> inRequest from the server. Optional if call def from request thread</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p>str or None</p>
@ -2375,11 +2451,11 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseFile">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebRequestParseFile</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebRequestParseFile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseFile" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebRequestParseFile</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebRequestParseFile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseFile" title="Permalink to this definition"></a></dt>
<dd><p>Parse the request - extract the file (name, body in bytes)</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>inRequest</strong> </p>
<dd class="field-odd"><p><strong>inRequest</strong> inRequest from the server. Optional if call def from request thread</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p>(FileNameStr, FileBodyBytes) or (None, None)</p>
@ -2389,11 +2465,11 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParsePath">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebRequestParsePath</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebRequestParsePath"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParsePath" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebRequestParsePath</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebRequestParsePath"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParsePath" title="Permalink to this definition"></a></dt>
<dd><p>Parse the request - extract the url. Example: /pyOpenRPA/Debugging/DefHelper/…</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>inRequest</strong> </p>
<dd class="field-odd"><p><strong>inRequest</strong> inRequest from the server. Optional if call def from request thread</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p>Str, Example: /pyOpenRPA/Debugging/DefHelper/…</p>
@ -2403,14 +2479,21 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestResponseSend">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebRequestResponseSend</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span></em>, <em class="sig-param"><span class="n">inResponeStr</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebRequestResponseSend"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestResponseSend" title="Permalink to this definition"></a></dt>
<dd><p>Send response for the request
:return:</p>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebRequestResponseSend</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inResponeStr</span></em>, <em class="sig-param"><span class="n">inRequest</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebRequestResponseSend"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestResponseSend" title="Permalink to this definition"></a></dt>
<dd><p>Send response for the request</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>inRequest</strong> inRequest from the server. Optional if call def from request thread</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p></p>
</dd>
</dl>
</dd></dl>
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectDef">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebURLConnectDef</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inMethodStr</span></em>, <em class="sig-param"><span class="n">inURLStr</span></em>, <em class="sig-param"><span class="n">inMatchTypeStr</span></em>, <em class="sig-param"><span class="n">inDef</span></em>, <em class="sig-param"><span class="n">inContentTypeStr</span><span class="o">=</span><span class="default_value">'application/octet-stream'</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebURLConnectDef"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectDef" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebURLConnectDef</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inMethodStr</span></em>, <em class="sig-param"><span class="n">inURLStr</span></em>, <em class="sig-param"><span class="n">inMatchTypeStr</span></em>, <em class="sig-param"><span class="n">inDef</span></em>, <em class="sig-param"><span class="n">inContentTypeStr</span><span class="o">=</span><span class="default_value">'application/octet-stream'</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inUACBool</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebURLConnectDef"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectDef" title="Permalink to this definition"></a></dt>
<dd><blockquote>
<div><dl class="simple">
<dt>Connect URL to DEF</dt><dd><p>“inMethodStr”:”GET|POST”,
@ -2425,11 +2508,12 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>inGSettings</strong> Global settings dict (singleton)</p></li>
<li><p><strong>inMethodStr</strong> </p></li>
<li><p><strong>inURLStr</strong> </p></li>
<li><p><strong>inMatchTypeStr</strong> </p></li>
<li><p><strong>inDef</strong> </p></li>
<li><p><strong>inContentTypeStr</strong> </p></li>
<li><p><strong>inMethodStr</strong> “GET|POST”,</p></li>
<li><p><strong>inURLStr</strong> example “/index”, #URL of the request</p></li>
<li><p><strong>inMatchTypeStr</strong> #”BeginWith|Contains|Equal|EqualCase”,</p></li>
<li><p><strong>inDef</strong> def arg allowed list: 2:[inRequest, inGSettings], 1: [inRequest], 0: []</p></li>
<li><p><strong>inContentTypeStr</strong> default: “application/octet-stream”</p></li>
<li><p><strong>inUACBool</strong> default: None; True - check user access before do this URL item. None - get Server flag if ask user</p></li>
</ul>
</dd>
</dl>
@ -2437,7 +2521,7 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFile">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebURLConnectFile</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inMethodStr</span></em>, <em class="sig-param"><span class="n">inURLStr</span></em>, <em class="sig-param"><span class="n">inMatchTypeStr</span></em>, <em class="sig-param"><span class="n">inFilePathStr</span></em>, <em class="sig-param"><span class="n">inContentTypeStr</span><span class="o">=</span><span class="default_value">'application/octet-stream'</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebURLConnectFile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFile" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebURLConnectFile</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inMethodStr</span></em>, <em class="sig-param"><span class="n">inURLStr</span></em>, <em class="sig-param"><span class="n">inMatchTypeStr</span></em>, <em class="sig-param"><span class="n">inFilePathStr</span></em>, <em class="sig-param"><span class="n">inContentTypeStr</span><span class="o">=</span><span class="default_value">'application/octet-stream'</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inUACBool</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebURLConnectFile"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFile" title="Permalink to this definition"></a></dt>
<dd><dl class="simple">
<dt>Connect URL to File</dt><dd><p>“inMethodStr”:”GET|POST”,
“inURLStr”: “/index”, #URL of the request
@ -2454,6 +2538,7 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<li><p><strong>inMatchTypeStr</strong> </p></li>
<li><p><strong>inFilePathStr</strong> </p></li>
<li><p><strong>inContentTypeStr</strong> </p></li>
<li><p><strong>inUACBool</strong> default: None; True - check user access before do this URL item. None - get Server flag if ask user</p></li>
</ul>
</dd>
</dl>
@ -2461,12 +2546,13 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFolder">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebURLConnectFolder</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inMethodStr</span></em>, <em class="sig-param"><span class="n">inURLStr</span></em>, <em class="sig-param"><span class="n">inMatchTypeStr</span></em>, <em class="sig-param"><span class="n">inFolderPathStr</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebURLConnectFolder"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFolder" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebURLConnectFolder</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inMethodStr</span></em>, <em class="sig-param"><span class="n">inURLStr</span></em>, <em class="sig-param"><span class="n">inMatchTypeStr</span></em>, <em class="sig-param"><span class="n">inFolderPathStr</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inUACBool</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebURLConnectFolder"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFolder" title="Permalink to this definition"></a></dt>
<dd><dl class="simple">
<dt>Connect URL to Folder</dt><dd><p>“inMethodStr”:”GET|POST”,
“inURLStr”: “/Folder/”, #URL of the request
“inMatchTypeStr”: “”, #”BeginWith|Contains|Equal|EqualCase”,
“inFolderPathStr”: “”, #Absolute or relative path</p>
“inFolderPathStr”: “”, #Absolute or relative path
“inUACBool”</p>
</dd>
</dl>
<dl class="field-list simple">
@ -2477,6 +2563,7 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<li><p><strong>inURLStr</strong> </p></li>
<li><p><strong>inMatchTypeStr</strong> </p></li>
<li><p><strong>inFolderPathStr</strong> </p></li>
<li><p><strong>inUACBool</strong> default: None; True - check user access before do this URL item. None - get Server flag if ask user</p></li>
</ul>
</dd>
</dl>
@ -2484,11 +2571,11 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.WebUserInfoGet">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebUserInfoGet</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebUserInfoGet"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserInfoGet" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebUserInfoGet</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebUserInfoGet"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserInfoGet" title="Permalink to this definition"></a></dt>
<dd><p>Return User info about request</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>inRequest</strong> </p>
<dd class="field-odd"><p><strong>inRequest</strong> inRequest from the server. Optional if call def from request thread</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p>{“DomainUpperStr”: “”, “UserNameUpperStr”: “”}</p>
@ -2498,12 +2585,12 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.WebUserIsSuperToken">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebUserIsSuperToken</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebUserIsSuperToken"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserIsSuperToken" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebUserIsSuperToken</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span><span class="o">=</span><span class="default_value">None</span></em>, <em class="sig-param"><span class="n">inGSettings</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebUserIsSuperToken"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserIsSuperToken" title="Permalink to this definition"></a></dt>
<dd><p>Return bool if request is authentificated with supetoken (token which is never expires)</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>inRequest</strong> </p></li>
<li><p><strong>inRequest</strong> inRequest from the server. Optional if call def from request thread</p></li>
<li><p><strong>inGSettings</strong> Global settings dict (singleton)</p></li>
</ul>
</dd>
@ -2515,11 +2602,11 @@ Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPo
<dl class="py function">
<dt id="pyOpenRPA.Orchestrator.__Orchestrator__.WebUserUACHierarchyGet">
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebUserUACHierarchyGet</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebUserUACHierarchyGet"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserUACHierarchyGet" title="Permalink to this definition"></a></dt>
<code class="sig-prename descclassname">pyOpenRPA.Orchestrator.__Orchestrator__.</code><code class="sig-name descname">WebUserUACHierarchyGet</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">inRequest</span><span class="o">=</span><span class="default_value">None</span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/pyOpenRPA/Orchestrator/__Orchestrator__.html#WebUserUACHierarchyGet"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserUACHierarchyGet" title="Permalink to this definition"></a></dt>
<dd><p>Return User UAC Hierarchy DICT Return {…}</p>
<dl class="field-list simple">
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><p><strong>inRequest</strong> </p>
<dd class="field-odd"><p><strong>inRequest</strong> inRequest from the server. Optional if call def from request thread</p>
</dd>
<dt class="field-even">Returns</dt>
<dd class="field-even"><p>UAC Dict {}</p>

@ -301,18 +301,20 @@
<span class="c1"># &quot;ResponseFilePath&quot;: &quot;&quot;, #Absolute or relative path</span>
<span class="c1"># &quot;ResponseFolderPath&quot;: &quot;&quot;, #Absolute or relative path</span>
<span class="c1"># &quot;ResponseContentType&quot;: &quot;&quot;, #HTTP Content-type</span>
<span class="c1"># &quot;ResponseDefRequestGlobal&quot;: None #Function with str result</span>
<span class="c1"># &quot;ResponseDefRequestGlobal&quot;: None ,#Function with str result</span>
<span class="c1"># &quot;UACBool&quot;: True # True - check user access before do this URL item. None - get Server flag if ask user</span>
<span class="c1"># }</span>
<span class="c1">#{</span>
<span class="c1"># &quot;Method&quot;: &quot;GET&quot;,</span>
<span class="c1"># &quot;URL&quot;: &quot;/test/&quot;, # URL of the request</span>
<span class="c1"># &quot;MatchType&quot;: &quot;BeginWith&quot;, # &quot;BeginWith|Contains|Equal|EqualCase&quot;,</span>
<span class="c1"># # &quot;ResponseFilePath&quot;: &quot;&quot;, #Absolute or relative path</span>
<span class="c1"># &quot;ResponseFolderPath&quot;: &quot;C:\Abs\Archive\scopeSrcUL\OpenRPA\Orchestrator\Settings&quot;,</span>
<span class="c1"># # Absolute or relative path</span>
<span class="c1"># # &quot;ResponseContentType&quot;: &quot;&quot;, #HTTP Content-type</span>
<span class="c1"># # &quot;ResponseDefRequestGlobal&quot;: None #Function with str result</span>
<span class="c1"># # &quot;UACBool&quot;: True # True - check user access before do this URL item</span>
<span class="c1">#}</span>
<span class="p">{</span>
<span class="s2">&quot;Method&quot;</span><span class="p">:</span> <span class="s2">&quot;GET&quot;</span><span class="p">,</span>
<span class="s2">&quot;URL&quot;</span><span class="p">:</span> <span class="s2">&quot;/test/&quot;</span><span class="p">,</span> <span class="c1"># URL of the request</span>
<span class="s2">&quot;MatchType&quot;</span><span class="p">:</span> <span class="s2">&quot;BeginWith&quot;</span><span class="p">,</span> <span class="c1"># &quot;BeginWith|Contains|Equal|EqualCase&quot;,</span>
<span class="c1"># &quot;ResponseFilePath&quot;: &quot;&quot;, #Absolute or relative path</span>
<span class="s2">&quot;ResponseFolderPath&quot;</span><span class="p">:</span> <span class="s2">&quot;C:\Abs\Archive\scopeSrcUL\OpenRPA\Orchestrator\Settings&quot;</span><span class="p">,</span>
<span class="c1"># Absolute or relative path</span>
<span class="c1"># &quot;ResponseContentType&quot;: &quot;&quot;, #HTTP Content-type</span>
<span class="c1"># &quot;ResponseDefRequestGlobal&quot;: None #Function with str result</span>
<span class="p">}</span>
<span class="p">],</span>
<span class="p">},</span>
@ -343,6 +345,7 @@
<span class="p">],</span>
<span class="p">},</span>
<span class="s2">&quot;ManagersProcessDict&quot;</span><span class="p">:{},</span> <span class="c1"># The key of the Process is (mAgentHostNameStr.upper(), mAgentUserNameStr.upper(), mProcessNameWOExeStr.upper())</span>
<span class="s2">&quot;ManagersGitDict&quot;</span><span class="p">:{},</span> <span class="c1"># The key of the Git instance is (mAgentHostNameStr.upper(), mAgentUserNameStr.upper(), mAbsPathUpperStr.upper())</span>
<span class="s2">&quot;ProcessorDict&quot;</span><span class="p">:</span> <span class="p">{</span> <span class="c1"># Has been changed. New general processor (one threaded) v.1.2.0</span>
<span class="s2">&quot;ActivityList&quot;</span><span class="p">:</span> <span class="p">[</span> <span class="c1"># List of the activities</span>
<span class="c1"># {</span>
@ -354,26 +357,13 @@
<span class="c1"># &quot;GUIDStr&quot;: ..., # GUID of the activity</span>
<span class="c1"># },</span>
<span class="p">],</span>
<span class="s2">&quot;ActivityItemNowDict&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># Activity Item which is executing now</span>
<span class="s2">&quot;AliasDefDict&quot;</span><span class="p">:</span> <span class="p">{},</span> <span class="c1"># Storage for def with Str alias. To use it see pyOpenRPA.Orchestrator.ControlPanel</span>
<span class="s2">&quot;CheckIntervalSecFloat&quot;</span><span class="p">:</span> <span class="mf">1.0</span><span class="p">,</span> <span class="c1"># Interval for check gSettings in ProcessorDict &gt; ActivityList</span>
<span class="s2">&quot;ExecuteBool&quot;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span> <span class="c1"># Flag to execute thread processor</span>
<span class="s2">&quot;ThreadIdInt&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># Technical field - will be setup when processor init</span>
<span class="s2">&quot;WarningExecutionMoreThanSecFloat&quot;</span><span class="p">:</span> <span class="mf">60.0</span> <span class="c1"># Push warning if execution more than n seconds</span>
<span class="p">},</span>
<span class="c1"># TODO REMOVE DEPRECATED KEYS IN v.2.0.0</span>
<span class="s2">&quot;ControlPanelDict&quot;</span><span class="p">:</span> <span class="p">{</span> <span class="c1"># Old structure &gt; CPDict</span>
<span class="s2">&quot;RefreshSeconds&quot;</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="c1"># deprecated parameter</span>
<span class="s2">&quot;RobotList&quot;</span><span class="p">:</span> <span class="p">[</span>
<span class="c1">#{</span>
<span class="c1"># &quot;RenderFunction&quot;: RenderRobotR01,</span>
<span class="c1"># &quot;KeyStr&quot;: &quot;TestControlPanelKey&quot;</span>
<span class="c1">#}</span>
<span class="p">]</span>
<span class="p">},</span>
<span class="c1"># TODO REMOVE DEPRECATED KEYS IN v.2.0.0</span>
<span class="s2">&quot;CPDict&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="c1"># &quot;CPKey&quot;: {&quot;HTMLRenderDef&quot;:None, &quot;JSONGeneratorDef&quot;:None, &quot;JSInitGeneratorDef&quot;:None}</span>
<span class="p">},</span>
<span class="c1"># # # # # # # # # # # # # #</span>
<span class="s2">&quot;RobotRDPActive&quot;</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">&quot;RecoveryDict&quot;</span><span class="p">:</span> <span class="p">{</span>

@ -198,7 +198,8 @@
</pre></div>
</div>
<p>If you need more configurations - so you can see here:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">psutil</span><span class="o">,</span> <span class="nn">datetime</span><span class="o">,</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">sys</span> <span class="c1"># stdout from logging</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">psutil</span><span class="o">,</span> <span class="nn">datetime</span><span class="o">,</span> <span class="nn">logging</span><span class="o">,</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">sys</span>
<span class="c1"># Config settings</span>
<span class="n">lPyOpenRPASourceFolderPathStr</span> <span class="o">=</span> <span class="sa">r</span><span class="s2">&quot;..\Sources&quot;</span> <span class="c1"># Path for test pyOpenRPA package</span>
@ -213,10 +214,10 @@
<span class="k">if</span> <span class="ow">not</span> <span class="n">Orchestrator</span><span class="o">.</span><span class="n">OrchestratorIsAdmin</span><span class="p">():</span>
<span class="n">Orchestrator</span><span class="o">.</span><span class="n">OrchestratorRerunAsAdmin</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Orchestrator will be run as administrator!&quot;</span><span class="p">)</span>
<span class="k">elif</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span> <span class="c1"># New init way - allow run as module -m PyOpenRPA.Orchestrator</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">gSettings</span> <span class="o">=</span> <span class="n">Orchestrator</span><span class="o">.</span><span class="n">GSettingsGet</span><span class="p">()</span>
<span class="c1">#gSettings = SettingsTemplate.Create(inModeStr=&quot;BASIC&quot;) # Create GSettings with basic configuration - no more config is available from the box - you can create own</span>
<span class="n">Orchestrator</span><span class="o">.</span><span class="n">OrchestratorLoggerGet</span><span class="p">()</span><span class="o">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>
<span class="c1"># TEST Add User ND - Add Login ND to superuser of the Orchestrator</span>
<span class="n">lUACClientDict</span> <span class="o">=</span> <span class="n">SettingsTemplate</span><span class="o">.</span><span class="n">__UACClientAdminCreate__</span><span class="p">()</span>
<span class="n">Orchestrator</span><span class="o">.</span><span class="n">UACUpdate</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">gSettings</span><span class="p">,</span> <span class="n">inADLoginStr</span><span class="o">=</span><span class="s2">&quot;ND&quot;</span><span class="p">,</span> <span class="n">inADStr</span><span class="o">=</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="n">inADIsDefaultBool</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">inURLList</span><span class="o">=</span><span class="p">[],</span> <span class="n">inRoleHierarchyAllowedDict</span><span class="o">=</span><span class="n">lUACClientDict</span><span class="p">)</span>
@ -229,35 +230,11 @@
<span class="c1"># Restore DUMP</span>
<span class="n">Orchestrator</span><span class="o">.</span><span class="n">OrchestratorSessionRestore</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">gSettings</span><span class="p">)</span>
<span class="c1"># Autoinit control panels starts with CP_</span>
<span class="n">lPyModules</span> <span class="o">=</span> <span class="n">Orchestrator</span><span class="o">.</span><span class="n">OrchestratorPySearchInit</span><span class="p">(</span><span class="n">inGlobPatternStr</span><span class="o">=</span><span class="s2">&quot;ControlPanel</span><span class="se">\\</span><span class="s2">CP_*.py&quot;</span><span class="p">,</span> <span class="n">inDefStr</span><span class="o">=</span><span class="s2">&quot;SettingsUpdate&quot;</span><span class="p">,</span> <span class="n">inDefArgNameGSettingsStr</span><span class="o">=</span><span class="s2">&quot;inGSettings&quot;</span><span class="p">)</span>
<span class="n">lPyModules</span> <span class="o">=</span> <span class="n">Orchestrator</span><span class="o">.</span><span class="n">OrchestratorPySearchInit</span><span class="p">(</span><span class="n">inGlobPatternStr</span><span class="o">=</span><span class="s2">&quot;ControlPanel</span><span class="se">\\</span><span class="s2">CP_*.py&quot;</span><span class="p">,</span> <span class="n">inDefStr</span><span class="o">=</span><span class="s2">&quot;SettingsUpdate&quot;</span><span class="p">,</span> <span class="n">inDefArgNameGSettingsStr</span><span class="o">=</span><span class="s2">&quot;inGSettings&quot;</span><span class="p">,</span> <span class="n">inAsyncInitBool</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="c1"># Call the orchestrator def</span>
<span class="n">Orchestrator</span><span class="o">.</span><span class="n">Orchestrator</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">gSettings</span><span class="p">,</span> <span class="n">inDumpRestoreBool</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="c1">#import atexit</span>
<span class="c1">#def test():</span>
<span class="c1"># Orchestrator.OrchestratorLoggerGet().info(123)</span>
<span class="c1">#atexit.register(test)</span>
<span class="kn">import</span> <span class="nn">signal</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">from</span> <span class="nn">pyOpenRPA.Tools</span> <span class="kn">import</span> <span class="n">Terminator</span>
<span class="n">Terminator</span><span class="o">.</span><span class="n">Init</span><span class="p">(</span><span class="n">inLogger</span><span class="o">=</span><span class="n">Orchestrator</span><span class="o">.</span><span class="n">OrchestratorLoggerGet</span><span class="p">())</span>
<span class="c1">#def signal_term_handler(signal, frame):</span>
<span class="c1"># Orchestrator.OrchestratorLoggerGet().info(&#39;got SIGTERM&#39;)</span>
<span class="c1"># sys.exit(0)</span>
<span class="c1">#signal.signal(signal.SIGTERM, signal_term_handler)</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="k">while</span> <span class="ow">not</span> <span class="n">Terminator</span><span class="o">.</span><span class="n">IsSignalClose</span><span class="p">():</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="mi">999</span><span class="p">)</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;!WARNING! Current orchestrator settings do not support old type of the Orchestrator start. Use new Orchestrator type start (see v1.2.0)&quot;</span><span class="p">)</span>
</pre></div>
</div>

File diff suppressed because it is too large Load Diff

@ -188,6 +188,9 @@
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">O2A</span><span class="p">,</span> <span class="n">A2O</span> <span class="c1"># Data flow Orchestrator To Agent</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">Processor</span> <span class="c1"># Processor Queue</span>
<span class="kn">from</span> <span class="nn">subprocess</span> <span class="kn">import</span> <span class="n">CREATE_NEW_CONSOLE</span> <span class="c1"># Flag to create new process in another CMD</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="n">gSettings</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1"># Create binary file by the base64 string (safe for JSON transmition)</span>
<div class="viewcode-block" id="OSFileBinaryDataBase64StrCreate"><a class="viewcode-back" href="../../../Agent/02_Defs.html#pyOpenRPA.Agent.__Agent__.OSFileBinaryDataBase64StrCreate">[docs]</a><span class="k">def</span> <span class="nf">OSFileBinaryDataBase64StrCreate</span><span class="p">(</span><span class="n">inFilePathStr</span><span class="p">,</span> <span class="n">inFileDataBase64Str</span><span class="p">,</span><span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
@ -244,16 +247,37 @@
<span class="sd"> :param inGSettings: global settings of the Agent (singleton)</span>
<span class="sd"> :return: File content in string base64 format (use base64.b64decode to decode data). Return None if file is not exist</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lL</span> <span class="o">=</span> <span class="n">inGSettings</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Logger&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">inGSettings</span><span class="p">)</span> <span class="ow">is</span> <span class="nb">dict</span> <span class="k">else</span> <span class="kc">None</span>
<span class="n">lFileDataBase64Str</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">inFilePathStr</span><span class="p">):</span>
<span class="n">lFile</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">inFilePathStr</span><span class="p">,</span> <span class="s2">&quot;rb&quot;</span><span class="p">)</span>
<span class="n">lFileDataBytes</span> <span class="o">=</span> <span class="n">lFile</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">lFile</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">lFileDataBase64Str</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">b64encode</span><span class="p">(</span><span class="n">lFileDataBytes</span><span class="p">)</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">&quot;utf-8&quot;</span><span class="p">)</span>
<span class="n">lL</span> <span class="o">=</span> <span class="n">inGSettings</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Logger&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">inGSettings</span><span class="p">)</span> <span class="ow">is</span> <span class="nb">dict</span> <span class="k">else</span> <span class="kc">None</span>
<span class="n">lMessageStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;AGENT Binary file </span><span class="si">{</span><span class="n">inFilePathStr</span><span class="si">}</span><span class="s2"> has been read.&quot;</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="n">lMessageStr</span><span class="p">)</span>
<span class="n">A2O</span><span class="o">.</span><span class="n">LogListSend</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">,</span> <span class="n">inLogList</span><span class="o">=</span><span class="p">[</span><span class="n">lMessageStr</span><span class="p">])</span>
<span class="n">lMessageStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;OSFileBinaryDataBase64StrReceive: file </span><span class="si">{</span><span class="n">inFilePathStr</span><span class="si">}</span><span class="s2"> has been read&quot;</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">lMessageStr</span><span class="p">)</span>
<span class="c1">#A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;OSFileBinaryDataBase64StrReceive: file </span><span class="si">{</span><span class="n">inFilePathStr</span><span class="si">}</span><span class="s2"> is not exists - return None&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">lFileDataBase64Str</span></div>
<div class="viewcode-block" id="OSFileMTimeGet"><a class="viewcode-back" href="../../../Agent/02_Defs.html#pyOpenRPA.Agent.__Agent__.OSFileMTimeGet">[docs]</a><span class="k">def</span> <span class="nf">OSFileMTimeGet</span><span class="p">(</span><span class="n">inFilePathStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">float</span> <span class="ow">or</span> <span class="kc">None</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Read file modification time timestamp format (float)</span>
<span class="sd"> :param inFilePathStr: File path to read</span>
<span class="sd"> :return: timestamp (float) Return None if file is not exist</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">gSettings</span>
<span class="n">lL</span> <span class="o">=</span> <span class="n">gSettings</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Logger&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">gSettings</span><span class="p">)</span> <span class="ow">is</span> <span class="nb">dict</span> <span class="k">else</span> <span class="kc">None</span>
<span class="n">lFileMTimeFloat</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">inFilePathStr</span><span class="p">):</span>
<span class="n">lFileMTimeFloat</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">getmtime</span><span class="p">(</span><span class="n">inFilePathStr</span><span class="p">)</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;OSFileMTimeGet: file </span><span class="si">{</span><span class="n">inFilePathStr</span><span class="si">}</span><span class="s2"> has been read&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;OSFileMTimeGet: file </span><span class="si">{</span><span class="n">inFilePathStr</span><span class="si">}</span><span class="s2"> is not exists - return None&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">lFileMTimeFloat</span></div>
<div class="viewcode-block" id="OSFileTextDataStrReceive"><a class="viewcode-back" href="../../../Agent/02_Defs.html#pyOpenRPA.Agent.__Agent__.OSFileTextDataStrReceive">[docs]</a><span class="k">def</span> <span class="nf">OSFileTextDataStrReceive</span><span class="p">(</span><span class="n">inFilePathStr</span><span class="p">,</span> <span class="n">inEncodingStr</span><span class="o">=</span><span class="s2">&quot;utf-8&quot;</span><span class="p">,</span> <span class="n">inGSettings</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Read text file in the agent GUI session</span>
@ -263,17 +287,21 @@
<span class="sd"> :param inGSettings: global settings of the Agent (singleton)</span>
<span class="sd"> :return: File text content in string format (use base64.b64decode to decode data). Return None if file is not exist</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lFileDataStr</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">lL</span> <span class="o">=</span> <span class="n">inGSettings</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Logger&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">inGSettings</span><span class="p">)</span> <span class="ow">is</span> <span class="nb">dict</span> <span class="k">else</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="n">inFilePathStr</span><span class="p">):</span>
<span class="n">lFile</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">inFilePathStr</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="n">inEncodingStr</span><span class="p">)</span>
<span class="n">lFileDataStr</span> <span class="o">=</span> <span class="n">lFile</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">lFile</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">lL</span> <span class="o">=</span> <span class="n">inGSettings</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Logger&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span> <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">inGSettings</span><span class="p">)</span> <span class="ow">is</span> <span class="nb">dict</span> <span class="k">else</span> <span class="kc">None</span>
<span class="n">lMessageStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;AGENT Text file </span><span class="si">{</span><span class="n">inFilePathStr</span><span class="si">}</span><span class="s2"> has been read.&quot;</span>
<span class="n">lMessageStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;OSFileTextDataStrReceive: file </span><span class="si">{</span><span class="n">inFilePathStr</span><span class="si">}</span><span class="s2"> has been read&quot;</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="n">lMessageStr</span><span class="p">)</span>
<span class="n">A2O</span><span class="o">.</span><span class="n">LogListSend</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">,</span> <span class="n">inLogList</span><span class="o">=</span><span class="p">[</span><span class="n">lMessageStr</span><span class="p">])</span>
<span class="c1">#A2O.LogListSend(inGSettings=inGSettings, inLogList=[lMessageStr])</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;OSFileTextDataStrReceive: file </span><span class="si">{</span><span class="n">inFilePathStr</span><span class="si">}</span><span class="s2"> is not exists - return None&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">lFileDataStr</span></div>
<span class="c1"># Send CMD to OS. Result return to log + Orchestrator by the A2O connection</span>
<div class="viewcode-block" id="OSCMD"><a class="viewcode-back" href="../../../Agent/02_Defs.html#pyOpenRPA.Agent.__Agent__.OSCMD">[docs]</a><span class="k">def</span> <span class="nf">OSCMD</span><span class="p">(</span><span class="n">inCMDStr</span><span class="p">,</span> <span class="n">inRunAsyncBool</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">inSendOutputToOrchestratorLogsBool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> <span class="n">inCMDEncodingStr</span> <span class="o">=</span> <span class="s2">&quot;cp1251&quot;</span><span class="p">):</span>
<div class="viewcode-block" id="OSCMD"><a class="viewcode-back" href="../../../Agent/02_Defs.html#pyOpenRPA.Agent.__Agent__.OSCMD">[docs]</a><span class="k">def</span> <span class="nf">OSCMD</span><span class="p">(</span><span class="n">inCMDStr</span><span class="p">,</span> <span class="n">inRunAsyncBool</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">inSendOutputToOrchestratorLogsBool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> <span class="n">inCMDEncodingStr</span> <span class="o">=</span> <span class="s2">&quot;cp1251&quot;</span><span class="p">,</span> <span class="n">inCaptureBool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Execute CMD on the Agent daemonic process</span>
@ -281,18 +309,21 @@
<span class="sd"> :param inRunAsyncBool: True - Agent processor don&#39;t wait execution; False - Agent processor wait cmd execution</span>
<span class="sd"> :param inGSettings: Agent global settings dict</span>
<span class="sd"> :param inSendOutputToOrchestratorLogsBool: True - catch cmd execution output and send it to the Orchestrator logs; Flase - else case; Default True</span>
<span class="sd"> !ATTENTION! If you need to start absolutely encapsulated app - set this flag as False. If you set True - the app output will come to Agent</span>
<span class="sd"> :param inCMDEncodingStr: Set the encoding of the DOS window on the Agent server session. Windows is beautiful :) . Default is &quot;cp1251&quot; early was &quot;cp866&quot; - need test</span>
<span class="sd"> :param inCaptureBool: !ATTENTION! If you need to start absolutely encapsulated app - set this flag as False. If you set True - the app output will come to Agent</span>
<span class="sd"> :return:</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lResultStr</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="c1"># New feature</span>
<span class="k">if</span> <span class="n">inSendOutputToOrchestratorLogsBool</span> <span class="o">==</span> <span class="kc">False</span> <span class="ow">and</span> <span class="n">inCaptureBool</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span>
<span class="n">inCMDStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;start </span><span class="si">{</span><span class="n">inCMDStr</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="c1"># Subdef to listen OS result</span>
<span class="k">def</span> <span class="nf">_CMDRunAndListenLogs</span><span class="p">(</span><span class="n">inCMDStr</span><span class="p">,</span> <span class="n">inSendOutputToOrchestratorLogsBool</span><span class="p">,</span> <span class="n">inCMDEncodingStr</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">_CMDRunAndListenLogs</span><span class="p">(</span><span class="n">inCMDStr</span><span class="p">,</span> <span class="n">inSendOutputToOrchestratorLogsBool</span><span class="p">,</span> <span class="n">inCMDEncodingStr</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">inCaptureBool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">):</span>
<span class="n">lL</span> <span class="o">=</span> <span class="n">inGSettings</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Logger&quot;</span><span class="p">,</span><span class="kc">None</span><span class="p">)</span> <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">inGSettings</span><span class="p">)</span> <span class="ow">is</span> <span class="nb">dict</span> <span class="k">else</span> <span class="kc">None</span>
<span class="n">lResultStr</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">lOSCMDKeyStr</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">uuid</span><span class="o">.</span><span class="n">uuid4</span><span class="p">())[</span><span class="mi">0</span><span class="p">:</span><span class="mi">4</span><span class="p">]</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span>
<span class="n">lCMDProcess</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">inSendOutputToOrchestratorLogsBool</span> <span class="o">==</span> <span class="kc">True</span><span class="p">:</span>
<span class="k">if</span> <span class="n">inCaptureBool</span> <span class="o">==</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">lCMDProcess</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;cmd /c </span><span class="si">{</span><span class="n">inCMDStr</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">stderr</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">STDOUT</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">lCMDProcess</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;cmd /c </span><span class="si">{</span><span class="n">inCMDStr</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">stderr</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
@ -300,12 +331,15 @@
<span class="n">lListenBool</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">lMessageStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">lOSCMDKeyStr</span><span class="si">}</span><span class="s2">: # # # # AGENT CMD Process has been STARTED # # # # &quot;</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="n">lMessageStr</span><span class="p">)</span>
<span class="k">if</span> <span class="n">inSendOutputToOrchestratorLogsBool</span> <span class="o">==</span> <span class="kc">True</span><span class="p">:</span> <span class="c1"># Capturing can be turned on!</span>
<span class="n">A2O</span><span class="o">.</span><span class="n">LogListSend</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">,</span><span class="n">inLogList</span><span class="o">=</span><span class="p">[</span><span class="n">lMessageStr</span><span class="p">])</span>
<span class="n">lMessageStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">lOSCMDKeyStr</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">inCMDStr</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="n">lMessageStr</span><span class="p">)</span>
<span class="k">if</span> <span class="n">inSendOutputToOrchestratorLogsBool</span> <span class="o">==</span> <span class="kc">True</span><span class="p">:</span> <span class="c1"># Capturing can be turned on!</span>
<span class="n">A2O</span><span class="o">.</span><span class="n">LogListSend</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">,</span> <span class="n">inLogList</span><span class="o">=</span><span class="p">[</span><span class="n">lMessageStr</span><span class="p">])</span>
<span class="k">while</span> <span class="n">lListenBool</span><span class="p">:</span>
<span class="k">if</span> <span class="n">inSendOutputToOrchestratorLogsBool</span> <span class="o">==</span> <span class="kc">True</span><span class="p">:</span> <span class="c1"># Capturing can be turned on!</span>
<span class="c1">#if inSendOutputToOrchestratorLogsBool == True: # Capturing can be turned on!</span>
<span class="k">if</span> <span class="n">inCaptureBool</span> <span class="o">==</span> <span class="kc">True</span><span class="p">:</span> <span class="c1"># Capturing can be turned on!</span>
<span class="n">lOutputLineBytes</span> <span class="o">=</span> <span class="n">lCMDProcess</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
<span class="k">if</span> <span class="n">lOutputLineBytes</span> <span class="o">==</span> <span class="sa">b</span><span class="s2">&quot;&quot;</span><span class="p">:</span>
<span class="n">lListenBool</span> <span class="o">=</span> <span class="kc">False</span>
@ -313,6 +347,7 @@
<span class="k">if</span> <span class="n">lStr</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">):</span> <span class="n">lStr</span> <span class="o">=</span> <span class="n">lStr</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="n">lMessageStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">lOSCMDKeyStr</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">lStr</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="n">lMessageStr</span><span class="p">)</span>
<span class="k">if</span> <span class="n">inSendOutputToOrchestratorLogsBool</span> <span class="o">==</span> <span class="kc">True</span><span class="p">:</span> <span class="c1"># Capturing can be turned on!</span>
<span class="n">A2O</span><span class="o">.</span><span class="n">LogListSend</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">,</span> <span class="n">inLogList</span><span class="o">=</span><span class="p">[</span><span class="n">lMessageStr</span><span class="p">])</span>
<span class="n">lResultStr</span><span class="o">+=</span><span class="n">lStr</span>
<span class="k">else</span><span class="p">:</span> <span class="c1">#Capturing is not turned on - wait until process will be closed</span>
@ -323,15 +358,16 @@
<span class="n">lListenBool</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">lMessageStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">lOSCMDKeyStr</span><span class="si">}</span><span class="s2">: # # # # AGENT CMD Process has been FINISHED # # # # &quot;</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="n">lMessageStr</span><span class="p">)</span>
<span class="k">if</span> <span class="n">inSendOutputToOrchestratorLogsBool</span> <span class="o">==</span> <span class="kc">True</span><span class="p">:</span> <span class="c1"># Capturing can be turned on!</span>
<span class="n">A2O</span><span class="o">.</span><span class="n">LogListSend</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">,</span> <span class="n">inLogList</span><span class="o">=</span><span class="p">[</span><span class="n">lMessageStr</span><span class="p">])</span>
<span class="k">return</span> <span class="n">lResultStr</span>
<span class="c1"># New call</span>
<span class="k">if</span> <span class="n">inRunAsyncBool</span><span class="p">:</span>
<span class="n">lThread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">_CMDRunAndListenLogs</span><span class="p">,</span> <span class="n">kwargs</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;inCMDStr&quot;</span><span class="p">:</span><span class="n">inCMDStr</span><span class="p">,</span> <span class="s2">&quot;inGSettings&quot;</span><span class="p">:</span><span class="n">inGSettings</span><span class="p">,</span> <span class="s2">&quot;inSendOutputToOrchestratorLogsBool&quot;</span><span class="p">:</span><span class="n">inSendOutputToOrchestratorLogsBool</span><span class="p">,</span> <span class="s2">&quot;inCMDEncodingStr&quot;</span><span class="p">:</span><span class="n">inCMDEncodingStr</span> <span class="p">})</span>
<span class="n">lThread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">_CMDRunAndListenLogs</span><span class="p">,</span> <span class="n">kwargs</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;inCMDStr&quot;</span><span class="p">:</span><span class="n">inCMDStr</span><span class="p">,</span> <span class="s2">&quot;inGSettings&quot;</span><span class="p">:</span><span class="n">inGSettings</span><span class="p">,</span> <span class="s2">&quot;inSendOutputToOrchestratorLogsBool&quot;</span><span class="p">:</span><span class="n">inSendOutputToOrchestratorLogsBool</span><span class="p">,</span> <span class="s2">&quot;inCMDEncodingStr&quot;</span><span class="p">:</span><span class="n">inCMDEncodingStr</span><span class="p">,</span> <span class="s2">&quot;inCaptureBool&quot;</span><span class="p">:</span> <span class="n">inCaptureBool</span> <span class="p">})</span>
<span class="n">lThread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="n">lResultStr</span><span class="o">=</span><span class="s2">&quot;ActivityList has been started in async mode - no output is available here.&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">lResultStr</span> <span class="o">=</span> <span class="n">_CMDRunAndListenLogs</span><span class="p">(</span><span class="n">inCMDStr</span><span class="o">=</span><span class="n">inCMDStr</span><span class="p">,</span> <span class="n">inGSettings</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">,</span> <span class="n">inSendOutputToOrchestratorLogsBool</span> <span class="o">=</span> <span class="n">inSendOutputToOrchestratorLogsBool</span><span class="p">,</span> <span class="n">inCMDEncodingStr</span> <span class="o">=</span> <span class="n">inCMDEncodingStr</span><span class="p">)</span>
<span class="n">lResultStr</span> <span class="o">=</span> <span class="n">_CMDRunAndListenLogs</span><span class="p">(</span><span class="n">inCMDStr</span><span class="o">=</span><span class="n">inCMDStr</span><span class="p">,</span> <span class="n">inGSettings</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">,</span> <span class="n">inSendOutputToOrchestratorLogsBool</span> <span class="o">=</span> <span class="n">inSendOutputToOrchestratorLogsBool</span><span class="p">,</span> <span class="n">inCMDEncodingStr</span> <span class="o">=</span> <span class="n">inCMDEncodingStr</span><span class="p">,</span> <span class="n">inCaptureBool</span><span class="o">=</span><span class="n">inCaptureBool</span><span class="p">)</span>
<span class="c1">#lCMDCode = &quot;cmd /c &quot; + inCMDStr</span>
<span class="c1">#subprocess.Popen(lCMDCode)</span>
<span class="c1">#lResultCMDRun = 1 # os.system(lCMDCode)</span>
@ -366,7 +402,8 @@
<span class="c1"># Main def</span>
<span class="k">def</span> <span class="nf">Agent</span><span class="p">(</span><span class="n">inGSettings</span><span class="p">):</span>
<span class="n">lL</span> <span class="o">=</span> <span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;Logger&quot;</span><span class="p">]</span>
<span class="k">global</span> <span class="n">gSettings</span>
<span class="n">gSettings</span> <span class="o">=</span> <span class="n">inGSettings</span>
<span class="c1"># Append Orchestrator def to ProcessorDictAlias</span>
<span class="n">lModule</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="vm">__name__</span><span class="p">]</span>
<span class="n">lModuleDefList</span> <span class="o">=</span> <span class="nb">dir</span><span class="p">(</span><span class="n">lModule</span><span class="p">)</span>

@ -206,6 +206,8 @@
<span class="sd"> # Usage example:</span>
<span class="sd"> lCPManager = Orchestrator.Managers.ControlPanel(inControlPanelNameStr=&quot;TestControlPanel&quot;,</span>
<span class="sd"> inRefreshHTMLJinja2TemplatePathStr=&quot;ControlPanel\\test.html&quot;, inJinja2TemplateRefreshBool = True)</span>
<span class="sd"> </span>
<span class="sd"> </span>
<span class="sd"> If you use Jinja2 you can use next data context:</span>
<span class="sd"> StorageRobotDict: Orchestrator.StorageRobotGet(inRobotNameStr=self.mRobotNameStr),</span>
@ -219,6 +221,9 @@
<span class="sd"> OperatorModule: operator,</span>
<span class="sd"> MathModule: math</span>
<span class="sd"> You can modify jinja context by use the function:</span>
<span class="sd"> Jinja2DataUpdateDictSet </span>
<span class="sd"> .. code-block:: html</span>
<span class="sd"> Hello my control panel!</span>
<span class="sd"> You can use any def from Orchestrator module here in Jinja2 HTML template:</span>

@ -188,12 +188,17 @@
<span class="kn">from</span> <span class="nn">..</span> <span class="kn">import</span> <span class="n">__Orchestrator__</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">from</span> <span class="nn">pyOpenRPA</span> <span class="kn">import</span> <span class="n">Orchestrator</span>
<div class="viewcode-block" id="Process"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process">[docs]</a><span class="k">class</span> <span class="nc">Process</span><span class="p">():</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Manager process, which is need to be started / stopped / restarted</span>
<span class="sd"> With Process instance you can automate your process activity. Use schedule package to set interval when process should be active and when not.</span>
<span class="sd"> All defs in class are pickle safe! After orchestrator restart (if not the force stop of the orchestrator process) your instance with properties will be restored. But it not coverage the scheduler which is in __Orchestrator__ .</span>
<span class="sd"> After orc restart you need to reinit all schedule rules: Orchestrator.OrchestratorScheduleGet</span>
<span class="sd"> Process instance has the following statuses:</span>
<span class="sd"> - 0_STOPPED</span>
<span class="sd"> - 1_STOPPED_MANUAL</span>
@ -202,9 +207,9 @@
<span class="sd"> - 4_STARTED</span>
<span class="sd"> - 5_STARTED_MANUAL</span>
<span class="sd"> .. code-block:: python</span>
<span class="sd"> lProcess = Orchestrator.Managers.Process(inAgentHostNameStr=&quot;PCNAME&quot;,inAgentUserNameStr=&quot;USER&quot;,</span>
<span class="sd"> # For the safe init class use ProcessInitSafe</span>
<span class="sd"> lProcess = Orchestrator.Managers.ProcessInitSafe(inAgentHostNameStr=&quot;PCNAME&quot;,inAgentUserNameStr=&quot;USER&quot;,</span>
<span class="sd"> inProcessNameWOExeStr=&quot;notepad&quot;,inStartCMDStr=&quot;notepad&quot;,inStopSafeTimeoutSecFloat=3)</span>
<span class="sd"> # Async way to run job</span>
<span class="sd"> lProcess.ScheduleStatusCheckEverySeconds(inIntervalSecondsInt=5)</span>
@ -214,6 +219,7 @@
<span class="sd"> Orchestrator.OrchestratorScheduleGet().every(5).seconds.do(lProcess.StartCheck)</span>
<span class="sd"> How to use StopSafe on the robot side</span>
<span class="sd"> .. code-block:: python</span>
<span class="sd"> from pyOpenRPA.Tools import StopSafe</span>
<span class="sd"> StopSafe.Init(inLogger=None)</span>
@ -224,6 +230,8 @@
<span class="n">mAgentUserNameStr</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">mStartPathStr</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">mStartCMDStr</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">mStartArgDict</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">mStatusCheckIntervalSecFloat</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">mProcessNameWOExeStr</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">mStopSafeTimeoutSecFloat</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">mStatusStr</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL</span>
@ -235,6 +243,8 @@
<span class="n">mAgentMuteBool</span> <span class="o">=</span> <span class="kc">False</span> <span class="c1"># Mute any sends to agent while some action is perfomed</span>
<span class="n">mStatusSavedStr</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Saved status to the further restore</span>
<div class="viewcode-block" id="Process.MuteWait"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.MuteWait">[docs]</a> <span class="k">def</span> <span class="nf">MuteWait</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Internal def. Wait when class is apply to send new activities to the agent</span>
@ -246,16 +256,43 @@
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="n">lIntervalSecFloat</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">None</span></div>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">inAgentHostNameStr</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span><span class="p">,</span> <span class="n">inProcessNameWOExeStr</span><span class="p">,</span> <span class="n">inStartPathStr</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inStartCMDStr</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">inStopSafeTimeoutSecFloat</span><span class="o">=</span><span class="mi">120</span><span class="p">):</span>
<div class="viewcode-block" id="Process.KeyTurpleGet"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.KeyTurpleGet">[docs]</a> <span class="k">def</span> <span class="nf">KeyTurpleGet</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get the key turple of the current process</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentHostNameStr</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">mAgentUserNameStr</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">mProcessNameWOExeStr</span><span class="o">.</span><span class="n">upper</span><span class="p">())</span></div>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">inAgentHostNameStr</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span><span class="p">,</span> <span class="n">inProcessNameWOExeStr</span><span class="p">,</span> <span class="n">inStartPathStr</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inStartCMDStr</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">inStopSafeTimeoutSecFloat</span><span class="o">=</span><span class="mi">300</span><span class="p">,</span> <span class="n">inStartArgDict</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inStatusCheckIntervalSecFloat</span><span class="o">=</span><span class="mi">30</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Init the class instance.</span>
<span class="sd"> !ATTENTION! Function can raise exception if process with the same (inAgentHostNameStr, inAgentUserNameStr, inProcessNameWOExeStr) is already exists in GSettings (can be restored from previous Orchestrator session). See ProcessInitSafe to sefaty init the instance or restore previous</span>
<span class="sd"> !ATTENTION! Schedule options you must</span>
<span class="sd"> :param inAgentHostNameStr: Agent hostname in any case. Required to identify Process</span>
<span class="sd"> :param inAgentUserNameStr: Agent user name in any case. Required to identify Process</span>
<span class="sd"> :param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case</span>
<span class="sd"> :param inStartPathStr: Path to start process (.cmd/ .exe or something else). Path can be relative (from orc working directory) or absolute</span>
<span class="sd"> :param inStartCMDStr: CMD script to start program (if no start file is exists)</span>
<span class="sd"> :param inStopSafeTimeoutSecFloat: Time to wait for stop safe. After that do the stop force (if process is not stopped)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lGS</span> <span class="o">=</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">GSettingsGet</span><span class="p">()</span>
<span class="c1"># Check if Process is not exists in GSettings</span>
<span class="k">if</span> <span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">inAgentUserNameStr</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">inProcessNameWOExeStr</span><span class="o">.</span><span class="n">upper</span><span class="p">())</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">lGS</span><span class="p">[</span><span class="s2">&quot;ManagersProcessDict&quot;</span><span class="p">]:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mStartArgDict</span> <span class="o">=</span> <span class="n">inStartArgDict</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mAgentHostNameStr</span> <span class="o">=</span> <span class="n">inAgentHostNameStr</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mAgentUserNameStr</span> <span class="o">=</span> <span class="n">inAgentUserNameStr</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mStartPathStr</span> <span class="o">=</span> <span class="n">inStartPathStr</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mStartCMDStr</span> <span class="o">=</span> <span class="n">inStartCMDStr</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mProcessNameWOExeStr</span> <span class="o">=</span> <span class="n">inProcessNameWOExeStr</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mStopSafeTimeoutSecFloat</span> <span class="o">=</span> <span class="n">inStopSafeTimeoutSecFloat</span>
<span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">GSettingsGet</span><span class="p">()[</span><span class="s2">&quot;ManagersProcessDict&quot;</span><span class="p">][(</span><span class="n">inAgentHostNameStr</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">inAgentUserNameStr</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">inProcessNameWOExeStr</span><span class="o">.</span><span class="n">upper</span><span class="p">())]</span><span class="o">=</span><span class="bp">self</span>
<span class="n">lActivityDict</span> <span class="o">=</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">ProcessorActivityItemCreate</span><span class="p">(</span><span class="n">inDef</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">StatusCheck</span><span class="p">,</span><span class="n">inArgList</span><span class="o">=</span><span class="p">[])</span>
<span class="n">lGS</span><span class="p">[</span><span class="s2">&quot;ManagersProcessDict&quot;</span><span class="p">][(</span><span class="n">inAgentHostNameStr</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">inAgentUserNameStr</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">inProcessNameWOExeStr</span><span class="o">.</span><span class="n">upper</span><span class="p">())]</span><span class="o">=</span><span class="bp">self</span>
<span class="n">lActivityDict</span> <span class="o">=</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">ProcessorActivityItemCreate</span><span class="p">(</span><span class="n">inDef</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">StatusCheck</span><span class="p">,</span><span class="n">inArgList</span><span class="o">=</span><span class="p">[],</span> <span class="n">inThreadBool</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">ProcessorActivityItemAppend</span><span class="p">(</span><span class="n">inActivityItemDict</span><span class="o">=</span><span class="n">lActivityDict</span><span class="p">)</span>
<span class="k">if</span> <span class="n">inStatusCheckIntervalSecFloat</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">OrchestratorScheduleGet</span><span class="p">()</span><span class="o">.</span><span class="n">every</span><span class="p">(</span><span class="n">inStatusCheckIntervalSecFloat</span><span class="p">)</span><span class="o">.</span><span class="n">seconds</span><span class="o">.</span><span class="n">do</span><span class="p">(</span><span class="n">Orchestrator</span><span class="o">.</span><span class="n">OrchestratorThreadStart</span><span class="p">,</span><span class="bp">self</span><span class="o">.</span><span class="n">StatusCheck</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mStatusCheckIntervalSecFloat</span> <span class="o">=</span> <span class="n">inStatusCheckIntervalSecFloat</span>
<span class="k">else</span><span class="p">:</span> <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Managers.Process (</span><span class="si">{</span><span class="n">inAgentHostNameStr</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">inAgentUserNameStr</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">inProcessNameWOExeStr</span><span class="si">}</span><span class="s2">): Can&#39;t init the Process instance because it already inited in early (see ProcessInitSafe)&quot;</span><span class="p">)</span>
<div class="viewcode-block" id="Process.ManualStopTriggerSet"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.ManualStopTriggerSet">[docs]</a> <span class="k">def</span> <span class="nf">ManualStopTriggerSet</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">inMSTdTSecFloat</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">inMSTdNInt</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
@ -317,7 +354,7 @@
<span class="k">if</span> <span class="n">lLogBool</span> <span class="o">==</span> <span class="kc">True</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">StatusChangeLog</span><span class="p">()</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span></div>
<div class="viewcode-block" id="Process.Start"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.Start">[docs]</a> <span class="k">def</span> <span class="nf">Start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">inIsManualBool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<div class="viewcode-block" id="Process.Start"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.Start">[docs]</a> <span class="k">def</span> <span class="nf">Start</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">inIsManualBool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> <span class="n">inStartArgDict</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Manual/Auto start. Manual start will block scheduling execution. To return schedule execution use def Manual2Auto.</span>
<span class="sd"> Will not start if STOP SAFE is now and don&#39;t start auto is stopped manual now</span>
@ -326,19 +363,25 @@
<span class="sd"> :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">inIsManualBool</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">ManualStopTriggerNewStart</span><span class="p">()</span> <span class="c1"># Set the time</span>
<span class="k">if</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span> <span class="o">==</span> <span class="s2">&quot;1_STOPPED_MANUAL&quot;</span> <span class="ow">or</span> <span class="s2">&quot;STOP_SAFE&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span><span class="p">)</span> <span class="ow">and</span> <span class="n">inIsManualBool</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span> <span class="o">==</span> <span class="s2">&quot;1_STOPPED_MANUAL&quot;</span> <span class="ow">or</span> <span class="s2">&quot;STOP_SAFE&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span><span class="p">)</span> <span class="ow">and</span> <span class="n">inIsManualBool</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span>
<span class="n">lStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;Managers.Process (</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentHostNameStr</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentUserNameStr</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mProcessNameWOExeStr</span><span class="si">}</span><span class="s2">): Process will not start because of stopped manual or stop safe is now.&quot;</span>
<span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">OrchestratorLoggerGet</span><span class="p">()</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="n">lStr</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span>
<span class="c1"># Send activity item to agent - wait result</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStartPathStr</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="n">lCMDStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;start </span><span class="si">{</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mStartPathStr</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStartCMDStr</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="n">lCMDStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;start </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mStartCMDStr</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStartPathStr</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="n">lCMDStr</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mStartPathStr</span><span class="p">)</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStartCMDStr</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="n">lCMDStr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStartCMDStr</span>
<span class="c1"># Append args</span>
<span class="k">if</span> <span class="n">inStartArgDict</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStartArgDict</span> <span class="o">=</span> <span class="n">inStartArgDict</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStartArgDict</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">for</span> <span class="n">lItemKeyStr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStartArgDict</span><span class="p">:</span>
<span class="n">lItemValueStr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStartArgDict</span><span class="p">[</span><span class="n">lItemKeyStr</span><span class="p">]</span>
<span class="n">lCMDStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">lCMDStr</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">lItemKeyStr</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">lItemValueStr</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="c1">#import pdb</span>
<span class="c1">#pdb.set_trace()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">MuteWait</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mAgentMuteBool</span><span class="o">=</span><span class="kc">True</span>
<span class="n">lActivityItemStart</span> <span class="o">=</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">ProcessorActivityItemCreate</span><span class="p">(</span><span class="n">inDef</span><span class="o">=</span><span class="s2">&quot;OSCMD&quot;</span><span class="p">,</span>
<span class="n">inArgDict</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;inCMDStr&quot;</span><span class="p">:</span><span class="n">lCMDStr</span><span class="p">,</span><span class="s2">&quot;inSendOutputToOrchestratorLogsBool&quot;</span><span class="p">:</span><span class="kc">False</span><span class="p">},</span>
<span class="n">inArgDict</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;inCMDStr&quot;</span><span class="p">:</span><span class="n">lCMDStr</span><span class="p">,</span><span class="s2">&quot;inSendOutputToOrchestratorLogsBool&quot;</span><span class="p">:</span><span class="kc">False</span><span class="p">,</span> <span class="s2">&quot;inCaptureBool&quot;</span><span class="p">:</span><span class="kc">False</span><span class="p">},</span>
<span class="n">inArgGSettingsStr</span><span class="o">=</span><span class="s2">&quot;inGSettings&quot;</span><span class="p">)</span>
<span class="n">lGUIDStr</span> <span class="o">=</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">AgentActivityItemAdd</span><span class="p">(</span><span class="n">inHostNameStr</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentHostNameStr</span><span class="p">,</span>
<span class="n">inUserStr</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentUserNameStr</span><span class="p">,</span>
@ -364,20 +407,22 @@
<span class="bp">self</span><span class="o">.</span><span class="n">Start</span><span class="p">(</span><span class="n">inIsManualBool</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span></div>
<div class="viewcode-block" id="Process.StopSafe"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StopSafe">[docs]</a> <span class="k">def</span> <span class="nf">StopSafe</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">inIsManualBool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<div class="viewcode-block" id="Process.StopSafe"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StopSafe">[docs]</a> <span class="k">def</span> <span class="nf">StopSafe</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">inIsManualBool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> <span class="n">inStopSafeTimeoutSecFloat</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Manual/Auto stop safe. Stop safe is the operation which send signal to process to terminate own work (send term signal to process). Managers.Process wait for the mStopSafeTimeoutSecFloat seconds. After that, if process is not terminated - self will StopForce it.</span>
<span class="sd"> Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto</span>
<span class="sd"> :param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation</span>
<span class="sd"> :param inStopSafeTimeoutSecFloat: Default value goes from the instance. You can specify time is second to wait while safe stop. After that program will stop force</span>
<span class="sd"> :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">inStopSafeTimeoutSecFloat</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">inStopSafeTimeoutSecFloat</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStopSafeTimeoutSecFloat</span>
<span class="bp">self</span><span class="o">.</span><span class="n">MuteWait</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mAgentMuteBool</span><span class="o">=</span><span class="kc">True</span>
<span class="c1"># Send activity item to agent - wait result</span>
<span class="n">lCMDStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">&#39;taskkill /im &quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mProcessNameWOExeStr</span><span class="si">}</span><span class="s1">.exe&quot; /fi &quot;username eq %USERNAME%&quot;&#39;</span>
<span class="n">lActivityItemStart</span> <span class="o">=</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">ProcessorActivityItemCreate</span><span class="p">(</span>
<span class="n">inDef</span><span class="o">=</span><span class="s2">&quot;OSCMD&quot;</span><span class="p">,</span><span class="n">inArgDict</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;inCMDStr&quot;</span><span class="p">:</span> <span class="n">lCMDStr</span><span class="p">,</span><span class="s2">&quot;inSendOutputToOrchestratorLogsBool&quot;</span><span class="p">:</span><span class="kc">False</span><span class="p">},</span><span class="n">inArgGSettingsStr</span><span class="o">=</span><span class="s2">&quot;inGSettings&quot;</span><span class="p">)</span>
<span class="n">inDef</span><span class="o">=</span><span class="s2">&quot;OSCMD&quot;</span><span class="p">,</span><span class="n">inArgDict</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;inCMDStr&quot;</span><span class="p">:</span> <span class="n">lCMDStr</span><span class="p">,</span><span class="s2">&quot;inSendOutputToOrchestratorLogsBool&quot;</span><span class="p">:</span><span class="kc">False</span><span class="p">,</span> <span class="s2">&quot;inCaptureBool&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">},</span><span class="n">inArgGSettingsStr</span><span class="o">=</span><span class="s2">&quot;inGSettings&quot;</span><span class="p">)</span>
<span class="n">lGUIDStr</span> <span class="o">=</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">AgentActivityItemAdd</span><span class="p">(</span><span class="n">inHostNameStr</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentHostNameStr</span><span class="p">,</span>
<span class="n">inUserStr</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentUserNameStr</span><span class="p">,</span>
<span class="n">inActivityItemDict</span><span class="o">=</span><span class="n">lActivityItemStart</span><span class="p">)</span>
@ -391,31 +436,33 @@
<span class="c1"># Interval check is stopped</span>
<span class="n">lTimeStartFloat</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
<span class="n">lIntervalCheckSafeStatusFLoat</span> <span class="o">=</span> <span class="mf">15.0</span>
<span class="k">while</span> <span class="s2">&quot;SAFE&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span> <span class="ow">and</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">lTimeStartFloat</span><span class="p">)</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStopSafeTimeoutSecFloat</span><span class="p">:</span>
<span class="k">while</span> <span class="s2">&quot;SAFE&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span> <span class="ow">and</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">lTimeStartFloat</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">inStopSafeTimeoutSecFloat</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">StatusCheck</span><span class="p">()</span>
<span class="k">if</span> <span class="s2">&quot;SAFE&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span><span class="p">:</span> <span class="k">break</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="n">lIntervalCheckSafeStatusFLoat</span><span class="p">)</span>
<span class="k">if</span> <span class="s2">&quot;SAFE&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span><span class="p">:</span>
<span class="c1"># Log info about process</span>
<span class="n">lL</span> <span class="o">=</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">OrchestratorLoggerGet</span><span class="p">()</span>
<span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Managers.Process (</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentHostNameStr</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentUserNameStr</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mProcessNameWOExeStr</span><span class="si">}</span><span class="s2">): Safe stop has been wait for </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mStopSafeTimeoutSecFloat</span><span class="si">}</span><span class="s2"> sec. Now do the force stop.&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">StopForce</span><span class="p">(</span><span class="n">inIsManualBool</span><span class="o">=</span><span class="n">inIsManualBool</span><span class="p">)</span>
<span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Managers.Process (</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentHostNameStr</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentUserNameStr</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mProcessNameWOExeStr</span><span class="si">}</span><span class="s2">): Safe stop has been wait for </span><span class="si">{</span><span class="n">inStopSafeTimeoutSecFloat</span><span class="si">}</span><span class="s2"> sec. Now do the force stop.&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">StopForce</span><span class="p">(</span><span class="n">inIsManualBool</span><span class="o">=</span><span class="n">inIsManualBool</span><span class="p">,</span><span class="n">inMuteIgnoreBool</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="c1"># Log info about process</span>
<span class="bp">self</span><span class="o">.</span><span class="n">StatusChangeLog</span><span class="p">()</span>
<span class="c1"># self.StatusChangeLog() status check has already log status (see above)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mAgentMuteBool</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span></div>
<div class="viewcode-block" id="Process.StopSafeCheck"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StopSafeCheck">[docs]</a> <span class="k">def</span> <span class="nf">StopSafeCheck</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<div class="viewcode-block" id="Process.StopSafeCheck"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StopSafeCheck">[docs]</a> <span class="k">def</span> <span class="nf">StopSafeCheck</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">inStopSafeTimeoutSecFloat</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Stop safe program if auto started (4_STARTED).</span>
<span class="sd"> :param inStopSafeTimeoutSecFloat: Default value goes from the instance. You can specify time is second to wait while safe stop. After that program will stop force</span>
<span class="sd"> :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">MuteWait</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span> <span class="o">==</span> <span class="s2">&quot;4_STARTED&quot;</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">StopSafe</span><span class="p">(</span><span class="n">inIsManualBool</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">StopSafe</span><span class="p">(</span><span class="n">inIsManualBool</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">inStopSafeTimeoutSecFloat</span> <span class="o">=</span> <span class="n">inStopSafeTimeoutSecFloat</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span></div>
<div class="viewcode-block" id="Process.StopForce"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StopForce">[docs]</a> <span class="k">def</span> <span class="nf">StopForce</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">inIsManualBool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<div class="viewcode-block" id="Process.StopForce"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StopForce">[docs]</a> <span class="k">def</span> <span class="nf">StopForce</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">inIsManualBool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> <span class="n">inMuteIgnoreBool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Manual/Auto stop force. Force stop don&#39;t wait process termination - it just terminate process now.</span>
<span class="sd"> Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto</span>
@ -423,12 +470,13 @@
<span class="sd"> :param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation</span>
<span class="sd"> :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">MuteWait</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mAgentMuteBool</span><span class="o">=</span><span class="kc">True</span>
<span class="k">if</span> <span class="n">inMuteIgnoreBool</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">MuteWait</span><span class="p">()</span>
<span class="n">lMuteWorkBool</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">mAgentMuteBool</span><span class="o">==</span><span class="kc">False</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">mAgentMuteBool</span><span class="o">=</span><span class="kc">True</span><span class="p">;</span> <span class="n">lMuteWorkBool</span><span class="o">=</span><span class="kc">True</span>
<span class="c1"># Send activity item to agent - wait result</span>
<span class="n">lCMDStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">&#39;taskkill /F /im &quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mProcessNameWOExeStr</span><span class="si">}</span><span class="s1">.exe&quot; /fi &quot;username eq %USERNAME%&quot;&#39;</span>
<span class="n">lActivityItemStart</span> <span class="o">=</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">ProcessorActivityItemCreate</span><span class="p">(</span>
<span class="n">inDef</span><span class="o">=</span><span class="s2">&quot;OSCMD&quot;</span><span class="p">,</span><span class="n">inArgDict</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;inCMDStr&quot;</span><span class="p">:</span> <span class="n">lCMDStr</span><span class="p">,</span><span class="s2">&quot;inSendOutputToOrchestratorLogsBool&quot;</span><span class="p">:</span><span class="kc">False</span><span class="p">},</span><span class="n">inArgGSettingsStr</span><span class="o">=</span><span class="s2">&quot;inGSettings&quot;</span><span class="p">)</span>
<span class="n">inDef</span><span class="o">=</span><span class="s2">&quot;OSCMD&quot;</span><span class="p">,</span><span class="n">inArgDict</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;inCMDStr&quot;</span><span class="p">:</span> <span class="n">lCMDStr</span><span class="p">,</span><span class="s2">&quot;inSendOutputToOrchestratorLogsBool&quot;</span><span class="p">:</span><span class="kc">False</span><span class="p">,</span> <span class="s2">&quot;inCaptureBool&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">},</span><span class="n">inArgGSettingsStr</span><span class="o">=</span><span class="s2">&quot;inGSettings&quot;</span><span class="p">)</span>
<span class="n">lGUIDStr</span> <span class="o">=</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">AgentActivityItemAdd</span><span class="p">(</span><span class="n">inHostNameStr</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentHostNameStr</span><span class="p">,</span>
<span class="n">inUserStr</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentUserNameStr</span><span class="p">,</span>
<span class="n">inActivityItemDict</span><span class="o">=</span><span class="n">lActivityItemStart</span><span class="p">)</span>
@ -439,6 +487,7 @@
<span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span> <span class="o">=</span> <span class="s2">&quot;0_STOPPED&quot;</span>
<span class="c1"># Log info about process</span>
<span class="bp">self</span><span class="o">.</span><span class="n">StatusChangeLog</span><span class="p">()</span>
<span class="k">if</span> <span class="n">lMuteWorkBool</span> <span class="o">==</span> <span class="kc">True</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mAgentMuteBool</span><span class="o">=</span><span class="kc">False</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span></div>
@ -475,6 +524,48 @@
<span class="bp">self</span><span class="o">.</span><span class="n">StopForce</span><span class="p">(</span><span class="n">inIsManualBool</span><span class="o">=</span><span class="n">inIsManualBool</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">Start</span><span class="p">(</span><span class="n">inIsManualBool</span><span class="o">=</span><span class="n">inIsManualBool</span><span class="p">)</span></div>
<div class="viewcode-block" id="Process.StatusSave"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StatusSave">[docs]</a> <span class="k">def</span> <span class="nf">StatusSave</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Save current status of the process. After that you can restore process activity. Work when orchestrator is restarted. Don&#39;t save &quot;STOP_SAFE&quot; status &gt; &quot;STOPPED&quot;</span>
<span class="sd"> :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lWarnSafeBool</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span> <span class="o">==</span> <span class="s2">&quot;2_STOP_SAFE&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusSavedStr</span> <span class="o">=</span> <span class="s2">&quot;0_STOPPED&quot;</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span> <span class="o">==</span> <span class="s2">&quot;3_STOP_SAFE_MANUAL&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusSavedStr</span> <span class="o">=</span> <span class="s2">&quot;1_STOPPED_MANUAL&quot;</span>
<span class="k">else</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusSavedStr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span><span class="p">;</span> <span class="n">lWarnSafeBool</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">lWarnSafeBool</span><span class="o">==</span><span class="kc">True</span><span class="p">:</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">OrchestratorLoggerGet</span><span class="p">()</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Managers.Process (</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentHostNameStr</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentUserNameStr</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mProcessNameWOExeStr</span><span class="si">}</span><span class="s2">): Safe status has been catched when safe &gt; change saved status to stopped.&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span></div>
<div class="viewcode-block" id="Process.StatusCheckIntervalRestore"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StatusCheckIntervalRestore">[docs]</a> <span class="k">def</span> <span class="nf">StatusCheckIntervalRestore</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Call from orchestrator when init</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusCheckIntervalSecFloat</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">OrchestratorLoggerGet</span><span class="p">()</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Managers.Process (</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentHostNameStr</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentUserNameStr</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mProcessNameWOExeStr</span><span class="si">}</span><span class="s2">): Restore schedule to StatusCheck in interval of </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mStatusCheckIntervalSecFloat</span><span class="si">}</span><span class="s2"> sec.&quot;</span><span class="p">)</span>
<span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">OrchestratorScheduleGet</span><span class="p">()</span><span class="o">.</span><span class="n">every</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mStatusCheckIntervalSecFloat</span><span class="p">)</span><span class="o">.</span><span class="n">seconds</span><span class="o">.</span><span class="n">do</span><span class="p">(</span><span class="n">Orchestrator</span><span class="o">.</span><span class="n">OrchestratorThreadStart</span><span class="p">,</span><span class="bp">self</span><span class="o">.</span><span class="n">StatusCheck</span><span class="p">)</span></div>
<div class="viewcode-block" id="Process.StatusRestore"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StatusRestore">[docs]</a> <span class="k">def</span> <span class="nf">StatusRestore</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Execute the StatusCheck, after that restore status to the saved state (see StatusSave). Work when orchestrator is restarted.</span>
<span class="sd"> :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">StatusCheck</span><span class="p">()</span> <span class="c1"># check current status</span>
<span class="c1"># Do some action</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusSavedStr</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusSavedStr</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="c1">#lManualBool = False</span>
<span class="c1">#if &quot;MANUAL&quot; in self.mStatusSavedStr:</span>
<span class="c1"># lManualBool = True</span>
<span class="k">if</span> <span class="s2">&quot;STOPPED&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusSavedStr</span> <span class="ow">and</span> <span class="s2">&quot;STOPPED&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">StopSafe</span><span class="p">(</span><span class="n">inIsManualBool</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">if</span> <span class="s2">&quot;STARTED&quot;</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusSavedStr</span> <span class="ow">and</span> <span class="s2">&quot;STARTED&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">Start</span><span class="p">(</span><span class="n">inIsManualBool</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">Orchestrator</span><span class="o">.</span><span class="n">OrchestratorLoggerGet</span><span class="p">()</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Managers.Process (</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentHostNameStr</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentUserNameStr</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mProcessNameWOExeStr</span><span class="si">}</span><span class="s2">): Status has been restored to </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mStatusSavedStr</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusSavedStr</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mStatusSavedStr</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span></div>
<div class="viewcode-block" id="Process.StatusChangeLog"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StatusChangeLog">[docs]</a> <span class="k">def</span> <span class="nf">StatusChangeLog</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Lof information about status change</span>
@ -488,14 +579,14 @@
<div class="viewcode-block" id="Process.StatusCheck"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StatusCheck">[docs]</a> <span class="k">def</span> <span class="nf">StatusCheck</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Check if process is alive. The def will save the manual flag is exists.</span>
<span class="sd"> Check if process is alive. The def will save the manual flag is exists. Don&#39;t wait mute but set mute if it is not set.</span>
<span class="sd"> :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Send activity item to agent - wait result</span>
<span class="n">lLogBool</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">lActivityItemUserProcessList</span> <span class="o">=</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">ProcessorActivityItemCreate</span><span class="p">(</span><span class="n">inDef</span><span class="o">=</span><span class="s2">&quot;ProcessWOExeUpperUserListGet&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">MuteWait</span><span class="p">()</span>
<span class="c1">#self.MuteWait()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">mAgentMuteBool</span><span class="o">=</span><span class="kc">True</span>
<span class="n">lGUIDStr</span> <span class="o">=</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">AgentActivityItemAdd</span><span class="p">(</span><span class="n">inHostNameStr</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentHostNameStr</span><span class="p">,</span><span class="n">inUserStr</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">mAgentUserNameStr</span><span class="p">,</span><span class="n">inActivityItemDict</span><span class="o">=</span><span class="n">lActivityItemUserProcessList</span><span class="p">)</span>
<span class="n">lUserProcessList</span> <span class="o">=</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">AgentActivityItemReturnGet</span><span class="p">(</span><span class="n">inGUIDStr</span><span class="o">=</span><span class="n">lGUIDStr</span><span class="p">)</span>
@ -543,17 +634,38 @@
<span class="n">lStatusStr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">StatusCheck</span><span class="p">()</span>
<span class="k">if</span> <span class="n">lStatusStr</span> <span class="o">==</span> <span class="s2">&quot;4_STARTED&quot;</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">StopSafe</span><span class="p">(</span><span class="n">inIsManualBool</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span></div>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">mStatusStr</span></div></div>
<div class="viewcode-block" id="Process.ScheduleStatusCheckEverySeconds"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.ScheduleStatusCheckEverySeconds">[docs]</a> <span class="k">def</span> <span class="nf">ScheduleStatusCheckEverySeconds</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">inIntervalSecondsInt</span><span class="o">=</span><span class="mi">120</span><span class="p">):</span>
<div class="viewcode-block" id="ProcessInitSafe"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessInitSafe">[docs]</a><span class="k">def</span> <span class="nf">ProcessInitSafe</span><span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span><span class="p">,</span> <span class="n">inProcessNameWOExeStr</span><span class="p">,</span> <span class="n">inStartPathStr</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inStartCMDStr</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">inStopSafeTimeoutSecFloat</span><span class="o">=</span><span class="mi">300</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Process</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Run status check every interval in second you specify.</span>
<span class="sd"> Exception safe function. Check if process instance is not exists in GSettings (it can be after restart because Orchestrator restore objects from dump of the previous Orchestrator session)</span>
<span class="sd"> Return existing instance (if exists) or create new instance and return it.</span>
<span class="sd"> :param inIntervalSecondsInt: Interval in seconds. Default is 120</span>
<span class="sd"> :return: None</span>
<span class="sd"> :param inAgentHostNameStr: Agent hostname in any case. Required to identify Process</span>
<span class="sd"> :param inAgentUserNameStr: Agent user name in any case. Required to identify Process</span>
<span class="sd"> :param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case</span>
<span class="sd"> :param inStartPathStr: Path to start process (.cmd/ .exe or something else). Path can be relative (from orc working directory) or absolute</span>
<span class="sd"> :param inStartCMDStr: CMD script to start program (if no start file is exists)</span>
<span class="sd"> :param inStopSafeTimeoutSecFloat: Time to wait for stop safe. After that do the stop force (if process is not stopped)</span>
<span class="sd"> :return: Process instance</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="c1"># Check job in threaded way</span>
<span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">OrchestratorScheduleGet</span><span class="p">()</span><span class="o">.</span><span class="n">every</span><span class="p">(</span><span class="n">inIntervalSecondsInt</span><span class="p">)</span><span class="o">.</span><span class="n">seconds</span><span class="o">.</span><span class="n">do</span><span class="p">(</span><span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">OrchestratorThreadStart</span><span class="p">,</span><span class="bp">self</span><span class="o">.</span><span class="n">StatusCheck</span><span class="p">)</span></div></div>
<span class="n">lProcess</span> <span class="o">=</span> <span class="n">ProcessGet</span><span class="p">(</span><span class="n">inAgentHostNameStr</span> <span class="o">=</span> <span class="n">inAgentHostNameStr</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span> <span class="o">=</span> <span class="n">inAgentUserNameStr</span><span class="p">,</span> <span class="n">inProcessNameWOExeStr</span><span class="o">=</span><span class="n">inProcessNameWOExeStr</span><span class="p">)</span>
<span class="k">if</span> <span class="n">lProcess</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="k">return</span> <span class="n">lProcess</span>
<span class="k">else</span><span class="p">:</span> <span class="k">return</span> <span class="n">Process</span><span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="o">=</span><span class="n">inAgentHostNameStr</span><span class="p">,</span><span class="n">inAgentUserNameStr</span><span class="o">=</span><span class="n">inAgentUserNameStr</span><span class="p">,</span><span class="n">inProcessNameWOExeStr</span><span class="o">=</span><span class="n">inProcessNameWOExeStr</span><span class="p">,</span>
<span class="n">inStartPathStr</span><span class="o">=</span><span class="n">inStartPathStr</span><span class="p">,</span><span class="n">inStartCMDStr</span><span class="o">=</span><span class="n">inStartCMDStr</span><span class="p">,</span><span class="n">inStopSafeTimeoutSecFloat</span><span class="o">=</span><span class="n">inStopSafeTimeoutSecFloat</span><span class="p">)</span></div>
<div class="viewcode-block" id="ProcessExists"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessExists">[docs]</a><span class="k">def</span> <span class="nf">ProcessExists</span><span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inProcessNameWOExeStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Check if the Process instance is exists in GSettings by the (inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)</span>
<span class="sd"> :param inAgentHostNameStr: Agent hostname in any case. Required to identify Process</span>
<span class="sd"> :param inAgentUserNameStr: Agent user name in any case. Required to identify Process</span>
<span class="sd"> :param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case</span>
<span class="sd"> :return: True - process exists in gsettings; False - else</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">inAgentUserNameStr</span><span class="o">.</span><span class="n">upper</span><span class="p">(),</span> <span class="n">inProcessNameWOExeStr</span><span class="o">.</span><span class="n">upper</span><span class="p">())</span> <span class="ow">in</span> <span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">GSettingsGet</span><span class="p">()[</span><span class="s2">&quot;ManagersProcessDict&quot;</span><span class="p">]</span></div>
<div class="viewcode-block" id="ProcessGet"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessGet">[docs]</a><span class="k">def</span> <span class="nf">ProcessGet</span><span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inProcessNameWOExeStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Process</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
@ -608,7 +720,7 @@
<span class="k">if</span> <span class="n">lProcess</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="k">return</span> <span class="n">lProcess</span><span class="o">.</span><span class="n">Start</span><span class="p">(</span><span class="n">inIsManualBool</span><span class="o">=</span><span class="n">inIsManualBool</span><span class="p">)</span></div>
<div class="viewcode-block" id="ProcessStopSafe"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStopSafe">[docs]</a><span class="k">def</span> <span class="nf">ProcessStopSafe</span><span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inProcessNameWOExeStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inIsManualBool</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<div class="viewcode-block" id="ProcessStopSafe"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStopSafe">[docs]</a><span class="k">def</span> <span class="nf">ProcessStopSafe</span><span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inProcessNameWOExeStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inIsManualBool</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> <span class="n">inStopSafeTimeoutSecFloat</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Manual/Auto stop safe. Stop safe is the operation which send signal to process to terminate own work (send term signal to process). Managers.Process wait for the mStopSafeTimeoutSecFloat seconds. After that, if process is not terminated - self will StopForce it.</span>
<span class="sd"> Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto</span>
@ -617,6 +729,7 @@
<span class="sd"> :param inAgentUserNameStr: Agent user name in any case. Required to identify Process</span>
<span class="sd"> :param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case</span>
<span class="sd"> :param inIsManualBool: Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation</span>
<span class="sd"> :param inStopSafeTimeoutSecFloat: Default value goes from the instance. You can specify time is second to wait while safe stop. After that program will stop force</span>
<span class="sd"> :return: Process status. See self.mStatusStr.</span>
<span class="sd"> Process instance has the following statuses:</span>
<span class="sd"> - 0_STOPPED</span>
@ -652,6 +765,30 @@
<span class="n">lProcess</span> <span class="o">=</span> <span class="n">ProcessGet</span><span class="p">(</span><span class="n">inAgentHostNameStr</span> <span class="o">=</span> <span class="n">inAgentHostNameStr</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span> <span class="o">=</span> <span class="n">inAgentUserNameStr</span><span class="p">,</span> <span class="n">inProcessNameWOExeStr</span><span class="o">=</span><span class="n">inProcessNameWOExeStr</span><span class="p">)</span>
<span class="k">if</span> <span class="n">lProcess</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="k">return</span> <span class="n">lProcess</span><span class="o">.</span><span class="n">StopForce</span><span class="p">(</span><span class="n">inIsManualBool</span><span class="o">=</span><span class="n">inIsManualBool</span><span class="p">)</span></div>
<div class="viewcode-block" id="ProcessStatusSave"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStatusSave">[docs]</a><span class="k">def</span> <span class="nf">ProcessStatusSave</span><span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inProcessNameWOExeStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Save current status of the process. After that you can restore process activity. Work when orchestrator is restarted. Don&#39;t save &quot;STOP_SAFE&quot; status &gt; &quot;STOPPED&quot;</span>
<span class="sd"> :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lProcess</span> <span class="o">=</span> <span class="n">ProcessGet</span><span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="o">=</span><span class="n">inAgentHostNameStr</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span><span class="o">=</span><span class="n">inAgentUserNameStr</span><span class="p">,</span>
<span class="n">inProcessNameWOExeStr</span><span class="o">=</span><span class="n">inProcessNameWOExeStr</span><span class="p">)</span>
<span class="k">if</span> <span class="n">lProcess</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">lProcess</span><span class="o">.</span><span class="n">StatusSave</span><span class="p">()</span>
<span class="k">return</span> <span class="n">lProcess</span><span class="o">.</span><span class="n">mStatusStr</span></div>
<div class="viewcode-block" id="ProcessStatusRestore"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStatusRestore">[docs]</a><span class="k">def</span> <span class="nf">ProcessStatusRestore</span><span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inProcessNameWOExeStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Execute the StatusCheck, after that restore status to the saved state (see StatusSave). Work when orchestrator is restarted.</span>
<span class="sd"> :return: Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lProcess</span> <span class="o">=</span> <span class="n">ProcessGet</span><span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="o">=</span><span class="n">inAgentHostNameStr</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span><span class="o">=</span><span class="n">inAgentUserNameStr</span><span class="p">,</span>
<span class="n">inProcessNameWOExeStr</span><span class="o">=</span><span class="n">inProcessNameWOExeStr</span><span class="p">)</span>
<span class="k">if</span> <span class="n">lProcess</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">lProcess</span><span class="o">.</span><span class="n">StatusRestore</span><span class="p">()</span>
<span class="k">return</span> <span class="n">lProcess</span><span class="o">.</span><span class="n">mStatusStr</span></div>
<div class="viewcode-block" id="ProcessStatusCheck"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStatusCheck">[docs]</a><span class="k">def</span> <span class="nf">ProcessStatusCheck</span><span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inProcessNameWOExeStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Check if process is alive. The def will save the manual flag is exists.</span>
@ -724,6 +861,21 @@
<span class="n">lProcess</span> <span class="o">=</span> <span class="n">ProcessGet</span><span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="o">=</span><span class="n">inAgentHostNameStr</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span><span class="o">=</span><span class="n">inAgentUserNameStr</span><span class="p">,</span>
<span class="n">inProcessNameWOExeStr</span><span class="o">=</span><span class="n">inProcessNameWOExeStr</span><span class="p">)</span>
<span class="k">if</span> <span class="n">lProcess</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="n">lProcess</span><span class="o">.</span><span class="n">ManualStopListClear</span><span class="p">()</span></div>
<div class="viewcode-block" id="ProcessScheduleStatusCheckEverySeconds"><a class="viewcode-back" href="../../../../Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessScheduleStatusCheckEverySeconds">[docs]</a><span class="k">def</span> <span class="nf">ProcessScheduleStatusCheckEverySeconds</span><span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">inProcessNameWOExeStr</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span><span class="n">inIntervalSecondsInt</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">120</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Run status check every interval in second you specify.</span>
<span class="sd"> :param inAgentHostNameStr: Agent hostname in any case. Required to identify Process</span>
<span class="sd"> :param inAgentUserNameStr: Agent user name in any case. Required to identify Process</span>
<span class="sd"> :param inProcessNameWOExeStr: The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case</span>
<span class="sd"> :param inIntervalSecondsInt: Interval in seconds. Default is 120</span>
<span class="sd"> :return: None</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lProcess</span> <span class="o">=</span> <span class="n">ProcessGet</span><span class="p">(</span><span class="n">inAgentHostNameStr</span><span class="o">=</span><span class="n">inAgentHostNameStr</span><span class="p">,</span> <span class="n">inAgentUserNameStr</span><span class="o">=</span><span class="n">inAgentUserNameStr</span><span class="p">,</span>
<span class="n">inProcessNameWOExeStr</span><span class="o">=</span><span class="n">inProcessNameWOExeStr</span><span class="p">)</span>
<span class="c1"># Check job in threaded way</span>
<span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">OrchestratorScheduleGet</span><span class="p">()</span><span class="o">.</span><span class="n">every</span><span class="p">(</span><span class="n">inIntervalSecondsInt</span><span class="p">)</span><span class="o">.</span><span class="n">seconds</span><span class="o">.</span><span class="n">do</span><span class="p">(</span><span class="n">__Orchestrator__</span><span class="o">.</span><span class="n">OrchestratorThreadStart</span><span class="p">,</span><span class="n">lProcess</span><span class="o">.</span><span class="n">StatusCheck</span><span class="p">)</span></div>
</pre></div>
</div>

@ -188,7 +188,7 @@
<span class="kn">import</span> <span class="nn">pickle</span>
<span class="kn">import</span> <span class="nn">inspect</span>
<span class="kn">import</span> <span class="nn">schedule</span>
<span class="kn">from</span> <span class="nn">partd</span> <span class="kn">import</span> <span class="n">Server</span>
<span class="c1">#from partd import Server</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">Server</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">Timer</span>
@ -310,7 +310,7 @@
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;__Orchestrator__.AgentActivityItemReturnGet !ATTENTION! Use this function only after Orchestrator initialization! Before orchestrator init exception will be raised.&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="AgentOSCMD"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSCMD">[docs]</a><span class="k">def</span> <span class="nf">AgentOSCMD</span><span class="p">(</span><span class="n">inHostNameStr</span><span class="p">,</span> <span class="n">inUserStr</span><span class="p">,</span> <span class="n">inCMDStr</span><span class="p">,</span> <span class="n">inRunAsyncBool</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">inSendOutputToOrchestratorLogsBool</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">inCMDEncodingStr</span><span class="o">=</span><span class="s2">&quot;cp1251&quot;</span><span class="p">,</span> <span class="n">inGSettings</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<div class="viewcode-block" id="AgentOSCMD"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSCMD">[docs]</a><span class="k">def</span> <span class="nf">AgentOSCMD</span><span class="p">(</span><span class="n">inHostNameStr</span><span class="p">,</span> <span class="n">inUserStr</span><span class="p">,</span> <span class="n">inCMDStr</span><span class="p">,</span> <span class="n">inRunAsyncBool</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">inSendOutputToOrchestratorLogsBool</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">inCMDEncodingStr</span><span class="o">=</span><span class="s2">&quot;cp1251&quot;</span><span class="p">,</span> <span class="n">inGSettings</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inCaptureBool</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Send CMD to OS thought the pyOpenRPA.Agent daemon. Result return to log + Orchestrator by the A2O connection</span>
@ -321,13 +321,14 @@
<span class="sd"> :param inRunAsyncBool: True - Agent processor don&#39;t wait execution; False - Agent processor wait cmd execution</span>
<span class="sd"> :param inSendOutputToOrchestratorLogsBool: True - catch cmd execution output and send it to the Orchestrator logs; Flase - else case; Default True</span>
<span class="sd"> :param inCMDEncodingStr: Set the encoding of the DOS window on the Agent server session. Windows is beautiful :) . Default is &quot;cp1251&quot; early was &quot;cp866&quot; - need test</span>
<span class="sd"> :param inCaptureBool: !ATTENTION! If you need to start absolutely encapsulated app - set this flag as False. If you set True - the app output will come to Agent</span>
<span class="sd"> :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid!</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">inGSettings</span> <span class="o">=</span> <span class="n">GSettingsGet</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">)</span> <span class="c1"># Set the global settings</span>
<span class="n">lActivityItemDict</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;Def&quot;</span><span class="p">:</span><span class="s2">&quot;OSCMD&quot;</span><span class="p">,</span> <span class="c1"># def alias (look pyOpeRPA.Agent gSettings[&quot;ProcessorDict&quot;][&quot;AliasDefDict&quot;])</span>
<span class="s2">&quot;ArgList&quot;</span><span class="p">:[],</span> <span class="c1"># Args list</span>
<span class="s2">&quot;ArgDict&quot;</span><span class="p">:{</span><span class="s2">&quot;inCMDStr&quot;</span><span class="p">:</span><span class="n">inCMDStr</span><span class="p">,</span><span class="s2">&quot;inRunAsyncBool&quot;</span><span class="p">:</span><span class="n">inRunAsyncBool</span><span class="p">,</span> <span class="s2">&quot;inSendOutputToOrchestratorLogsBool&quot;</span><span class="p">:</span> <span class="n">inSendOutputToOrchestratorLogsBool</span><span class="p">,</span> <span class="s2">&quot;inCMDEncodingStr&quot;</span><span class="p">:</span> <span class="n">inCMDEncodingStr</span><span class="p">},</span> <span class="c1"># Args dictionary</span>
<span class="s2">&quot;ArgDict&quot;</span><span class="p">:{</span><span class="s2">&quot;inCMDStr&quot;</span><span class="p">:</span><span class="n">inCMDStr</span><span class="p">,</span><span class="s2">&quot;inRunAsyncBool&quot;</span><span class="p">:</span><span class="n">inRunAsyncBool</span><span class="p">,</span> <span class="s2">&quot;inSendOutputToOrchestratorLogsBool&quot;</span><span class="p">:</span> <span class="n">inSendOutputToOrchestratorLogsBool</span><span class="p">,</span> <span class="s2">&quot;inCMDEncodingStr&quot;</span><span class="p">:</span> <span class="n">inCMDEncodingStr</span><span class="p">,</span> <span class="s2">&quot;inCaptureBool&quot;</span><span class="p">:</span><span class="n">inCaptureBool</span><span class="p">},</span> <span class="c1"># Args dictionary</span>
<span class="s2">&quot;ArgGSettings&quot;</span><span class="p">:</span> <span class="s2">&quot;inGSettings&quot;</span><span class="p">,</span> <span class="c1"># Name of GSettings attribute: str (ArgDict) or index (for ArgList)</span>
<span class="s2">&quot;ArgLogger&quot;</span><span class="p">:</span> <span class="kc">None</span> <span class="c1"># Name of GSettings attribute: str (ArgDict) or index (for ArgList)</span>
<span class="p">}</span>
@ -533,6 +534,45 @@
<span class="c1">#Send item in AgentDict for the futher data transmition</span>
<span class="k">return</span> <span class="n">AgentActivityItemAdd</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">,</span> <span class="n">inHostNameStr</span><span class="o">=</span><span class="n">inHostNameStr</span><span class="p">,</span> <span class="n">inUserStr</span><span class="o">=</span><span class="n">inUserStr</span><span class="p">,</span> <span class="n">inActivityItemDict</span><span class="o">=</span><span class="n">lActivityItemDict</span><span class="p">)</span></div>
<div class="viewcode-block" id="AgentOSFileBinaryDataReceive"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileBinaryDataReceive">[docs]</a><span class="k">def</span> <span class="nf">AgentOSFileBinaryDataReceive</span><span class="p">(</span><span class="n">inHostNameStr</span><span class="p">,</span> <span class="n">inUserStr</span><span class="p">,</span> <span class="n">inFilePathStr</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Read binary file from agent (synchronious)</span>
<span class="sd"> :param inGSettings: Global settings dict (singleton)</span>
<span class="sd"> :param inHostNameStr:</span>
<span class="sd"> :param inUserStr:</span>
<span class="sd"> :param inFilePathStr: File path to read</span>
<span class="sd"> :return: file data bytes</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lFileDataBytes</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">inGSettings</span> <span class="o">=</span> <span class="n">GSettingsGet</span><span class="p">()</span> <span class="c1"># Set the global settings</span>
<span class="c1"># Check thread</span>
<span class="k">if</span> <span class="n">OrchestratorIsInited</span><span class="p">()</span> <span class="o">==</span> <span class="kc">False</span><span class="p">:</span>
<span class="k">if</span> <span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;Logger&quot;</span><span class="p">]:</span> <span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;Logger&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;AgentOSFileBinaryDataReceive run before orc init - activity will be append in the processor queue.&quot;</span><span class="p">)</span>
<span class="n">lResult</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;Def&quot;</span><span class="p">:</span> <span class="n">AgentOSFileBinaryDataReceive</span><span class="p">,</span> <span class="c1"># def link or def alias (look gSettings[&quot;Processor&quot;][&quot;AliasDefDict&quot;])</span>
<span class="s2">&quot;ArgList&quot;</span><span class="p">:</span> <span class="p">[],</span> <span class="c1"># Args list</span>
<span class="s2">&quot;ArgDict&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;inHostNameStr&quot;</span><span class="p">:</span><span class="n">inHostNameStr</span><span class="p">,</span> <span class="s2">&quot;inUserStr&quot;</span><span class="p">:</span><span class="n">inUserStr</span><span class="p">,</span> <span class="s2">&quot;inFilePathStr&quot;</span><span class="p">:</span><span class="n">inFilePathStr</span><span class="p">},</span> <span class="c1"># Args dictionary</span>
<span class="s2">&quot;ArgGSettings&quot;</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># Name of GSettings attribute: str (ArgDict) or index (for ArgList)</span>
<span class="s2">&quot;ArgLogger&quot;</span><span class="p">:</span> <span class="kc">None</span> <span class="c1"># Name of GSettings attribute: str (ArgDict) or index (for ArgList)</span>
<span class="p">}</span>
<span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;ProcessorDict&quot;</span><span class="p">][</span><span class="s2">&quot;ActivityList&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">lResult</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span> <span class="c1"># In processor - do execution</span>
<span class="n">lActivityItemDict</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;Def&quot;</span><span class="p">:</span><span class="s2">&quot;OSFileBinaryDataBase64StrReceive&quot;</span><span class="p">,</span> <span class="c1"># def alias (look pyOpeRPA.Agent gSettings[&quot;ProcessorDict&quot;][&quot;AliasDefDict&quot;])</span>
<span class="s2">&quot;ArgList&quot;</span><span class="p">:[],</span> <span class="c1"># Args list</span>
<span class="s2">&quot;ArgDict&quot;</span><span class="p">:{</span><span class="s2">&quot;inFilePathStr&quot;</span><span class="p">:</span><span class="n">inFilePathStr</span><span class="p">},</span> <span class="c1"># Args dictionary</span>
<span class="s2">&quot;ArgGSettings&quot;</span><span class="p">:</span> <span class="s2">&quot;inGSettings&quot;</span><span class="p">,</span> <span class="c1"># Name of GSettings attribute: str (ArgDict) or index (for ArgList)</span>
<span class="s2">&quot;ArgLogger&quot;</span><span class="p">:</span> <span class="kc">None</span> <span class="c1"># Name of GSettings attribute: str (ArgDict) or index (for ArgList)</span>
<span class="p">}</span>
<span class="c1">#Send item in AgentDict for the futher data transmition</span>
<span class="n">lGUIDStr</span> <span class="o">=</span> <span class="n">AgentActivityItemAdd</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">,</span> <span class="n">inHostNameStr</span><span class="o">=</span><span class="n">inHostNameStr</span><span class="p">,</span> <span class="n">inUserStr</span><span class="o">=</span><span class="n">inUserStr</span><span class="p">,</span> <span class="n">inActivityItemDict</span><span class="o">=</span><span class="n">lActivityItemDict</span><span class="p">)</span>
<span class="n">lFileBase64Str</span> <span class="o">=</span> <span class="n">AgentActivityItemReturnGet</span><span class="p">(</span><span class="n">inGUIDStr</span><span class="o">=</span><span class="n">lGUIDStr</span><span class="p">)</span>
<span class="k">if</span> <span class="n">lFileBase64Str</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="n">lFileDataBytes</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">b64decode</span><span class="p">(</span><span class="n">lFileBase64Str</span><span class="p">)</span>
<span class="k">return</span> <span class="n">lFileDataBytes</span></div>
<div class="viewcode-block" id="AgentOSFileTextDataStrReceive"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileTextDataStrReceive">[docs]</a><span class="k">def</span> <span class="nf">AgentOSFileTextDataStrReceive</span><span class="p">(</span><span class="n">inHostNameStr</span><span class="p">,</span> <span class="n">inUserStr</span><span class="p">,</span> <span class="n">inFilePathStr</span><span class="p">,</span> <span class="n">inEncodingStr</span><span class="o">=</span><span class="s2">&quot;utf-8&quot;</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Read text file in the agent GUI session</span>
@ -629,6 +669,9 @@
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">inLogger</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">inLogger</span> <span class="o">=</span> <span class="n">OrchestratorLoggerGet</span><span class="p">()</span>
<span class="n">lResultStr</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="c1"># New feature</span>
<span class="k">if</span> <span class="n">inRunAsyncBool</span> <span class="o">==</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">inCMDStr</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;start </span><span class="si">{</span><span class="n">inCMDStr</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="c1"># Subdef to listen OS result</span>
<span class="k">def</span> <span class="nf">_CMDRunAndListenLogs</span><span class="p">(</span><span class="n">inCMDStr</span><span class="p">,</span> <span class="n">inLogger</span><span class="p">):</span>
<span class="n">lResultStr</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
@ -675,7 +718,7 @@
<span class="n">os</span><span class="o">.</span><span class="n">execl</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">executable</span><span class="p">,</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="vm">__file__</span><span class="p">),</span> <span class="o">*</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span></div>
<div class="viewcode-block" id="OrchestratorLoggerGet"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorLoggerGet">[docs]</a><span class="k">def</span> <span class="nf">OrchestratorLoggerGet</span><span class="p">():</span>
<div class="viewcode-block" id="OrchestratorLoggerGet"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorLoggerGet">[docs]</a><span class="k">def</span> <span class="nf">OrchestratorLoggerGet</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">logging</span><span class="o">.</span><span class="n">Logger</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get the logger from the Orchestrator</span>
@ -683,6 +726,7 @@
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">GSettingsGet</span><span class="p">()</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Logger&quot;</span><span class="p">,</span><span class="kc">None</span><span class="p">)</span></div>
<div class="viewcode-block" id="OrchestratorScheduleGet"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorScheduleGet">[docs]</a><span class="k">def</span> <span class="nf">OrchestratorScheduleGet</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">schedule</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get the schedule (schedule.readthedocs.io) from the Orchestrator</span>
@ -726,6 +770,24 @@
<span class="k">except</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span></div>
<div class="viewcode-block" id="OrchestratorIsInited"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorIsInited">[docs]</a><span class="k">def</span> <span class="nf">OrchestratorIsInited</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Check if Orchestrator initial actions were processed</span>
<span class="sd"> :return: True - orc is already inited; False - else</span>
<span class="sd"> :rtype: bool</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">Core</span><span class="o">.</span><span class="n">IsOrchestratorInitialized</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">GSettingsGet</span><span class="p">())</span></div>
<div class="viewcode-block" id="OrchestratorInitWait"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorInitWait">[docs]</a><span class="k">def</span> <span class="nf">OrchestratorInitWait</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Wait thread while orc will process initial action. </span>
<span class="sd"> ATTENTION: DO NOT CALL THIS DEF IN THREAD WHERE ORCHESTRATOR MUST BE INITIALIZED - INFINITE LOOP</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lIntervalSecFloat</span> <span class="o">=</span> <span class="mf">0.5</span>
<span class="k">while</span> <span class="ow">not</span> <span class="n">OrchestratorIsInited</span><span class="p">():</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="n">lIntervalSecFloat</span><span class="p">)</span></div>
<div class="viewcode-block" id="OrchestratorRerunAsAdmin"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorRerunAsAdmin">[docs]</a><span class="k">def</span> <span class="nf">OrchestratorRerunAsAdmin</span><span class="p">():</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Check if not admin - then rerun orchestrator as administrator</span>
@ -738,10 +800,10 @@
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;!SKIPPED! Already run as administrator!&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="OrchestratorPySearchInit"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorPySearchInit">[docs]</a><span class="k">def</span> <span class="nf">OrchestratorPySearchInit</span><span class="p">(</span><span class="n">inGlobPatternStr</span><span class="p">,</span> <span class="n">inDefStr</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">inDefArgNameGSettingsStr</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
<div class="viewcode-block" id="OrchestratorPySearchInit"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorPySearchInit">[docs]</a><span class="k">def</span> <span class="nf">OrchestratorPySearchInit</span><span class="p">(</span><span class="n">inGlobPatternStr</span><span class="p">,</span> <span class="n">inDefStr</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">inDefArgNameGSettingsStr</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">inAsyncInitBool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Search the py files by the glob and do the safe init (in try except). Also add inited module in sys.modules as imported (module name = file name without extension).</span>
<span class="sd"> You can init CP in async way!</span>
<span class="sd"> .. code-block:: python</span>
<span class="sd"> # USAGE VAR 1 (without the def auto call)</span>
@ -765,14 +827,14 @@
<span class="sd"> :param inGlobPatternStr: example&quot;..\\*\\*\\*X64*.cmd&quot;</span>
<span class="sd"> :param inDefStr: OPTIONAL The string name of the def. For backward compatibility if you need to auto call some def from initialized module</span>
<span class="sd"> :param inDefArgNameGSettingsStr: OPTIONAL The name of the GSettings argument in def (if exists)</span>
<span class="sd"> :param inAsyncInitBool: OPTIONAL True - init py modules in many threads - parallel execution. False (default) - sequence execution</span>
<span class="sd"> :return: { &quot;ModuleNameStr&quot;:{&quot;PyPathStr&quot;: &quot;&quot;, &quot;Module&quot;: ...}, ...}</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lResultDict</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">lPyPathStrList</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="n">inGlobPatternStr</span><span class="p">)</span> <span class="c1"># get the file list</span>
<span class="n">lL</span> <span class="o">=</span> <span class="n">OrchestratorLoggerGet</span><span class="p">()</span> <span class="c1"># get the logger</span>
<span class="k">for</span> <span class="n">lPyPathItemStr</span> <span class="ow">in</span> <span class="n">lPyPathStrList</span><span class="p">:</span>
<span class="c1"># # # # # # # #</span>
<span class="k">def</span> <span class="nf">__execute__</span><span class="p">(</span><span class="n">inResultDict</span><span class="p">,</span> <span class="n">inPyPathItemStr</span><span class="p">,</span> <span class="n">inDefStr</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">inDefArgNameGSettingsStr</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">lPyPathItemStr</span> <span class="o">=</span> <span class="n">inPyPathItemStr</span>
<span class="n">lModuleNameStr</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">lPyPathItemStr</span><span class="p">)[</span><span class="mi">0</span><span class="p">:</span><span class="o">-</span><span class="mi">3</span><span class="p">]</span>
<span class="n">lTechSpecification</span> <span class="o">=</span> <span class="n">importlib</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">spec_from_file_location</span><span class="p">(</span><span class="n">lModuleNameStr</span><span class="p">,</span> <span class="n">lPyPathItemStr</span><span class="p">)</span>
<span class="n">lTechModuleFromSpec</span> <span class="o">=</span> <span class="n">importlib</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">module_from_spec</span><span class="p">(</span><span class="n">lTechSpecification</span><span class="p">)</span>
@ -780,7 +842,7 @@
<span class="n">lTechSpecificationModuleLoader</span> <span class="o">=</span> <span class="n">lTechSpecification</span><span class="o">.</span><span class="n">loader</span><span class="o">.</span><span class="n">exec_module</span><span class="p">(</span><span class="n">lTechModuleFromSpec</span><span class="p">)</span>
<span class="n">lItemDict</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;ModuleNameStr&quot;</span><span class="p">:</span> <span class="n">lModuleNameStr</span><span class="p">,</span> <span class="s2">&quot;PyPathStr&quot;</span><span class="p">:</span> <span class="n">lPyPathItemStr</span><span class="p">,</span> <span class="s2">&quot;Module&quot;</span><span class="p">:</span> <span class="n">lTechModuleFromSpec</span><span class="p">}</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Py module </span><span class="si">{</span><span class="n">lModuleNameStr</span><span class="si">}</span><span class="s2"> has been successfully initialized.&quot;</span><span class="p">)</span>
<span class="n">lResultDict</span><span class="p">[</span><span class="n">lModuleNameStr</span><span class="p">]</span><span class="o">=</span><span class="n">lItemDict</span>
<span class="n">inResultDict</span><span class="p">[</span><span class="n">lModuleNameStr</span><span class="p">]</span><span class="o">=</span><span class="n">lItemDict</span>
<span class="c1"># Backward compatibility to call def with gsettings when init</span>
<span class="k">if</span> <span class="n">inDefStr</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">inDefStr</span> <span class="ow">is</span> <span class="ow">not</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
<span class="n">lDef</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">lTechModuleFromSpec</span><span class="p">,</span> <span class="n">inDefStr</span><span class="p">)</span>
@ -790,11 +852,31 @@
<span class="n">lDef</span><span class="p">(</span><span class="o">**</span><span class="n">lArgDict</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">exception</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Exception when init the .py file </span><span class="si">{</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">lPyPathItemStr</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="c1"># # # # # # # #</span>
<span class="n">lResultDict</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">lPyPathStrList</span> <span class="o">=</span> <span class="n">glob</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="n">inGlobPatternStr</span><span class="p">)</span> <span class="c1"># get the file list</span>
<span class="n">lL</span> <span class="o">=</span> <span class="n">OrchestratorLoggerGet</span><span class="p">()</span> <span class="c1"># get the logger</span>
<span class="k">for</span> <span class="n">lPyPathItemStr</span> <span class="ow">in</span> <span class="n">lPyPathStrList</span><span class="p">:</span>
<span class="k">if</span> <span class="n">inAsyncInitBool</span> <span class="o">==</span> <span class="kc">True</span><span class="p">:</span>
<span class="c1"># ASYNC EXECUTION</span>
<span class="n">lThreadInit</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">__execute__</span><span class="p">,</span><span class="n">kwargs</span><span class="o">=</span><span class="p">{</span>
<span class="s2">&quot;inResultDict&quot;</span><span class="p">:</span><span class="n">lResultDict</span><span class="p">,</span> <span class="s2">&quot;inPyPathItemStr&quot;</span><span class="p">:</span> <span class="n">lPyPathItemStr</span><span class="p">,</span>
<span class="s2">&quot;inDefStr&quot;</span><span class="p">:</span> <span class="n">inDefStr</span><span class="p">,</span> <span class="s2">&quot;inDefArgNameGSettingsStr&quot;</span><span class="p">:</span> <span class="n">inDefArgNameGSettingsStr</span><span class="p">},</span> <span class="n">daemon</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="n">lThreadInit</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># SYNC EXECUTION</span>
<span class="n">__execute__</span><span class="p">(</span><span class="n">inResultDict</span><span class="o">=</span><span class="n">lResultDict</span><span class="p">,</span> <span class="n">inPyPathItemStr</span><span class="o">=</span><span class="n">lPyPathItemStr</span><span class="p">,</span> <span class="n">inDefStr</span> <span class="o">=</span> <span class="n">inDefStr</span><span class="p">,</span> <span class="n">inDefArgNameGSettingsStr</span> <span class="o">=</span> <span class="n">inDefArgNameGSettingsStr</span><span class="p">)</span>
<span class="k">return</span> <span class="n">lResultDict</span></div>
<div class="viewcode-block" id="OrchestratorSessionSave"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionSave">[docs]</a><span class="k">def</span> <span class="nf">OrchestratorSessionSave</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Orchestrator session save in file</span>
<span class="sd"> (from version 1.2.7)</span>
<span class="sd"> _SessionLast_GSettings.pickle (binary)</span>
<span class="sd"> (above the version 1.2.7)</span>
<span class="sd"> _SessionLast_RDPList.json (encoding = &quot;utf-8&quot;)</span>
<span class="sd"> _SessionLast_StorageDict.pickle (binary)</span>
@ -805,26 +887,38 @@
<span class="n">lL</span> <span class="o">=</span> <span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;Logger&quot;</span><span class="p">]</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># Dump RDP List in file json</span>
<span class="n">lFile</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s2">&quot;_SessionLast_RDPList.json&quot;</span><span class="p">,</span> <span class="s2">&quot;w&quot;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s2">&quot;utf-8&quot;</span><span class="p">)</span>
<span class="n">lFile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;RobotRDPActive&quot;</span><span class="p">][</span><span class="s2">&quot;RDPList&quot;</span><span class="p">]))</span> <span class="c1"># dump json to file</span>
<span class="n">lFile</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> <span class="c1"># Close the file</span>
<span class="k">if</span> <span class="n">inGSettings</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;Orchestrator has dump the RDP list before the restart.&quot;</span><span class="p">)</span>
<span class="c1"># _SessionLast_StorageDict.pickle (binary)</span>
<span class="k">if</span> <span class="s2">&quot;StorageDict&quot;</span> <span class="ow">in</span> <span class="n">inGSettings</span><span class="p">:</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">&#39;_SessionLast_StorageDict.pickle&#39;</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">lFile</span><span class="p">:</span>
<span class="n">pickle</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;StorageDict&quot;</span><span class="p">],</span> <span class="n">lFile</span><span class="p">)</span>
<span class="c1">#lFile = open(&quot;_SessionLast_RDPList.json&quot;, &quot;w&quot;, encoding=&quot;utf-8&quot;)</span>
<span class="c1">#lFile.write(json.dumps(inGSettings[&quot;RobotRDPActive&quot;][&quot;RDPList&quot;])) # dump json to file</span>
<span class="c1">#lFile.close() # Close the file</span>
<span class="c1">#if inGSettings is not None:</span>
<span class="c1"># if lL: lL.info(</span>
<span class="c1"># f&quot;Orchestrator has dump the RDP list before the restart.&quot;)</span>
<span class="c1">## _SessionLast_StorageDict.pickle (binary)</span>
<span class="c1">#if &quot;StorageDict&quot; in inGSettings:</span>
<span class="c1"># with open(&#39;_SessionLast_StorageDict.pickle&#39;, &#39;wb&#39;) as lFile:</span>
<span class="c1"># pickle.dump(inGSettings[&quot;StorageDict&quot;], lFile)</span>
<span class="c1"># if lL: lL.info(</span>
<span class="c1"># f&quot;Orchestrator has dump the StorageDict before the restart.&quot;)</span>
<span class="c1">#SessionLast</span>
<span class="n">lDumpDict</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;StorageDict&quot;</span><span class="p">:</span><span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;StorageDict&quot;</span><span class="p">],</span> <span class="s2">&quot;ManagersProcessDict&quot;</span><span class="p">:</span><span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;ManagersProcessDict&quot;</span><span class="p">],</span>
<span class="s2">&quot;RobotRDPActive&quot;</span><span class="p">:{</span><span class="s2">&quot;RDPList&quot;</span><span class="p">:</span> <span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;RobotRDPActive&quot;</span><span class="p">][</span><span class="s2">&quot;RDPList&quot;</span><span class="p">]}}</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">&#39;_SessionLast_GSettings.pickle&#39;</span><span class="p">,</span> <span class="s1">&#39;wb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">lFile</span><span class="p">:</span>
<span class="n">pickle</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">lDumpDict</span><span class="p">,</span> <span class="n">lFile</span><span class="p">)</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;Orchestrator has dump the StorageDict before the restart.&quot;</span><span class="p">)</span>
<span class="sa">f</span><span class="s2">&quot;Orchestrator has dump the GSettings (new dump mode from v1.2.7) before the restart.&quot;</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">exception</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Exception when dump data before restart the Orchestrator&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span></div>
<div class="viewcode-block" id="OrchestratorSessionRestore"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionRestore">[docs]</a><span class="k">def</span> <span class="nf">OrchestratorSessionRestore</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Check _SessionLast_RDPList.json and _SessionLast_StorageDict.pickle in working directory. if exist - load into gsettings</span>
<span class="sd"> # _SessionLast_StorageDict.pickle (binary)</span>
<span class="sd"> Check _SessioLast... files in working directory. if exist - load into gsettings</span>
<span class="sd"> (from version 1.2.7)</span>
<span class="sd"> _SessionLast_GSettings.pickle (binary)</span>
<span class="sd"> (above the version 1.2.7)</span>
<span class="sd"> _SessionLast_RDPList.json (encoding = &quot;utf-8&quot;)</span>
<span class="sd"> _SessionLast_StorageDict.pickle (binary)</span>
@ -850,7 +944,19 @@
<span class="n">Server</span><span class="o">.</span><span class="n">__ComplexDictMerge2to1Overwrite__</span><span class="p">(</span><span class="n">in1Dict</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;StorageDict&quot;</span><span class="p">],</span>
<span class="n">in2Dict</span><span class="o">=</span><span class="n">lStorageDictDumpDict</span><span class="p">)</span> <span class="c1"># Merge dict 2 into dict 1</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;StorageDict was restored from previous Orchestrator session&quot;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="s2">&quot;_SessionLast_StorageDict.pickle&quot;</span><span class="p">)</span> <span class="c1"># remove the temp file</span></div>
<span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="s2">&quot;_SessionLast_StorageDict.pickle&quot;</span><span class="p">)</span> <span class="c1"># remove the temp file</span>
<span class="c1"># _SessionLast_Gsettings.pickle (binary)</span>
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="s2">&quot;_SessionLast_GSettings.pickle&quot;</span><span class="p">):</span>
<span class="k">if</span> <span class="s2">&quot;StorageDict&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">inGSettings</span><span class="p">:</span>
<span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;StorageDict&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">if</span> <span class="s2">&quot;ManagersProcessDict&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">inGSettings</span><span class="p">:</span>
<span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;ManagersProcessDict&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">&#39;_SessionLast_GSettings.pickle&#39;</span><span class="p">,</span> <span class="s1">&#39;rb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">lFile</span><span class="p">:</span>
<span class="n">lStorageDictDumpDict</span> <span class="o">=</span> <span class="n">pickle</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">lFile</span><span class="p">)</span>
<span class="n">Server</span><span class="o">.</span><span class="n">__ComplexDictMerge2to1Overwrite__</span><span class="p">(</span><span class="n">in1Dict</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">,</span>
<span class="n">in2Dict</span><span class="o">=</span><span class="n">lStorageDictDumpDict</span><span class="p">)</span> <span class="c1"># Merge dict 2 into dict 1</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;GSettings was restored from previous Orchestrator session&quot;</span><span class="p">)</span>
<span class="n">os</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="s2">&quot;_SessionLast_GSettings.pickle&quot;</span><span class="p">)</span> <span class="c1"># remove the temp file</span></div>
<div class="viewcode-block" id="UACKeyListCheck"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.UACKeyListCheck">[docs]</a><span class="k">def</span> <span class="nf">UACKeyListCheck</span><span class="p">(</span><span class="n">inRequest</span><span class="p">,</span> <span class="n">inRoleKeyList</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
@ -926,7 +1032,7 @@
<span class="c1"># # # # # # # # # # # # # # # # # # # # # # #</span>
<div class="viewcode-block" id="WebURLConnectDef"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectDef">[docs]</a><span class="k">def</span> <span class="nf">WebURLConnectDef</span><span class="p">(</span><span class="n">inMethodStr</span><span class="p">,</span> <span class="n">inURLStr</span><span class="p">,</span> <span class="n">inMatchTypeStr</span><span class="p">,</span> <span class="n">inDef</span><span class="p">,</span> <span class="n">inContentTypeStr</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
<div class="viewcode-block" id="WebURLConnectDef"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectDef">[docs]</a><span class="k">def</span> <span class="nf">WebURLConnectDef</span><span class="p">(</span><span class="n">inMethodStr</span><span class="p">,</span> <span class="n">inURLStr</span><span class="p">,</span> <span class="n">inMatchTypeStr</span><span class="p">,</span> <span class="n">inDef</span><span class="p">,</span> <span class="n">inContentTypeStr</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">inUACBool</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Connect URL to DEF</span>
<span class="sd"> &quot;inMethodStr&quot;:&quot;GET|POST&quot;,</span>
@ -936,11 +1042,12 @@
<span class="sd"> &quot;inDef&quot;: None #Function with str result</span>
<span class="sd"> :param inGSettings: Global settings dict (singleton)</span>
<span class="sd"> :param inMethodStr:</span>
<span class="sd"> :param inURLStr:</span>
<span class="sd"> :param inMatchTypeStr:</span>
<span class="sd"> :param inDef:</span>
<span class="sd"> :param inContentTypeStr:</span>
<span class="sd"> :param inMethodStr: &quot;GET|POST&quot;,</span>
<span class="sd"> :param inURLStr: example &quot;/index&quot;, #URL of the request</span>
<span class="sd"> :param inMatchTypeStr: #&quot;BeginWith|Contains|Equal|EqualCase&quot;,</span>
<span class="sd"> :param inDef: def arg allowed list: 2:[inRequest, inGSettings], 1: [inRequest], 0: []</span>
<span class="sd"> :param inContentTypeStr: default: &quot;application/octet-stream&quot;</span>
<span class="sd"> :param inUACBool: default: None; True - check user access before do this URL item. None - get Server flag if ask user</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">inGSettings</span> <span class="o">=</span> <span class="n">GSettingsGet</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">)</span> <span class="c1"># Set the global settings</span>
<span class="n">lURLItemDict</span> <span class="o">=</span> <span class="p">{</span>
@ -951,24 +1058,27 @@
<span class="c1">#&quot;ResponseFolderPath&quot;: &quot;C:\Abs\Archive\scopeSrcUL\OpenRPA\Orchestrator\Settings&quot;,</span>
<span class="c1"># Absolute or relative path</span>
<span class="s2">&quot;ResponseContentType&quot;</span><span class="p">:</span> <span class="n">inContentTypeStr</span><span class="p">,</span> <span class="c1">#HTTP Content-type</span>
<span class="s2">&quot;ResponseDefRequestGlobal&quot;</span><span class="p">:</span> <span class="n">inDef</span> <span class="c1">#Function with str result</span>
<span class="s2">&quot;ResponseDefRequestGlobal&quot;</span><span class="p">:</span> <span class="n">inDef</span><span class="p">,</span> <span class="c1">#Function with str result</span>
<span class="s2">&quot;UACBool&quot;</span><span class="p">:</span> <span class="n">inUACBool</span>
<span class="p">}</span>
<span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;ServerDict&quot;</span><span class="p">][</span><span class="s2">&quot;URLList&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">lURLItemDict</span><span class="p">)</span></div>
<div class="viewcode-block" id="WebURLConnectFolder"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFolder">[docs]</a><span class="k">def</span> <span class="nf">WebURLConnectFolder</span><span class="p">(</span><span class="n">inMethodStr</span><span class="p">,</span> <span class="n">inURLStr</span><span class="p">,</span> <span class="n">inMatchTypeStr</span><span class="p">,</span> <span class="n">inFolderPathStr</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
<div class="viewcode-block" id="WebURLConnectFolder"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFolder">[docs]</a><span class="k">def</span> <span class="nf">WebURLConnectFolder</span><span class="p">(</span><span class="n">inMethodStr</span><span class="p">,</span> <span class="n">inURLStr</span><span class="p">,</span> <span class="n">inMatchTypeStr</span><span class="p">,</span> <span class="n">inFolderPathStr</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">inUACBool</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Connect URL to Folder</span>
<span class="sd"> &quot;inMethodStr&quot;:&quot;GET|POST&quot;,</span>
<span class="sd"> &quot;inURLStr&quot;: &quot;/Folder/&quot;, #URL of the request</span>
<span class="sd"> &quot;inMatchTypeStr&quot;: &quot;&quot;, #&quot;BeginWith|Contains|Equal|EqualCase&quot;,</span>
<span class="sd"> &quot;inFolderPathStr&quot;: &quot;&quot;, #Absolute or relative path</span>
<span class="sd"> &quot;inUACBool&quot;</span>
<span class="sd"> :param inGSettings: Global settings dict (singleton)</span>
<span class="sd"> :param inMethodStr:</span>
<span class="sd"> :param inURLStr:</span>
<span class="sd"> :param inMatchTypeStr:</span>
<span class="sd"> :param inFolderPathStr:</span>
<span class="sd"> :param inUACBool: default: None; True - check user access before do this URL item. None - get Server flag if ask user</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">inGSettings</span> <span class="o">=</span> <span class="n">GSettingsGet</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">)</span> <span class="c1"># Set the global settings</span>
<span class="c1"># Check if last symbol is &quot;/&quot; - append if not exist</span>
@ -983,11 +1093,12 @@
<span class="s2">&quot;ResponseFolderPath&quot;</span><span class="p">:</span> <span class="n">lFolderPathStr</span><span class="p">,</span> <span class="c1"># Absolute or relative path</span>
<span class="s2">&quot;ResponseContentType&quot;</span><span class="p">:</span> <span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span> <span class="c1">#HTTP Content-type</span>
<span class="c1">#&quot;ResponseDefRequestGlobal&quot;: inDef #Function with str result</span>
<span class="s2">&quot;UACBool&quot;</span><span class="p">:</span> <span class="n">inUACBool</span>
<span class="p">}</span>
<span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;ServerDict&quot;</span><span class="p">][</span><span class="s2">&quot;URLList&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">lURLItemDict</span><span class="p">)</span></div>
<div class="viewcode-block" id="WebURLConnectFile"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFile">[docs]</a><span class="k">def</span> <span class="nf">WebURLConnectFile</span><span class="p">(</span><span class="n">inMethodStr</span><span class="p">,</span> <span class="n">inURLStr</span><span class="p">,</span> <span class="n">inMatchTypeStr</span><span class="p">,</span> <span class="n">inFilePathStr</span><span class="p">,</span> <span class="n">inContentTypeStr</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
<div class="viewcode-block" id="WebURLConnectFile"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFile">[docs]</a><span class="k">def</span> <span class="nf">WebURLConnectFile</span><span class="p">(</span><span class="n">inMethodStr</span><span class="p">,</span> <span class="n">inURLStr</span><span class="p">,</span> <span class="n">inMatchTypeStr</span><span class="p">,</span> <span class="n">inFilePathStr</span><span class="p">,</span> <span class="n">inContentTypeStr</span><span class="o">=</span><span class="s2">&quot;application/octet-stream&quot;</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">inUACBool</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Connect URL to File</span>
<span class="sd"> &quot;inMethodStr&quot;:&quot;GET|POST&quot;,</span>
@ -1001,6 +1112,7 @@
<span class="sd"> :param inMatchTypeStr:</span>
<span class="sd"> :param inFilePathStr:</span>
<span class="sd"> :param inContentTypeStr:</span>
<span class="sd"> :param inUACBool: default: None; True - check user access before do this URL item. None - get Server flag if ask user</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">inGSettings</span> <span class="o">=</span> <span class="n">GSettingsGet</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">)</span> <span class="c1"># Set the global settings</span>
<span class="n">lURLItemDict</span> <span class="o">=</span> <span class="p">{</span>
@ -1011,6 +1123,7 @@
<span class="c1">#&quot;ResponseFolderPath&quot;: os.path.abspath(inFilePathStr), # Absolute or relative path</span>
<span class="s2">&quot;ResponseContentType&quot;</span><span class="p">:</span> <span class="n">inContentTypeStr</span><span class="p">,</span> <span class="c1">#HTTP Content-type</span>
<span class="c1">#&quot;ResponseDefRequestGlobal&quot;: inDef #Function with str result</span>
<span class="s2">&quot;UACBool&quot;</span><span class="p">:</span><span class="n">inUACBool</span>
<span class="p">}</span>
<span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;ServerDict&quot;</span><span class="p">][</span><span class="s2">&quot;URLList&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">lURLItemDict</span><span class="p">)</span></div>
@ -1054,7 +1167,7 @@
<span class="k">if</span> <span class="n">inJSInitGeneratorDef</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span> <span class="n">lCPManager</span><span class="o">.</span><span class="n">mBackwardCompatibilityJSDef</span> <span class="o">=</span> <span class="n">inJSInitGeneratorDef</span></div>
<div class="viewcode-block" id="WebAuditMessageCreate"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebAuditMessageCreate">[docs]</a><span class="k">def</span> <span class="nf">WebAuditMessageCreate</span><span class="p">(</span><span class="n">inRequest</span><span class="p">,</span> <span class="n">inOperationCodeStr</span><span class="o">=</span><span class="s2">&quot;-&quot;</span><span class="p">,</span> <span class="n">inMessageStr</span><span class="o">=</span><span class="s2">&quot;-&quot;</span><span class="p">):</span>
<div class="viewcode-block" id="WebAuditMessageCreate"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebAuditMessageCreate">[docs]</a><span class="k">def</span> <span class="nf">WebAuditMessageCreate</span><span class="p">(</span><span class="n">inRequest</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inOperationCodeStr</span><span class="o">=</span><span class="s2">&quot;-&quot;</span><span class="p">,</span> <span class="n">inMessageStr</span><span class="o">=</span><span class="s2">&quot;-&quot;</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Create message string with request user details (IP, Login etc...). Very actual for IT security in big company.</span>
@ -1071,12 +1184,13 @@
<span class="sd"> # Log the WebAudit message</span>
<span class="sd"> lLogger.info(lWebAuditMessageStr)</span>
<span class="sd"> :param inRequest: HTTP request handler</span>
<span class="sd"> :param inRequest: HTTP request handler. Optional if call def from request thread</span>
<span class="sd"> :param inOperationCodeStr: operation code in string format (actual for IT audit in control panels)</span>
<span class="sd"> :param inMessageStr: additional message after</span>
<span class="sd"> :return: format &quot;WebAudit :: DOMAIN\\USER@101.121.123.12 :: operation code :: message&quot;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="n">inRequest</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">inRequest</span> <span class="o">=</span> <span class="n">WebRequestGet</span><span class="p">()</span>
<span class="n">lClientIPStr</span> <span class="o">=</span> <span class="n">inRequest</span><span class="o">.</span><span class="n">client_address</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">lUserDict</span> <span class="o">=</span> <span class="n">WebUserInfoGet</span><span class="p">(</span><span class="n">inRequest</span><span class="o">=</span><span class="n">inRequest</span><span class="p">)</span>
<span class="n">lDomainUpperStr</span> <span class="o">=</span> <span class="n">lUserDict</span><span class="p">[</span><span class="s2">&quot;DomainUpperStr&quot;</span><span class="p">]</span>
@ -1087,54 +1201,58 @@
<span class="n">lResultStr</span> <span class="o">=</span> <span class="n">inMessageStr</span>
<span class="k">return</span> <span class="n">lResultStr</span></div>
<div class="viewcode-block" id="WebRequestParseBodyBytes"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyBytes">[docs]</a><span class="k">def</span> <span class="nf">WebRequestParseBodyBytes</span><span class="p">(</span><span class="n">inRequest</span><span class="p">):</span>
<div class="viewcode-block" id="WebRequestParseBodyBytes"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyBytes">[docs]</a><span class="k">def</span> <span class="nf">WebRequestParseBodyBytes</span><span class="p">(</span><span class="n">inRequest</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Extract the body in bytes from the request</span>
<span class="sd"> :param inRequest: inRequest from the server</span>
<span class="sd"> :param inRequest: inRequest from the server. Optional if call def from request thread</span>
<span class="sd"> :return: Bytes or None</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">inRequest</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">inRequest</span> <span class="o">=</span> <span class="n">WebRequestGet</span><span class="p">()</span>
<span class="n">lBodyBytes</span><span class="o">=</span><span class="kc">None</span>
<span class="k">if</span> <span class="n">inRequest</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;Content-Length&#39;</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">lInputByteArrayLength</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">inRequest</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;Content-Length&#39;</span><span class="p">))</span>
<span class="n">lBodyBytes</span> <span class="o">=</span> <span class="n">inRequest</span><span class="o">.</span><span class="n">rfile</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">lInputByteArrayLength</span><span class="p">)</span>
<span class="k">return</span> <span class="n">lBodyBytes</span></div>
<div class="viewcode-block" id="WebRequestParseBodyStr"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyStr">[docs]</a><span class="k">def</span> <span class="nf">WebRequestParseBodyStr</span><span class="p">(</span><span class="n">inRequest</span><span class="p">):</span>
<div class="viewcode-block" id="WebRequestParseBodyStr"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyStr">[docs]</a><span class="k">def</span> <span class="nf">WebRequestParseBodyStr</span><span class="p">(</span><span class="n">inRequest</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Extract the body in str from the request</span>
<span class="sd"> :param inRequest: inRequest from the server</span>
<span class="sd"> :param inRequest: inRequest from the server. Optional if call def from request thread</span>
<span class="sd"> :return: str or None</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">inRequest</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">inRequest</span> <span class="o">=</span> <span class="n">WebRequestGet</span><span class="p">()</span>
<span class="k">return</span> <span class="n">WebRequestParseBodyBytes</span><span class="p">(</span><span class="n">inRequest</span><span class="o">=</span><span class="n">inRequest</span><span class="p">)</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;utf-8&#39;</span><span class="p">)</span></div>
<div class="viewcode-block" id="WebRequestParseBodyJSON"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyJSON">[docs]</a><span class="k">def</span> <span class="nf">WebRequestParseBodyJSON</span><span class="p">(</span><span class="n">inRequest</span><span class="p">):</span>
<div class="viewcode-block" id="WebRequestParseBodyJSON"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyJSON">[docs]</a><span class="k">def</span> <span class="nf">WebRequestParseBodyJSON</span><span class="p">(</span><span class="n">inRequest</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Extract the body in dict/list from the request</span>
<span class="sd"> :param inRequest:</span>
<span class="sd"> :param inRequest: inRequest from the server. Optional if call def from request thread</span>
<span class="sd"> :return: dict or list</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">inRequest</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">inRequest</span> <span class="o">=</span> <span class="n">WebRequestGet</span><span class="p">()</span>
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">WebRequestParseBodyStr</span><span class="p">(</span><span class="n">inRequest</span><span class="o">=</span><span class="n">inRequest</span><span class="p">))</span></div>
<div class="viewcode-block" id="WebRequestParsePath"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParsePath">[docs]</a><span class="k">def</span> <span class="nf">WebRequestParsePath</span><span class="p">(</span><span class="n">inRequest</span><span class="p">):</span>
<div class="viewcode-block" id="WebRequestParsePath"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParsePath">[docs]</a><span class="k">def</span> <span class="nf">WebRequestParsePath</span><span class="p">(</span><span class="n">inRequest</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Parse the request - extract the url. Example: /pyOpenRPA/Debugging/DefHelper/...</span>
<span class="sd"> :param inRequest:</span>
<span class="sd"> :param inRequest: inRequest from the server. Optional if call def from request thread</span>
<span class="sd"> :return: Str, Example: /pyOpenRPA/Debugging/DefHelper/...</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">inRequest</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">inRequest</span> <span class="o">=</span> <span class="n">WebRequestGet</span><span class="p">()</span>
<span class="k">return</span> <span class="n">urllib</span><span class="o">.</span><span class="n">parse</span><span class="o">.</span><span class="n">unquote</span><span class="p">(</span><span class="n">inRequest</span><span class="o">.</span><span class="n">path</span><span class="p">)</span></div>
<div class="viewcode-block" id="WebRequestParseFile"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseFile">[docs]</a><span class="k">def</span> <span class="nf">WebRequestParseFile</span><span class="p">(</span><span class="n">inRequest</span><span class="p">):</span>
<div class="viewcode-block" id="WebRequestParseFile"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseFile">[docs]</a><span class="k">def</span> <span class="nf">WebRequestParseFile</span><span class="p">(</span><span class="n">inRequest</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Parse the request - extract the file (name, body in bytes)</span>
<span class="sd"> :param inRequest:</span>
<span class="sd"> :param inRequest: inRequest from the server. Optional if call def from request thread</span>
<span class="sd"> :return: (FileNameStr, FileBodyBytes) or (None, None)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">inRequest</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">inRequest</span> <span class="o">=</span> <span class="n">WebRequestGet</span><span class="p">()</span>
<span class="n">lResultTurple</span><span class="o">=</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span><span class="kc">None</span><span class="p">)</span>
<span class="k">if</span> <span class="n">inRequest</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;Content-Length&#39;</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">lInputByteArray</span> <span class="o">=</span> <span class="n">WebRequestParseBodyBytes</span><span class="p">(</span><span class="n">inRequest</span><span class="o">=</span><span class="n">inRequest</span><span class="p">)</span>
@ -1154,45 +1272,61 @@
<span class="k">return</span> <span class="n">lResultTurple</span></div>
<div class="viewcode-block" id="WebRequestResponseSend"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestResponseSend">[docs]</a><span class="k">def</span> <span class="nf">WebRequestResponseSend</span><span class="p">(</span><span class="n">inRequest</span><span class="p">,</span> <span class="n">inResponeStr</span><span class="p">):</span>
<div class="viewcode-block" id="WebRequestResponseSend"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestResponseSend">[docs]</a><span class="k">def</span> <span class="nf">WebRequestResponseSend</span><span class="p">(</span><span class="n">inResponeStr</span><span class="p">,</span> <span class="n">inRequest</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Send response for the request</span>
<span class="sd"> :param inRequest: inRequest from the server. Optional if call def from request thread</span>
<span class="sd"> :return:</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">inRequest</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">inRequest</span> <span class="o">=</span> <span class="n">WebRequestGet</span><span class="p">()</span>
<span class="n">inRequest</span><span class="o">.</span><span class="n">OpenRPAResponseDict</span><span class="p">[</span><span class="s2">&quot;Body&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">(</span><span class="n">inResponeStr</span><span class="p">,</span> <span class="s2">&quot;utf8&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="WebUserInfoGet"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserInfoGet">[docs]</a><span class="k">def</span> <span class="nf">WebUserInfoGet</span><span class="p">(</span><span class="n">inRequest</span><span class="p">):</span>
<div class="viewcode-block" id="WebRequestGet"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestGet">[docs]</a><span class="k">def</span> <span class="nf">WebRequestGet</span><span class="p">():</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return the web request instance if current thread was created by web request from client. else return None</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lCurrentThread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">current_thread</span><span class="p">()</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">lCurrentThread</span><span class="p">,</span> <span class="s2">&quot;request&quot;</span><span class="p">):</span>
<span class="k">return</span> <span class="n">lCurrentThread</span><span class="o">.</span><span class="n">request</span></div>
<div class="viewcode-block" id="WebUserInfoGet"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserInfoGet">[docs]</a><span class="k">def</span> <span class="nf">WebUserInfoGet</span><span class="p">(</span><span class="n">inRequest</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return User info about request</span>
<span class="sd"> :param inRequest:</span>
<span class="sd"> :param inRequest: inRequest from the server. Optional if call def from request thread</span>
<span class="sd"> :return: {&quot;DomainUpperStr&quot;: &quot;&quot;, &quot;UserNameUpperStr&quot;: &quot;&quot;}</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">inRequest</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">inRequest</span> <span class="o">=</span> <span class="n">WebRequestGet</span><span class="p">()</span>
<span class="n">lDomainUpperStr</span> <span class="o">=</span> <span class="n">inRequest</span><span class="o">.</span><span class="n">OpenRPA</span><span class="p">[</span><span class="s2">&quot;Domain&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span>
<span class="n">lUserUpperStr</span> <span class="o">=</span> <span class="n">inRequest</span><span class="o">.</span><span class="n">OpenRPA</span><span class="p">[</span><span class="s2">&quot;User&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span>
<span class="k">return</span> <span class="p">{</span><span class="s2">&quot;DomainUpperStr&quot;</span><span class="p">:</span> <span class="n">lDomainUpperStr</span><span class="p">,</span> <span class="s2">&quot;UserNameUpperStr&quot;</span><span class="p">:</span> <span class="n">lUserUpperStr</span><span class="p">}</span></div>
<div class="viewcode-block" id="WebUserIsSuperToken"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserIsSuperToken">[docs]</a><span class="k">def</span> <span class="nf">WebUserIsSuperToken</span><span class="p">(</span><span class="n">inRequest</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
<div class="viewcode-block" id="WebUserIsSuperToken"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserIsSuperToken">[docs]</a><span class="k">def</span> <span class="nf">WebUserIsSuperToken</span><span class="p">(</span><span class="n">inRequest</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return bool if request is authentificated with supetoken (token which is never expires)</span>
<span class="sd"> :param inRequest:</span>
<span class="sd"> :param inRequest: inRequest from the server. Optional if call def from request thread</span>
<span class="sd"> :param inGSettings: Global settings dict (singleton)</span>
<span class="sd"> :return: bool True - is supertoken; False - is not supertoken</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">inRequest</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">inRequest</span> <span class="o">=</span> <span class="n">WebRequestGet</span><span class="p">()</span>
<span class="n">inGSettings</span> <span class="o">=</span> <span class="n">GSettingsGet</span><span class="p">(</span><span class="n">inGSettings</span><span class="o">=</span><span class="n">inGSettings</span><span class="p">)</span> <span class="c1"># Set the global settings</span>
<span class="n">lIsSuperTokenBool</span> <span class="o">=</span> <span class="kc">False</span>
<span class="c1"># Get Flag is supertoken (True|False)</span>
<span class="n">lIsSuperTokenBool</span> <span class="o">=</span> <span class="n">inGSettings</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;ServerDict&quot;</span><span class="p">,</span> <span class="p">{})</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;AccessUsers&quot;</span><span class="p">,</span> <span class="p">{})</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;AuthTokensDict&quot;</span><span class="p">,</span> <span class="p">{})</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">inRequest</span><span class="o">.</span><span class="n">OpenRPA</span><span class="p">[</span><span class="s2">&quot;AuthToken&quot;</span><span class="p">],</span> <span class="p">{})</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;FlagDoNotExpire&quot;</span><span class="p">,</span> <span class="kc">False</span><span class="p">)</span>
<span class="k">return</span> <span class="n">lIsSuperTokenBool</span></div>
<div class="viewcode-block" id="WebUserUACHierarchyGet"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserUACHierarchyGet">[docs]</a><span class="k">def</span> <span class="nf">WebUserUACHierarchyGet</span><span class="p">(</span><span class="n">inRequest</span><span class="p">):</span>
<div class="viewcode-block" id="WebUserUACHierarchyGet"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebUserUACHierarchyGet">[docs]</a><span class="k">def</span> <span class="nf">WebUserUACHierarchyGet</span><span class="p">(</span><span class="n">inRequest</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return User UAC Hierarchy DICT Return {...}</span>
<span class="sd"> :param inRequest:</span>
<span class="sd"> :param inRequest: inRequest from the server. Optional if call def from request thread</span>
<span class="sd"> :return: UAC Dict {}</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">inRequest</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">inRequest</span> <span class="o">=</span> <span class="n">WebRequestGet</span><span class="p">()</span>
<span class="k">return</span> <span class="n">inRequest</span><span class="o">.</span><span class="n">UserRoleHierarchyGet</span><span class="p">()</span></div>
@ -1585,12 +1719,16 @@
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">lL</span> <span class="o">=</span> <span class="n">OrchestratorLoggerGet</span><span class="p">()</span>
<span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;ActivityItem aliases: start to load sys.modules&quot;</span><span class="p">)</span>
<span class="k">for</span> <span class="n">lModuleItemStr</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">:</span>
<span class="n">lModuleItem</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="n">lModuleItemStr</span><span class="p">]</span>
<span class="n">lSysModulesSnapshot</span> <span class="o">=</span> <span class="n">copy</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">)</span> <span class="c1"># Actual when start from jupyter</span>
<span class="k">for</span> <span class="n">lModuleItemStr</span> <span class="ow">in</span> <span class="n">lSysModulesSnapshot</span><span class="p">:</span>
<span class="n">lModuleItem</span> <span class="o">=</span> <span class="n">lSysModulesSnapshot</span><span class="p">[</span><span class="n">lModuleItemStr</span><span class="p">]</span>
<span class="k">for</span> <span class="n">lDefItemStr</span> <span class="ow">in</span> <span class="nb">dir</span><span class="p">(</span><span class="n">lModuleItem</span><span class="p">):</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">lDefItem</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">lModuleItem</span><span class="p">,</span><span class="n">lDefItemStr</span><span class="p">)</span>
<span class="k">if</span> <span class="n">callable</span><span class="p">(</span><span class="n">lDefItem</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">lDefItemStr</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">&quot;_&quot;</span><span class="p">):</span>
<span class="n">ActivityItemDefAliasCreate</span><span class="p">(</span><span class="n">inDef</span><span class="o">=</span><span class="n">lDefItem</span><span class="p">,</span> <span class="n">inAliasStr</span><span class="o">=</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">lModuleItemStr</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="n">lDefItemStr</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ModuleNotFoundError</span><span class="p">:</span>
<span class="k">pass</span>
<span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;ActivityItem aliases: finish to load sys.modules&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="ActivityItemDefAliasUpdate"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.ActivityItemDefAliasUpdate">[docs]</a><span class="k">def</span> <span class="nf">ActivityItemDefAliasUpdate</span><span class="p">(</span><span class="n">inDef</span><span class="p">,</span> <span class="n">inAliasStr</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
@ -2085,7 +2223,7 @@
<span class="c1"># # # # # # # # # # # # # # # # # # # # # # #</span>
<div class="viewcode-block" id="RDPTemplateCreate"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.RDPTemplateCreate">[docs]</a><span class="k">def</span> <span class="nf">RDPTemplateCreate</span><span class="p">(</span><span class="n">inLoginStr</span><span class="p">,</span> <span class="n">inPasswordStr</span><span class="p">,</span> <span class="n">inHostStr</span><span class="o">=</span><span class="s2">&quot;127.0.0.1&quot;</span><span class="p">,</span> <span class="n">inPortInt</span> <span class="o">=</span> <span class="mi">3389</span><span class="p">,</span> <span class="n">inWidthPXInt</span> <span class="o">=</span> <span class="mi">1680</span><span class="p">,</span> <span class="n">inHeightPXInt</span> <span class="o">=</span> <span class="mi">1050</span><span class="p">,</span>
<span class="n">inUseBothMonitorBool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span> <span class="n">inDepthBitInt</span> <span class="o">=</span> <span class="mi">32</span><span class="p">,</span> <span class="n">inSharedDriveList</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="n">inUseBothMonitorBool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span> <span class="n">inDepthBitInt</span> <span class="o">=</span> <span class="mi">32</span><span class="p">,</span> <span class="n">inSharedDriveList</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inRedirectClipboardBool</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Create RDP connect dict item/ Use it connect/reconnect (Orchestrator.RDPSessionConnect)</span>
@ -2108,6 +2246,7 @@
<span class="sd"> # &quot;Host&quot;: &quot;127.0.0.1&quot;, &quot;Port&quot;: &quot;3389&quot;, &quot;Login&quot;: &quot;USER_99&quot;, &quot;Password&quot;: &quot;USER_PASS_HERE&quot;,</span>
<span class="sd"> # &quot;Screen&quot;: { &quot;Width&quot;: 1680, &quot;Height&quot;: 1050, &quot;FlagUseAllMonitors&quot;: False, &quot;DepthBit&quot;: &quot;32&quot; },</span>
<span class="sd"> # &quot;SharedDriveList&quot;: [&quot;c&quot;],</span>
<span class="sd"> # &quot;RedirectClipboardBool&quot;: True, # True - share clipboard to RDP; False - else</span>
<span class="sd"> # ###### Will updated in program ############</span>
<span class="sd"> # &quot;SessionHex&quot;: &quot;77777sdfsdf77777dsfdfsf77777777&quot;, # Hex is created when robot runs, example &quot;&quot;</span>
<span class="sd"> # &quot;SessionIsWindowExistBool&quot;: False, &quot;SessionIsWindowResponsibleBool&quot;: False, &quot;SessionIsIgnoredBool&quot;: False</span>
@ -2122,6 +2261,7 @@
<span class="sd"> :param inUseBothMonitorBool: True - connect to the RDP with both monitors. False - else case</span>
<span class="sd"> :param inDepthBitInt: Remote desktop bitness. Available: 32 or 24 or 16 or 15, example 32</span>
<span class="sd"> :param inSharedDriveList: Host local disc to connect to the RDP session. Example: [&quot;c&quot;, &quot;d&quot;]</span>
<span class="sd"> :param inRedirectClipboardBool: # True - share clipboard to RDP; False - else</span>
<span class="sd"> :return:</span>
<span class="sd"> {</span>
<span class="sd"> &quot;Host&quot;: inHostStr, # Host address, example &quot;77.77.22.22&quot;</span>
@ -2136,6 +2276,7 @@
<span class="sd"> &quot;DepthBit&quot;: str(inDepthBitInt) # &quot;32&quot; or &quot;24&quot; or &quot;16&quot; or &quot;15&quot;, example &quot;32&quot;</span>
<span class="sd"> },</span>
<span class="sd"> &quot;SharedDriveList&quot;: inSharedDriveList, # List of the Root sesion hard drives, example [&quot;c&quot;]</span>
<span class="sd"> &quot;RedirectClipboardBool&quot;: True, # True - share clipboard to RDP; False - else</span>
<span class="sd"> ###### Will updated in program ############</span>
<span class="sd"> &quot;SessionHex&quot;: &quot;77777sdfsdf77777dsfdfsf77777777&quot;, # Hex is created when robot runs, example &quot;&quot;</span>
<span class="sd"> &quot;SessionIsWindowExistBool&quot;: False,</span>
@ -2147,6 +2288,8 @@
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">inSharedDriveList</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">inSharedDriveList</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;c&quot;</span><span class="p">]</span>
<span class="k">if</span> <span class="n">inPortInt</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">inPortInt</span> <span class="o">=</span> <span class="mi">3389</span>
<span class="k">if</span> <span class="n">inRedirectClipboardBool</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span> <span class="n">inRedirectClipboardBool</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">lRDPTemplateDict</span><span class="o">=</span> <span class="p">{</span> <span class="c1"># Init the configuration item</span>
<span class="s2">&quot;Host&quot;</span><span class="p">:</span> <span class="n">inHostStr</span><span class="p">,</span> <span class="c1"># Host address, example &quot;77.77.22.22&quot;</span>
<span class="s2">&quot;Port&quot;</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="n">inPortInt</span><span class="p">),</span> <span class="c1"># RDP Port, example &quot;3389&quot;</span>
@ -2159,7 +2302,8 @@
<span class="s2">&quot;FlagUseAllMonitors&quot;</span><span class="p">:</span> <span class="n">inUseBothMonitorBool</span><span class="p">,</span> <span class="c1"># True or False, example False</span>
<span class="s2">&quot;DepthBit&quot;</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="n">inDepthBitInt</span><span class="p">)</span> <span class="c1"># &quot;32&quot; or &quot;24&quot; or &quot;16&quot; or &quot;15&quot;, example &quot;32&quot;</span>
<span class="p">},</span>
<span class="s2">&quot;SharedDriveList&quot;</span><span class="p">:</span> <span class="n">inSharedDriveList</span><span class="p">,</span> <span class="c1"># List of the Root sesion hard drives, example [&quot;c&quot;]</span>
<span class="s2">&quot;SharedDriveList&quot;</span><span class="p">:</span> <span class="n">inSharedDriveList</span><span class="p">,</span> <span class="c1"># List of the Root sesion hard drives, example [&quot;c&quot;],</span>
<span class="s2">&quot;RedirectClipboardBool&quot;</span><span class="p">:</span> <span class="n">inRedirectClipboardBool</span><span class="p">,</span> <span class="c1"># True - share clipboard to RDP; False - else</span>
<span class="c1">###### Will updated in program ############</span>
<span class="s2">&quot;SessionHex&quot;</span><span class="p">:</span> <span class="s2">&quot;77777sdfsdf77777dsfdfsf77777777&quot;</span><span class="p">,</span> <span class="c1"># Hex is created when robot runs, example &quot;&quot;</span>
<span class="s2">&quot;SessionIsWindowExistBool&quot;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span>
@ -2184,7 +2328,7 @@
<span class="c1">#for lItemKeyStr in inGSettings[&quot;RobotRDPActive&quot;][&quot;RDPList&quot;]:</span>
<span class="c1"># lItemDict = inGSettings[&quot;RobotRDPActive&quot;][&quot;RDPList&quot;][lItemKeyStr]</span>
<div class="viewcode-block" id="RDPSessionConnect"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionConnect">[docs]</a><span class="k">def</span> <span class="nf">RDPSessionConnect</span><span class="p">(</span><span class="n">inRDPSessionKeyStr</span><span class="p">,</span> <span class="n">inRDPTemplateDict</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inHostStr</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inPortStr</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inLoginStr</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inPasswordStr</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
<div class="viewcode-block" id="RDPSessionConnect"><a class="viewcode-back" href="../../../Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionConnect">[docs]</a><span class="k">def</span> <span class="nf">RDPSessionConnect</span><span class="p">(</span><span class="n">inRDPSessionKeyStr</span><span class="p">,</span> <span class="n">inRDPTemplateDict</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inHostStr</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inPortStr</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inLoginStr</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inPasswordStr</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">inGSettings</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">inRedirectClipboardBool</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Create new RDPSession in RobotRDPActive. Attention - activity will be ignored if RDP key is already exists</span>
<span class="sd"> 2 way of the use</span>
@ -2223,7 +2367,7 @@
<span class="s2">&quot;Def&quot;</span><span class="p">:</span> <span class="n">RDPSessionConnect</span><span class="p">,</span> <span class="c1"># def link or def alias (look gSettings[&quot;Processor&quot;][&quot;AliasDefDict&quot;])</span>
<span class="s2">&quot;ArgList&quot;</span><span class="p">:</span> <span class="p">[],</span> <span class="c1"># Args list</span>
<span class="s2">&quot;ArgDict&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;inRDPSessionKeyStr&quot;</span><span class="p">:</span> <span class="n">inRDPSessionKeyStr</span><span class="p">,</span> <span class="s2">&quot;inRDPTemplateDict&quot;</span><span class="p">:</span><span class="n">inRDPTemplateDict</span><span class="p">,</span> <span class="s2">&quot;inHostStr&quot;</span><span class="p">:</span> <span class="n">inHostStr</span><span class="p">,</span> <span class="s2">&quot;inPortStr&quot;</span><span class="p">:</span> <span class="n">inPortStr</span><span class="p">,</span>
<span class="s2">&quot;inLoginStr&quot;</span><span class="p">:</span> <span class="n">inLoginStr</span><span class="p">,</span> <span class="s2">&quot;inPasswordStr&quot;</span><span class="p">:</span> <span class="n">inPasswordStr</span><span class="p">},</span> <span class="c1"># Args dictionary</span>
<span class="s2">&quot;inLoginStr&quot;</span><span class="p">:</span> <span class="n">inLoginStr</span><span class="p">,</span> <span class="s2">&quot;inPasswordStr&quot;</span><span class="p">:</span> <span class="n">inPasswordStr</span><span class="p">,</span> <span class="s2">&quot;inRedirectClipboardBool&quot;</span><span class="p">:</span> <span class="n">inRedirectClipboardBool</span><span class="p">},</span> <span class="c1"># Args dictionary</span>
<span class="s2">&quot;ArgGSettings&quot;</span><span class="p">:</span> <span class="s2">&quot;inGSettings&quot;</span><span class="p">,</span> <span class="c1"># Name of GSettings attribute: str (ArgDict) or index (for ArgList)</span>
<span class="s2">&quot;ArgLogger&quot;</span><span class="p">:</span> <span class="kc">None</span> <span class="c1"># Name of GSettings attribute: str (ArgDict) or index (for ArgList)</span>
<span class="p">}</span>
@ -2234,7 +2378,7 @@
<span class="c1"># Var 2 - backward compatibility</span>
<span class="k">if</span> <span class="n">lRDPConfigurationItem</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">lRDPConfigurationItem</span> <span class="o">=</span> <span class="n">RDPTemplateCreate</span><span class="p">(</span><span class="n">inLoginStr</span><span class="o">=</span><span class="n">inLoginStr</span><span class="p">,</span> <span class="n">inPasswordStr</span><span class="o">=</span><span class="n">inPasswordStr</span><span class="p">,</span>
<span class="n">inHostStr</span><span class="o">=</span><span class="n">inHostStr</span><span class="p">,</span> <span class="n">inPortInt</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">inPortStr</span><span class="p">))</span> <span class="c1"># ATTENTION - dont connect if RDP session is exist</span>
<span class="n">inHostStr</span><span class="o">=</span><span class="n">inHostStr</span><span class="p">,</span> <span class="n">inPortInt</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">inPortStr</span><span class="p">),</span> <span class="n">inRedirectClipboardBool</span><span class="o">=</span><span class="n">inRedirectClipboardBool</span><span class="p">)</span> <span class="c1"># ATTENTION - dont connect if RDP session is exist</span>
<span class="c1"># Start the connect</span>
<span class="k">if</span> <span class="n">inRDPSessionKeyStr</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;RobotRDPActive&quot;</span><span class="p">][</span><span class="s2">&quot;RDPList&quot;</span><span class="p">]:</span>
<span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;RobotRDPActive&quot;</span><span class="p">][</span><span class="s2">&quot;RDPList&quot;</span><span class="p">][</span><span class="n">inRDPSessionKeyStr</span><span class="p">]</span> <span class="o">=</span> <span class="n">lRDPConfigurationItem</span> <span class="c1"># Add item in RDPList</span>
@ -2705,7 +2849,6 @@
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;Autocleaner&quot;</span><span class="p">][</span><span class="s2">&quot;IntervalSecFloat&quot;</span><span class="p">])</span> <span class="c1"># Wait for the next iteration</span>
<span class="n">lL</span> <span class="o">=</span> <span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;Logger&quot;</span><span class="p">]</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Autocleaner is running&quot;</span><span class="p">)</span> <span class="c1"># Info</span>
<span class="n">lNowDatetime</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="c1"># Get now time</span>
<span class="c1"># Clean old items in Client &gt; Session &gt; TechnicalSessionGUIDCache</span>
<span class="n">lTechnicalSessionGUIDCacheNew</span> <span class="o">=</span> <span class="p">{}</span>
@ -2830,6 +2973,8 @@
<span class="n">lRobotRDPActiveThread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> <span class="c1"># Start the thread execution.</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Robot RDP active has been started&quot;</span><span class="p">)</span> <span class="c1">#Logging</span>
<span class="c1"># Init autocleaner in another thread</span>
<span class="n">lAutocleanerThread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span> <span class="n">GSettingsAutocleaner</span><span class="p">,</span> <span class="n">kwargs</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;inGSettings&quot;</span><span class="p">:</span><span class="n">gSettingsDict</span><span class="p">})</span>
<span class="n">lAutocleanerThread</span><span class="o">.</span><span class="n">daemon</span> <span class="o">=</span> <span class="kc">True</span> <span class="c1"># Run the thread in daemon mode.</span>
@ -2862,13 +3007,18 @@
<span class="n">lSchedulerThread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> <span class="c1"># Start the thread execution.</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Scheduler (old) loop start&quot;</span><span class="p">)</span> <span class="c1">#Logging</span>
<span class="c1"># Schedule (new) loop</span>
<span class="n">lScheduleThread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span> <span class="n">__schedule_loop__</span><span class="p">)</span>
<span class="n">lScheduleThread</span><span class="o">.</span><span class="n">daemon</span> <span class="o">=</span> <span class="kc">True</span> <span class="c1"># Run the thread in daemon mode.</span>
<span class="n">lScheduleThread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> <span class="c1"># Start the thread execution.</span>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Schedule module (new) loop start&quot;</span><span class="p">)</span> <span class="c1">#Logging</span></div>
<span class="k">if</span> <span class="n">lL</span><span class="p">:</span> <span class="n">lL</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;Schedule module (new) loop start&quot;</span><span class="p">)</span> <span class="c1">#Logging</span>
<span class="c1"># Restore state for process</span>
<span class="k">for</span> <span class="n">lProcessKeyTuple</span> <span class="ow">in</span> <span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;ManagersProcessDict&quot;</span><span class="p">]:</span>
<span class="n">lProcess</span> <span class="o">=</span> <span class="n">inGSettings</span><span class="p">[</span><span class="s2">&quot;ManagersProcessDict&quot;</span><span class="p">][</span><span class="n">lProcessKeyTuple</span><span class="p">]</span>
<span class="n">lProcess</span><span class="o">.</span><span class="n">StatusCheckIntervalRestore</span><span class="p">()</span>
<span class="n">lThread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span> <span class="n">lProcess</span><span class="o">.</span><span class="n">StatusRestore</span><span class="p">)</span>
<span class="n">lThread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span></div>
<span class="k">def</span> <span class="nf">__schedule_loop__</span><span class="p">():</span>
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>

@ -5,7 +5,7 @@
####################################
pyOpenRPA is created by Ivan Maslov (Russia).
Use it absolutely for free!
Hosted by PYOPENRPA LLC (Russia)
My purpose is to create #IT4Business models in the companies.
I can help you to create the new #IT4Business in your company.

@ -14,25 +14,19 @@ Welcome to pyOpenRPA's wiki
! ATTENTION ! pyOpenRPA works only on MS Windows 7+/Server 2008+. Guys from Unix/Mac - sorry. We will come to you soon :)
**************************************************
Donate
**************************************************
pyOpenRPA is absolutely non-commercial project.
Please donate some $ if pyOpenRPA project is actual for you. Link to online donations.
https://yoomoney.ru/to/4100115560661986
**************************************************
About
**************************************************
Dear RPA-tors. Let me congratulate you with great change in the RPA world. Since 2019 the first enterprise level open source RPA platform is here!
pyOpenRPA is absolutely open source commercial project. Hosted by LLC PYOPENRPA (RUSSIA)
The pyOpenRPA - free, fast and reliable
Powerful OpenSource RPA tool for business (based on python 3). Best performance and absolutely free!
The pyOpenRPA is based on Python and using well known OpenSource solutions such as Selenium, OpenCV, Win32, UI automation and others. Thanks to it we were able to create consolidated platform with all possible features.
The pyOpenRPA is distributed under the MIT license which allows you to use it in any way you want and any time you need without any restrictions.
The pyOpenRPA is distributed under the PYOPENRPA license.
At the time of this writing the pyOpenRPA is successfully using in several big Russian companies. Companies in which it was decided to develop own RPA division with no dependencies on expensive licenses.
**************************************************

@ -193,6 +193,7 @@
| <a href="#G"><strong>G</strong></a>
| <a href="#I"><strong>I</strong></a>
| <a href="#J"><strong>J</strong></a>
| <a href="#K"><strong>K</strong></a>
| <a href="#M"><strong>M</strong></a>
| <a href="#O"><strong>O</strong></a>
| <a href="#P"><strong>P</strong></a>
@ -236,6 +237,8 @@
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileBinaryDataBase64StrReceive">AgentOSFileBinaryDataBase64StrReceive() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileBinaryDataBytesCreate">AgentOSFileBinaryDataBytesCreate() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileBinaryDataReceive">AgentOSFileBinaryDataReceive() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileSend">AgentOSFileSend() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
@ -253,7 +256,7 @@
<h2 id="C">C</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="Orchestrator/06_Defs%20Managers.html#id29">ControlPanel (class in pyOpenRPA.Orchestrator.Managers.ControlPanel)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id37">ControlPanel (class in pyOpenRPA.Orchestrator.Managers.ControlPanel)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel">[1]</a>
</li>
</ul></td>
</tr></table>
@ -261,7 +264,7 @@
<h2 id="D">D</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="Orchestrator/06_Defs%20Managers.html#id30">DataDictGenerate() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.DataDictGenerate">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id38">DataDictGenerate() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.DataDictGenerate">[1]</a>
</li>
</ul></td>
</tr></table>
@ -293,11 +296,11 @@
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="Tools/02_Defs.html#pyOpenRPA.Tools.StopSafe.Init">Init() (in module pyOpenRPA.Tools.StopSafe)</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id31">InitJSJinja2StrGenerate() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.InitJSJinja2StrGenerate">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id39">InitJSJinja2StrGenerate() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.InitJSJinja2StrGenerate">[1]</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="Orchestrator/06_Defs%20Managers.html#id32">InitJSJinja2TemplatePathSet() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.InitJSJinja2TemplatePathSet">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id40">InitJSJinja2TemplatePathSet() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.InitJSJinja2TemplatePathSet">[1]</a>
</li>
<li><a href="Tools/02_Defs.html#pyOpenRPA.Tools.StopSafe.IsStopSafe">IsStopSafe() (in module pyOpenRPA.Tools.StopSafe)</a>
</li>
@ -307,7 +310,7 @@
<h2 id="J">J</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="Orchestrator/06_Defs%20Managers.html#id33">Jinja2DataUpdateDictSet() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.Jinja2DataUpdateDictSet">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id41">Jinja2DataUpdateDictSet() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.Jinja2DataUpdateDictSet">[1]</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
@ -318,16 +321,24 @@
</ul></td>
</tr></table>
<h2 id="K">K</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="Orchestrator/06_Defs%20Managers.html#id1">KeyTurpleGet() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.KeyTurpleGet">[1]</a>
</li>
</ul></td>
</tr></table>
<h2 id="M">M</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="Orchestrator/06_Defs%20Managers.html#id1">Manual2Auto() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.Manual2Auto">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id2">Manual2Auto() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.Manual2Auto">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id2">ManualStopListClear() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.ManualStopListClear">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id3">ManualStopListClear() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.ManualStopListClear">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id3">ManualStopTriggerNewStart() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.ManualStopTriggerNewStart">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id4">ManualStopTriggerNewStart() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.ManualStopTriggerNewStart">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id4">ManualStopTriggerSet() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.ManualStopTriggerSet">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id5">ManualStopTriggerSet() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.ManualStopTriggerSet">[1]</a>
</li>
<li>
module
@ -350,7 +361,7 @@
</ul></li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="Orchestrator/06_Defs%20Managers.html#id5">MuteWait() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.MuteWait">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id6">MuteWait() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.MuteWait">[1]</a>
</li>
</ul></td>
</tr></table>
@ -358,21 +369,25 @@
<h2 id="O">O</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="Orchestrator/06_Defs%20Managers.html#id34">OnInitJSDataDict() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.OnInitJSDataDict">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id42">OnInitJSDataDict() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.OnInitJSDataDict">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id35">OnInitJSStr() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.OnInitJSStr">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id43">OnInitJSStr() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.OnInitJSStr">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id36">OnRefreshHTMLDataDict() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.OnRefreshHTMLDataDict">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id44">OnRefreshHTMLDataDict() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.OnRefreshHTMLDataDict">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id37">OnRefreshHTMLHashStr() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.OnRefreshHTMLHashStr">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id45">OnRefreshHTMLHashStr() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.OnRefreshHTMLHashStr">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id38">OnRefreshHTMLStr() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.OnRefreshHTMLStr">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id46">OnRefreshHTMLStr() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.OnRefreshHTMLStr">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id39">OnRefreshJSONDict() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.OnRefreshJSONDict">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id47">OnRefreshJSONDict() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.OnRefreshJSONDict">[1]</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.Orchestrator">Orchestrator() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorInitWait">OrchestratorInitWait() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorIsAdmin">OrchestratorIsAdmin() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorIsInited">OrchestratorIsInited() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorLoggerGet">OrchestratorLoggerGet() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
@ -381,11 +396,11 @@
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorRerunAsAdmin">OrchestratorRerunAsAdmin() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorRestart">OrchestratorRestart() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorScheduleGet">OrchestratorScheduleGet() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorScheduleGet">OrchestratorScheduleGet() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionRestore">OrchestratorSessionRestore() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionSave">OrchestratorSessionSave() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
@ -405,6 +420,8 @@
<li><a href="Agent/02_Defs.html#pyOpenRPA.Agent.__Agent__.OSFileBinaryDataBase64StrCreate">OSFileBinaryDataBase64StrCreate() (in module pyOpenRPA.Agent.__Agent__)</a>
</li>
<li><a href="Agent/02_Defs.html#pyOpenRPA.Agent.__Agent__.OSFileBinaryDataBase64StrReceive">OSFileBinaryDataBase64StrReceive() (in module pyOpenRPA.Agent.__Agent__)</a>
</li>
<li><a href="Agent/02_Defs.html#pyOpenRPA.Agent.__Agent__.OSFileMTimeGet">OSFileMTimeGet() (in module pyOpenRPA.Agent.__Agent__)</a>
</li>
<li><a href="Agent/02_Defs.html#pyOpenRPA.Agent.__Agent__.OSFileTextDataStrCreate">OSFileTextDataStrCreate() (in module pyOpenRPA.Agent.__Agent__)</a>
</li>
@ -424,17 +441,21 @@
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessDefIntervalCall">ProcessDefIntervalCall() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id20">ProcessGet() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessGet">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id23">ProcessExists() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessExists">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id24">ProcessGet() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessGet">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id25">ProcessInitSafe() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessInitSafe">[1]</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessIsStarted">ProcessIsStarted() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessListGet">ProcessListGet() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id21">ProcessManual2Auto() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessManual2Auto">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id26">ProcessManual2Auto() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessManual2Auto">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id22">ProcessManualStopListClear() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessManualStopListClear">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id27">ProcessManualStopListClear() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessManualStopListClear">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id23">ProcessManualStopTriggerSet() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessManualStopTriggerSet">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id28">ProcessManualStopTriggerSet() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessManualStopTriggerSet">[1]</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorActivityItemAppend">ProcessorActivityItemAppend() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
@ -443,24 +464,30 @@
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorAliasDefCreate">ProcessorAliasDefCreate() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessorAliasDefUpdate">ProcessorAliasDefUpdate() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id29">ProcessScheduleStatusCheckEverySeconds() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessScheduleStatusCheckEverySeconds">[1]</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessStart">ProcessStart() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
<ul>
<li><a href="Orchestrator/06_Defs%20Managers.html#id24">(in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStart">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id30">(in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStart">[1]</a>
</li>
</ul></li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id25">ProcessStatusCheck() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStatusCheck">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id31">ProcessStatusCheck() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStatusCheck">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id26">ProcessStatusStrGet() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStatusStrGet">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id32">ProcessStatusRestore() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStatusRestore">[1]</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessStop">ProcessStop() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id33">ProcessStatusSave() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStatusSave">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id27">ProcessStopForce() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStopForce">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id34">ProcessStatusStrGet() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStatusStrGet">[1]</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="Orchestrator/06_Defs%20Managers.html#id28">ProcessStopSafe() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStopSafe">[1]</a>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.ProcessStop">ProcessStop() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id35">ProcessStopForce() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStopForce">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id36">ProcessStopSafe() (in module pyOpenRPA.Orchestrator.Managers.Process)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.ProcessStopSafe">[1]</a>
</li>
<li><a href="Agent/02_Defs.html#pyOpenRPA.Agent.__Agent__.ProcessWOExeUpperUserListGet">ProcessWOExeUpperUserListGet() (in module pyOpenRPA.Agent.__Agent__)</a>
</li>
@ -553,13 +580,13 @@
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.RDPTemplateCreate">RDPTemplateCreate() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id40">RefreshHTMLJinja2StrGenerate() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.RefreshHTMLJinja2StrGenerate">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id48">RefreshHTMLJinja2StrGenerate() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.RefreshHTMLJinja2StrGenerate">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id41">RefreshHTMLJinja2TemplatePathSet() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.RefreshHTMLJinja2TemplatePathSet">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id49">RefreshHTMLJinja2TemplatePathSet() (pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.ControlPanel.ControlPanel.RefreshHTMLJinja2TemplatePathSet">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id6">RestartForce() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.RestartForce">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id7">RestartForce() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.RestartForce">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id7">RestartSafe() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.RestartSafe">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id8">RestartSafe() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.RestartSafe">[1]</a>
</li>
</ul></td>
</tr></table>
@ -568,8 +595,6 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.SchedulerActivityTimeAddWeekly">SchedulerActivityTimeAddWeekly() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id8">ScheduleStatusCheckEverySeconds() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.ScheduleStatusCheckEverySeconds">[1]</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.Start">Start() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
@ -583,21 +608,27 @@
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id12">StatusCheck() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StatusCheck">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id13">StatusCheckStart() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StatusCheckStart">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id13">StatusCheckIntervalRestore() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StatusCheckIntervalRestore">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id14">StatusCheckStart() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StatusCheckStart">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id15">StatusCheckStopForce() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StatusCheckStopForce">[1]</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="Orchestrator/06_Defs%20Managers.html#id14">StatusCheckStopForce() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StatusCheckStopForce">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id16">StatusCheckStopSafe() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StatusCheckStopSafe">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id17">StatusRestore() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StatusRestore">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id15">StatusCheckStopSafe() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StatusCheckStopSafe">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id18">StatusSave() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StatusSave">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id16">StopForce() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StopForce">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id19">StopForce() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StopForce">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id17">StopForceCheck() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StopForceCheck">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id20">StopForceCheck() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StopForceCheck">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id18">StopSafe() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StopSafe">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id21">StopSafe() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StopSafe">[1]</a>
</li>
<li><a href="Orchestrator/06_Defs%20Managers.html#id19">StopSafeCheck() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StopSafeCheck">[1]</a>
<li><a href="Orchestrator/06_Defs%20Managers.html#id22">StopSafeCheck() (pyOpenRPA.Orchestrator.Managers.Process.Process method)</a>, <a href="Orchestrator/06_Defs%20Managers.html#pyOpenRPA.Orchestrator.Managers.Process.Process.StopSafeCheck">[1]</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.StorageRobotExists">StorageRobotExists() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
@ -668,6 +699,8 @@
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebCPUpdate">WebCPUpdate() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebListenCreate">WebListenCreate() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestGet">WebRequestGet() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>
<li><a href="Orchestrator/02_Defs.html#pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyBytes">WebRequestParseBodyBytes() (in module pyOpenRPA.Orchestrator.__Orchestrator__)</a>
</li>

@ -191,19 +191,14 @@
<img alt="ModalGuide.png" src="_images/ModalGuide.png" />
<p><em>by Ivan Maslov (Russia)</em> - see <a class="reference internal" href="03_Copyrights_Contacts.html#copyrights-contacts"><span class="std std-ref">3. Copyrights &amp; Contacts</span></a>.</p>
<p>! ATTENTION ! pyOpenRPA works only on MS Windows 7+/Server 2008+. Guys from Unix/Mac - sorry. We will come to you soon :)</p>
<div class="section" id="donate">
<h2>Donate<a class="headerlink" href="#donate" title="Permalink to this headline"></a></h2>
<p>pyOpenRPA is absolutely non-commercial project.</p>
<p>Please donate some $ if pyOpenRPA project is actual for you. Link to online donations.
<a class="reference external" href="https://yoomoney.ru/to/4100115560661986">https://yoomoney.ru/to/4100115560661986</a></p>
</div>
<div class="section" id="about">
<h2>About<a class="headerlink" href="#about" title="Permalink to this headline"></a></h2>
<p>Dear RPA-tors. Let me congratulate you with great change in the RPA world. Since 2019 the first enterprise level open source RPA platform is here!</p>
<p>pyOpenRPA is absolutely open source commercial project. Hosted by LLC PYOPENRPA (RUSSIA)</p>
<p>The pyOpenRPA - free, fast and reliable
Powerful OpenSource RPA tool for business (based on python 3). Best performance and absolutely free!</p>
<p>The pyOpenRPA is based on Python and using well known OpenSource solutions such as Selenium, OpenCV, Win32, UI automation and others. Thanks to it we were able to create consolidated platform with all possible features.
The pyOpenRPA is distributed under the MIT license which allows you to use it in any way you want and any time you need without any restrictions.
The pyOpenRPA is distributed under the PYOPENRPA license.
At the time of this writing the pyOpenRPA is successfully using in several big Russian companies. Companies in which it was decided to develop own RPA division with no dependencies on expensive licenses.</p>
</div>
<div class="section" id="repo-structure">

Binary file not shown.

File diff suppressed because one or more lines are too long

@ -1,7 +1,7 @@
# 3. Copyrights & Contacts
pyOpenRPA is created by Ivan Maslov (Russia).
Use it absolutely for free!
Hosted by PYOPENRPA LLC (Russia)
My purpose is to create #IT4Business models in the companies.
I can help you to create the new #IT4Business in your company.

@ -23,6 +23,11 @@
| Read binary file and encode in base64 to transmit (safe for JSON transmition)
|
| `OSFileMTimeGet`(inFilePathStr)
| Read file modification time timestamp format (float)
|
| `OSFileTextDataStrCreate`(inFilePathStr, …)
@ -40,7 +45,7 @@
|
### pyOpenRPA.Agent.__Agent__.OSCMD(inCMDStr, inRunAsyncBool=True, inGSettings=None, inSendOutputToOrchestratorLogsBool=True, inCMDEncodingStr='cp1251')
### pyOpenRPA.Agent.__Agent__.OSCMD(inCMDStr, inRunAsyncBool=True, inGSettings=None, inSendOutputToOrchestratorLogsBool=True, inCMDEncodingStr='cp1251', inCaptureBool=True)
Execute CMD on the Agent daemonic process
@ -59,9 +64,16 @@ Execute CMD on the Agent daemonic process
* **inSendOutputToOrchestratorLogsBool** True - catch cmd execution output and send it to the Orchestrator logs; Flase - else case; Default True
!ATTENTION! If you need to start absolutely encapsulated app - set this flag as False. If you set True - the app output will come to Agent
:param inCMDEncodingStr: Set the encoding of the DOS window on the Agent server session. Windows is beautiful :) . Default is “cp1251” early was “cp866” - need test
:return:
* **inCMDEncodingStr** Set the encoding of the DOS window on the Agent server session. Windows is beautiful :) . Default is “cp1251” early was “cp866” - need test
* **inCaptureBool** !ATTENTION! If you need to start absolutely encapsulated app - set this flag as False. If you set True - the app output will come to Agent
* **Returns**
### pyOpenRPA.Agent.__Agent__.OSFileBinaryDataBase64StrAppend(inFilePathStr, inFileDataBase64Str, inGSettings=None)
@ -92,6 +104,22 @@ Read binary file and encode in base64 to transmit (safe for JSON transmition)
### pyOpenRPA.Agent.__Agent__.OSFileMTimeGet(inFilePathStr: str)
Read file modification time timestamp format (float)
* **Parameters**
**inFilePathStr** File path to read
* **Returns**
timestamp (float) Return None if file is not exist
### pyOpenRPA.Agent.__Agent__.OSFileTextDataStrCreate(inFilePathStr, inFileDataStr, inEncodingStr='utf-8', inGSettings=None)
Create text file in the agent GUI session

@ -132,6 +132,11 @@ Work with activity scheduling.
| Create binary file by the base64 string by the pyOpenRPA.Agent daemon process (safe for JSON transmition)
|
| `AgentOSFileBinaryDataReceive`(inHostNameStr, …)
| Read binary file from agent (synchronious)
|
| `AgentOSFileSend`(inHostNameStr, inUserStr, …)
@ -212,11 +217,21 @@ Work with activity scheduling.
| Main def to start orchestrator
|
| `OrchestratorInitWait`()
| Wait thread while orc will process initial action.
|
| `OrchestratorIsAdmin`()
| Check if Orchestrator process is running as administrator
|
| `OrchestratorIsInited`()
| Check if Orchestrator initial actions were processed
|
| `OrchestratorLoggerGet`()
@ -245,12 +260,12 @@ Work with activity scheduling.
|
| `OrchestratorSessionRestore`([inGSettings])
| Check _SessionLast_RDPList.json and _SessionLast_StorageDict.pickle in working directory. if exist - load into gsettings # _SessionLast_StorageDict.pickle (binary) _SessionLast_RDPList.json (encoding = “utf-8”) _SessionLast_StorageDict.pickle (binary).
| Check _SessioLast… files in working directory. if exist - load into gsettings (from version 1.2.7) _SessionLast_GSettings.pickle (binary).
|
| `OrchestratorSessionSave`([inGSettings])
| Orchestrator session save in file
| Orchestrator session save in file (from version 1.2.7) _SessionLast_GSettings.pickle (binary)
|
| `OrchestratorThreadStart`(inDef, \*inArgList, …)
@ -413,7 +428,7 @@ Work with activity scheduling.
| Return user UAC hierarchy dict of the inRequest object.
|
| `WebAuditMessageCreate`(inRequest[, …])
| `WebAuditMessageCreate`([inRequest, …])
| Create message string with request user details (IP, Login etc…).
@ -428,34 +443,39 @@ Work with activity scheduling.
| Create listen interface for the web server
|
| `WebRequestParseBodyBytes`(inRequest)
| `WebRequestGet`()
| Return the web request instance if current thread was created by web request from client.
|
| `WebRequestParseBodyBytes`([inRequest])
| Extract the body in bytes from the request
|
| `WebRequestParseBodyJSON`(inRequest)
| `WebRequestParseBodyJSON`([inRequest])
| Extract the body in dict/list from the request
|
| `WebRequestParseBodyStr`(inRequest)
| `WebRequestParseBodyStr`([inRequest])
| Extract the body in str from the request
|
| `WebRequestParseFile`(inRequest)
| `WebRequestParseFile`([inRequest])
| Parse the request - extract the file (name, body in bytes)
|
| `WebRequestParsePath`(inRequest)
| `WebRequestParsePath`([inRequest])
| Parse the request - extract the url.
|
| `WebRequestResponseSend`(inRequest, inResponeStr)
| `WebRequestResponseSend`(inResponeStr[, inRequest])
| Send response for the request :return:
| Send response for the request
|
| `WebURLConnectDef`(inMethodStr, inURLStr, …)
@ -473,17 +493,17 @@ Work with activity scheduling.
| Connect URL to Folder
|
| `WebUserInfoGet`(inRequest)
| `WebUserInfoGet`([inRequest])
| Return User info about request
|
| `WebUserIsSuperToken`(inRequest[, inGSettings])
| `WebUserIsSuperToken`([inRequest, inGSettings])
| Return bool if request is authentificated with supetoken (token which is never expires)
|
| `WebUserUACHierarchyGet`(inRequest)
| `WebUserUACHierarchyGet`([inRequest])
| Return User UAC Hierarchy DICT Return {…}
@ -775,7 +795,7 @@ Work synchroniously! Wait while result will be recieved. Get the result of the A
### pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSCMD(inHostNameStr, inUserStr, inCMDStr, inRunAsyncBool=True, inSendOutputToOrchestratorLogsBool=True, inCMDEncodingStr='cp1251', inGSettings=None)
### pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSCMD(inHostNameStr, inUserStr, inCMDStr, inRunAsyncBool=True, inSendOutputToOrchestratorLogsBool=True, inCMDEncodingStr='cp1251', inGSettings=None, inCaptureBool=True)
Send CMD to OS thought the pyOpenRPA.Agent daemon. Result return to log + Orchestrator by the A2O connection
@ -803,6 +823,9 @@ Send CMD to OS thought the pyOpenRPA.Agent daemon. Result return to log + Orches
* **inCMDEncodingStr** Set the encoding of the DOS window on the Agent server session. Windows is beautiful :) . Default is “cp1251” early was “cp866” - need test
* **inCaptureBool** !ATTENTION! If you need to start absolutely encapsulated app - set this flag as False. If you set True - the app output will come to Agent
* **Returns**
@ -923,6 +946,32 @@ Create binary file by the base64 string by the pyOpenRPA.Agent daemon process (s
### pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileBinaryDataReceive(inHostNameStr, inUserStr, inFilePathStr)
Read binary file from agent (synchronious)
* **Parameters**
* **inGSettings** Global settings dict (singleton)
* **inHostNameStr**
* **inUserStr**
* **inFilePathStr** File path to read
* **Returns**
file data bytes
### pyOpenRPA.Orchestrator.__Orchestrator__.AgentOSFileSend(inHostNameStr, inUserStr, inOrchestratorFilePathStr, inAgentFilePathStr, inGSettings=None)
Send the file from the Orchestrator to Agent (synchroniously) pyOpenRPA.Agent daemon process (safe for JSON transmition).
Work safety with big files
@ -1307,6 +1356,11 @@ Main def to start orchestrator
### pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorInitWait()
Wait thread while orc will process initial action.
ATTENTION: DO NOT CALL THIS DEF IN THREAD WHERE ORCHESTRATOR MUST BE INITIALIZED - INFINITE LOOP
### pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorIsAdmin()
Check if Orchestrator process is running as administrator
@ -1317,6 +1371,22 @@ Check if Orchestrator process is running as administrator
### pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorIsInited()
Check if Orchestrator initial actions were processed
* **Returns**
True - orc is already inited; False - else
* **Return type**
bool
### pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorLoggerGet()
Get the logger from the Orchestrator
@ -1326,27 +1396,42 @@ Get the logger from the Orchestrator
### pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorPySearchInit(inGlobPatternStr, inDefStr=None, inDefArgNameGSettingsStr=None)
### pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorPySearchInit(inGlobPatternStr, inDefStr=None, inDefArgNameGSettingsStr=None, inAsyncInitBool=False)
Search the py files by the glob and do the safe init (in try except). Also add inited module in sys.modules as imported (module name = file name without extension).
You can init CP in async way!
.. code-block:: python
```
# USAGE VAR 1 (without the def auto call)
# Autoinit control panels starts with CP_
Orchestrator.OrchestratorPySearchInit(inGlobPatternStr="ControlPanel\CP_*.py")
# USAGE VAR 2 (with the def auto call) - for the backward compatibility CP for the Orchestrator ver. < 1.2.7
# Autoinit control panels starts with CP_
Orchestrator.OrchestratorPySearchInit(inGlobPatternStr="ControlPanel\CP_*.py", inDefStr="SettingsUpdate", inDefArgNameGSettingsStr="inGSettings")
# INFO: The code above will replace the code below
## !!! For Relative import !!! CP Version Check
try:
sys.path.insert(0,os.path.abspath(os.path.join(r"")))
from ControlPanel import CP_VersionCheck
CP_VersionCheck.SettingsUpdate(inGSettings=gSettings)
except Exception as e:
gSettings["Logger"].exception(f"Exception when init CP. See below.")
```
> # USAGE VAR 1 (without the def auto call)
> # Autoinit control panels starts with
> ```
> CP_
> ```
> Orchestrator.OrchestratorPySearchInit(inGlobPatternStr=”ControlPanelCP_\*.py”)
> # USAGE VAR 2 (with the def auto call) - for the backward compatibility CP for the Orchestrator ver. < 1.2.7
> # Autoinit control panels starts with
> ```
> CP_
> ```
> Orchestrator.OrchestratorPySearchInit(inGlobPatternStr=”ControlPanelCP_\*.py”, inDefStr=”SettingsUpdate”, inDefArgNameGSettingsStr=”inGSettings”)
> # INFO: The code above will replace the code below
> ## !!! For Relative import !!! CP Version Check
> try:
> > sys.path.insert(0,os.path.abspath(os.path.join(r””)))
> > from ControlPanel import CP_VersionCheck
> > CP_VersionCheck.SettingsUpdate(inGSettings=gSettings)
> except Exception as e:
> gSettings[“Logger”].exception(f”Exception when init CP. See below.”)
* **Parameters**
@ -1361,6 +1446,9 @@ except Exception as e:
* **inDefArgNameGSettingsStr** OPTIONAL The name of the GSettings argument in def (if exists)
* **inAsyncInitBool** OPTIONAL True - init py modules in many threads - parallel execution. False (default) - sequence execution
* **Returns**
@ -1401,11 +1489,15 @@ Fro example you can use:
### pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionRestore(inGSettings=None)
Check _SessionLast_RDPList.json and _SessionLast_StorageDict.pickle in working directory. if exist - load into gsettings
# _SessionLast_StorageDict.pickle (binary)
Check _SessioLast… files in working directory. if exist - load into gsettings
(from version 1.2.7)
> _SessionLast_GSettings.pickle (binary)
> _SessionLast_RDPList.json (encoding = “utf-8”)
> _SessionLast_StorageDict.pickle (binary)
(above the version 1.2.7)
_SessionLast_RDPList.json (encoding = “utf-8”)
_SessionLast_StorageDict.pickle (binary)
* **Parameters**
@ -1421,6 +1513,11 @@ Check _SessionLast_RDPList.json and _SessionLast_StorageDict.pickle in working d
### pyOpenRPA.Orchestrator.__Orchestrator__.OrchestratorSessionSave(inGSettings=None)
Orchestrator session save in file
(from version 1.2.7)
> _SessionLast_GSettings.pickle (binary)
(above the version 1.2.7)
_SessionLast_RDPList.json (encoding = “utf-8”)
_SessionLast_StorageDict.pickle (binary)
@ -1958,7 +2055,7 @@ lResultDict = Orchestrator.RDPSessionCMDRun(
### pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionConnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inHostStr=None, inPortStr=None, inLoginStr=None, inPasswordStr=None, inGSettings=None)
### pyOpenRPA.Orchestrator.__Orchestrator__.RDPSessionConnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inHostStr=None, inPortStr=None, inLoginStr=None, inPasswordStr=None, inGSettings=None, inRedirectClipboardBool=True)
Create new RDPSession in RobotRDPActive. Attention - activity will be ignored if RDP key is already exists
2 way of the use
@ -2342,7 +2439,7 @@ DEVELOPING, MAYBE NOT USEFUL Check RDP Session responsibility TODO NEED DEV + TE
### pyOpenRPA.Orchestrator.__Orchestrator__.RDPTemplateCreate(inLoginStr, inPasswordStr, inHostStr='127.0.0.1', inPortInt=3389, inWidthPXInt=1680, inHeightPXInt=1050, inUseBothMonitorBool=False, inDepthBitInt=32, inSharedDriveList=None)
### pyOpenRPA.Orchestrator.__Orchestrator__.RDPTemplateCreate(inLoginStr, inPasswordStr, inHostStr='127.0.0.1', inPortInt=3389, inWidthPXInt=1680, inHeightPXInt=1050, inUseBothMonitorBool=False, inDepthBitInt=32, inSharedDriveList=None, inRedirectClipboardBool=True)
Create RDP connect dict item/ Use it connect/reconnect (Orchestrator.RDPSessionConnect)
```
@ -2363,6 +2460,7 @@ lRDPItemDict = Orchestrator.RDPTemplateCreate(
# "Host": "127.0.0.1", "Port": "3389", "Login": "USER_99", "Password": "USER_PASS_HERE",
# "Screen": { "Width": 1680, "Height": 1050, "FlagUseAllMonitors": False, "DepthBit": "32" },
# "SharedDriveList": ["c"],
# "RedirectClipboardBool": True, # True - share clipboard to RDP; False - else
# ###### Will updated in program ############
# "SessionHex": "77777sdfsdf77777dsfdfsf77777777", # Hex is created when robot runs, example ""
# "SessionIsWindowExistBool": False, "SessionIsWindowResponsibleBool": False, "SessionIsIgnoredBool": False
@ -2400,6 +2498,9 @@ lRDPItemDict = Orchestrator.RDPTemplateCreate(
* **inSharedDriveList** Host local disc to connect to the RDP session. Example: [“c”, “d”]
* **inRedirectClipboardBool** # True - share clipboard to RDP; False - else
* **Returns**
@ -2419,6 +2520,7 @@ lRDPItemDict = Orchestrator.RDPTemplateCreate(
},
“SharedDriveList”: inSharedDriveList, # List of the Root sesion hard drives, example [“c”]
“RedirectClipboardBool”: True, # True - share clipboard to RDP; False - else
###### Will updated in program ############
“SessionHex”: “77777sdfsdf77777dsfdfsf77777777”, # Hex is created when robot runs, example “”
“SessionIsWindowExistBool”: False,
@ -2606,7 +2708,7 @@ Return user UAC hierarchy dict of the inRequest object. Empty dict - superuser a
### pyOpenRPA.Orchestrator.__Orchestrator__.WebAuditMessageCreate(inRequest, inOperationCodeStr='-', inMessageStr='-')
### pyOpenRPA.Orchestrator.__Orchestrator__.WebAuditMessageCreate(inRequest=None, inOperationCodeStr='-', inMessageStr='-')
Create message string with request user details (IP, Login etc…). Very actual for IT security in big company.
```
@ -2626,7 +2728,7 @@ lLogger.info(lWebAuditMessageStr)
* **Parameters**
* **inRequest** HTTP request handler
* **inRequest** HTTP request handler. Optional if call def from request thread
* **inOperationCodeStr** operation code in string format (actual for IT audit in control panels)
@ -2693,13 +2795,17 @@ Create listen interface for the web server
### pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyBytes(inRequest)
### pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestGet()
Return the web request instance if current thread was created by web request from client. else return None
### pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyBytes(inRequest=None)
Extract the body in bytes from the request
* **Parameters**
**inRequest** inRequest from the server
**inRequest** inRequest from the server. Optional if call def from request thread
@ -2709,13 +2815,13 @@ Extract the body in bytes from the request
### pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyJSON(inRequest)
### pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyJSON(inRequest=None)
Extract the body in dict/list from the request
* **Parameters**
**inRequest**
**inRequest** inRequest from the server. Optional if call def from request thread
@ -2725,13 +2831,13 @@ Extract the body in dict/list from the request
### pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyStr(inRequest)
### pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseBodyStr(inRequest=None)
Extract the body in str from the request
* **Parameters**
**inRequest** inRequest from the server
**inRequest** inRequest from the server. Optional if call def from request thread
@ -2741,13 +2847,13 @@ Extract the body in str from the request
### pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseFile(inRequest)
### pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParseFile(inRequest=None)
Parse the request - extract the file (name, body in bytes)
* **Parameters**
**inRequest**
**inRequest** inRequest from the server. Optional if call def from request thread
@ -2757,13 +2863,13 @@ Parse the request - extract the file (name, body in bytes)
### pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParsePath(inRequest)
### pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestParsePath(inRequest=None)
Parse the request - extract the url. Example: /pyOpenRPA/Debugging/DefHelper/…
* **Parameters**
**inRequest**
**inRequest** inRequest from the server. Optional if call def from request thread
@ -2773,12 +2879,22 @@ Parse the request - extract the url. Example: /pyOpenRPA/Debugging/DefHelper/…
### pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestResponseSend(inRequest, inResponeStr)
### pyOpenRPA.Orchestrator.__Orchestrator__.WebRequestResponseSend(inResponeStr, inRequest=None)
Send response for the request
:return:
### pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectDef(inMethodStr, inURLStr, inMatchTypeStr, inDef, inContentTypeStr='application/octet-stream', inGSettings=None)
* **Parameters**
**inRequest** inRequest from the server. Optional if call def from request thread
* **Returns**
### pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectDef(inMethodStr, inURLStr, inMatchTypeStr, inDef, inContentTypeStr='application/octet-stream', inGSettings=None, inUACBool=None)
> Connect URL to DEF
> “inMethodStr”:”GET|POST”,
@ -2794,23 +2910,26 @@ Send response for the request
* **inGSettings** Global settings dict (singleton)
* **inMethodStr**
* **inMethodStr** “GET|POST”,
* **inURLStr**
* **inURLStr** example “/index”, #URL of the request
* **inMatchTypeStr**
* **inMatchTypeStr** #”BeginWith|Contains|Equal|EqualCase”,
* **inDef**
* **inDef** def arg allowed list: 2:[inRequest, inGSettings], 1: [inRequest], 0: []
* **inContentTypeStr**
* **inContentTypeStr** default: “application/octet-stream”
* **inUACBool** default: None; True - check user access before do this URL item. None - get Server flag if ask user
### pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFile(inMethodStr, inURLStr, inMatchTypeStr, inFilePathStr, inContentTypeStr='application/octet-stream', inGSettings=None)
### pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFile(inMethodStr, inURLStr, inMatchTypeStr, inFilePathStr, inContentTypeStr='application/octet-stream', inGSettings=None, inUACBool=None)
Connect URL to File
“inMethodStr”:”GET|POST”,
@ -2840,14 +2959,18 @@ Connect URL to File
* **inContentTypeStr**
* **inUACBool** default: None; True - check user access before do this URL item. None - get Server flag if ask user
### pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFolder(inMethodStr, inURLStr, inMatchTypeStr, inFolderPathStr, inGSettings=None)
### pyOpenRPA.Orchestrator.__Orchestrator__.WebURLConnectFolder(inMethodStr, inURLStr, inMatchTypeStr, inFolderPathStr, inGSettings=None, inUACBool=None)
Connect URL to Folder
“inMethodStr”:”GET|POST”,
“inURLStr”: “/Folder/”, #URL of the request
“inMatchTypeStr”: “”, #”BeginWith|Contains|Equal|EqualCase”,
“inFolderPathStr”: “”, #Absolute or relative path
“inUACBool”
* **Parameters**
@ -2868,14 +2991,17 @@ Connect URL to Folder
* **inFolderPathStr**
* **inUACBool** default: None; True - check user access before do this URL item. None - get Server flag if ask user
### pyOpenRPA.Orchestrator.__Orchestrator__.WebUserInfoGet(inRequest)
### pyOpenRPA.Orchestrator.__Orchestrator__.WebUserInfoGet(inRequest=None)
Return User info about request
* **Parameters**
**inRequest**
**inRequest** inRequest from the server. Optional if call def from request thread
@ -2885,14 +3011,14 @@ Return User info about request
### pyOpenRPA.Orchestrator.__Orchestrator__.WebUserIsSuperToken(inRequest, inGSettings=None)
### pyOpenRPA.Orchestrator.__Orchestrator__.WebUserIsSuperToken(inRequest=None, inGSettings=None)
Return bool if request is authentificated with supetoken (token which is never expires)
* **Parameters**
* **inRequest**
* **inRequest** inRequest from the server. Optional if call def from request thread
* **inGSettings** Global settings dict (singleton)
@ -2905,13 +3031,13 @@ Return bool if request is authentificated with supetoken (token which is never e
### pyOpenRPA.Orchestrator.__Orchestrator__.WebUserUACHierarchyGet(inRequest)
### pyOpenRPA.Orchestrator.__Orchestrator__.WebUserUACHierarchyGet(inRequest=None)
Return User UAC Hierarchy DICT Return {…}
* **Parameters**
**inRequest**
**inRequest** inRequest from the server. Optional if call def from request thread

@ -114,18 +114,20 @@ def __Create__():
# "ResponseFilePath": "", #Absolute or relative path
# "ResponseFolderPath": "", #Absolute or relative path
# "ResponseContentType": "", #HTTP Content-type
# "ResponseDefRequestGlobal": None #Function with str result
# "ResponseDefRequestGlobal": None ,#Function with str result
# "UACBool": True # True - check user access before do this URL item. None - get Server flag if ask user
# }
#{
# "Method": "GET",
# "URL": "/test/", # URL of the request
# "MatchType": "BeginWith", # "BeginWith|Contains|Equal|EqualCase",
# # "ResponseFilePath": "", #Absolute or relative path
# "ResponseFolderPath": "C:\Abs\Archive\scopeSrcUL\OpenRPA\Orchestrator\Settings",
# # Absolute or relative path
# # "ResponseContentType": "", #HTTP Content-type
# # "ResponseDefRequestGlobal": None #Function with str result
# # "UACBool": True # True - check user access before do this URL item
#}
{
"Method": "GET",
"URL": "/test/", # URL of the request
"MatchType": "BeginWith", # "BeginWith|Contains|Equal|EqualCase",
# "ResponseFilePath": "", #Absolute or relative path
"ResponseFolderPath": "C:\Abs\Archive\scopeSrcUL\OpenRPA\Orchestrator\Settings",
# Absolute or relative path
# "ResponseContentType": "", #HTTP Content-type
# "ResponseDefRequestGlobal": None #Function with str result
}
],
},
@ -156,6 +158,7 @@ def __Create__():
],
},
"ManagersProcessDict":{}, # The key of the Process is (mAgentHostNameStr.upper(), mAgentUserNameStr.upper(), mProcessNameWOExeStr.upper())
"ManagersGitDict":{}, # The key of the Git instance is (mAgentHostNameStr.upper(), mAgentUserNameStr.upper(), mAbsPathUpperStr.upper())
"ProcessorDict": { # Has been changed. New general processor (one threaded) v.1.2.0
"ActivityList": [ # List of the activities
# {
@ -167,26 +170,13 @@ def __Create__():
# "GUIDStr": ..., # GUID of the activity
# },
],
"ActivityItemNowDict": None, # Activity Item which is executing now
"AliasDefDict": {}, # Storage for def with Str alias. To use it see pyOpenRPA.Orchestrator.ControlPanel
"CheckIntervalSecFloat": 1.0, # Interval for check gSettings in ProcessorDict > ActivityList
"ExecuteBool": True, # Flag to execute thread processor
"ThreadIdInt": None, # Technical field - will be setup when processor init
"WarningExecutionMoreThanSecFloat": 60.0 # Push warning if execution more than n seconds
},
# TODO REMOVE DEPRECATED KEYS IN v.2.0.0
"ControlPanelDict": { # Old structure > CPDict
"RefreshSeconds": 5, # deprecated parameter
"RobotList": [
#{
# "RenderFunction": RenderRobotR01,
# "KeyStr": "TestControlPanelKey"
#}
]
},
# TODO REMOVE DEPRECATED KEYS IN v.2.0.0
"CPDict": {
# "CPKey": {"HTMLRenderDef":None, "JSONGeneratorDef":None, "JSInitGeneratorDef":None}
},
# # # # # # # # # # # # # #
"RobotRDPActive": {
"RecoveryDict": {

@ -13,7 +13,8 @@ if __name__ == "__main__": # New init way - allow run as module -m PyOpenRPA.Orc
If you need more configurations - so you can see here:
```
import psutil, datetime, logging, os, sys # stdout from logging
import psutil, datetime, logging, os, sys
# Config settings
lPyOpenRPASourceFolderPathStr = r"..\Sources" # Path for test pyOpenRPA package
@ -28,10 +29,10 @@ from pyOpenRPA import Orchestrator # Import orchestrator main
if not Orchestrator.OrchestratorIsAdmin():
Orchestrator.OrchestratorRerunAsAdmin()
print(f"Orchestrator will be run as administrator!")
elif __name__ == "__main__": # New init way - allow run as module -m PyOpenRPA.Orchestrator
else:
gSettings = Orchestrator.GSettingsGet()
#gSettings = SettingsTemplate.Create(inModeStr="BASIC") # Create GSettings with basic configuration - no more config is available from the box - you can create own
Orchestrator.OrchestratorLoggerGet().setLevel(logging.INFO)
# TEST Add User ND - Add Login ND to superuser of the Orchestrator
lUACClientDict = SettingsTemplate.__UACClientAdminCreate__()
Orchestrator.UACUpdate(inGSettings=gSettings, inADLoginStr="ND", inADStr="", inADIsDefaultBool=True, inURLList=[], inRoleHierarchyAllowedDict=lUACClientDict)
@ -44,34 +45,10 @@ elif __name__ == "__main__": # New init way - allow run as module -m PyOpenRPA.O
# Restore DUMP
Orchestrator.OrchestratorSessionRestore(inGSettings=gSettings)
# Autoinit control panels starts with CP_
lPyModules = Orchestrator.OrchestratorPySearchInit(inGlobPatternStr="ControlPanel\\CP_*.py", inDefStr="SettingsUpdate", inDefArgNameGSettingsStr="inGSettings")
lPyModules = Orchestrator.OrchestratorPySearchInit(inGlobPatternStr="ControlPanel\\CP_*.py", inDefStr="SettingsUpdate", inDefArgNameGSettingsStr="inGSettings", inAsyncInitBool=True)
# Call the orchestrator def
Orchestrator.Orchestrator(inGSettings=gSettings, inDumpRestoreBool=False)
#import atexit
#def test():
# Orchestrator.OrchestratorLoggerGet().info(123)
#atexit.register(test)
import signal
import sys
from pyOpenRPA.Tools import Terminator
Terminator.Init(inLogger=Orchestrator.OrchestratorLoggerGet())
#def signal_term_handler(signal, frame):
# Orchestrator.OrchestratorLoggerGet().info('got SIGTERM')
# sys.exit(0)
#signal.signal(signal.SIGTERM, signal_term_handler)
import time
while not Terminator.IsSignalClose():
time.sleep(2)
print(999)
time.sleep(2)
else:
print("!WARNING! Current orchestrator settings do not support old type of the Orchestrator start. Use new Orchestrator type start (see v1.2.0)")
```

@ -17,10 +17,20 @@ lProcess = Orchestrator.Managers.Process(inAgentHostNameStr="PC-DESKTOP",inAgent
|
**Functions:**
| `ProcessExists`(inAgentHostNameStr, …)
| Check if the Process instance is exists in GSettings by the (inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
|
| `ProcessGet`(inAgentHostNameStr, …)
| Return the process instance by the inProcessNameWOExeStr
|
| `ProcessInitSafe`(inAgentHostNameStr, …[, …])
| Exception safe function.
|
| `ProcessManual2Auto`(inAgentHostNameStr, …)
@ -36,6 +46,11 @@ lProcess = Orchestrator.Managers.Process(inAgentHostNameStr="PC-DESKTOP",inAgent
| Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self):
|
| `ProcessScheduleStatusCheckEverySeconds`(…)
| Run status check every interval in second you specify.
|
| `ProcessStart`(inAgentHostNameStr, …[, …])
@ -46,6 +61,16 @@ lProcess = Orchestrator.Managers.Process(inAgentHostNameStr="PC-DESKTOP",inAgent
| Check if process is alive.
|
| `ProcessStatusRestore`(inAgentHostNameStr, …)
| Execute the StatusCheck, after that restore status to the saved state (see StatusSave).
|
| `ProcessStatusSave`(inAgentHostNameStr, …)
| Save current status of the process.
|
| `ProcessStatusStrGet`(inAgentHostNameStr, …)
@ -63,11 +88,14 @@ lProcess = Orchestrator.Managers.Process(inAgentHostNameStr="PC-DESKTOP",inAgent
|
### class pyOpenRPA.Orchestrator.Managers.Process.Process(inAgentHostNameStr, inAgentUserNameStr, inProcessNameWOExeStr, inStartPathStr=None, inStartCMDStr=None, inStopSafeTimeoutSecFloat=120)
### class pyOpenRPA.Orchestrator.Managers.Process.Process(inAgentHostNameStr, inAgentUserNameStr, inProcessNameWOExeStr, inStartPathStr=None, inStartCMDStr=None, inStopSafeTimeoutSecFloat=300, inStartArgDict=None, inStatusCheckIntervalSecFloat=30)
Manager process, which is need to be started / stopped / restarted
With Process instance you can automate your process activity. Use schedule package to set interval when process should be active and when not.
All defs in class are pickle safe! After orchestrator restart (if not the force stop of the orchestrator process) your instance with properties will be restored. But it not coverage the scheduler which is in __Orchestrator__ .
After orc restart you need to reinit all schedule rules: Orchestrator.OrchestratorScheduleGet
Process instance has the following statuses:
@ -89,14 +117,14 @@ Process instance has the following statuses:
* 5_STARTED_MANUAL
How to use StopSafe on the robot side
.. code-block:: python
> from pyOpenRPA.Tools import StopSafe
> StopSafe.Init(inLogger=None)
> StopSafe.IsSafeStop() # True - WM_CLOSE SIGNAL has come. taskkill /im someprocess.exe
**Methods:**
| `KeyTurpleGet`()
| Get the key turple of the current process
|
| `Manual2Auto`()
| Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self):
@ -132,12 +160,7 @@ How to use StopSafe on the robot side
| Manual/Auto restart safe.
|
| `ScheduleStatusCheckEverySeconds`([…])
| Run status check every interval in second you specify.
|
| `Start`([inIsManualBool])
| `Start`([inIsManualBool, inStartArgDict])
| Manual/Auto start.
@ -156,6 +179,11 @@ How to use StopSafe on the robot side
| Check if process is alive.
|
| `StatusCheckIntervalRestore`()
| Call from orchestrator when init
|
| `StatusCheckStart`()
@ -172,7 +200,17 @@ How to use StopSafe on the robot side
| Check process status and auto stop safe it if self.mStatusStr is 4_STARTED
|
| `StopForce`([inIsManualBool])
| `StatusRestore`()
| Execute the StatusCheck, after that restore status to the saved state (see StatusSave).
|
| `StatusSave`()
| Save current status of the process.
|
| `StopForce`([inIsManualBool, inMuteIgnoreBool])
| Manual/Auto stop force.
@ -182,17 +220,21 @@ How to use StopSafe on the robot side
| Stop force program if auto started (4_STARTED).
|
| `StopSafe`([inIsManualBool])
| `StopSafe`([inIsManualBool, …])
| Manual/Auto stop safe.
|
| `StopSafeCheck`()
| `StopSafeCheck`([inStopSafeTimeoutSecFloat])
| Stop safe program if auto started (4_STARTED).
|
#### KeyTurpleGet()
Get the key turple of the current process
#### Manual2Auto()
Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self):
@ -286,23 +328,7 @@ Manual stop safe will block scheduling execution. To return schedule execution u
#### ScheduleStatusCheckEverySeconds(inIntervalSecondsInt=120)
Run status check every interval in second you specify.
* **Parameters**
**inIntervalSecondsInt** Interval in seconds. Default is 120
* **Returns**
None
#### Start(inIsManualBool=True)
#### Start(inIsManualBool=True, inStartArgDict=None)
Manual/Auto start. Manual start will block scheduling execution. To return schedule execution use def Manual2Auto.
Will not start if STOP SAFE is now and dont start auto is stopped manual now
@ -339,7 +365,7 @@ Lof information about status change
#### StatusCheck()
Check if process is alive. The def will save the manual flag is exists.
Check if process is alive. The def will save the manual flag is exists. Dont wait mute but set mute if it is not set.
* **Returns**
@ -348,6 +374,10 @@ Check if process is alive. The def will save the manual flag is exists.
#### StatusCheckIntervalRestore()
Call from orchestrator when init
#### StatusCheckStart()
Check process status and run it if auto stopped self.mStatusStr is “0_STOPPED”
@ -377,7 +407,27 @@ Check process status and auto stop safe it if self.mStatusStr is 4_STARTED
#### StopForce(inIsManualBool=True)
#### StatusRestore()
Execute the StatusCheck, after that restore status to the saved state (see StatusSave). Work when orchestrator is restarted.
* **Returns**
Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
#### StatusSave()
Save current status of the process. After that you can restore process activity. Work when orchestrator is restarted. Dont save “STOP_SAFE” status > “STOPPED”
* **Returns**
Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
#### StopForce(inIsManualBool=True, inMuteIgnoreBool=False)
Manual/Auto stop force. Force stop dont wait process termination - it just terminate process now.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
@ -404,14 +454,18 @@ Stop force program if auto started (4_STARTED).
#### StopSafe(inIsManualBool=True)
#### StopSafe(inIsManualBool=True, inStopSafeTimeoutSecFloat=None)
Manual/Auto stop safe. Stop safe is the operation which send signal to process to terminate own work (send term signal to process). Managers.Process wait for the mStopSafeTimeoutSecFloat seconds. After that, if process is not terminated - self will StopForce it.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
* **Parameters**
**inIsManualBool** Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
* **inIsManualBool** Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
* **inStopSafeTimeoutSecFloat** Default value goes from the instance. You can specify time is second to wait while safe stop. After that program will stop force
@ -421,16 +475,45 @@ Manual stop safe will block scheduling execution. To return schedule execution u
#### StopSafeCheck()
#### StopSafeCheck(inStopSafeTimeoutSecFloat=None)
Stop safe program if auto started (4_STARTED).
* **Parameters**
**inStopSafeTimeoutSecFloat** Default value goes from the instance. You can specify time is second to wait while safe stop. After that program will stop force
* **Returns**
Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
### pyOpenRPA.Orchestrator.Managers.Process.ProcessExists(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
Check if the Process instance is exists in GSettings by the (inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
* **Parameters**
* **inAgentHostNameStr** Agent hostname in any case. Required to identify Process
* **inAgentUserNameStr** Agent user name in any case. Required to identify Process
* **inProcessNameWOExeStr** The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
* **Returns**
True - process exists in gsettings; False - else
### pyOpenRPA.Orchestrator.Managers.Process.ProcessGet(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
Return the process instance by the inProcessNameWOExeStr
@ -454,6 +537,39 @@ Return the process instance by the inProcessNameWOExeStr
### pyOpenRPA.Orchestrator.Managers.Process.ProcessInitSafe(inAgentHostNameStr, inAgentUserNameStr, inProcessNameWOExeStr, inStartPathStr=None, inStartCMDStr=None, inStopSafeTimeoutSecFloat=300)
Exception safe function. Check if process instance is not exists in GSettings (it can be after restart because Orchestrator restore objects from dump of the previous Orchestrator session)
Return existing instance (if exists) or create new instance and return it.
* **Parameters**
* **inAgentHostNameStr** Agent hostname in any case. Required to identify Process
* **inAgentUserNameStr** Agent user name in any case. Required to identify Process
* **inProcessNameWOExeStr** The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
* **inStartPathStr** Path to start process (.cmd/ .exe or something else). Path can be relative (from orc working directory) or absolute
* **inStartCMDStr** CMD script to start program (if no start file is exists)
* **inStopSafeTimeoutSecFloat** Time to wait for stop safe. After that do the stop force (if process is not stopped)
* **Returns**
Process instance
### pyOpenRPA.Orchestrator.Managers.Process.ProcessManual2Auto(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self):
@ -537,6 +653,32 @@ Remove Manual flag from process (if exists) - it will allow the schedule operati
### pyOpenRPA.Orchestrator.Managers.Process.ProcessScheduleStatusCheckEverySeconds(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inIntervalSecondsInt: int = 120)
Run status check every interval in second you specify.
* **Parameters**
* **inAgentHostNameStr** Agent hostname in any case. Required to identify Process
* **inAgentUserNameStr** Agent user name in any case. Required to identify Process
* **inProcessNameWOExeStr** The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
* **inIntervalSecondsInt** Interval in seconds. Default is 120
* **Returns**
None
### pyOpenRPA.Orchestrator.Managers.Process.ProcessStart(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inIsManualBool: bool = True)
Manual/Auto start. Manual start will block scheduling execution. To return schedule execution use def Manual2Auto
@ -602,6 +744,26 @@ Check if process is alive. The def will save the manual flag is exists.
### pyOpenRPA.Orchestrator.Managers.Process.ProcessStatusRestore(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
Execute the StatusCheck, after that restore status to the saved state (see StatusSave). Work when orchestrator is restarted.
* **Returns**
Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
### pyOpenRPA.Orchestrator.Managers.Process.ProcessStatusSave(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
Save current status of the process. After that you can restore process activity. Work when orchestrator is restarted. Dont save “STOP_SAFE” status > “STOPPED”
* **Returns**
Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
### pyOpenRPA.Orchestrator.Managers.Process.ProcessStatusStrGet(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
Get the status of the Process instance.
@ -668,7 +830,7 @@ Manual stop safe will block scheduling execution. To return schedule execution u
### pyOpenRPA.Orchestrator.Managers.Process.ProcessStopSafe(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inIsManualBool: bool = True)
### pyOpenRPA.Orchestrator.Managers.Process.ProcessStopSafe(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inIsManualBool: bool = True, inStopSafeTimeoutSecFloat=None)
Manual/Auto stop safe. Stop safe is the operation which send signal to process to terminate own work (send term signal to process). Managers.Process wait for the mStopSafeTimeoutSecFloat seconds. After that, if process is not terminated - self will StopForce it.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
@ -688,6 +850,9 @@ Manual stop safe will block scheduling execution. To return schedule execution u
* **inIsManualBool** Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
* **inStopSafeTimeoutSecFloat** Default value goes from the instance. You can specify time is second to wait while safe stop. After that program will stop force
* **Returns**
@ -713,10 +878,20 @@ Manual stop safe will block scheduling execution. To return schedule execution u
|
**Functions:**
| `ProcessExists`(inAgentHostNameStr, …)
| Check if the Process instance is exists in GSettings by the (inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
|
| `ProcessGet`(inAgentHostNameStr, …)
| Return the process instance by the inProcessNameWOExeStr
|
| `ProcessInitSafe`(inAgentHostNameStr, …[, …])
| Exception safe function.
|
| `ProcessManual2Auto`(inAgentHostNameStr, …)
@ -732,6 +907,11 @@ Manual stop safe will block scheduling execution. To return schedule execution u
| Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self):
|
| `ProcessScheduleStatusCheckEverySeconds`(…)
| Run status check every interval in second you specify.
|
| `ProcessStart`(inAgentHostNameStr, …[, …])
@ -742,6 +922,16 @@ Manual stop safe will block scheduling execution. To return schedule execution u
| Check if process is alive.
|
| `ProcessStatusRestore`(inAgentHostNameStr, …)
| Execute the StatusCheck, after that restore status to the saved state (see StatusSave).
|
| `ProcessStatusSave`(inAgentHostNameStr, …)
| Save current status of the process.
|
| `ProcessStatusStrGet`(inAgentHostNameStr, …)
@ -759,11 +949,14 @@ Manual stop safe will block scheduling execution. To return schedule execution u
|
### class pyOpenRPA.Orchestrator.Managers.Process.Process(inAgentHostNameStr, inAgentUserNameStr, inProcessNameWOExeStr, inStartPathStr=None, inStartCMDStr=None, inStopSafeTimeoutSecFloat=120)
### class pyOpenRPA.Orchestrator.Managers.Process.Process(inAgentHostNameStr, inAgentUserNameStr, inProcessNameWOExeStr, inStartPathStr=None, inStartCMDStr=None, inStopSafeTimeoutSecFloat=300, inStartArgDict=None, inStatusCheckIntervalSecFloat=30)
Manager process, which is need to be started / stopped / restarted
With Process instance you can automate your process activity. Use schedule package to set interval when process should be active and when not.
All defs in class are pickle safe! After orchestrator restart (if not the force stop of the orchestrator process) your instance with properties will be restored. But it not coverage the scheduler which is in __Orchestrator__ .
After orc restart you need to reinit all schedule rules: Orchestrator.OrchestratorScheduleGet
Process instance has the following statuses:
@ -785,14 +978,14 @@ Process instance has the following statuses:
* 5_STARTED_MANUAL
How to use StopSafe on the robot side
.. code-block:: python
> from pyOpenRPA.Tools import StopSafe
> StopSafe.Init(inLogger=None)
> StopSafe.IsSafeStop() # True - WM_CLOSE SIGNAL has come. taskkill /im someprocess.exe
**Methods:**
| `KeyTurpleGet`()
| Get the key turple of the current process
|
| `Manual2Auto`()
| Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self):
@ -828,12 +1021,7 @@ How to use StopSafe on the robot side
| Manual/Auto restart safe.
|
| `ScheduleStatusCheckEverySeconds`([…])
| Run status check every interval in second you specify.
|
| `Start`([inIsManualBool])
| `Start`([inIsManualBool, inStartArgDict])
| Manual/Auto start.
@ -852,6 +1040,11 @@ How to use StopSafe on the robot side
| Check if process is alive.
|
| `StatusCheckIntervalRestore`()
| Call from orchestrator when init
|
| `StatusCheckStart`()
@ -868,7 +1061,17 @@ How to use StopSafe on the robot side
| Check process status and auto stop safe it if self.mStatusStr is 4_STARTED
|
| `StopForce`([inIsManualBool])
| `StatusRestore`()
| Execute the StatusCheck, after that restore status to the saved state (see StatusSave).
|
| `StatusSave`()
| Save current status of the process.
|
| `StopForce`([inIsManualBool, inMuteIgnoreBool])
| Manual/Auto stop force.
@ -878,17 +1081,21 @@ How to use StopSafe on the robot side
| Stop force program if auto started (4_STARTED).
|
| `StopSafe`([inIsManualBool])
| `StopSafe`([inIsManualBool, …])
| Manual/Auto stop safe.
|
| `StopSafeCheck`()
| `StopSafeCheck`([inStopSafeTimeoutSecFloat])
| Stop safe program if auto started (4_STARTED).
|
#### KeyTurpleGet()
Get the key turple of the current process
#### Manual2Auto()
Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self):
@ -982,23 +1189,7 @@ Manual stop safe will block scheduling execution. To return schedule execution u
#### ScheduleStatusCheckEverySeconds(inIntervalSecondsInt=120)
Run status check every interval in second you specify.
* **Parameters**
**inIntervalSecondsInt** Interval in seconds. Default is 120
* **Returns**
None
#### Start(inIsManualBool=True)
#### Start(inIsManualBool=True, inStartArgDict=None)
Manual/Auto start. Manual start will block scheduling execution. To return schedule execution use def Manual2Auto.
Will not start if STOP SAFE is now and dont start auto is stopped manual now
@ -1035,7 +1226,7 @@ Lof information about status change
#### StatusCheck()
Check if process is alive. The def will save the manual flag is exists.
Check if process is alive. The def will save the manual flag is exists. Dont wait mute but set mute if it is not set.
* **Returns**
@ -1044,6 +1235,10 @@ Check if process is alive. The def will save the manual flag is exists.
#### StatusCheckIntervalRestore()
Call from orchestrator when init
#### StatusCheckStart()
Check process status and run it if auto stopped self.mStatusStr is “0_STOPPED”
@ -1073,7 +1268,27 @@ Check process status and auto stop safe it if self.mStatusStr is 4_STARTED
#### StopForce(inIsManualBool=True)
#### StatusRestore()
Execute the StatusCheck, after that restore status to the saved state (see StatusSave). Work when orchestrator is restarted.
* **Returns**
Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
#### StatusSave()
Save current status of the process. After that you can restore process activity. Work when orchestrator is restarted. Dont save “STOP_SAFE” status > “STOPPED”
* **Returns**
Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
#### StopForce(inIsManualBool=True, inMuteIgnoreBool=False)
Manual/Auto stop force. Force stop dont wait process termination - it just terminate process now.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
@ -1100,14 +1315,18 @@ Stop force program if auto started (4_STARTED).
#### StopSafe(inIsManualBool=True)
#### StopSafe(inIsManualBool=True, inStopSafeTimeoutSecFloat=None)
Manual/Auto stop safe. Stop safe is the operation which send signal to process to terminate own work (send term signal to process). Managers.Process wait for the mStopSafeTimeoutSecFloat seconds. After that, if process is not terminated - self will StopForce it.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
* **Parameters**
**inIsManualBool** Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
* **inIsManualBool** Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
* **inStopSafeTimeoutSecFloat** Default value goes from the instance. You can specify time is second to wait while safe stop. After that program will stop force
@ -1117,16 +1336,45 @@ Manual stop safe will block scheduling execution. To return schedule execution u
#### StopSafeCheck()
#### StopSafeCheck(inStopSafeTimeoutSecFloat=None)
Stop safe program if auto started (4_STARTED).
* **Parameters**
**inStopSafeTimeoutSecFloat** Default value goes from the instance. You can specify time is second to wait while safe stop. After that program will stop force
* **Returns**
Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
### pyOpenRPA.Orchestrator.Managers.Process.ProcessExists(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
Check if the Process instance is exists in GSettings by the (inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
* **Parameters**
* **inAgentHostNameStr** Agent hostname in any case. Required to identify Process
* **inAgentUserNameStr** Agent user name in any case. Required to identify Process
* **inProcessNameWOExeStr** The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
* **Returns**
True - process exists in gsettings; False - else
### pyOpenRPA.Orchestrator.Managers.Process.ProcessGet(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
Return the process instance by the inProcessNameWOExeStr
@ -1150,6 +1398,39 @@ Return the process instance by the inProcessNameWOExeStr
### pyOpenRPA.Orchestrator.Managers.Process.ProcessInitSafe(inAgentHostNameStr, inAgentUserNameStr, inProcessNameWOExeStr, inStartPathStr=None, inStartCMDStr=None, inStopSafeTimeoutSecFloat=300)
Exception safe function. Check if process instance is not exists in GSettings (it can be after restart because Orchestrator restore objects from dump of the previous Orchestrator session)
Return existing instance (if exists) or create new instance and return it.
* **Parameters**
* **inAgentHostNameStr** Agent hostname in any case. Required to identify Process
* **inAgentUserNameStr** Agent user name in any case. Required to identify Process
* **inProcessNameWOExeStr** The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
* **inStartPathStr** Path to start process (.cmd/ .exe or something else). Path can be relative (from orc working directory) or absolute
* **inStartCMDStr** CMD script to start program (if no start file is exists)
* **inStopSafeTimeoutSecFloat** Time to wait for stop safe. After that do the stop force (if process is not stopped)
* **Returns**
Process instance
### pyOpenRPA.Orchestrator.Managers.Process.ProcessManual2Auto(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
Remove Manual flag from process (if exists) - it will allow the schedule operations via def StatusCheckStart(self): def StatusCheckStorForce(self): def StatusCheckStopSafe(self):
@ -1233,6 +1514,32 @@ Remove Manual flag from process (if exists) - it will allow the schedule operati
### pyOpenRPA.Orchestrator.Managers.Process.ProcessScheduleStatusCheckEverySeconds(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inIntervalSecondsInt: int = 120)
Run status check every interval in second you specify.
* **Parameters**
* **inAgentHostNameStr** Agent hostname in any case. Required to identify Process
* **inAgentUserNameStr** Agent user name in any case. Required to identify Process
* **inProcessNameWOExeStr** The process name without extension .exe (the key of the Process instance). Any case - will be processed to the upper case
* **inIntervalSecondsInt** Interval in seconds. Default is 120
* **Returns**
None
### pyOpenRPA.Orchestrator.Managers.Process.ProcessStart(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inIsManualBool: bool = True)
Manual/Auto start. Manual start will block scheduling execution. To return schedule execution use def Manual2Auto
@ -1298,6 +1605,26 @@ Check if process is alive. The def will save the manual flag is exists.
### pyOpenRPA.Orchestrator.Managers.Process.ProcessStatusRestore(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
Execute the StatusCheck, after that restore status to the saved state (see StatusSave). Work when orchestrator is restarted.
* **Returns**
Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
### pyOpenRPA.Orchestrator.Managers.Process.ProcessStatusSave(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
Save current status of the process. After that you can restore process activity. Work when orchestrator is restarted. Dont save “STOP_SAFE” status > “STOPPED”
* **Returns**
Process status. See self.mStatusStr. 0_STOPPED 1_STOPPED_MANUAL 2_STOP_SAFE 3_STOP_SAFE_MANUAL 4_STARTED 5_STARTED_MANUAL
### pyOpenRPA.Orchestrator.Managers.Process.ProcessStatusStrGet(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str)
Get the status of the Process instance.
@ -1364,7 +1691,7 @@ Manual stop safe will block scheduling execution. To return schedule execution u
### pyOpenRPA.Orchestrator.Managers.Process.ProcessStopSafe(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inIsManualBool: bool = True)
### pyOpenRPA.Orchestrator.Managers.Process.ProcessStopSafe(inAgentHostNameStr: str, inAgentUserNameStr: str, inProcessNameWOExeStr: str, inIsManualBool: bool = True, inStopSafeTimeoutSecFloat=None)
Manual/Auto stop safe. Stop safe is the operation which send signal to process to terminate own work (send term signal to process). Managers.Process wait for the mStopSafeTimeoutSecFloat seconds. After that, if process is not terminated - self will StopForce it.
Manual stop safe will block scheduling execution. To return schedule execution use def Manual2Auto
@ -1384,6 +1711,9 @@ Manual stop safe will block scheduling execution. To return schedule execution u
* **inIsManualBool** Default is True - Mark this operation as manual - StatusCheckStart/Stop will be blocked - only StatusCheck will be working. False - Auto operation
* **inStopSafeTimeoutSecFloat** Default value goes from the instance. You can specify time is second to wait while safe stop. After that program will stop force
* **Returns**
@ -1440,6 +1770,9 @@ EnumerateDef: enumerate,
OperatorModule: operator,
MathModule: math
You can modify jinja context by use the function:
Jinja2DataUpdateDictSet
**Methods:**
| `DataDictGenerate`(inRequest)
@ -1712,6 +2045,9 @@ EnumerateDef: enumerate,
OperatorModule: operator,
MathModule: math
You can modify jinja context by use the function:
Jinja2DataUpdateDictSet
**Methods:**
| `DataDictGenerate`(inRequest)

@ -12,22 +12,17 @@ contain the root `toctree` directive. -->
! ATTENTION ! pyOpenRPA works only on MS Windows 7+/Server 2008+. Guys from Unix/Mac - sorry. We will come to you soon :)
## Donate
pyOpenRPA is absolutely non-commercial project.
Please donate some $ if pyOpenRPA project is actual for you. Link to online donations.
[https://yoomoney.ru/to/4100115560661986](https://yoomoney.ru/to/4100115560661986)
## About
Dear RPA-tors. Let me congratulate you with great change in the RPA world. Since 2019 the first enterprise level open source RPA platform is here!
pyOpenRPA is absolutely open source commercial project. Hosted by LLC PYOPENRPA (RUSSIA)
The pyOpenRPA - free, fast and reliable
Powerful OpenSource RPA tool for business (based on python 3). Best performance and absolutely free!
The pyOpenRPA is based on Python and using well known OpenSource solutions such as Selenium, OpenCV, Win32, UI automation and others. Thanks to it we were able to create consolidated platform with all possible features.
The pyOpenRPA is distributed under the MIT license which allows you to use it in any way you want and any time you need without any restrictions.
The pyOpenRPA is distributed under the PYOPENRPA license.
At the time of this writing the pyOpenRPA is successfully using in several big Russian companies. Companies in which it was decided to develop own RPA division with no dependencies on expensive licenses.
## Repo structure

Loading…
Cancel
Save