diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/INSTALLER b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/INSTALLER similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/INSTALLER rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/INSTALLER diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/METADATA b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/METADATA similarity index 99% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/METADATA rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/METADATA index ee047299..be5fb345 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/METADATA +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyOpenRPA -Version: 1.2.12 +Version: 1.2.13 Summary: First open source RPA platform for business Home-page: https://pyopenrpa.ru/ Author: Ivan Maslov diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/RECORD b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/RECORD similarity index 96% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/RECORD rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/RECORD index 4f6a71f0..a559ce98 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/RECORD +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/RECORD @@ -1,9 +1,9 @@ -pyOpenRPA-1.2.12.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pyOpenRPA-1.2.12.dist-info/METADATA,sha256=AmdWISfrdsF9DvjBrn42JJUXBb-TLln5OFBWKxX0VaE,4111 -pyOpenRPA-1.2.12.dist-info/RECORD,, -pyOpenRPA-1.2.12.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pyOpenRPA-1.2.12.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 -pyOpenRPA-1.2.12.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 +pyOpenRPA-1.2.13.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pyOpenRPA-1.2.13.dist-info/METADATA,sha256=HrNqM4-bPHXjqazFT4215H6pPafnYdCqattouxZIzVc,4111 +pyOpenRPA-1.2.13.dist-info/RECORD,, +pyOpenRPA-1.2.13.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pyOpenRPA-1.2.13.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 +pyOpenRPA-1.2.13.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 @@ -26,9 +26,9 @@ pyOpenRPA/LICENSE.pdf,sha256=HEqffy8FIWpylw0zF7k-Wgwd8ppWQT9s9EGBgKV-6G8,321175 pyOpenRPA/Orchestrator/BackwardCompatibility.py,sha256=ABr0RugbBsIGdL5GE_EFC9QndSaKjvrjawvluhUNuMY,37795 pyOpenRPA/Orchestrator/ControlPanel.py,sha256=OzS8HjG__8OZgqhajr8L8owyugXPuSLWHLtXuKdEP78,103 pyOpenRPA/Orchestrator/Core.py,sha256=OHa3mSC3_wRAizqrWBVjlR6ln4-xVVvBpOSnWl6qVvY,529 -pyOpenRPA/Orchestrator/Managers/ControlPanel.py,sha256=BgtLjb6PR6kTlOjPLCg2YGP458LS9JOaYEfNurhS0nk,16544 +pyOpenRPA/Orchestrator/Managers/ControlPanel.py,sha256=XpmN_LB--phNq4VpsbdWHJC6ybIt7jWBsl6HKfxHP1I,16550 pyOpenRPA/Orchestrator/Managers/Git.py,sha256=dgXx2UzSwiEev4ov2hBbb-5MhXVhFKWZo2lmr19QSCQ,12582 -pyOpenRPA/Orchestrator/Managers/Process.py,sha256=7T_qofdkRJHdPQbaiEsTDOboImSf2N6d_Ku513rURkw,41369 +pyOpenRPA/Orchestrator/Managers/Process.py,sha256=DYX1pBK4gaxcfmDj-1OaLNyk83D_R_7ztZyt0SHWoik,41377 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,, @@ -81,7 +81,7 @@ pyOpenRPA/Orchestrator/Web/Index.js,sha256=YACiZAvjr6NmFlDhQu6urkJp49BX7L8WJU9p- pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=5JUAs5rEiU0XtHM9QO6EdNMBGt-W6QOVGY7xJ_HLPFM,19257 pyOpenRPA/Orchestrator/Web/__pycache__/Basic.cpython-37.pyc,, pyOpenRPA/Orchestrator/Web/favicon.ico,sha256=6S8XwSQ_3FXPpaX6zYkf8uUewVXO9bHnrrDHEoWrEgw,112922 -pyOpenRPA/Orchestrator/__Orchestrator__.py,sha256=Zud6HTAHSsfTJVrszML5EjGTqlA7k5qhthZTsSD1pX8,151055 +pyOpenRPA/Orchestrator/__Orchestrator__.py,sha256=rlM-j8LK4BdcPfI8KNMOi1Rq-Ht8kCLs6WYsPBZgDTU,203081 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,, @@ -270,15 +270,15 @@ pyOpenRPA/Resources/Web/Semantic-UI-CSS-master/themes/default/assets/fonts/outli pyOpenRPA/Resources/Web/Semantic-UI-CSS-master/themes/default/assets/images/flags.png,sha256=lNXH8WYTAcSm3Ekdct1VmgYgzZF6gm8N8bAju5bqnd0,28123 pyOpenRPA/Resources/Web/jQuery/jquery-3.1.1.min.js,sha256=HPMOWdIdSuVgr3FD9ZE-_MgiK8qk_MdQjrgCtfqp6U4,86713 pyOpenRPA/Resources/Web/pyOpenRPA_logo.png,sha256=7rulXo_C57xJQEaYWmAkChxXb6xbDW2zq-werzVbDbc,4899 -pyOpenRPA/Robot/Clipboard.py,sha256=q76X8L21zJwcwdoJJNPeCEwAV30xS6ylHP1WwvtxoWI,722 -pyOpenRPA/Robot/Keyboard.py,sha256=k_5uNh7UWq5F4TKGbe4LpJwqWgUrftNieWm51HOgOBI,22 -pyOpenRPA/Robot/Mouse.py,sha256=tBW9yteyEv9znJePOfbZcU3YqxX42wyu4Wc09fVaO0c,23 +pyOpenRPA/Robot/Clipboard.py,sha256=ntvXqnJpgmTPnehrjfVibrM72-AYLrqOn-CI2xVOaDs,1577 +pyOpenRPA/Robot/Keyboard.py,sha256=6Ah71EaETse2_nPiz8EPW_fZBlhpaZg5WZ6tWZ2wC9U,17898 +pyOpenRPA/Robot/Mouse.py,sha256=Wvai_tpanqREj5jA4tFEl_-0L45cpk41cX5_Ex68mBg,16079 pyOpenRPA/Robot/OrchestratorConnector.py,sha256=JUtdiUXCruqUqBD19gJBl9jk_b-tpWWx_v3MfBoKzoQ,20445 -pyOpenRPA/Robot/README.md,sha256=e2hKh7Tx6DAsX6jY_hBDhguL1L2Wiv6iugDB5otMzIA,2293 +pyOpenRPA/Robot/README.md,sha256=bwiTAygxuMZzBlwpsndw2QgxA2smIjUyOPZnsnR341k,1623 pyOpenRPA/Robot/Screen.py,sha256=tBW9yteyEv9znJePOfbZcU3YqxX42wyu4Wc09fVaO0c,23 pyOpenRPA/Robot/SettingsTemplate.py,sha256=Rp5XPeV2I4tCS2uf4Zkqm_ERJ6pZMg4-e5_lMqGJYLk,1453 pyOpenRPA/Robot/Test.py,sha256=qXr990nXiFZX5SNv6QN9GLb_U4HZRmJnbZR2qSnwilY,2878 -pyOpenRPA/Robot/UIDesktop.py,sha256=EllVup0umNNFqcQrrO6pffdoTBzc5Y-jEKrY0oO7joU,82938 +pyOpenRPA/Robot/UIDesktop.py,sha256=y0lHHtn-Cd7I1rUQGgBYfZQpfcrGBAfMST9F5aPIxtM,124815 pyOpenRPA/Robot/UIWeb.py,sha256=NFH0brDKEmWWOJxMzO7404K5lJ4LaDn5XMnkoH13Y64,22 pyOpenRPA/Robot/Utils/JSONNormalize.py,sha256=aIuVzuZDazhxkCOzoOjfhHVz66mp2FWdfPv5E7KWF5Y,3890 pyOpenRPA/Robot/Utils/ProcessBitness.py,sha256=WlKL-DklGaoTnchtapOTM_ydxSB4yOeo9lcG3zr2VME,4524 @@ -364,6 +364,6 @@ pyOpenRPA/Tools/__pycache__/License.cpython-37.pyc,, pyOpenRPA/Tools/__pycache__/StopSafe.cpython-37.pyc,, pyOpenRPA/Tools/__pycache__/Usage.cpython-37.pyc,, pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,, -pyOpenRPA/__init__.py,sha256=fmC6rG7L4TIer8c0qUyp-Ypv2d7C2TBucEjIg7Wwip4,175 +pyOpenRPA/__init__.py,sha256=Q9zi3T0F5hLslWv3SoO1EvZt17wEU5fq3JJ59uqdtg8,156 pyOpenRPA/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/test.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/REQUESTED b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/REQUESTED similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/REQUESTED rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/REQUESTED diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/WHEEL b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/WHEEL similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/WHEEL rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/WHEEL diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/top_level.txt b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/top_level.txt similarity index 100% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/top_level.txt rename to Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/top_level.txt diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/ControlPanel.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/ControlPanel.py index cef4acd4..599eed11 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/ControlPanel.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/ControlPanel.py @@ -39,6 +39,7 @@ class ControlPanel(): 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") diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/Process.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/Process.py index 276e4adc..ff47c075 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/Process.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/Process.py @@ -22,6 +22,7 @@ class Process(): - 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) @@ -35,6 +36,7 @@ class Process(): 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 diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/__Orchestrator__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/__Orchestrator__.py index b47d891d..dca95b25 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/__Orchestrator__.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Orchestrator/__Orchestrator__.py @@ -41,13 +41,13 @@ gSettingsDict = None def AgentActivityItemAdd(inHostNameStr, inUserStr, inActivityItemDict, inGSettings=None): """ - Add activity in AgentDict. Check if item is created + Добавить активность в словарь активностей выбранного Агента - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: Agent host name - :param inUserStr: User login, where agent is based - :param inActivityItemDict: ActivityItem - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inActivityItemDict: Активность (ActivityItem). См. функцию ProcessorActivityitemCreate + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -72,11 +72,11 @@ def AgentActivityItemAdd(inHostNameStr, inUserStr, inActivityItemDict, inGSettin def AgentActivityItemExists(inHostNameStr, inUserStr, inGUIDStr, inGSettings = None): """ - Check by GUID if ActivityItem has exists in request list. If exist - the result response has not been recieved from the agent + Выполнить проверку, что активность (ActivityItem) была отправлена на сторону Агента. - :param inGSettings: Global settings dict (singleton) - :param inGUIDStr: GUID String of the ActivityItem - :return: True - ActivityItem is exist in AgentDict ; False - else case + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inGUIDStr: ГУИД (GUID) активности (ActivityItem) + :return: True - Активность присутствует ; False - Активность еще не была отправлена на сторону Агента """ # Check if GUID is exists in dict - has been recieved inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -92,11 +92,11 @@ def AgentActivityItemExists(inHostNameStr, inUserStr, inGUIDStr, inGSettings = N def AgentActivityItemReturnExists(inGUIDStr, inGSettings = None): """ - Check by GUID if ActivityItem has been executed and result has come to the Orchestrator + Выполнить проверку, что активность (ActivityItem) была выполнена на стороне Агента и результат был получен на стороне Оркестратора. - :param inGSettings: Global settings dict (singleton) - :param inGUIDStr: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! - :return: True - result has been received from the Agent to orc; False - else case + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inGUIDStr: ГУИД (GUID) активности (ActivityItem) + :return: True - Активность присутствует; False - Активность еще не была выполнена на стороне Агента """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -106,14 +106,15 @@ def AgentActivityItemReturnExists(inGUIDStr, inGSettings = None): def AgentActivityItemReturnGet(inGUIDStr, inCheckIntervalSecFloat = 0.5, inGSettings=None): """ - Work synchroniously! Wait while result will be recieved. Get the result of the ActivityItem execution on the Agent side. Before this please check by the def AgentActivityItemReturnExists that result has come to the Orchestrator - - !ATTENTION! Use only after Orchestrator initialization! Before orchestrator init exception will be raised. + Ожидает появления результата по активности (ActivityItem). Возвращает результат выполнения активности. + + !ВНИМАНИЕ! Замораживает поток, пока не будет получен результат. + !ВНИМАНИЕ! Запускать следует после того как будет инициализировано ядро Оркестратора (см. функцию OrchestratorInitWait), иначе будет инициирована ошибка. - :param inGSettings: Global settings dict (singleton) - :param inGUIDStr: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! - :param inCheckIntervalSecFloat: Interval in sec of the check Activity Item result - :return: Result of the ActivityItem executed on the Agent side anr transmitted to the Orchestrator. IMPORTANT! ONLY JSON ENABLED Types CAN BE TRANSMITTED TO ORCHESTRATOR! + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inGUIDStr: ГУИД (GUID) активности (ActivityItem) + :param inCheckIntervalSecFloat: Интервал в секундах, с какой частотой выполнять проверку результата. По умолчанию 0.5 + :return: Результат выполнения активности. !ВНИМАНИЕ! Возвращаются только то результаты, которые могут быть интерпретированы в JSON формате. """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings #Check if Orchestrator has been initialized - else raise exception @@ -128,17 +129,17 @@ def AgentActivityItemReturnGet(inGUIDStr, inCheckIntervalSecFloat = 0.5, inGSett def 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 + Отправка команды командной строки на сессию, где работает pyOpenRPA.Agent. Результат выполнения команды можно выводить в лог оркестратора. - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: Agent host name in upper case (example "RPA01", "RPA_99" and so on). Active agent session you can see on the orchestrator dashboard as Orchestrator admin - :param inUserStr: Agent user name in upper case (example "UserRPA"). Active agent session you can see on the orchestrator dashboard as Orchestrator admin - :param inCMDStr: command to execute on the Agent session - :param inRunAsyncBool: True - Agent processor don't wait execution; False - Agent processor wait cmd execution - :param inSendOutputToOrchestratorLogsBool: True - catch cmd execution output and send it to the Orchestrator logs; Flase - else case; Default True - :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: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inCMDStr: Команда для исполнения на стороне сессии Агента + :param inRunAsyncBool: True - Агент не ожидает окончания выполнения команды. !ВНИМАНИЕ! Логирование в такой ситуации будет невозможно; False - Агент ожидает окончания выполнения операции. + :param inSendOutputToOrchestratorLogsBool: True - отправлять весь вывод от команды в логи Оркестратора; Flase - Не отправлять; Default True + :param inCMDEncodingStr: Кодировка DOS среды, в которой исполняется команда. Если некорректно установить кодировку - русские символы будут испорчены. По умолчанию установлена "cp1251" + :param inCaptureBool: True - не запускать приложение как отдельное. Результат выполнения команды будет выводиться в окне Агента (если окно Агента присутствует на экране). False - команда будет запущена в отдельном DOS окне. + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lActivityItemDict = { @@ -153,9 +154,11 @@ def AgentOSCMD(inHostNameStr, inUserStr, inCMDStr, inRunAsyncBool=True, inSendOu def AgentOSLogoff(inHostNameStr, inUserStr): """ - Logoff the agent user session + Выполнить операцию logoff на стороне пользователя. - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet() # Set the global settings lCMDStr = "shutdown /l" @@ -171,16 +174,17 @@ def AgentOSLogoff(inHostNameStr, inUserStr): def 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 - Thread safe - you can call def even if you dont init the orchestrator - def will be executed later + Отправить файл по адресу inOrchestratorFilePathStr со стороны Оркестратора и сохранить по адресу inAgentFilePathStr на стороне Агента. + Поддерживает передачу крупных файлов (более 2-х Гб.). Функция является синхронной - не закончит свое выполнение, пока файл не будет передан полностью. - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: - :param inFileDataBytes: - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + !ВНИМАНИЕ - ПОТОКОБЕЗОПАСНАЯ! Вы можете вызвать эту функцию до инициализации ядра Оркестратора. Оркестратор добавит эту функцию в процессорную очередь на исполение. Если вам нужен результат функции, то необходимо сначала убедиться в том, что ядро Оркестратора было инициализированно (см. функцию OrchestratorInitWait). + + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inOrchestratorFilePathStr: Полный путь к передаваемому файлу на стороне Оркестратора. + :param inAgentFilePathStr: Полный путь к локации, в которую требуется сохранить передаваемый файл. + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -237,14 +241,14 @@ def AgentOSFileSend(inHostNameStr, inUserStr, inOrchestratorFilePathStr, inAgent def AgentOSFileBinaryDataBytesCreate(inHostNameStr, inUserStr, inFilePathStr, inFileDataBytes, inGSettings=None): """ - Create binary file by the base64 string by the pyOpenRPA.Agent daemon process (safe for JSON transmition) + Создать бинарный файл, который будет расположен по адресу inFilePathStr на стороне Агента с содержимым inFileDataBytes - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: - :param inFileDataBytes: - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inFilePathStr: Полный путь к сохраняемому файлу на стороне Агента. + :param inFileDataBytes: Строка байт (b'') для отправки в создаваемый файл на стороне Агента. + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lFileDataBase64Str = base64.b64encode(inFileDataBytes).decode("utf-8") @@ -261,14 +265,14 @@ def AgentOSFileBinaryDataBytesCreate(inHostNameStr, inUserStr, inFilePathStr, in def AgentOSFileBinaryDataBase64StrCreate(inHostNameStr, inUserStr, inFilePathStr, inFileDataBase64Str, inGSettings=None): """ - Create binary file by the base64 string by the pyOpenRPA.Agent daemon process (safe for JSON transmission) - - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: - :param inFileDataBase64Str: - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + Создать бинарный файл, который будет расположен по адресу inFilePathStr на стороне Агента с содержимым, декодированным с формата base64: inFileDataBase64Str + + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inFilePathStr: Полный путь к сохраняемому файлу на стороне Агента. + :param inFileDataBase64Str: Строка в формате base64 для отправки в создаваемый файл на стороне Агента. + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lActivityItemDict = { @@ -284,14 +288,14 @@ def AgentOSFileBinaryDataBase64StrCreate(inHostNameStr, inUserStr, inFilePathStr def AgentOSFileBinaryDataBase64StrAppend(inHostNameStr, inUserStr, inFilePathStr, inFileDataBase64Str, inGSettings = None): """ - Append binary file by the base64 string by the pyOpenRPA.Agent daemon process (safe for JSON transmission) - - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: - :param inFileDataBase64Str: - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + Добавить бинарную информацию в существующий бинарный файл, который будет расположен по адресу inFilePathStr на стороне Агента с содержимым, декодированным с формата base64: inFileDataBase64Str + + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inFilePathStr: Полный путь к сохраняемому файлу на стороне Агента. + :param inFileDataBase64Str: Строка в формате base64 для отправки в создаваемый файл на стороне Агента. + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lActivityItemDict = { @@ -308,15 +312,15 @@ def AgentOSFileBinaryDataBase64StrAppend(inHostNameStr, inUserStr, inFilePathStr # Send text file to Agent (string) def AgentOSFileTextDataStrCreate(inHostNameStr, inUserStr, inFilePathStr, inFileDataStr, inEncodingStr = "utf-8",inGSettings=None): """ - Create text file by the string by the pyOpenRPA.Agent daemon process - - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: - :param inFileDataStr: - :param inEncodingStr: - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + Создать текстовый файл, который будет расположен по адресу inFilePathStr на стороне Агента с содержимым inFileDataStr в кодировке inEncodingStr + + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inFilePathStr: Полный путь к сохраняемому файлу на стороне Агента. + :param inFileDataStr: Строка для отправки в создаваемый файл на стороне Агента. + :param inEncodingStr: Кодировка текстового файла. По умолчанию utf-8 + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lActivityItemDict = { @@ -331,13 +335,13 @@ def AgentOSFileTextDataStrCreate(inHostNameStr, inUserStr, inFilePathStr, inFile def AgentOSFileBinaryDataBase64StrReceive(inHostNameStr, inUserStr, inFilePathStr, inGSettings = None): """ - Read binary file and encode in base64 to transmit (safe for JSON transmition) + Выполнить чтение бинарного файла и получить содержимое в формате base64 (строка) - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: File path to read - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inFilePathStr: Путь к бинарному файлу на чтение на стороне Агента + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lActivityItemDict = { @@ -353,13 +357,14 @@ def AgentOSFileBinaryDataBase64StrReceive(inHostNameStr, inUserStr, inFilePathSt def AgentOSFileBinaryDataReceive(inHostNameStr, inUserStr, inFilePathStr): """ - Read binary file from agent (synchronious) - - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: File path to read - :return: file data bytes + Чтение бинарного файла на стороне Агента по адресу inFilePathStr. + + !ВНИМАНИЕ - СИНХРОННАЯ! Функция не завершится, пока не будет получен результат чтения на стороне Агента. + + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inFilePathStr: Путь к бинарному файлу, который требуется прочитать на стороне Агента + :return: Строка байт (b'') - содержимое бинарного файла """ lFileDataBytes = None inGSettings = GSettingsGet() # Set the global settings @@ -391,14 +396,16 @@ def AgentOSFileBinaryDataReceive(inHostNameStr, inUserStr, inFilePathStr): def AgentOSFileTextDataStrReceive(inHostNameStr, inUserStr, inFilePathStr, inEncodingStr="utf-8", inGSettings = None): """ - Read text file in the agent GUI session - - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: File path to read - :param inEncodingStr: Text file encoding. Default 'utf-8' - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + Чтение текстового файла на стороне Агента по адресу inFilePathStr. По ГИУД с помощью функции AgentActivityItemReturnGet можно будет получить текстовую строку данных, которые были расположены в файле. + + !ВНИМАНИЕ - АСИНХРОННАЯ! Функция завершится сразу, не дожидаясь окончания выполнения операции на стороне Агента. + + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inFilePathStr: Путь к бинарному файлу, который требуется прочитать на стороне Агента + :param inEncodingStr: Кодировка текстового файла. По умолчанию utf-8 + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lActivityItemDict = { @@ -413,12 +420,14 @@ def AgentOSFileTextDataStrReceive(inHostNameStr, inUserStr, inFilePathStr, inEnc def AgentProcessWOExeUpperUserListGet(inHostNameStr, inUserStr, inGSettings = None): """ - Return the process list only for the current user (where Agent is running) without .EXE in upper case. Can use in ActivityItem from Orchestrator to Agent + Получить список процессов, которые выполняется на сессии Агента. Все процессы фиксируются без постфикса .exe, а также в верхнем регистре. + + ПРИМЕР РЕЗУЛЬТАТА, КОТОРЫЙ МОЖНО ПОЛУЧИТЬ ПО ГУИД ЧЕРЕЗ ФУНКЦИЮ AgentActivityItemReturnGet: ["ORCHESTRATOR", "AGENT", "CHROME", "EXPLORER", ...] - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lActivityItemDict = { @@ -432,22 +441,22 @@ def AgentProcessWOExeUpperUserListGet(inHostNameStr, inUserStr, inGSettings = No return AgentActivityItemAdd(inGSettings=inGSettings, inHostNameStr=inHostNameStr, inUserStr=inUserStr, inActivityItemDict=lActivityItemDict) # OS DEFS - def OSLogoff(): """ - Logoff the current orchestrator session + Выполнить отключение сессии, на которой выполняется Оркестратор. + :return: """ os.system("shutdown /l") def OSCredentialsVerify(inUserStr, inPasswordStr, inDomainStr=""): ## """ - Verify user credentials in windows. Return bool + Выполнить верификацию доменного (локального) пользователя по паре логин/пароль - :param inUserStr: - :param inPasswordStr: - :param inDomainStr: - :return: True - Credentials are actual; False - Credentials are not actual + :param inUserStr: Наименование пользователя + :param inPasswordStr: Пароль + :param inDomainStr: Домен. Если домена нет - не указывать или "" + :return: True - Учетные данные верны; False - Учетные данные представлены некорректно """ try: hUser = win32security.LogonUser( @@ -461,12 +470,13 @@ def OSCredentialsVerify(inUserStr, inPasswordStr, inDomainStr=""): ## def OSRemotePCRestart(inHostStr, inForceBool=True, inLogger = None): """ - Send signal via power shell to restart remote PC - ATTENTION: Orchestrator user need to have restart right on the Remote machine to restart PC. + Отправить сигнал на удаленную перезагрузку операционной системы. + + !ВНИМАНИЕ! Перезапуск будет принят, если учетная запись имеет полномочия на перезапуск на соответсвующей машине. - :param inLogger: logger to log powershell result in logs - :param inHostStr: PC hostname which you need to restart. - :param inForceBool: True - send signal to force retart PC; False - else case + :param inHostStr: Имя хоста, который требуется перезагрузить + :param inForceBool: True - принудительная перезагрузка; False - мягкая перезагрузка (дождаться окончания выполнения всех операций). По умолчанию True + :param inLogger: Логгер, в который отправлять информацию о результате выполнения команды :return: """ if inLogger is None: inLogger = OrchestratorLoggerGet() @@ -476,12 +486,12 @@ def OSRemotePCRestart(inHostStr, inForceBool=True, inLogger = None): def OSCMD(inCMDStr, inRunAsyncBool=True, inLogger = None): """ - OS send command in shell locally + Отправить команду на выполнение на сессию, где выполняется Оркестратор. - :param inCMDStr: - :param inRunAsyncBool: - :param inLogger: - :return: CMD result string + :param inCMDStr: Команда на отправку + :param inRunAsyncBool: True - выполнить команду в асинхронном режиме (не дожидаться окончания выполнения программы и не захватывать результат выполнения); False - Ждать окончания выполнения и захватывать результат + :param inLogger: Логгер, в который отправлять информацию о результате выполнения команды + :return: Строка результата выполнения команды. Если inRunAsyncBool = False """ if inLogger is None: inLogger = OrchestratorLoggerGet() lResultStr = "" @@ -521,9 +531,9 @@ def OSCMD(inCMDStr, inRunAsyncBool=True, inLogger = None): def OrchestratorRestart(inGSettings=None): """ - Orchestrator restart + Перезапуск Оркестратора с сохранением информации о запущенных RDP сессиях. - :param inGSettings: Global settings dict (singleton) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings OrchestratorSessionSave(inGSettings=inGSettings) # Dump RDP List in file json @@ -536,27 +546,27 @@ def OrchestratorRestart(inGSettings=None): def OrchestratorLoggerGet() -> logging.Logger: """ - Get the logger from the Orchestrator + Получить логгер Оркестратора - :return: + :return: Логгер """ return GSettingsGet().get("Logger",None) def OrchestratorScheduleGet() -> schedule: """ - Get the schedule (schedule.readthedocs.io) from the Orchestrator - - Fro example you can use: + Базовый объект расписания, который можно использовать для запуска / остановки роботов. + Подробнее про объект schedule и его примеры использования см. по адресу: schedule.readthedocs.io .. code-block:: python - # One schedule threaded + + # Однопоточный schedule Orchestrator.OrchestratorScheduleGet().every(5).seconds.do(lProcess.StatusCheckStart) - #New schedule thread # See def description Orchestrator.OrchestratorThreadStart + #Многопоточный schedule. cм. описание Orchestrator.OrchestratorThreadStart Orchestrator.OrchestratorScheduleGet().every(5).seconds.do(Orchestrator.OrchestratorThreadStart,lProcess.StatusCheckStart) - :return: schedule module. Example see here https://schedule.readthedocs.io/en/stable/examples.html + :return: schedule объект """ if GSettingsGet().get("SchedulerDict",{}).get("Schedule",None) is None: GSettingsGet()["SchedulerDict"]["Schedule"]=schedule @@ -564,12 +574,12 @@ def OrchestratorScheduleGet() -> schedule: def OrchestratorThreadStart(inDef, *inArgList, **inArgDict): """ - Execute def in new thread and pass some args with list and dict types + Запустить функцию в отдельном потоке. В таком случае получить результат выполнения функции можно только через общие переменные. (Например через GSettings) - :param inDef: Python Def - :param inArgList: args as list - :param inArgDict: args as dict - :return: threading.Thread object + :param inDef: Python функция + :param inArgList: Список неименованных аргументов функции inDef + :param inArgDict: Словарь именованных аргументов функции inDef + :return: threading.Thread экземпляр """ lDefThread = threading.Thread(target=inDef,args=inArgList,kwargs=inArgDict) lDefThread.start() @@ -577,9 +587,9 @@ def OrchestratorThreadStart(inDef, *inArgList, **inArgDict): def OrchestratorIsAdmin(): """ - Check if Orchestrator process is running as administrator + Проверить, запущен ли Оркестратор с правами администратора. Права администратора нужны Оркестратору только для контроля графической сессии, на которой он запущен. Если эти права выделить индивидуально, то права администратора будут необязательны. - :return: True - run as administrator; False - not as administrator + :return: True - Запущен с правами администратора; False - Не запущен с правами администратора """ try: return ctypes.windll.shell32.IsUserAnAdmin() @@ -587,17 +597,20 @@ def OrchestratorIsAdmin(): return False def OrchestratorIsInited() -> bool: - """Check if Orchestrator initial actions were processed + """ + Проверить, было ли проинициализировано ядро Оркестратора - :return: True - orc is already inited; False - else + :return: True - Ядро Оркестратора было проинициализировано; False - Требуется время на инициализацию :rtype: bool """ return Core.IsOrchestratorInitialized(inGSettings=GSettingsGet()) def OrchestratorInitWait() -> None: - """Wait thread while orc will process initial action. - ATTENTION: DO NOT CALL THIS DEF IN THREAD WHERE ORCHESTRATOR MUST BE INITIALIZED - INFINITE LOOP + """ + Ожидать инициализацию ядра Оркестратора + + !ВНИМАНИЕ!: НИ В КОЕМ СЛУЧАЕ НЕ ЗАПУСКАТЬ ЭТУ ФУНКЦИЮ В ОСНОВНОМ ПОТОКЕ, ГДЕ ПРОИСХОДИТ ИНИЦИАЛИЗАЦИЯ ЯДРА ОРКЕСТРАТОРА - ВОЗНИКНЕТ ВЕЧНЫЙ ЦИКЛ """ lIntervalSecFloat = 0.5 while not OrchestratorIsInited(): @@ -606,9 +619,9 @@ def OrchestratorInitWait() -> None: def OrchestratorRerunAsAdmin(): """ - Check if not admin - then rerun orchestrator as administrator + Перезапустить Оркестратор с правами локального администратора. Права администратора нужны Оркестратору только для контроля графической сессии, на которой он запущен. Если эти права выделить индивидуально, то права администратора будут необязательны. - :return: True - run as administrator; False - not as administrator + :return: True - Запущен с правами администратора; False - Не запущен с правами администратора """ if not OrchestratorIsAdmin(): # Re-run the program with admin rights @@ -618,19 +631,21 @@ def OrchestratorRerunAsAdmin(): def 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! + Выполнить поиск и инициализацию пользовательских .py файлов в Оркестраторе (например панелей управления роботов) + + Добавляет инициализированный модуль в пространство sys.modules как imported (имя модуля = имя файла без расширения). + .. code-block:: python - # USAGE VAR 1 (without the def auto call) - # Autoinit control panels starts with CP_ + # ВАРИАНТ ИСПОЛЬЗОВАНИЯ 1 (инициализация модуля py без вызова каких-либо функций внутри) + # автоинициализация всех .py файлов, с префиксом CP_, которые расположены в папке ControlPanel 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_ + # ВАРИАНТ ИСПОЛЬЗОВАНИЯ 2 (инициализация модуля py с вызовом функции внутри) - преимущественно для обратной совместимости старых версий панелей управления < 1.2.7 + # автоинициализация всех .py файлов, с префиксом CP_, которые расположены в папке ControlPanel Orchestrator.OrchestratorPySearchInit(inGlobPatternStr="ControlPanel\\CP_*.py", inDefStr="SettingsUpdate", inDefArgNameGSettingsStr="inGSettings") - # INFO: The code above will replace the code below + # ДЛЯ СПРАВКИ & ИСТОРИИ: Код выше позволил отказаться от блока кода ниже для каждого .py файла ## !!! For Relative import !!! CP Version Check try: sys.path.insert(0,os.path.abspath(os.path.join(r""))) @@ -639,12 +654,11 @@ def OrchestratorPySearchInit(inGlobPatternStr, inDefStr = None, inDefArgNameGSet except Exception as e: gSettings["Logger"].exception(f"Exception when init CP. See below.") - - :param inGlobPatternStr: example"..\\*\\*\\*X64*.cmd" - :param inDefStr: OPTIONAL The string name of the def. For backward compatibility if you need to auto call some def from initialized module - :param inDefArgNameGSettingsStr: OPTIONAL The name of the GSettings argument in def (if exists) - :param inAsyncInitBool: OPTIONAL True - init py modules in many threads - parallel execution. False (default) - sequence execution - :return: { "ModuleNameStr":{"PyPathStr": "", "Module": ...}, ...} + :param inGlobPatternStr: Пример "..\\*\\*\\*_CP*.py" + :param inDefStr: ОПЦИОНАЛЬНО Строковое наименование функции. Преимущественно для обратной совместимости + :param inDefArgNameGSettingsStr: ОПЦИОНАЛЬНО Наименование аргумента, в который требуется передать GSettings (если необходимо) + :param inAsyncInitBool: ОПЦИОНАЛЬНО True - Инициализация py модулей в отдельных параллельных потоках - псевдопараллельное выполнение. False - последовательная инициализация + :return: Сведения об инициализированных модулях в структуре: { "ModuleNameStr":{"PyPathStr": "", "Module": ...}, ...} """ # # # # # # # # @@ -688,16 +702,19 @@ def OrchestratorPySearchInit(inGlobPatternStr, inDefStr = None, inDefArgNameGSet def OrchestratorSessionSave(inGSettings=None): """ - Orchestrator session save in file - (from version 1.2.7) + Сохранить состояние Оркестратора (для дальнейшего восстановления в случае перезапуска): + + - RDP сессий, которые контролирует Оркестратор + - Хранилища DataStorage в глобальном словаре настроек GSettings. DataStorage поддерживает хранение объектов Python + + (до версии 1.2.7) _SessionLast_GSettings.pickle (binary) - (above the version 1.2.7) + (начиная с версии 1.2.7) _SessionLast_RDPList.json (encoding = "utf-8") _SessionLast_StorageDict.pickle (binary) - :param inGSettings: Global settings dict (singleton) - :return: True every time + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lL = inGSettings["Logger"] @@ -730,16 +747,19 @@ def OrchestratorSessionSave(inGSettings=None): def OrchestratorSessionRestore(inGSettings=None): """ - Check _SessioLast... files in working directory. if exist - load into gsettings - (from version 1.2.7) + Восстановить состояние Оркестратора, если ранее состояние Оркестратора было сохранено с помощью функции OrchestratorSessionSave: + + - RDP сессий, которые контролирует Оркестратор + - Хранилища DataStorage в глобальном словаре настроек GSettings. DataStorage поддерживает хранение объектов Python + + (до версии 1.2.7) _SessionLast_GSettings.pickle (binary) - (above the version 1.2.7) + (начиная с версии 1.2.7) _SessionLast_RDPList.json (encoding = "utf-8") _SessionLast_StorageDict.pickle (binary) - :param inGSettings: Global settings dict (singleton) - :return: + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lL = inGSettings.get("Logger",None) @@ -776,33 +796,47 @@ def OrchestratorSessionRestore(inGSettings=None): def UACKeyListCheck(inRequest, inRoleKeyList) -> bool: """ - Check is client is has access for the key list + Проверить права доступа для пользователя запроса по списку ключей до права. + + .. code-block:: python + + # ВАРИАНТ ИСПОЛЬЗОВАНИЯ 1 (инициализация модуля py без вызова каких-либо функций внутри) + # автоинициализация всех .py файлов, с префиксом CP_, которые расположены в папке ControlPanel + Orchestrator.UACKeyListCheck(inRequest=lRequest, inRoleKeyList=["ROBOT1","DISPLAY_DASHBOARD"]) - :param inRequest: request handler (from http.server import BaseHTTPRequestHandler) - :param inRoleKeyList: - :return: bool + :param inRequest: Экземпляр request (from http.server import BaseHTTPRequestHandler) + :param inRoleKeyList: Список ключей, права доступа к которому требуется проверить + :return: True - Пользователь обладает соответствующим правом; False - Пользователь не обладает соответствующим правом """ return inRequest.UACClientCheck(inRoleKeyList=inRoleKeyList) def UACUserDictGet(inRequest) -> dict: """ - Return user UAC hierarchy dict of the inRequest object. Empty dict - superuser access + Вернуть UAC (User Access Control) словарб доступов для пользователя, который отправил запрос. Пустой словарь - супердоступ (доступ ко всему) - :param inRequest: request handler (from http.server import BaseHTTPRequestHandler) - :return: user UAC hierarchy dict + :param inRequest: Экземпляр request (from http.server import BaseHTTPRequestHandler) + :return: Словарь доступов пользователя. Пустой словарь - супердоступ (доступ ко всему) """ return inRequest.UserRoleHierarchyGet() # get the Hierarchy def UACUpdate(inADLoginStr, inADStr="", inADIsDefaultBool=True, inURLList=None, inRoleHierarchyAllowedDict=None, inGSettings = None): """ - Update user access (UAC) - - :param inGSettings: Global settings dict (singleton) - :param inADLoginStr: - :param inADStr: - :param inADIsDefaultBool: - :param inURLList: - :param inRoleHierarchyAllowedDict: + Дообогащение словаря доступа UAC пользователя inADStr\\inADLoginStr. Если ранее словарь не устанавливался, то по умолчанию он {}. Далее идет дообогащение теми ключами, которые присутствуют в inRoleHierarchyAllowedDict + + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inADLoginStr: Логин пользователя + :param inADStr: Домен пользователя. Если пусто - локальный компьютер или домен по-умолчанию, который настроен в ОС + :param inADIsDefaultBool: True - домен настроен по умолчанию; False - домен требуется обязательно указывать + :param inURLList: Список разрешенных URL для пользователя. Для добавления URL рекомендуем использовать функции WebURLConnectDef, WebURLConnectFile, WebURLConnectFolder + Формат: { + "Method": "GET" || "POST", + "URL": "/GetScreenshot", + "MatchType": "BeginWith" || "Equal" || "EqualCase" || "Contains" || "EqualNoParam", + "ResponseDefRequestGlobal": Функция python || "ResponseFilePath": Путь к файлу || "ResponseFolderPath": Путь к папке, в которой искать файлы, + "ResponseContentType": пример MIME "image/png", + "UACBool":False - не выполнять проверку прав доступа по запросу, + "UseCacheBool": True - кэшировать ответ}, + :param inRoleHierarchyAllowedDict: Словарь доступа пользователя UAC. Пустой словарь - полный доступ """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lUserTurple = (inADStr.upper(),inADLoginStr.upper()) # Create turple key for inGSettings["ServerDict"]["AccessUsers"]["RuleDomainUserDict"] @@ -831,10 +865,10 @@ def UACUpdate(inADLoginStr, inADStr="", inADIsDefaultBool=True, inURLList=None, def UACSuperTokenUpdate(inSuperTokenStr, inGSettings=None): """ - Add supertoken for the all access (it is need for the robot communication without human) + Добавить супертокен (полный доступ). Супертокены используются для подключения к Оркестратору по API - :param inGSettings: Global settings dict (singleton) - :param inSuperTokenStr: + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inSuperTokenStr: Кодовая строковая комбинация, которая будет предоставлять доступ роботу / агенту для взаимодействия с Оркестратором по API """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lLoginStr = "SUPERTOKEN" @@ -846,31 +880,26 @@ def UACSuperTokenUpdate(inSuperTokenStr, inGSettings=None): # # # # # # # # # # # # # # # # # # # # # # # # OrchestratorWeb defs # # # # # # # # # # # # # # # # # # # # # # # - def WebURLIndexChange(inURLIndexStr:str ="/"): - """Change the index page of the orchestrator if you dont want the '/' (main) path + """ + Изменить адрес главной страницы Оркестратора. По умолчанию '/' - :param inURLIndexStr: New url for the index page of the orchestrator, defaults to "/" - :type inURLIndexStr: str, optional + :param inURLIndexStr: Новый адрес главной страницы Оркестратора. + :type inURLIndexStr: str, опционально """ GSettingsGet()["ServerDict"]["URLIndexStr"] = inURLIndexStr def WebURLConnectDef(inMethodStr, inURLStr, inMatchTypeStr, inDef, inContentTypeStr="application/octet-stream", inGSettings = None, inUACBool = None): """ - Connect URL to DEF - "inMethodStr":"GET|POST", - "inURLStr": "/index", #URL of the request - "inMatchTypeStr": "", #"BeginWith|Contains|Equal|EqualCase", - "inContentTypeStr": "", #HTTP Content-type - "inDef": None #Function with str result - - :param inGSettings: Global settings dict (singleton) - :param inMethodStr: "GET|POST", - :param inURLStr: example "/index", #URL of the request - :param inMatchTypeStr: #"BeginWith|Contains|Equal|EqualCase", - :param inDef: def arg allowed list: 2:[inRequest, inGSettings], 1: [inRequest], 0: [] - :param inContentTypeStr: default: "application/octet-stream" - :param inUACBool: default: None; True - check user access before do this URL item. None - get Server flag if ask user + Подключить функцию Python к URL. + + :param inMethodStr: Метод доступа по URL "GET" || "POST" + :param inURLStr: URL адрес. Пример "/index" + :param inMatchTypeStr: Тип соответсвия строки URL с inURLStr: "BeginWith" || "Contains" || "Equal" || "EqualCase" || "EqualNoParam" + :param inDef: Функция Python. Допускаются функции, которые принимают следующие наборы параметров: 2:[inRequest, inGSettings], 1: [inRequest], 0: [] + :param inContentTypeStr: МИМЕ тип. По умолчанию: "application/octet-stream" + :param inUACBool: True - Выполнять проверку прав доступа пользователя перед отправкой ответа; False - не выполнять проверку прав доступа пользователя + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lURLItemDict = { @@ -889,20 +918,15 @@ def WebURLConnectDef(inMethodStr, inURLStr, inMatchTypeStr, inDef, inContentType def WebURLConnectFolder(inMethodStr, inURLStr, inMatchTypeStr, inFolderPathStr, inGSettings = None, inUACBool = None, inUseCacheBool= False): """ - Connect URL to Folder - "inMethodStr":"GET|POST", - "inURLStr": "/Folder/", #URL of the request - "inMatchTypeStr": "", #"BeginWith|Contains|Equal|EqualCase", - "inFolderPathStr": "", #Absolute or relative path - "inUACBool" - - :param inGSettings: Global settings dict (singleton) - :param inMethodStr: - :param inURLStr: - :param inMatchTypeStr: - :param inFolderPathStr: - :param inUACBool: default: None; True - check user access before do this URL item. None - get Server flag if ask user - :param inUseCacheBool: True - cache this page - dont open ever + Подключить папку к URL. + + :param inMethodStr: Метод доступа по URL "GET" || "POST" + :param inURLStr: URL адрес. Пример "/index" + :param inMatchTypeStr: Тип соответсвия строки URL с inURLStr: "BeginWith" || "Contains" || "Equal" || "EqualCase" || "EqualNoParam" + :param inFolderPathStr: Путь к папке на диске, в которой искать файл и возвращать пользователю по HTTP + :param inUACBool: True - Выполнять проверку прав доступа пользователя перед отправкой ответа; False - не выполнять проверку прав доступа пользователя + :param inUseCacheBool: True - выполнить кэширование страницы, чтобы в следющих запросах открыть быстрее; False - не кэшировать + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check if last symbol is "/" - append if not exist @@ -925,20 +949,18 @@ def WebURLConnectFolder(inMethodStr, inURLStr, inMatchTypeStr, inFolderPathStr, def WebURLConnectFile(inMethodStr, inURLStr, inMatchTypeStr, inFilePathStr, inContentTypeStr=None, inGSettings = None, inUACBool = None, inUseCacheBool = False): """ - Connect URL to File - "inMethodStr":"GET|POST", - "inURLStr": "/index", #URL of the request - "inMatchTypeStr": "", #"BeginWith|Contains|Equal|EqualCase", - "inFolderPathStr": "", #Absolute or relative path - - :param inGSettings: Global settings dict (singleton) - :param inMethodStr: - :param inURLStr: - :param inMatchTypeStr: - :param inFilePathStr: - :param inContentTypeStr: If none - autodetect - :param inUACBool: default: None; True - check user access before do this URL item. None - get Server flag if ask user - :param inUseCacheBool: True - cache this page - dont open ever + + Подключить файл к URL. + + :param inMethodStr: Метод доступа по URL "GET" || "POST" + :param inURLStr: URL адрес. Пример "/index" + :param inMatchTypeStr: Тип соответсвия строки URL с inURLStr: "BeginWith" || "Contains" || "Equal" || "EqualCase" || "EqualNoParam" + :param inFilePathStr: Путь к файлу на диске, который возвращать пользователю по HTTP + :param inContentTypeStr: МИМЕ тип. Если None - выполнить автоматическое определение + :param inUACBool: True - Выполнять проверку прав доступа пользователя перед отправкой ответа; False - не выполнять проверку прав доступа пользователя + :param inUseCacheBool: True - выполнить кэширование страницы, чтобы в следющих запросах открыть быстрее; False - не кэшировать + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lURLItemDict = { @@ -956,13 +978,13 @@ def WebURLConnectFile(inMethodStr, inURLStr, inMatchTypeStr, inFilePathStr, inCo def WebListenCreate(inServerKeyStr="Default", inAddressStr="", inPortInt=80, inCertFilePEMPathStr=None, inKeyFilePathStr=None, inGSettings = None): """ - Create listen interface for the web server - - :param inGSettings: Global settings dict (singleton) - :param inAddressStr: IP interface to listen - :param inPortInt: Port int to listen for HTTP default is 80; for HTTPS default is 443 - :param inCertFilePEMPathStr: Path to .pem (base 64) certificate. Required for SSL connection. ATTENTION - do not use certificate with password - :param inKeyFilePathStr: Path to the private key file + Настроить веб-сервер Оркестратора. + + :param inAddressStr: IP адрес для прослушивания. Если "", то прослушивать запросы со всех сетевых карт. Если "127.0.0.1", то слушать запросы только с той ОС, на которой работает Оркестратор + :param inPortInt: Номер порта для прослушивания. Если HTTP - 80; Если HTTPS - 443. По умолчанию 80. Допускается установка других портов + :param inCertFilePEMPathStr: Путь файлу сертификата, сгенерированного в .pem (base64) формате. Обязателен при использовании защищенного HTTPS/SSL соединения. + :param inKeyFilePathStr: Путь к файлу закрытого ключа в base64 формате + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) :return: """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -977,13 +999,13 @@ def WebListenCreate(inServerKeyStr="Default", inAddressStr="", inPortInt=80, inC def WebCPUpdate(inCPKeyStr, inHTMLRenderDef=None, inJSONGeneratorDef=None, inJSInitGeneratorDef=None, inGSettings = None): """ - Add control panel HTML, JSON generator or JS when page init + Добавить панель управления робота в Оркестратор. Для панели управления открыт доступ для использования функции-генератора HTML, генератора JSON данных, генератора JS кода. - :param inGSettings: Global settings dict (singleton) - :param inCPKeyStr: - :param inHTMLRenderDef: - :param inJSONGeneratorDef: - :param inJSInitGeneratorDef: + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inCPKeyStr: Текстовый ключ панели управления. Ключ для каждой панели управления должен быть уникальным! + :param inHTMLRenderDef: Функция Python для генерации HTML кода. Для использования Jinja2 шаблонов HTML см. pyOpenRPA.Orchestrator.Managers.ControlPanel + :param inJSONGeneratorDef: Функция Python для генерации JSON контейнера для отправки на клиентскую часть Оркестратора + :param inJSInitGeneratorDef: Функция Python для генерации JS кода для отправки на клиентскую часть Оркестратора """ lCPManager = Managers.ControlPanel(inControlPanelNameStr=inCPKeyStr, inRefreshHTMLJinja2TemplatePathStr=None) # CASE HTMLRender @@ -996,11 +1018,11 @@ def WebCPUpdate(inCPKeyStr, inHTMLRenderDef=None, inJSONGeneratorDef=None, inJSI def WebAuditMessageCreate(inRequest=None, inOperationCodeStr="-", inMessageStr="-"): """ - Create message string with request user details (IP, Login etc...). Very actual for IT security in big company. - + Создание сообщения ИТ аудита с такими сведениями как (Домен, IP, логин и тд.). Данная функция особенно актуальна в том случае, если требуется реализовать дополнительные меры контроля ИТ системы. + .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lWebAuditMessageStr = Orchestrator.WebAuditMessageCreate( @@ -1008,13 +1030,13 @@ def WebAuditMessageCreate(inRequest=None, inOperationCodeStr="-", inMessageStr=" inOperationCodeStr = "OP_CODE_1", inMessageStr="Success"): - # Log the WebAudit message + # Логгирование сообщения lLogger.info(lWebAuditMessageStr) - :param inRequest: HTTP request handler. Optional if call def from request thread - :param inOperationCodeStr: operation code in string format (actual for IT audit in control panels) - :param inMessageStr: additional message after - :return: format "WebAudit :: DOMAIN\\USER@101.121.123.12 :: operation code :: message" + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :param inOperationCodeStr: Код операции, который принят в компании в соответствии с регламентными процедурами + :param inMessageStr: Дополнительное сообщение, которое необходимо отправить в сообщение об ИТ аудите + :return: Формат сообщения: "WebAudit :: DOMAIN\\USER@101.121.123.12 :: operation code :: message" """ try: if inRequest is None: inRequest = WebRequestGet() @@ -1030,10 +1052,10 @@ def WebAuditMessageCreate(inRequest=None, inOperationCodeStr="-", inMessageStr=" def WebRequestParseBodyBytes(inRequest=None): """ - Extract the body in bytes from the request + Извлечь данные в байт виде из тела (body) HTTP запроса. - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: Bytes or None + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :return: Строка байт b'' или None (если тело запроса было пустым) """ if inRequest is None: inRequest = WebRequestGet() lBodyBytes=None @@ -1044,40 +1066,40 @@ def WebRequestParseBodyBytes(inRequest=None): def WebRequestParseBodyStr(inRequest=None): """ - Extract the body in str from the request + Извлечь данные в виде строки из тела (body) HTTP запроса. - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: str or None + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :return: Текстовая строка '' или None (если тело запроса было пустым) """ if inRequest is None: inRequest = WebRequestGet() return WebRequestParseBodyBytes(inRequest=inRequest).decode('utf-8') def WebRequestParseBodyJSON(inRequest=None): """ - Extract the body in dict/list from the request + Извлечь из тела (body) запроса HTTP JSON данные и преобразовать в Dict / List структуры языка Python. - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: dict or list + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :return: Словарь (dict), список (list) или None (если тело запроса было пустым) """ if inRequest is None: inRequest = WebRequestGet() return json.loads(WebRequestParseBodyStr(inRequest=inRequest)) def WebRequestParsePath(inRequest=None): """ - Parse the request - extract the url. Example: /pyOpenRPA/Debugging/DefHelper/... + Извлечь декодированный URL путь из HTTP запроса пользователя в формате строки. - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: Str, Example: /pyOpenRPA/Debugging/DefHelper/... + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :return: str, пример: /pyOpenRPA/Debugging/DefHelper """ if inRequest is None: inRequest = WebRequestGet() return urllib.parse.unquote(inRequest.path) def WebRequestParseFile(inRequest=None): """ - Parse the request - extract the file (name, body in bytes) + Извлечь файл (наименование + содержимое в виде строки байт b'') из HTTP запроса пользователя. - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: (FileNameStr, FileBodyBytes) or (None, None) + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :return: Кортеж формата (FileNameStr, FileBodyBytes) or (None, None), если файл не был обнаружен """ if inRequest is None: inRequest = WebRequestGet() lResultTurple=(None,None) @@ -1099,21 +1121,26 @@ def WebRequestParseFile(inRequest=None): return lResultTurple -def WebRequestResponseSend(inResponeStr, inRequest=None): +def WebRequestResponseSend(inResponeStr, inRequest=None, inContentTypeStr: str = None, inHeadersDict: dict = None): """ - Send response for the request + Установить ответ на HTTP запрос пользователя. - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: + :param inResponeStr: Тело ответа (строка) + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :param inContentTypeStr: МИМЕ тип. Пример: "html/text" + :param inHeadersDict: Словарь (dict) ключей, которые добавить в headers HTTP ответа на запрос пользователя """ if inRequest is None: inRequest = WebRequestGet() inRequest.OpenRPAResponseDict["Body"] = bytes(inResponeStr, "utf8") + if inHeadersDict is not None: + inRequest.OpenRPAResponseDict["Headers"].update(inHeadersDict) + if inContentTypeStr is not None: + inRequest.OpenRPAResponseDict["Headers"]["Content-type"] = inContentTypeStr def WebRequestGet(): """ - Return the web request instance if current thread was created by web request from client. else return None - + Вернуть экземпляр HTTP запроса, если функция вызвана в потоке, который был порожден для отработки HTTP запроса пользователя. """ lCurrentThread = threading.current_thread() if hasattr(lCurrentThread, "request"): @@ -1121,10 +1148,10 @@ def WebRequestGet(): def WebUserInfoGet(inRequest=None): """ - Return User info about request + Информация о пользователе, который отправил HTTP запрос. - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: {"DomainUpperStr": "", "UserNameUpperStr": ""} + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :return: Сведения в формате {"DomainUpperStr": "PYOPENRPA", "UserNameUpperStr": "IVAN.MASLOV"} """ if inRequest is None: inRequest = WebRequestGet() lDomainUpperStr = inRequest.OpenRPA["Domain"].upper() @@ -1133,11 +1160,11 @@ def WebUserInfoGet(inRequest=None): def WebUserIsSuperToken(inRequest = None, inGSettings = None): """ - Return bool if request is authentificated with supetoken (token which is never expires) + Проверить, авторизован ли HTTP запрос с помощью супер токена (токен, который не истекает). - :param inRequest: inRequest from the server. Optional if call def from request thread - :param inGSettings: Global settings dict (singleton) - :return: bool True - is supertoken; False - is not supertoken + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: True - является супертокеном; False - не является супертокеном """ if inRequest is None: inRequest = WebRequestGet() inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -1148,10 +1175,10 @@ def WebUserIsSuperToken(inRequest = None, inGSettings = None): def WebUserUACHierarchyGet(inRequest = None): """ - Return User UAC Hierarchy DICT Return {...} + Вернуть словарь доступа UAC в отношении пользователя, который выполнил HTTP запрос inRequest - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: UAC Dict {} + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :return: UAC словарь доступа или {}, что означает полный доступ """ if inRequest is None: inRequest = WebRequestGet() return inRequest.UserRoleHierarchyGet() @@ -1171,10 +1198,10 @@ if __name__ == "pyOpenRPA.Orchestrator.__Orchestrator__" and "pyOpenRPA.Orchestr def GSettingsGet(inGSettings=None): """ - Get the GSettings from the singleton module. + Вернуть глобальный словарь настроек Оркестратора. Во время выполнения программы глобальный словарь настроек существует в единственном экземпляре (синглтон) - :param inGSettings: You can pass some GSettings to check if it equal to base gsettings. If not equal - def will merge it - :return: GSettings + :param inGSettings: Дополнительный словарь настроек, который необходимо добавить в основной глобальный словарь настроек Оркестратора (синглтон) + :return: Глобальный словарь настроек GSettings """ global GSettings # identify the global variable # Merge dictionaries if some new dictionary has come @@ -1184,12 +1211,13 @@ def GSettingsGet(inGSettings=None): def GSettingsKeyListValueSet(inValue, inKeyList=None, inGSettings = None): """ - Set value in GSettings by the key list + Установить значение из глобального словаря настроек Оркестратора GSettings по списку ключей. + + Пример: Для того, чтобы установить значение для ключа car в словаре {"complex":{"car":"green"}, "simple":"HELLO"}, необходимо передать список ключей: ["complex", "car"] - :param inGSettings: Global settings dict (singleton) - :param inValue: - :param inKeyList: - :return: bool + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inValue: Значение для установки в глобальный словарь настроек Оркестратора GSettings + :param inKeyList: Список ключей, по адресу которого установить значение в GSettings """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inKeyList is None: inKeyList = [] @@ -1206,11 +1234,11 @@ def GSettingsKeyListValueSet(inValue, inKeyList=None, inGSettings = None): def GSettingsKeyListValueGet(inKeyList=None, inGSettings = None): """ - Get the value from the GSettings by the key list + Получить значение из глобального словаря настроек Оркестратора GSettings по списку ключей. - :param inGSettings: Global settings dict (singleton) - :param inKeyList: - :return: value any type + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inKeyList: Список ключей, по адресу которого получить значение из GSettings + :return: Значение (тип данных определяется форматом хранения в GSettings) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inKeyList is None: inKeyList = [] @@ -1226,11 +1254,11 @@ def GSettingsKeyListValueGet(inKeyList=None, inGSettings = None): def GSettingsKeyListValueAppend(inValue, inKeyList=None, inGSettings = None): """ - Append value in GSettings by the key list + Применить операцию .append к обьекту, расположенному по адресу списка ключей inKeyList в глобальном словаре настроек Оркестратора GSettings. Пример: Добавить значение в конец списка (list). .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.GSettingsKeyListValueAppend( @@ -1246,10 +1274,9 @@ def GSettingsKeyListValueAppend(inValue, inKeyList=None, inGSettings = None): # } #} - :param inGSettings: Global settings dict (singleton) - :param inValue: Any value to be appended in gSettings Dict by the key list - :param inKeyList: List of the nested keys (see example) - :return: True every time + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inValue: Значение для установки в глобальный словарь настроек Оркестратора GSettings + :param inKeyList: Список ключей, по адресу которого выполнить добавление в конец списка (list) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inKeyList is None: inKeyList = [] @@ -1266,11 +1293,11 @@ def GSettingsKeyListValueAppend(inValue, inKeyList=None, inGSettings = None): def GSettingsKeyListValueOperatorPlus(inValue, inKeyList=None, inGSettings = None): """ - Execute plus operation between 2 lists (1:inValue and 2:gSettings by the inKeyList) + Применить оператор сложения (+) к обьекту, расположенному по адресу списка ключей inKeyList в глобальном словаре настроек Оркестратора GSettings. Пример: соединить 2 списка (list). .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.GSettingsKeyListValueOperatorPlus( @@ -1289,10 +1316,9 @@ def GSettingsKeyListValueOperatorPlus(inValue, inKeyList=None, inGSettings = Non # } #} - :param inGSettings: Global settings dict (singleton) - :param inValue: List with values to be merged with list in gSettings - :param inKeyList: List of the nested keys (see example) - :return: True every time + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inValue: Значение для установки в глобальный словарь настроек Оркестратора GSettings + :param inKeyList: Список ключей, по адресу которого выполнить добавление в конец списка (list) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inKeyList is None: inKeyList = [] @@ -1309,19 +1335,19 @@ def GSettingsKeyListValueOperatorPlus(inValue, inKeyList=None, inGSettings = Non def StorageRobotExists(inRobotNameStr): """ - Check if robot storage exists + Проверить, существует ли ключ inRobotNameStr в хранилище пользовательской информации StorageDict (GSettings > StarageDict) - :param inRobotNameStr: Robot name (case sensitive) - :return: True - robot storage exist; False - does not exist + :param inRobotNameStr: Наименование (ключ) робота. !ВНИМАНИЕ! Наименование чувствительно к регистру + :return: True - ключ робота присутствует в хранилище; False - отсутствует """ return inRobotNameStr in GSettingsGet()["StorageDict"] def StorageRobotGet(inRobotNameStr): """ - Get the robot storage by the robot name. If Robot storage is not exist - function will create it + Получить содержимое по ключу робота inRobotNameStr в хранилище пользовательской информации StorageDict (GSettings > StarageDict) - :param inRobotNameStr: Robot name (case sensitive) - :return: Dict + :param inRobotNameStr: Наименование (ключ) робота. !ВНИМАНИЕ! Наименование чувствительно к регистру + :return: Значение или структура, которая расположена по адресу (GSettings > StarageDict > inRobotNameStr) """ if inRobotNameStr not in GSettingsGet()["StorageDict"]: GSettingsGet()["StorageDict"][inRobotNameStr]={} @@ -1329,9 +1355,9 @@ def StorageRobotGet(inRobotNameStr): def ProcessorAliasDefCreate(inDef, inAliasStr=None, inGSettings = None): """ - 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 can't transmit Python def object out of the Python environment) - Deprecated. See ActivityItemDefAliasCreate + Создать синоним (текстовый ключ) для инициации выполнения функции в том случае, если запрос на выполнения пришел из вне (передача функций невозможна). + + Старая версия. Новую версию см. ActivityItemDefAliasCreate .. code-block:: python @@ -1346,18 +1372,19 @@ def ProcessorAliasDefCreate(inDef, inAliasStr=None, inGSettings = None): inAliasStr="TestDefAlias") # Now you can call TestDef by the alias from var lAliasStr with help of ActivityItem (key Def = lAliasStr) - :param inGSettings: Global settings dict (singleton) - :param inDef: Def - :param inAliasStr: String alias for associated def - :return: str Alias string (Alias can be regenerated if previous alias was occupied) + + :param inDef: функция Python + :param inAliasStr: Строковый ключ (синоним), который можно будет использовать в Активности (ActivityItem) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: Строковый ключ, который был назначен. Ключ может быть изменен, если входящий текстовый ключ был уже занят. """ return ActivityItemDefAliasCreate(inDef=inDef, inAliasStr=inAliasStr, inGSettings = inGSettings) def ProcessorAliasDefUpdate(inDef, inAliasStr, inGSettings = None): """ - Update 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 can't transmit Python def object out of the Python environment) - Deprecated. See ActivityItemDefAliasUpdate + Обновить синоним (текстовый ключ) для инициации выполнения функции в том случае, если запрос на выполнения пришел из вне (передача функций невозможна). + + Старая версия. Новую версию см. ActivityItemDefAliasUpdate .. code-block:: python @@ -1372,20 +1399,20 @@ def ProcessorAliasDefUpdate(inDef, inAliasStr, inGSettings = None): inAliasStr="TestDefAlias") # Now you can call TestDef by the alias "TestDefAlias" with help of ActivityItem (key Def = "TestDefAlias") - :param inGSettings: Global settings dict (singleton) - :param inDef: Def - :param inAliasStr: String alias for associated def - :return: str Alias string + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inDef: функция Python + :param inAliasStr: Строковый ключ (синоним), который можно будет использовать в Активности (ActivityItem) + :return: Строковый ключ, который был назначен. Ключ будет тем же, если входящий текстовый ключ был уже занят. """ return ActivityItemDefAliasUpdate(inDef=inDef, inAliasStr=inAliasStr, inGSettings = inGSettings) # ActivityItem defs def ActivityItemHelperDefList(inDefQueryStr=None): """ - Create list of the available Def names in activity item. You can use query def filter via arg inDefQueryStr + Получить список синонимов (текстовых ключей), доступных для использования в Активностях (ActivityItem). - :param inDefStr: - :return: ["ActivityItemDefAliasUpdate", "ActivityItemDefAliasCreate", etc...] + :param inDefStr: Часть текстового ключ (начало / середина / конец) + :return: Список доступных ключей в формате: ["ActivityItemDefAliasUpdate", "ActivityItemDefAliasCreate", etc...] """ lResultList = [] if inDefQueryStr is not None: # do search alg @@ -1399,10 +1426,17 @@ def ActivityItemHelperDefList(inDefQueryStr=None): def ActivityItemHelperDefAutofill(inDef): """ - Detect def by the name and prepare the activity item dict with values. + Анализ аргументов функции по синониму (текстовому ключу). - :param inDef: - :return: + :param inDef: Часть текстового ключ (начало / середина / конец) + :return: Преднастроенная структура активности (ActivityItem) + { + "Def": None, + "ArgList": [], + "ArgDict": {}, + "ArgGSettingsStr": None, + "ArgLoggerStr": None + } """ lResultDict = { "Def": None, @@ -1431,14 +1465,14 @@ def ActivityItemHelperDefAutofill(inDef): def ActivityItemCreate(inDef, inArgList=None, inArgDict=None, inArgGSettingsStr=None, inArgLoggerStr=None, inGUIDStr = None, inThreadBool = False): """ - Create activity item. Activity item can be used as list item in ProcessorActivityItemAppend or in Processor.ActivityListExecute. + Создать Активность (ActivityItem). Активность можно использовать в ProcessorActivityItemAppend или в Processor.ActivityListExecute или в функциях работы с Агентами. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator - # EXAMPLE 1 + # ВАРИАНТ 1 def TestDef(inArg1Str, inGSettings, inLogger): pass lActivityItem = Orchestrator.ActivityItemCreate( @@ -1456,7 +1490,7 @@ def ActivityItemCreate(inDef, inArgList=None, inArgDict=None, inArgGSettingsStr= # "ArgLogger": "inLogger" # } - # EXAMPLE 2 + # ВАРИАНТ 2 def TestDef(inArg1Str): pass Orchestrator.ActivityItemDefAliasUpdate( @@ -1478,14 +1512,23 @@ def ActivityItemCreate(inDef, inArgList=None, inArgDict=None, inArgGSettingsStr= # "ArgLogger": None # } - :param inDef: def link or def alias (look gSettings["Processor"]["AliasDefDict"]) - :param inArgList: Args list for the Def - :param inArgDict: Args dict for the def - :param inArgGSettingsStr: Name of def argument of the GSettings dict - :param inArgLoggerStr: Name of def argument of the logging object - :param inGUIDStr: GUID which you can specify. If None the GUID will be generated - :param inThreadBool: True - execute ActivityItem in new thread; False - in processor thread - :return: {} + :param inDef: Функция Python или синоним (текстовый ключ) + :param inArgList: Список (list) неименованных аргументов к функции + :param inArgDict: Словарь (dict) именованных аргументов к функции + :param inArgGSettingsStr: Текстовое наименование аргумента GSettings (если требуется передавать) + :param inArgLoggerStr: Текстовое наименование аргумента logger (если требуется передавать) + :param inGUIDStr: ГУИД идентификатор активности (ActivityItem). Если ГУИД не указан, то он будет сгенерирован автоматически + :param inThreadBool: True - выполнить ActivityItem в новом потоке; False - выполнить последовательно в общем потоке процессорной очереди + :return: + lActivityItemDict= { + "Def":inDef, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "ArgList":inArgList, # Args list + "ArgDict":inArgDict, # Args dictionary + "ArgGSettings": inArgGSettingsStr, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": inArgLoggerStr, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "GUIDStr": inGUIDStr, + "ThreadBool": inThreadBool + } """ # Work about GUID in Activity items if inGUIDStr is None: @@ -1506,12 +1549,11 @@ def ActivityItemCreate(inDef, inArgList=None, inArgDict=None, inArgGSettingsStr= def ActivityItemDefAliasCreate(inDef, inAliasStr=None, inGSettings = None): """ - 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 can't transmit Python def object out of the Python environment) - + Создать синоним (текстовый ключ) для инициации выполнения функции в том случае, если запрос на выполнения пришел из вне (передача функций невозможна). + .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator def TestDef(): @@ -1522,10 +1564,10 @@ def ActivityItemDefAliasCreate(inDef, inAliasStr=None, inGSettings = None): inAliasStr="TestDefAlias") # Now you can call TestDef by the alias from var lAliasStr with help of ActivityItem (key Def = lAliasStr) - :param inGSettings: Global settings dict (singleton) - :param inDef: Def - :param inAliasStr: String alias for associated def - :return: str Alias string (Alias can be regenerated if previous alias was occupied) + :param inDef: функция Python + :param inAliasStr: Строковый ключ (синоним), который можно будет использовать в Активности (ActivityItem) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: Строковый ключ, который был назначен. Ключ может быть изменен, если входящий текстовый ключ был уже занят. """ #TODO Pay attention - New alias can be used too - need to create more complex algorythm to create new alias! inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -1540,9 +1582,7 @@ def ActivityItemDefAliasCreate(inDef, inAliasStr=None, inGSettings = None): def ActivityItemDefAliasModulesLoad(): """ - Load all def from sys.modules... in ActivityItem def alias dict - - :return: None + Загрузить все функции из импортированных модулей sys.modules в ActivityItem синонимы - полезно для отладки со стороны панели управления. """ lL = OrchestratorLoggerGet() lL.info(f"ActivityItem aliases: start to load sys.modules") @@ -1560,9 +1600,8 @@ def ActivityItemDefAliasModulesLoad(): def ActivityItemDefAliasUpdate(inDef, inAliasStr, inGSettings = None): """ - Update 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 can't transmit Python def object out of the Python environment) - + Обновить синоним (текстовый ключ) для инициации выполнения функции в том случае, если запрос на выполнения пришел из вне (передача функций невозможна). + .. code-block:: python # USAGE @@ -1576,10 +1615,10 @@ def ActivityItemDefAliasUpdate(inDef, inAliasStr, inGSettings = None): inAliasStr="TestDefAlias") # Now you can call TestDef by the alias "TestDefAlias" with help of ActivityItem (key Def = "TestDefAlias") - :param inGSettings: Global settings dict (singleton) - :param inDef: Def - :param inAliasStr: String alias for associated def - :return: str Alias string + :param inDef: функция Python + :param inAliasStr: Строковый ключ (синоним), который можно будет использовать в Активности (ActivityItem) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: Строковый ключ, который был назначен. Ключ будет тем же, если входящий текстовый ключ был уже занят. """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if callable(inDef): inGSettings["ProcessorDict"]["AliasDefDict"][inAliasStr] = inDef @@ -1590,14 +1629,16 @@ def ActivityItemDefAliasUpdate(inDef, inAliasStr, inGSettings = None): def ProcessorActivityItemCreate(inDef, inArgList=None, inArgDict=None, inArgGSettingsStr=None, inArgLoggerStr=None, inGUIDStr = None, inThreadBool = False): """ - Create activity item. Activity item can be used as list item in ProcessorActivityItemAppend or in Processor.ActivityListExecute. - Deprecated. See ActivityItemCreate + Создать Активность (ActivityItem). Активность можно использовать в ProcessorActivityItemAppend или в Processor.ActivityListExecute или в функциях работы с Агентами. + + Старая версия. Новую версию см. в ActivityItemCreate + .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator - # EXAMPLE 1 + # ВАРИАНТ 1 def TestDef(inArg1Str, inGSettings, inLogger): pass lActivityItem = Orchestrator.ProcessorActivityItemCreate( @@ -1615,7 +1656,7 @@ def ProcessorActivityItemCreate(inDef, inArgList=None, inArgDict=None, inArgGSet # "ArgLogger": "inLogger" # } - # EXAMPLE 2 + # ВАРИАНТ 2 def TestDef(inArg1Str): pass Orchestrator.ProcessorAliasDefUpdate( @@ -1637,22 +1678,31 @@ def ProcessorActivityItemCreate(inDef, inArgList=None, inArgDict=None, inArgGSet # "ArgLogger": None # } - :param inDef: def link or def alias (look gSettings["Processor"]["AliasDefDict"]) - :param inArgList: Args list for the Def - :param inArgDict: Args dict for the def - :param inArgGSettingsStr: Name of def argument of the GSettings dict - :param inArgLoggerStr: Name of def argument of the logging object - :param inGUIDStr: GUID which you can specify. If None the GUID will be generated - :param inThreadBool: True - execute ActivityItem in new thread; False - in processor thread - :return: {} + :param inDef: Функция Python или синоним (текстовый ключ) + :param inArgList: Список (list) неименованных аргументов к функции + :param inArgDict: Словарь (dict) именованных аргументов к функции + :param inArgGSettingsStr: Текстовое наименование аргумента GSettings (если требуется передавать) + :param inArgLoggerStr: Текстовое наименование аргумента logger (если требуется передавать) + :param inGUIDStr: ГУИД идентификатор активности (ActivityItem). Если ГУИД не указан, то он будет сгенерирован автоматически + :param inThreadBool: True - выполнить ActivityItem в новом потоке; False - выполнить последовательно в общем потоке процессорной очереди + :return: + lActivityItemDict= { + "Def":inDef, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "ArgList":inArgList, # Args list + "ArgDict":inArgDict, # Args dictionary + "ArgGSettings": inArgGSettingsStr, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": inArgLoggerStr, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "GUIDStr": inGUIDStr, + "ThreadBool": inThreadBool + } """ return ActivityItemCreate(inDef=inDef, inArgList=inArgList, inArgDict=inArgDict, inArgGSettingsStr=inArgGSettingsStr, inArgLoggerStr=inArgLoggerStr, inGUIDStr=inGUIDStr, inThreadBool=inThreadBool) def ProcessorActivityItemAppend(inGSettings = None, inDef=None, inArgList=None, inArgDict=None, inArgGSettingsStr=None, inArgLoggerStr=None, inActivityItemDict=None): """ - Create and add activity item in processor queue. - + Добавить активность (ActivityItem) в процессорную очередь. + .. code-block:: python # USAGE @@ -1688,14 +1738,16 @@ def ProcessorActivityItemAppend(inGSettings = None, inDef=None, inArgList=None, inActivityItemDict = lActivityItem) # Activity have been already append in the processor queue - :param inGSettings: Global settings dict (singleton) - :param inDef: def link or def alias (look gSettings["Processor"]["AliasDefDict"]) - :param inArgList: Args list for the Def - :param inArgDict: Args dict for the Def - :param inArgGSettingsStr: Name of def argument of the GSettings dict - :param inArgLoggerStr: Name of def argument of the logging object - :param inActivityItemDict: Fill if you already have ActivityItemDict (don't fill inDef, inArgList, inArgDict, inArgGSettingsStr, inArgLoggerStr) - :return ActivityItem GUIDStr + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inDef: Функция Python или синоним (текстовый ключ) + :param inArgList: Список (list) неименованных аргументов к функции + :param inArgDict: Словарь (dict) именованных аргументов к функции + :param inArgGSettingsStr: Текстовое наименование аргумента GSettings (если требуется передавать) + :param inArgLoggerStr: Текстовое наименование аргумента logger (если требуется передавать) + :param inGUIDStr: ГУИД идентификатор активности (ActivityItem). Если ГУИД не указан, то он будет сгенерирован автоматически + :param inThreadBool: True - выполнить ActivityItem в новом потоке; False - выполнить последовательно в общем потоке процессорной очереди + :param inActivityItemDict: Альтернативный вариант заполнения, если уже имеется Активность (ActivityItem). В таком случае не требуется заполнять аргументы inDef, inArgList, inArgDict, inArgGSettingsStr, inArgLoggerStr + :return ГУИД активности (ActivityItem) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inActivityItemDict is None: @@ -1727,18 +1779,20 @@ def ProcessorActivityItemAppend(inGSettings = None, inDef=None, inArgList=None, ## Process defs def ProcessIsStarted(inProcessNameWOExeStr): # Check if process is started """ - Check if there is any running process that contains the given name processName. + Проверить, запущен ли процесс, который в наименовании содержит inProcessNameWOExeStr. + !ВНИМАНИЕ! ПРОВЕРЯЕТ ВСЕ ПРОЦЕССЫ ОПЕРАЦИОННОЙ СИСТЕМЫ. И ДРУГИХ ПОЛЬЗОВАТЕЛЬСКИХ СЕССИЙ, ЕСЛИ ОНИ ЗАПУЩЕНЫ НА ЭТОЙ МАШИНЕ. + .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lProcessIsStartedBool = Orchestrator.ProcessIsStarted(inProcessNameWOExeStr = "notepad") # lProcessIsStartedBool is True - notepad.exe is running on the Orchestrator machine - :param inProcessNameWOExeStr: Process name WithOut (WO) '.exe' postfix. Example: "notepad" (not "notepad.exe") - :return: True - process is running on the orchestrator machine; False - process is not running on the orchestrator machine + :param inProcessNameWOExeStr: Наименование процесса без расширения .exe (WO = WithOut = Без) Пример: Для проверки процесса блокнота нужно указывать "notepad", не "notepad.exe" + :return: True - Процесс запущен на ОС ; False - Процесс не запущен на ОС, где работает Оркестратор """ #Iterate over the all the running process for proc in psutil.process_iter(): @@ -1752,11 +1806,13 @@ def ProcessIsStarted(inProcessNameWOExeStr): # Check if process is started def ProcessStart(inPathStr, inArgList, inStopProcessNameWOExeStr=None): """ - Start process locally. Extra feature: Use inStopProcessNameWOExeStr to stop the execution if current process is running. + Запуск процесса на сессии Оркестратора, если на ОС не запущен процесс inStopProcessNameWOExeStr. + + !ВНИМАНИЕ! ПРИ ПРОВЕРКЕ РАНЕЕ ЗАПУЩЕННЫХ ПРОЦЕССОВ ПРОВЕРЯЕТ ВСЕ ПРОЦЕССЫ ОПЕРАЦИОННОЙ СИСТЕМЫ. И ДРУГИХ ПОЛЬЗОВАТЕЛЬСКИХ СЕССИЙ, ЕСЛИ ОНИ ЗАПУЩЕНЫ НА ЭТОЙ МАШИНЕ. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.ProcessStart( @@ -1765,10 +1821,9 @@ def ProcessStart(inPathStr, inArgList, inStopProcessNameWOExeStr=None): inStopProcessNameWOExeStr = "notepad") # notepad.exe will be started if no notepad.exe is active on the machine - :param inPathStr: Command to send in CMD - :param inArgList: List of the arguments for the CMD command. Example: ["test.txt"] - :param inStopProcessNameWOExeStr: Trigger: stop execution if process is running. Process name WithOut (WO) '.exe' postfix. Example: "notepad" (not "notepad.exe") - :return: None - nothing is returned. If process will not start -exception will be raised + :param inPathStr: Путь к файлу запускаемого процесса + :param inArgList: Список аргументов, передаваемых в запускаемый процесс. Пример: ["test.txt"] + :param inStopProcessNameWOExeStr: Доп. контроль: Не запускать процесс, если обнаружен запущенный процесс под наименованием inStopProcessNameWOExeStr без расширения .exe (WO = WithOut = Без) """ lStartProcessBool = True if inStopProcessNameWOExeStr is not None: #Check if process running @@ -1789,11 +1844,11 @@ def ProcessStart(inPathStr, inArgList, inStopProcessNameWOExeStr=None): def ProcessStop(inProcessNameWOExeStr, inCloseForceBool, inUserNameStr = "%username%"): """ - Stop process on the orchestrator machine. You can set user session on the machine and set flag about to force close process. + Остановить процесс на ОС, где работает Оркестратор, под учетной записью inUserNameStr. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.ProcessStop( @@ -1802,10 +1857,9 @@ def ProcessStop(inProcessNameWOExeStr, inCloseForceBool, inUserNameStr = "%usern inUserNameStr = "USER_99") # Will close process "notepad.exe" on the user session "USER_99" (!ATTENTION! if process not exists no exceptions will be raised) - :param inProcessNameWOExeStr: Process name WithOut (WO) '.exe' postfix. Example: "notepad" (not "notepad.exe") - :param inCloseForceBool: True - do force close. False - send signal to safe close (!ATTENTION! - Safe close works only in orchestrator session. Win OS doens't allow to send safe close signal between GUI sessions) - :param inUserNameStr: User name which is has current process to close. Default value is close process on the Orchestrator session - :return: None + :param inProcessNameWOExeStr: Наименование процесса без расширения .exe (WO = WithOut = Без). Пример: Для проверки процесса блокнота нужно указывать "notepad", не "notepad.exe" + :param inCloseForceBool: True - принудительно завершить процесс. False - отправить сигнал на безопасное отключение (!ВНИМАНИЕ! - ОС не позволяет отправлять сигнал на безопасное отключение на другую сесиию - только на той, где работает Оркестратор) + :param inUserNameStr: Наименование пользователя, под именем которого искать процесс для остановки. По умолчанию "%username%" - искать процесс на текущей сессии """ # Support input arg if with .exe lProcessNameWExeStr = inProcessNameWOExeStr @@ -1826,30 +1880,32 @@ def ProcessStop(inProcessNameWOExeStr, inCloseForceBool, inUserNameStr = "%usern def ProcessListGet(inProcessNameWOExeList=None): """ - Return process list on the orchestrator machine sorted by Memory Usage. You can determine the list of the processes you are interested - def will return the list about it. + Вернуть список процессов, запущенных на ОС, где работает Оркестратор. В списке отсортировать процессы по количеству используемой оперативной памяти. Также можно указать перечень процессов, которые интересуют - функция будет показывать активные из них. + + !ВНИМАНИЕ! ДЛЯ ПОЛУЧЕНИЯ СПИСКА ВСЕХ ПРОЦЕССОВ ОС НЕОБХОДИМО ЗАПУСКАТЬ ОРКЕСТРАТОР С ПРАВАМИ АДМИНИСТРАТОРА. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lProcessList = Orchestrator.ProcessListGet() # Return the list of the process on the machine. # !ATTENTION! RUn orchestrator as administrator to get all process list on the machine. - :param inProcessNameWOExeList: - :return: { - "ProcessWOExeList": ["notepad","..."], - "ProcessWOExeUpperList": ["NOTEPAD","..."], - "ProcessDetailList": [ - { - 'pid': 412, - 'username': "DESKTOP\\USER", - 'name': 'notepad.exe', - 'vms': 13.77767775, - 'NameWOExeUpperStr': 'NOTEPAD', - 'NameWOExeStr': "'notepad'"}, - {...}] + :param inProcessNameWOExeList: Список процессов, среди которых искать активные. Если параметр не указывать - вернет перечень всех доступных процессов + :return: Сведения о запущенных процессах в следующем формате { + "ProcessWOExeList": ["notepad","..."], + "ProcessWOExeUpperList": ["NOTEPAD","..."], + "ProcessDetailList": [ + { + 'pid': 412, # Идентификатор процесса + 'username': "DESKTOP\\USER", + 'name': 'notepad.exe', + 'vms': 13.77767775, # В Мб + 'NameWOExeUpperStr': 'NOTEPAD', + 'NameWOExeStr': "'notepad'"}, + {...}] """ if inProcessNameWOExeList is None: inProcessNameWOExeList = [] @@ -1884,19 +1940,18 @@ def ProcessListGet(inProcessNameWOExeList=None): def ProcessDefIntervalCall(inDef, inIntervalSecFloat, inIntervalAsyncBool=False, inDefArgList=None, inDefArgDict=None, inDefArgGSettingsNameStr=None, inDefArgLoggerNameStr=None, inExecuteInNewThreadBool=True, inLogger=None, inGSettings = None): """ - Use this procedure if you need to run periodically some def. Set def, args, interval and enjoy :) - - :param inGSettings: global settings - :param inDef: def link, which will be called with interval inIntervalSecFloat - :param inIntervalSecFloat: Interval in seconds between call - :param inIntervalAsyncBool: False - wait interval before next call after the previous iteration result; True - wait interval after previous iteration call - :param inDefArgList: List of the args in def. Default None (empty list) - :param inDefArgDict: Dict of the args in def. Default None (empty dict) - :param inDefArgGSettingsNameStr: Name of the GSettings arg name for def (optional) - :param inDefArgLoggerNameStr: Name of the Logger arg name for def (optional). If Use - please check fill of the inLogger arg. - :param inExecuteInNewThreadBool: True - create new thread for the periodic execution; False - execute in current thread. Default: True - :param inLogger: logging def if some case is appear - :return: + Периодический вызов функции Python. + + :param inDef: Функция Python, которую потребуется периодически вызывать + :param inIntervalSecFloat: Интервал между вызовами функции в сек. + :param inIntervalAsyncBool: False - ожидать интервал inIntervalSecFloat только после окончания выполнения предыдущей итерации; True - Ожидать интервал сразу после запуска итерации + :param inDefArgList: Список (list) неименованных аргументов для передачи в функцию. По умолчанию None + :param inDefArgDict: Словарь (dict) именованных аргументов для передачи в функцию. По умолчанию None + :param inDefArgGSettingsNameStr: Наименование аргумента глобального словаря настроек Оркестратора GSettings (опционально) + :param inDefArgLoggerNameStr: Наименование аргумента логгера Оркестратора (опционально) + :param inExecuteInNewThreadBool: True - периодический вызов выполнять в отдельном потоке (не останавливать выполнение текущего потока); False - Выполнение периодического вызова в текущем потоке, в котором была вызвана функция ProcessDefIntervalCall. По умолчанию: True + :param inLogger: Логгер для фиксации сообщений выполнения функции (опционально) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inLogger is None: inLogger = OrchestratorLoggerGet() @@ -1965,15 +2020,15 @@ def ProcessDefIntervalCall(inDef, inIntervalSecFloat, inIntervalAsyncBool=False, # Python def - start module function def PythonStart(inModulePathStr, inDefNameStr, inArgList=None, inArgDict=None, inLogger = None): """ - Import module and run def in the Orchestrator process. + Импорт модуля и выполнение функции в процессе Оркестратора. .. note:: - Import module will be each time when PythonStart def will be called. + Импорт модуля inModulePathStr будет происходить каждый раз в вызовом функции PythonStart. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.PythonStart( @@ -1981,12 +2036,11 @@ def PythonStart(inModulePathStr, inDefNameStr, inArgList=None, inArgDict=None, i inDefNameStr="TestDef") # Import module in Orchestrator process and call def "TestDef" from module "ModuleToCall.py" - :param inModulePathStr: Absolute or relative (working directory of the orchestrator process) path to the importing module .py - :param inDefNameStr: Def name in module - :param inArgList: List of the arguments for callable def - :param inArgDict: Dict of the named arguments for callable def - :param inLogger: Logger instance to log some information when PythonStart def is running - :return: None + :param inModulePathStr: Абсолютный или относительный путь (относительно рабочей директории процесса Оркестратора), по которому расположен импортируемый .py файл + :param inDefNameStr: Наименование функции в модуле .py + :param inArgList: Список (list) неименованных аргументов для передачи в функцию. По умолчанию None + :param inArgDict: Словарь (dict) именованных аргументов для передачи в функцию. По умолчанию None + :param inLogger: Логгер для фиксации сообщений выполнения функции (опционально) """ if inLogger is None: inLogger = OrchestratorLoggerGet() if inArgList is None: inArgList=[] @@ -2001,17 +2055,16 @@ def PythonStart(inModulePathStr, inDefNameStr, inArgList=None, inArgDict=None, i # # # # # # # # # # # # # # # # # # # # # # # # Scheduler # # # # # # # # # # # # # # # # # # # # # # # - def SchedulerActivityTimeAddWeekly(inTimeHHMMStr="23:55:", inWeekdayList=None, inActivityList=None, inGSettings = None): """ - Add activity item list in scheduler. You can set weekday list and set time when launch. Activity list will be executed at planned time/day. + Добавить активность по расписанию. Допускается указание времени и дней недели, в которые производить запуск. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator - # EXAMPLE 1 + # ВАРИАНТ 1 def TestDef(inArg1Str): pass lActivityItem = Orchestrator.ProcessorActivityItemCreate( @@ -2027,11 +2080,10 @@ def SchedulerActivityTimeAddWeekly(inTimeHHMMStr="23:55:", inWeekdayList=None, i inActivityList = [lActivityItem]) # Activity will be executed at 04:34 Wednesday (2), thursday (3), friday (4) - :param inGSettings: Global settings dict (singleton) - :param inTimeHHMMStr: Activation time from "00:00" to "23:59". Example: "05:29" - :param inWeekdayList: Week day list to initiate activity list. Use int from 0 (monday) to 6 (sunday) as list items. Example: [0,1,2,3,4]. Default value is everyday ([0,1,2,3,4,5,6]) - :param inActivityList: Activity list structure - :return: None + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inTimeHHMMStr: Время запуска активности. Допускаются значения от "00:00" до "23:59". Example: "05:29" + :param inWeekdayList: Список (list) дней недели, в которые выполнять запуск список активностей (ActivityItem list). 0 (понедельник) - 6 (воскресенье). Пример: [0,1,2,3,4]. По умолчанию устанавливается каждый день [0,1,2,3,4,5,6] + :param inActivityList: Список активностей (ActivityItem list) на исполнение """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inWeekdayList is None: inWeekdayList=[0,1,2,3,4,5,6] @@ -2052,11 +2104,11 @@ def SchedulerActivityTimeAddWeekly(inTimeHHMMStr="23:55:", inWeekdayList=None, i def RDPTemplateCreate(inLoginStr, inPasswordStr, inHostStr="127.0.0.1", inPortInt = 3389, inWidthPXInt = 1680, inHeightPXInt = 1050, inUseBothMonitorBool = False, inDepthBitInt = 32, inSharedDriveList=None, inRedirectClipboardBool=True): """ - Create RDP connect dict item/ Use it connect/reconnect (Orchestrator.RDPSessionConnect) + Создать шаблон подключения RDP (dict). Данный шаблон далее можно использовать в Orchestrator.RDPSessionConnect .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lRDPItemDict = Orchestrator.RDPTemplateCreate( @@ -2068,49 +2120,38 @@ def RDPTemplateCreate(inLoginStr, inPasswordStr, inHostStr="127.0.0.1", inPortIn inHeightPXInt = 1050, inUseBothMonitorBool = False, inDepthBitInt = 32, - inSharedDriveList=None) - # lRDPTemplateDict= { # Init the configuration item - # "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 - # } - - :param inLoginStr: User/Robot Login, example "USER_99" - :param inPasswordStr: Password, example "USER_PASS_HERE" - :param inHostStr: Host address, example "77.77.22.22" - :param inPortInt: RDP Port, example "3389" (default) - :param inWidthPXInt: Width of the remote desktop in pixels, example 1680 - :param inHeightPXInt: Height of the remote desktop in pixels, example 1050 - :param inUseBothMonitorBool: True - connect to the RDP with both monitors. False - else case - :param inDepthBitInt: Remote desktop bitness. Available: 32 or 24 or 16 or 15, example 32 - :param inSharedDriveList: Host local disc to connect to the RDP session. Example: ["c", "d"] - :param inRedirectClipboardBool: # True - share clipboard to RDP; False - else + inSharedDriveList=None, + inRedirectClipboardBool=False) + + :param inLoginStr: Логин учетной записи, на которую будет происходить вход по RDP + :param inPasswordStr: Пароль учетной записи, на которую будет происходить вход по RDP. !ВНИМАНИЕ! Пароль нигде не сохраняется - конфиденциальность обеспечена + :param inHostStr: Имя хоста, к которому планируется подключение по RDP. Пример "77.77.22.22" + :param inPortInt: RDP порт, по которому будет происходить подключение. По умолчанию 3389 (стандартный порт RDP) + :param inWidthPXInt: Разрешение ширины RDP графической сессии в пикселях. По умолчанию 1680 + :param inHeightPXInt: Разрешение высоты RDP графической сессии в пикселях. По умолчанию 1050 + :param inUseBothMonitorBool: True - Использовать все подключенные мониторы на RDP сессии; False - Использовать только один монитор на подключенной RDP сессии + :param inDepthBitInt: Глубина цвета на удаленной RDP графической сессии. Допустимые варианты: 32 || 24 || 16 || 15. По умолчанию 32 + :param inSharedDriveList: Перечень общих дисков, доступ к которым предоставить на сторону удаленной RDP сессии. Пример: ["c", "d"] + :param inRedirectClipboardBool: True - Синхронизировать буфер обмена между сессией Оркестратора и удаленной RDP сессией; False - Не синхронизировать буфер обмена. По умолчанию True (в целях обратной совместимости). !ВНИМАНИЕ! Для учетных записей роботов мы рекомендуем не синхронизировать буфер обмена, так как это может привести к ошибкам роботов, которые работают с клавиатурой и буфером обмена :return: { - "Host": inHostStr, # Host address, example "77.77.22.22" - "Port": str(inPortInt), # RDP Port, example "3389" - "Login": inLoginStr, # Login, example "test" - "Password": inPasswordStr, # Password, example "test" + "Host": inHostStr, # Адрес хоста, пример "77.77.22.22" + "Port": str(inPortInt), # RDP порт, пример "3389" + "Login": inLoginStr, # Логин УЗ, пример "test" + "Password": inPasswordStr, # Пароль УЗ, пример "test" "Screen": { - "Width": inWidthPXInt, # Width of the remote desktop in pixels, example 1680 - "Height": inHeightPXInt, # Height of the remote desktop in pixels, example 1050 - # "640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen, example - "FlagUseAllMonitors": inUseBothMonitorBool, # True or False, example False - "DepthBit": str(inDepthBitInt) # "32" or "24" or "16" or "15", example "32" + "Width": inWidthPXInt, # Разрешение ширины RDP графической сессии в пикселях. По умолчанию 1680 + "Height": inHeightPXInt, Разрешение высоты RDP графической сессии в пикселях. По умолчанию 1050 + "FlagUseAllMonitors": inUseBothMonitorBool, + "DepthBit": str(inDepthBitInt) }, - "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 "" + "SharedDriveList": inSharedDriveList, + "RedirectClipboardBool": True, + ###### PROGRAM VARIABLE ############ + "SessionHex": "77777sdfsdf77777dsfdfsf77777777", "SessionIsWindowExistBool": False, - # Flag if the RDP window is exist, old name "FlagSessionIsActive". Check every n seconds , example False "SessionIsWindowResponsibleBool": False, - # Flag if RDP window is responsible (recieve commands). Check every nn seconds. If window is Responsible - window is Exist too , example False - "SessionIsIgnoredBool": False # Flag to ignore RDP window False - dont ignore, True - ignore, example False + "SessionIsIgnoredBool": False } """ @@ -2144,27 +2185,22 @@ def RDPTemplateCreate(inLoginStr, inPasswordStr, inHostStr="127.0.0.1", inPortIn # TODO Search dublicates in GSettings RDPlist ! # Return list if dublicates def RDPSessionDublicatesResolve(inGSettings): - """ - DEVELOPING Search duplicates in GSettings RDPlist - !def is developing! - - :param inGSettings: Global settings dict (singleton) - :return: - """ pass #for lItemKeyStr in inGSettings["RobotRDPActive"]["RDPList"]: # lItemDict = inGSettings["RobotRDPActive"]["RDPList"][lItemKeyStr] def RDPSessionConnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inHostStr=None, inPortStr=None, inLoginStr=None, inPasswordStr=None, inGSettings = None, inRedirectClipboardBool=True): """ - Create new RDPSession in RobotRDPActive. Attention - activity will be ignored if RDP key is already exists - 2 way of the use - Var 1 (Main stream): inGSettings, inRDPSessionKeyStr, inRDPTemplateDict - Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPasswordStr + Выполнить подключение к RDP и следить за стабильностью соединения со стороны Оркестратора. + !ВНИМАНИЕ! - Подключение будет проигнорировано, если соединение по таком RDP ключу уже было инициализировано ранее. + + 2 способа использования функции: + ВАРИАНТ 1 (ОСНОВНОЙ): inGSettings, inRDPSessionKeyStr, inRDPTemplateDict. Для получения inRDPTemplateDict см. функцию Orchestrator.RDPTemplateCreate + ВАРИАНТ 2 (ОБРАТНАЯ СОВМЕСТИМОСТЬ ДО ВЕРСИИ 1.1.20): inGSettings, inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPasswordStr .. code-block:: python - # USAGE + # ПРИМЕР (ВАРИАНТ 1) from pyOpenRPA import Orchestrator lRDPItemDict = Orchestrator.RDPTemplateCreate( @@ -2176,15 +2212,15 @@ def RDPSessionConnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inHostStr=None inRDPSessionKeyStr = "RDPKey", inRDPTemplateDict = lRDPItemDict) # Orchestrator will create RDP session by the lRDPItemDict configuration - - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inRDPTemplateDict: RDP configuration dict with settings (see def Orchestrator.RDPTemplateCreate) - :param inHostStr: Backward compatibility from Orchestrator v 1.1.20. Use inRDPTemplateDict - :param inPortStr: Backward compatibility from Orchestrator v 1.1.20. Use inRDPTemplateDict - :param inLoginStr: Backward compatibility from Orchestrator v 1.1.20. Use inRDPTemplateDict - :param inPasswordStr: Backward compatibility from Orchestrator v 1.1.20. Use inRDPTemplateDict - :return: True every time :) + + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inRDPTemplateDict: Конфигурационный словарь (dict) RDP подключения (см. функцию Orchestrator.RDPTemplateCreate) + :param inLoginStr: Логин учетной записи, на которую будет происходить вход по RDP. Обратная совместимость до версии v 1.1.20. Мы рекомендуем использовать inRDPTemplateDict (см. функцию Orchestrator.RDPTemplateCreate) + :param inPasswordStr: Пароль учетной записи, на которую будет происходить вход по RDP. !ВНИМАНИЕ! Пароль нигде не сохраняется - конфиденциальность обеспечена. Обратная совместимость до версии v 1.1.20. Мы рекомендуем использовать inRDPTemplateDict (см. функцию Orchestrator.RDPTemplateCreate) + :param inHostStr: Имя хоста, к которому планируется подключение по RDP. Пример "77.77.22.22". Обратная совместимость до версии v 1.1.20. Мы рекомендуем использовать inRDPTemplateDict (см. функцию Orchestrator.RDPTemplateCreate) + :param inPortInt: RDP порт, по которому будет происходить подключение. По умолчанию 3389 (стандартный порт RDP). Обратная совместимость до версии v 1.1.20. Мы рекомендуем использовать inRDPTemplateDict (см. функцию Orchestrator.RDPTemplateCreate) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inRedirectClipboardBool: True - Синхронизировать буфер обмена между сессией Оркестратора и удаленной RDP сессией; False - Не синхронизировать буфер обмена. По умолчанию True (в целях обратной совместимости). !ВНИМАНИЕ! Для учетных записей роботов мы рекомендуем не синхронизировать буфер обмена, так как это может привести к ошибкам роботов, которые работают с клавиатурой и буфером обмена """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check thread @@ -2217,11 +2253,11 @@ def RDPSessionConnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inHostStr=None def RDPSessionDisconnect(inRDPSessionKeyStr, inBreakTriggerProcessWOExeList = None, inGSettings = None): """ - Disconnect the RDP session and stop monitoring it. + Выполнить отключение RDP сессии и прекратить мониторить его активность. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.RDPSessionDisconnect( @@ -2229,14 +2265,9 @@ def RDPSessionDisconnect(inRDPSessionKeyStr, inBreakTriggerProcessWOExeList = No inRDPSessionKeyStr = "RDPKey") # Orchestrator will disconnect RDP session and will stop to monitoring current RDP - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inBreakTriggerProcessWOExeList: List of the processes, which will stop the execution. Example ["notepad"] - - .. note:: - - Orchestrator look processes on the current machine - :return: True every time + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inBreakTriggerProcessWOExeList: Список процессов, наличие которых в диспетчере задач приведет к прерыванию задачи по остановке RDP соединения. Пример ["notepad"] + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inBreakTriggerProcessWOExeList is None: inBreakTriggerProcessWOExeList = [] @@ -2265,11 +2296,11 @@ def RDPSessionDisconnect(inRDPSessionKeyStr, inBreakTriggerProcessWOExeList = No def RDPSessionReconnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inGSettings = None): """ - Reconnect the RDP session + Выполнить переподключение RDP сессии и продолжить мониторить его активность. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lRDPItemDict = Orchestrator.RDPTemplateCreate( @@ -2282,10 +2313,9 @@ def RDPSessionReconnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inGSettings inRDPTemplateDict = inRDPTemplateDict) # Orchestrator will reconnect RDP session and will continue to monitoring current RDP - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inRDPTemplateDict: RDP configuration dict with settings (see def Orchestrator.RDPTemplateCreate) - :return: + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inRDPTemplateDict: Конфигурационный словарь (dict) RDP подключения (см. функцию Orchestrator.RDPTemplateCreate) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check thread @@ -2312,11 +2342,11 @@ def RDPSessionReconnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inGSettings def RDPSessionMonitorStop(inRDPSessionKeyStr, inGSettings = None): """ - Stop monitoring the RDP session by the Orchestrator process. Current def don't kill RDP session - only stop to track it (it can give ) - + Прекратить мониторить активность RDP соединения со стороны Оркестратора. Данная функция не уничтожает активное RDP соединение. + .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.RDPSessionMonitorStop( @@ -2324,9 +2354,8 @@ def RDPSessionMonitorStop(inRDPSessionKeyStr, inGSettings = None): inRDPSessionKeyStr = "RDPKey") # Orchestrator will stop the RDP monitoring - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :return: True every time :> + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lResult = True @@ -2335,11 +2364,11 @@ def RDPSessionMonitorStop(inRDPSessionKeyStr, inGSettings = None): def RDPSessionLogoff(inRDPSessionKeyStr, inBreakTriggerProcessWOExeList = None, inGSettings = None): """ - Logoff the RDP session from the Orchestrator process (close all apps in session when logoff) + Выполнить отключение (logoff) на RDP сессии и прекратить мониторить активность со стороны Оркестратора. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.RDPSessionLogoff( @@ -2348,10 +2377,11 @@ def RDPSessionLogoff(inRDPSessionKeyStr, inBreakTriggerProcessWOExeList = None, inBreakTriggerProcessWOExeList = ['Notepad']) # Orchestrator will logoff the RDP session - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inBreakTriggerProcessWOExeList: List of the processes, which will stop the execution. Example ["notepad"] - :return: True - logoff is successful + + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inBreakTriggerProcessWOExeList: Список процессов, наличие которых в диспетчере задач приведет к прерыванию задачи по остановке RDP соединения. Пример ["notepad"] + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: True - Отключение прошло успешно; False - были зафиксированы ошибки при отключении. """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inBreakTriggerProcessWOExeList is None: inBreakTriggerProcessWOExeList = [] @@ -2382,13 +2412,6 @@ def RDPSessionLogoff(inRDPSessionKeyStr, inBreakTriggerProcessWOExeList = None, return lResult def RDPSessionResponsibilityCheck(inRDPSessionKeyStr, inGSettings = None): - """ - DEVELOPING, MAYBE NOT USEFUL Check RDP Session responsibility TODO NEED DEV + TEST - - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :return: True every time - """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check thread if not Core.IsProcessorThread(inGSettings=inGSettings): @@ -2427,11 +2450,13 @@ def RDPSessionResponsibilityCheck(inRDPSessionKeyStr, inGSettings = None): def RDPSessionProcessStartIfNotRunning(inRDPSessionKeyStr, inProcessNameWEXEStr, inFilePathStr, inFlagGetAbsPathBool=True, inGSettings = None): """ - Start process in RDP if it is not running (check by the arg inProcessNameWEXEStr) + Выполнить запуск процесса на RDP сессии через графические UI инструменты (без Агента). + + !ВНИМАНИЕ! Данная функция может работать нестабильно из-за использования графических элементов UI при работе с RDP. Мы рекомендуем использовать конструкцию взаимодействия Оркестратора с Агентом. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.RDPSessionProcessStartIfNotRunning( @@ -2442,12 +2467,11 @@ def RDPSessionProcessStartIfNotRunning(inRDPSessionKeyStr, inProcessNameWEXEStr, inFlagGetAbsPathBool = True) # Orchestrator will start the process in RDP session - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inProcessNameWEXEStr: Process name with extension (.exe). This arg allow to check the process is running. Example: "Notepad.exe" - :param inFilePathStr: Path to run process if it is not running. - :param inFlagGetAbsPathBool: True - get abs path from the relative path in inFilePathStr. False - else case - :return: True every time :) + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inProcessNameWEXEStr: Наименование процесса с расширением .exe (WEXE - WITH EXE - С EXE). Параметр позволяет не допустить повторного запуска процесса, если он уже был запущен. Example: "Notepad.exe" + :param inFilePathStr: Путь к файлу запуска процесса на стороне RDP сессии + :param inFlagGetAbsPathBool: True - Преобразовать относительный путь inFilePathStr в абсолютный с учетом рабочей директории Оркестратора; False - Не выполнять преобразований + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check thread @@ -2474,11 +2498,13 @@ def RDPSessionProcessStartIfNotRunning(inRDPSessionKeyStr, inProcessNameWEXEStr, def RDPSessionCMDRun(inRDPSessionKeyStr, inCMDStr, inModeStr="CROSSCHECK", inGSettings = None): """ - Send CMD command to the RDP session "RUN" window + Отправить CMD команду на удаленную сесиию через RDP окно (без Агента). + + !ВНИМАНИЕ! Данная функция может работать нестабильно из-за использования графических элементов UI при работе с RDP. Мы рекомендуем использовать конструкцию взаимодействия Оркестратора с Агентом. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lResultDict = Orchestrator.RDPSessionCMDRun( @@ -2486,18 +2512,18 @@ def RDPSessionCMDRun(inRDPSessionKeyStr, inCMDStr, inModeStr="CROSSCHECK", inGSe inRDPSessionKeyStr = "RDPKey", inModeStr = 'LISTEN') # Orchestrator will send CMD to RDP and return the result (see return section) - - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inCMDStr: Any CMD string - :param inModeStr: Variants: - "LISTEN" - Get result of the cmd command in result; - "CROSSCHECK" - Check if the command was successfully sent - "RUN" - Run without crosscheck and get clipboard - :return: # OLD > True - CMD was executed successfully + + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inCMDStr: Команда CMD, которую отправить на удаленную сессию + :param inModeStr: По умолчанию "CROSSCHECK". Варианты: + "LISTEN" - Получить результат выполнения операции. Внимание! необходим общий буфер обмена с сессией Оркестратора! + "CROSSCHECK" - Выполнить проверку, что операция была выполнена (без получения результата отработки CMD команды). Внимание! необходим общий буфер обмена с сессией Оркестратора! + "RUN" - Не получать результат и не выполнять проверку + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: Результат выполнения операции в соответсвии с параметрами инициализации функции. Выходная структура: { - "OutStr": <> # Result string - "IsResponsibleBool": True|False # Flag is RDP is responsible - works only when inModeStr = CROSSCHECK + "OutStr": <> # Результат выполнения CMD (если inModeStr = "LISTEN") + "IsResponsibleBool": True|False # True - RDP приняло команду; False - обратная связь не была получена (если inModeStr = "CROSSCHECK") } """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -2528,11 +2554,13 @@ def RDPSessionCMDRun(inRDPSessionKeyStr, inCMDStr, inModeStr="CROSSCHECK", inGSe def RDPSessionProcessStop(inRDPSessionKeyStr, inProcessNameWEXEStr, inFlagForceCloseBool, inGSettings = None): """ - Send CMD command to the RDP session "RUN" window. + Отправка CMD команды в RDP окне на остановку процесса (без Агента). + + !ВНИМАНИЕ! Данная функция может работать нестабильно из-за использования графических элементов UI при работе с RDP. Мы рекомендуем использовать конструкцию взаимодействия Оркестратора с Агентом. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lResultDict = Orchestrator.RDPSessionProcessStop( @@ -2542,11 +2570,11 @@ def RDPSessionProcessStop(inRDPSessionKeyStr, inProcessNameWEXEStr, inFlagForceC inFlagForceCloseBool = True) # Orchestrator will send CMD to RDP and return the result (see return section) - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inProcessNameWEXEStr: Process name to kill. Example: 'notepad.exe' - :param inFlagForceCloseBool: True - force close the process. False - safe close the process - :return: True every time + + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inProcessNameWEXEStr: Наименование процесса, который требуется выключить с расширением .exe (WEXE - WITH EXE - С EXE). Пример: "Notepad.exe" + :param inFlagForceCloseBool: True - Принудительное отключение. False - Отправка сигнала на безопасное отключение (если процесс поддерживает) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check thread @@ -2574,11 +2602,15 @@ def RDPSessionProcessStop(inRDPSessionKeyStr, inProcessNameWEXEStr, inFlagForceC def RDPSessionFileStoredSend(inRDPSessionKeyStr, inHostFilePathStr, inRDPFilePathStr, inGSettings = None): """ - Send file from Orchestrator session to the RDP session using shared drive in RDP (see RDP Configuration Dict, Shared drive) + Отправка файла со стороны Оркестратора на сторону RDP сессии через UI инструменты RDP окна (без Агента). + + !ВНИМАНИЕ! Данная функция может работать нестабильно из-за использования графических элементов UI при работе с RDP. Мы рекомендуем использовать конструкцию взаимодействия Оркестратора с Агентом. + + !ВНИМАНИЕ! Для работы функции требуется открыть доступ по RDP к тем дискам, с которых будет производится копирование файла. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lResultDict = Orchestrator.RDPSessionFileStoredSend( @@ -2588,11 +2620,10 @@ def RDPSessionFileStoredSend(inRDPSessionKeyStr, inHostFilePathStr, inRDPFilePat inRDPFilePathStr = "C:\\RPA\\TESTDIR\\Test.py") # Orchestrator will send CMD to RDP and return the result (see return section) - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inHostFilePathStr: Relative or absolute path to the file location on the Orchestrator side. Example: "TESTDIR\\Test.py" - :param inRDPFilePathStr: !Absolute! path to the destination file location on the RDP side. Example: "C:\\RPA\\TESTDIR\\Test.py" - :return: True every time + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inHostFilePathStr: Откуда взять файл. Относительный или абсолютный путь к файлу на стороне Оркестратора. Пример: "TESTDIR\\Test.py" + :param inRDPFilePathStr: Куда скопировать файл. !Абсолютный! путь на стороне RDP сессии. Пример: "C:\\RPA\\TESTDIR\\Test.py" + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check thread @@ -2619,11 +2650,15 @@ def RDPSessionFileStoredSend(inRDPSessionKeyStr, inHostFilePathStr, inRDPFilePat def RDPSessionFileStoredRecieve(inRDPSessionKeyStr, inRDPFilePathStr, inHostFilePathStr, inGSettings = None): """ - Recieve file from RDP session to the Orchestrator session using shared drive in RDP (see RDP Configuration Dict, Shared drive) + Получение файла со стороны RDP сессии на сторону Оркестратора через UI инструменты RDP окна (без Агента). + + !ВНИМАНИЕ! Данная функция может работать нестабильно из-за использования графических элементов UI при работе с RDP. Мы рекомендуем использовать конструкцию взаимодействия Оркестратора с Агентом. + + !ВНИМАНИЕ! Для работы функции требуется открыть доступ по RDP к тем дискам, с которых будет производится копирование файла. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lResultDict = Orchestrator.RDPSessionFileStoredRecieve( @@ -2633,11 +2668,10 @@ def RDPSessionFileStoredRecieve(inRDPSessionKeyStr, inRDPFilePathStr, inHostFile inRDPFilePathStr = "C:\\RPA\\TESTDIR\\Test.py") # Orchestrator will send CMD to RDP and return the result (see return section) - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inRDPFilePathStr: !Absolute! path to the destination file location on the RDP side. Example: "C:\\RPA\\TESTDIR\\Test.py" - :param inHostFilePathStr: Relative or absolute path to the file location on the Orchestrator side. Example: "TESTDIR\\Test.py" - :return: True every time + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inRDPFilePathStr: Откуда скопировать файл. !Абсолютный! путь на стороне RDP сессии. Пример: "C:\\RPA\\TESTDIR\\Test.py" + :param inHostFilePathStr: Куда скопировать файл. Относительный или абсолютный путь к файлу на стороне Оркестратора. Пример: "TESTDIR\\Test.py" + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check thread @@ -2665,13 +2699,8 @@ def RDPSessionFileStoredRecieve(inRDPSessionKeyStr, inRDPFilePathStr, inHostFile # # # # # Start orchestrator # # # # # # # # # # # # # # # # # # # # # # # +#HIDDEN Interval gSettings auto cleaner def to clear some garbage. def GSettingsAutocleaner(inGSettings=None): - """ - HIDDEN Interval gSettings auto cleaner def to clear some garbage. - - :param inGSettings: Global settings dict (singleton) - :return: None - """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings while True: time.sleep(inGSettings["Autocleaner"]["IntervalSecFloat"]) # Wait for the next iteration @@ -2700,23 +2729,15 @@ def GSettingsAutocleaner(inGSettings=None): from .. import __version__ # Get version from the package def Start(inDumpRestoreBool = True, inRunAsAdministratorBool = True): - """ - Start the orchestrator threads execution - - :param inDumpRestoreBool: True - restore data from the dumo - :param inRunAsAdministratorBool: True - rerun as admin if not - :return: - """ Orchestrator(inDumpRestoreBool = True, inRunAsAdministratorBool = True) def Orchestrator(inGSettings=None, inDumpRestoreBool = True, inRunAsAdministratorBool = True): """ - Main def to start orchestrator + Инициализация ядра Оркестратора (всех потоков) - :param inGSettings: - :param inDumpRestoreBool: - :param inRunAsAdministratorBool: - :return: + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inDumpRestoreBool: True - Восстановить информацию о RDP сессиях и StorageDict; False - не восстанавливать + :param inRunAsAdministratorBool: True - Проверить права администратратора и обеспечить их; False - Не обеспечивать права администратора """ lL = inGSettings["Logger"] # https://stackoverflow.com/questions/130763/request-uac-elevation-from-within-a-python-script @@ -2801,8 +2822,6 @@ def Orchestrator(inGSettings=None, inDumpRestoreBool = True, inRunAsAdministrato lRobotRDPActiveThread.start() # Start the thread execution. if lL: lL.info("Robot RDP active has been started") #Logging - - # Init autocleaner in another thread lAutocleanerThread = threading.Thread(target= GSettingsAutocleaner, kwargs={"inGSettings":gSettingsDict}) lAutocleanerThread.daemon = True # Run the thread in daemon mode. diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Clipboard.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Clipboard.py index 12b43186..279e699b 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Clipboard.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Clipboard.py @@ -4,17 +4,42 @@ import win32clipboard #################################### # GUI Module - interaction with Windows clipboard -################ -###ClipboardGet -################ +def Get(): + """ + Получить текстовое содержимое буфера обмена. + + .. code-block:: python + + # Clipboard: Взаимодействие с буфером + from pyOpenRPA.Robot import Clipboard + lClipStr = Clipboard.Get() + + :return: Текстовое содержимое буфера обмена + :rtype: str + """ + return ClipboardGet() + +def Set(inTextStr:str): + """ + Установить текстовое содержимое в буфер обмена. + + .. code-block:: python + + # Clipboard: Взаимодействие с буфером + from pyOpenRPA.Robot import Clipboard + lClipStr = Clipboard.Set(inTextStr="HELLO WORLD") + + :param inTextStr: Текстовое содержимое для установки в буфера обмена + :type inTextStr: str + """ + ClipboardSet(inText=inTextStr) + def ClipboardGet(): win32clipboard.OpenClipboard() lResult = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT) win32clipboard.CloseClipboard() return lResult -################ -###ClipboardSet -################ + def ClipboardSet(inText): win32clipboard.OpenClipboard() win32clipboard.EmptyClipboard() diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Keyboard.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Keyboard.py index b6a278fc..d6cbacc5 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Keyboard.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Keyboard.py @@ -1 +1,344 @@ -from keyboard import * \ No newline at end of file +from keyboard import * +import time + +# Настройки модуля Keyboard +WAIT_AFTER_SEC_FLOAT = 0.4 # Время, которое ожидать после выполнения любой операции модуля Keyboard. Настройка является единой для всех участов кода, использующих модуль Keyboard. Если для некоторой функции требуется изменить данное время ожидания, то в отношении этой функции можно применить соответсвующий аргумент. + +# ШЕСТНАДЦАТИРИЧНЫЙ СКАН-КОД В РУССКОЙ РАСКЛАДКЕ (НЕЗАВИСИМО ОТ ВЫБРАННОГО ЯЗЫКА НА КЛАВИАТУРЕ) +# ОТОБРАЖЕНИЕ СКАН КОДОВ НА КЛАВИАТУРЕ https://snipp.ru/handbk/scan-codes + +KEY_RUS_Ф = 0x1E #A +KEY_RUS_И = 0x30 #B +KEY_RUS_С = 0x2E #C +KEY_RUS_В = 0x20 #D +KEY_RUS_У = 0x12 #E +KEY_RUS_А = 0x21 #F +KEY_RUS_П = 0x22 #G +KEY_RUS_Р = 0x23 #H +KEY_RUS_Ш = 0x17 #I +KEY_RUS_О = 0x24 #J +KEY_RUS_Л = 0x25 #K +KEY_RUS_Д = 0x26 #L +KEY_RUS_Ь = 0x32 #M +KEY_RUS_Т = 0x31 #N +KEY_RUS_Щ = 0x18 #O +KEY_RUS_З = 0x19 #P +KEY_RUS_Й = 0x10 #Q +KEY_RUS_К = 0x13 #R +KEY_RUS_Ы = 0x1F #S +KEY_RUS_Е = 0x14 #T +KEY_RUS_Г = 0x16 #U +KEY_RUS_М = 0x2F #V +KEY_RUS_Ц = 0x11 #W +KEY_RUS_Ч = 0x2D #X +KEY_RUS_Н = 0x15 #Y +KEY_RUS_Я = 0x2C #Z +KEY_RUS_Ё = 0x29 #~ +KEY_RUS_Ж = 0x27 #: +KEY_RUS_Б = 0x33 #< +KEY_RUS_Ю = 0x34 #> +KEY_RUS_Х = 0x1A #[ +KEY_RUS_Ъ = 0x1B #] +KEY_RUS_Э = 0x28 #' + +KEY_ENG_A = 0x1E #A +KEY_ENG_B = 0x30 #B +KEY_ENG_C = 0x2E #C +KEY_ENG_D = 0x20 #D +KEY_ENG_E = 0x12 #E +KEY_ENG_F = 0x21 #F +KEY_ENG_G = 0x22 #G +KEY_ENG_H = 0x23 #H +KEY_ENG_I = 0x17 #I +KEY_ENG_J = 0x24 #J +KEY_ENG_K = 0x25 #K +KEY_ENG_L = 0x26 #L +KEY_ENG_M = 0x32 #M +KEY_ENG_N = 0x31 #N +KEY_ENG_O = 0x18 #O +KEY_ENG_P = 0x19 #P +KEY_ENG_Q = 0x10 #Q +KEY_ENG_R = 0x13 #R +KEY_ENG_S = 0x1F #S +KEY_ENG_T = 0x14 #T +KEY_ENG_U = 0x16 #U +KEY_ENG_V = 0x2F #V +KEY_ENG_W = 0x11 #W +KEY_ENG_X = 0x2D #X +KEY_ENG_Y = 0x15 #Y +KEY_ENG_Z = 0x2C #Z + + +KEY_HOT_NUMPAD_0 = 0x52 +KEY_HOT_NUMPAD_1 = 0x4F +KEY_HOT_NUMPAD_2 = 0x50 +KEY_HOT_NUMPAD_3 = 0x51 +KEY_HOT_NUMPAD_4 = 0x4B +KEY_HOT_NUMPAD_5 = 0x4C +KEY_HOT_NUMPAD_6 = 0x4D +KEY_HOT_NUMPAD_7 = 0x47 +KEY_HOT_NUMPAD_8 = 0x48 +KEY_HOT_NUMPAD_9 = 0x49 +KEY_HOT_NUMPAD_ASTERISK = 0x37 #* +KEY_HOT_NUMPAD_PLUS = 0x4E +KEY_HOT_NUMPAD_MINUS = 0x4A +KEY_HOT_NUMPAD_DELETE = 0x53 +KEY_HOT_NUMPAD_SOLIDUS = 0x35 #/ +KEY_HOT_NUMPAD_ENTER = 0x11c + +KEY_HOT_F1 = 0x3B +KEY_HOT_F2 = 0x3C +KEY_HOT_F3 = 0x3D +KEY_HOT_F4 = 0x3E +KEY_HOT_F5 = 0x3F +KEY_HOT_F6 = 0x40 +KEY_HOT_F7 = 0x41 +KEY_HOT_F8 = 0x42 +KEY_HOT_F9 = 0x43 +KEY_HOT_F10 = 0x44 +KEY_HOT_F11 = 0x57 +KEY_HOT_F12 = 0x58 +KEY_HOT_F13 = 0x7C +KEY_HOT_F14 = 0x7D +KEY_HOT_F15 = 0x7E +KEY_HOT_F16 = 0x7F +KEY_HOT_F17 = 0x80 +KEY_HOT_F18 = 0x81 +KEY_HOT_F19 = 0x82 +KEY_HOT_F20 = 0x83 +KEY_HOT_F21 = 0x84 +KEY_HOT_F22 = 0x85 +KEY_HOT_F23 = 0x86 +KEY_HOT_F24 = 0x87 + +KEY_HOT_TILDE = 0x29 #~ +KEY_HOT_COLON = 0x27 #: +KEY_HOT_PLUS = 0x0D #+ +KEY_HOT_MINUS = 0x0C #- +KEY_HOT_LESS_THAN = 0x33 #< , +KEY_HOT_GREATER_THAN = 0x34 #> . +KEY_HOT_SOLIDUS = 0x35 #/ ? +KEY_HOT_SQUARE_BRACKET_LEFT = 0x1A #[ +KEY_HOT_SQUARE_BRACKET_RIGHT = 0x1B #] +KEY_HOT_APOSTROPHE = 0x28 #' " +KEY_HOT_VERTICAL_LINE = 0x2B #| \ + +KEY_HOT_ESC = 0x1 +KEY_HOT_BACKSPACE = 0x0E +KEY_HOT_TAB = 0x0F +KEY_HOT_ENTER = 0x1C +KEY_HOT_CONTEXT_MENU = 0x15D +KEY_HOT_SHIFT_LEFT = 0x2A +KEY_HOT_SHIFT_RIGHT = 0x36 +KEY_HOT_CTRL_LEFT = 0x1D +KEY_HOT_CTRL_RIGHT = 0x11D +KEY_HOT_ALT_LEFT = 0x38 +KEY_HOT_ALT_RIGHT = 0x138 +KEY_HOT_WIN_LEFT = 57435 #OLD AND DONT WORK 0x5B +KEY_HOT_WIN_RIGHT = 57436 #OLD AND DONT WORK 0x5C +KEY_HOT_CAPS_LOCK = 0x3A +KEY_HOT_NUM_LOCK = 0x45 +KEY_HOT_SCROLL_LOCK = 0x46 +KEY_HOT_END = 0x4F +KEY_HOT_HOME = 0x47 +KEY_HOT_SPACE = 0x39 +KEY_HOT_PAGE_UP = 0x49 +KEY_HOT_PAGE_DOWN = 0x51 +KEY_HOT_CLEAR = 0x4C +KEY_HOT_LEFT = 0x4B +KEY_HOT_UP = 0x48 +KEY_HOT_RIGHT = 0x4D +KEY_HOT_DOWN = 0x50 +KEY_HOT_PRINT_SCREEN = 0x137 +KEY_HOT_INSERT = 0x52 +KEY_HOT_DELETE = 0x53 + +KEY_HOT_0 = 0xB +KEY_HOT_1 = 0x2 +KEY_HOT_2 = 0x3 +KEY_HOT_3 = 0x4 +KEY_HOT_4 = 0x5 +KEY_HOT_5 = 0x6 +KEY_HOT_6 = 0x7 +KEY_HOT_7 = 0x8 +KEY_HOT_8 = 0x9 +KEY_HOT_9 = 0xA + +def Write(inTextStr:str, inDelayFloat:float=0, inRestoreStateAfterBool:bool=True, inExactBool:bool=None, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """ + Печатает текст, который был передан в переменной inTextStr (поддерживает передачу в одной строке символов разного языка). Не зависит от текущей раскладки клавиатуры! Посылает искусственные клавишные события в ОС, моделируя печать данного текста. Знаки, не доступные на клавиатуре, напечатаны как явный unicode знаки, использующие определенную для ОС функциональность, такие как alt+codepoint. + Чтобы гарантировать текстовую целостность, все в настоящее время нажатые ключи выпущены прежде текст напечатан, и модификаторы восстановлены впоследствии. + + ВНИМАНИЕ! ПЕЧАТАЕТ ЛЮБУЮ СТРОКУ, ДАЖЕ В СОЧЕТАНИИ НЕСКОЛЬКИХ ЯЗЫКОВ ОДНОВРЕМЕННО. ДЛЯ РАБОТЫ С ГОРЯЧИМИ КЛАВИШАМИ ИСПОЛЬЗУЙ ФУНКЦИЮ Send, Up, Down, HotkeyCombination + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + Keyboard.Write("Привет мой милый мир! Hello my dear world!") + + :param inTextStr: Текст, отправляемый на печать. Не зависит от текущей раскладки клавиатуры! + :type inTextStr: str + :param inDelayFloat: Число секунд, которое ожидать между нажатиями. По умолчанию 0 + :type inDelayFloat: float, опциональный + :param inRestoreStateAfterBool: Может использоваться, чтобы восстановить регистр нажатых ключей после того, как текст напечатан, т.е. нажимает ключи, которые были выпущены в начало. + :type inRestoreStateAfterBool: bool, опциональный + :param inExactBool: Печатает все знаки как явный unicode. Необязательный параметр + :type inExactBool: bool, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Keyboard (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + write(text=inTextStr, delay=inDelayFloat, restore_state_after=inRestoreStateAfterBool, exact=inExactBool) + time.sleep(inWaitAfterSecFloat) + +def HotkeyCombination(*inKeyList, inDelaySecFloat = 0.3,inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Получает перечень клавиш для одновременного нажатия. Между нажатиями программа ожидания время inDelaySecFloat + ВНИМАНИЕ! НЕ ЗАВИСИТ ОТ ТЕКУЩЕЙ РАСКЛАДКИ КЛАВИАТУРЫ + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + Keyboard.HotkeyCombination(Keyboard.KEY_HOT_CTRL_LEFT,Keyboard.KEY_ENG_A) # Ctrl + a + Keyboard.HotkeyCombination(Keyboard.KEY_HOT_CTRL_LEFT,Keyboard.KEY_ENG_C) # Ctrl + c + Keyboard.HotkeyCombination(Keyboard.KEY_HOT_CTRL_LEFT,Keyboard.KEY_ENG_A) + Keyboard.HotkeyCombination(Keyboard.KEY_HOT_ALT_LEFT,Keyboard.KEY_HOT_TAB, Keyboard.KEY_HOT_TAB) + + :param inKeyList: Список клавиш для одновременного нажатия. Перечень клавиш см. в разделе "Коды клавиш". Пример: KEY_HOT_CTRL_LEFT,KEY_ENG_A + :param inDelaySecFloat: Интервал между нажатиями. Необходим в связи с тем, что операционной системе требуется время на реакцию на нажатие клавиш, по умолчанию: 0.3 + :type inDelaySecFloat: float, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Keyboard (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + for l_key_item in inKeyList: + if l_key_item == inKeyList[-1]: + send(l_key_item) + else: + press(l_key_item) + time.sleep(inDelaySecFloat) + lRevKeyList = list(reversed(inKeyList)) + for l_key_item in lRevKeyList: + if l_key_item == lRevKeyList[0]: + pass + else: + release(l_key_item) + time.sleep(inDelaySecFloat) + time.sleep(inWaitAfterSecFloat) + +def HotkeyCtrlA_CtrlC(inWaitAfterSecFloat:float=0.4) -> None: + """Выполнить выделение текста, после чего скопировать его в буфер обмена + ВНИМАНИЕ! НЕ ЗАВИСИТ ОТ ТЕКУЩЕЙ РАСКЛАДКИ КЛАВИАТУРЫ + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + Keyboard.HotkeyCtrlA_CtrlC() # Отправить команды: выделить все, скопировать в буфер обмена + + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Keyboard (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + HotkeyCombination(KEY_HOT_CTRL_LEFT,KEY_ENG_A) # Ctrl + a + HotkeyCombination(KEY_HOT_CTRL_LEFT,KEY_ENG_C) # Ctrl + c + time.sleep(inWaitAfterSecFloat) + +def Send(inKeyInt:int, inDoPressBool:bool=True, inDoReleaseBool:bool=True,inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT) -> None: + """ + Имитация нажатия/отпускания любой физической клавиши. Посылает событие в операционную систему, которые выполняет нажатие и отпускание данной клавиши + + ВНИМАНИЕ! ПРИ ПОПЫТКЕ ПЕЧАТИ ТЕКСТА БУДЕТ УЧИТЫВАТЬ ТЕКУЩУЮ РАСКЛАДКУ КЛАВИАТУРЫ. ДЛЯ ПЕЧАТИ ТЕКСТА ИСПОЛЬЗУЙ Write! + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + Keyboard.Send(Keyboard.KEY_ENG_A) # Нажать клавишу A. Если будет активна русская раскладка, то будет выведена буква ф. + + :param inKeyInt: Перечень клавиш см. в разделе "Коды клавиш". Пример: KEY_HOT_CTRL_LEFT,KEY_ENG_A + :type inKeyInt: int + :param inDoPressBool: Выполнить событие нажатия клавиши, По умолчанию True + :type inDoPressBool: bool, опциональный + :param inDoReleaseBool: Выполнить событие отпускания клавиши, По умолчанию True + :type inDoReleaseBool: bool, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Keyboard (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + send(hotkey=inKeyInt, do_press=inDoPressBool, do_release=inDoReleaseBool) + time.sleep(inWaitAfterSecFloat) + +def Up(inKeyInt:int, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT) -> None: + """ + Отпустить (поднять) клавишу. Если клавиша уже была поднята, то ничего не произойдет. + + ВНИМАНИЕ! ПРИ ПОПЫТКЕ ПЕЧАТИ ТЕКСТА БУДЕТ УЧИТЫВАТЬ ТЕКУЩУЮ РАСКЛАДКУ КЛАВИАТУРЫ. ДЛЯ ПЕЧАТИ ТЕКСТА ИСПОЛЬЗУЙ Write! + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + Keyboard.Up(Keyboard.KEY_ENG_A) # Отпустить клавишу A. + + :param inKeyInt: Перечень клавиш см. в разделе "Коды клавиш". Пример: KEY_HOT_CTRL_LEFT, KEY_ENG_A + :type inKeyInt: int + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Keyboard (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + send(hotkey=inKeyInt, do_press=False, do_release=True) + time.sleep(inWaitAfterSecFloat) + +def Down(inKeyInt:int, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT) -> None: + """ + Нажать (опустить) клавишу. Если клавиша уже была опущена, то ничего не произойдет. + + ВНИМАНИЕ! ПРИ ПОПЫТКЕ ПЕЧАТИ ТЕКСТА БУДЕТ УЧИТЫВАТЬ ТЕКУЩУЮ РАСКЛАДКУ КЛАВИАТУРЫ. ДЛЯ ПЕЧАТИ ТЕКСТА ИСПОЛЬЗУЙ Write! + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + Keyboard.Down(Keyboard.KEY_ENG_A) # Отпустить клавишу A. + + :param inKeyInt: Перечень клавиш см. в разделе "Коды клавиш". Пример: KEY_HOT_CTRL_LEFT, KEY_ENG_A + :type inKeyInt: int + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Keyboard (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + send(hotkey=inKeyInt, do_press=True, do_release=False) + time.sleep(inWaitAfterSecFloat) + +def IsDown(inKeyInt:int) -> bool: + """ + Проверить, опущена ли клавиша. Вернет True если опущена; False если поднята. + + ВНИМАНИЕ! ПРИ ПОПЫТКЕ ПЕЧАТИ ТЕКСТА БУДЕТ УЧИТЫВАТЬ ТЕКУЩУЮ РАСКЛАДКУ КЛАВИАТУРЫ. ДЛЯ ПЕЧАТИ ТЕКСТА ИСПОЛЬЗУЙ Write! + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + lKeyAIsPressedBool = Keyboard.IsDown(Keyboard.KEY_ENG_A) # Проверить, опущена ли клавиша A. + + :param inKeyInt: Перечень клавиш см. в разделе "Коды клавиш". Пример: KEY_HOT_CTRL_LEFT, KEY_ENG_A + :type inKeyInt: int + """ + return is_pressed(inKeyInt) + +def Wait(inKeyInt:int,inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Блокирует осуществление программы, пока данная обозначенная клавиша не будет нажата. + ВНИМАНИЕ! НЕ ЗАВИСИТ ОТ ТЕКУЩЕЙ РАСКЛАДКИ КЛАВИАТУРЫ. ОЖИДАЕТ НАЖАТИЕ СООТВЕТСВУЮЩЕЙ ФИЗИЧЕСКОЙ КЛАВИШИ + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + Keyboard.Wait(Keyboard.KEY_ENG_A) # Ждать нажатие клавиши A. + + :param inKeyInt: Перечень клавиш см. в разделе "Коды клавиш". Пример: KEY_HOT_CTRL_LEFT,KEY_ENG_A + :type inKeyInt: int + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Keyboard (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + wait(hotkey=inKeyInt) + time.sleep(inWaitAfterSecFloat) + +key_to_scan_codes("win") # 2022 06 10 Люблю смотреть скан код клавиши Виндовс :) \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Mouse.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Mouse.py index 49af0760..e693a900 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Mouse.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/Mouse.py @@ -1 +1,173 @@ -from pyautogui import * \ No newline at end of file +from pyautogui import * +import time + +WAIT_AFTER_SEC_FLOAT = 0.4 # Настройка модуля Mouse: Время, которое ожидать после выполнения любой операции модуля Mouse. Настройка является единой для всех участов кода, использующих модуль Mouse. Если для некоторой функции требуется изменить данное время ожидания, то в отношении этой функции можно применить соответсвующий аргумент. + +def Click(inXInt:int=None, inYInt:int=None, inClickCountInt:int=1, inIntervalSecFloat:float=0.0, inButtonStr:str='left', inMoveDurationSecFloat:float=0.0, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Нажатие (вниз) кнопки мыши и затем немедленно выпуск (вверх) её. Допускается следующая параметризация. Если не указаны inXInt и inYInt - клик производится по месту нахождения указателя мыши. + + !ВНИМАНИЕ! Отсчет координат inXInt, inYInt начинается с левого верхнего края рабочей области (экрана). + + .. code-block:: python + + # Mouse: Взаимодействие с мышью + from pyOpenRPA.Robot import Mouse + Mouse.Click(100,150) #Выполнить нажатие левой клавиши мыши на экране по координатам: X(гор) 100px, Y(вер) 150px. + + :param inXInt: Целевая позиция указателя мыши по оси X (горизонтальная ось). + :type inXInt: int, опциональный + :param inYInt: Целевая позиция указателя мыши по оси Y (вертикальная ось). + :type inYInt: int, опциональный + :param inClickCountInt: Количество нажатий (вниз и вверх) кнопкой мыши, По умолчанию 1 + :type inClickCountInt: int, опциональный + :param inIntervalSecFloat: Интервал ожидания в секундах между нажатиями, По умолчанию 0.0 + :type inIntervalSecFloat: float, опциональный + :param inButtonStr: Номер кнопки, которую требуется нажать. Возможные варианты: 'left', 'middle', 'right' или 1, 2, 3. В остальных случаях инициирует исключение ValueError. По умолчанию 'left' + :type inButtonStr: str, опциональный + :param inMoveDurationSecFloat: Время перемещения указателя мыши, По умолчанию 0.0 (моментальное перемещение) + :type inMoveDurationSecFloat: float, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Mouse (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + click(x=inXInt, y=inYInt, clicks=inClickCountInt, interval=inIntervalSecFloat, button=inButtonStr, duration=inMoveDurationSecFloat) + time.sleep(inWaitAfterSecFloat) + +def ClickDouble(inXInt:int=None, inYInt:int=None, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Двойное нажатие левой клавиши мыши. Данное действие аналогично вызову функции (см. ниже). + + !ВНИМАНИЕ! Отсчет координат inXInt, inYInt начинается с левого верхнего края рабочей области (экрана). + + .. code-block:: python + + # Mouse: Взаимодействие с мышью + from pyOpenRPA.Robot import Mouse + Mouse.ClickDouble(100,150) #Выполнить двойное нажатие левой клавиши мыши на экране по координатам: X(гор) 100px, Y(вер) 150px. + + :param inXInt: Целевая позиция указателя мыши по оси X (горизонтальная ось). + :type inXInt: int, опциональный + :param inYInt: Целевая позиция указателя мыши по оси Y (вертикальная ось). + :type inYInt: int, опциональный + :param inButtonStr: Номер кнопки, которую требуется нажать. Возможные варианты: 'left', 'middle', 'right' или 1, 2, 3. В остальных случаях инициирует исключение ValueError. По умолчанию 'left' + :type inButtonStr: str, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Mouse (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + doubleClick(x=inXInt, y=inYInt) + time.sleep(inWaitAfterSecFloat) + +def Down(inXInt:int=None, inYInt:int=None, inButtonStr:str='left', inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Переместить указатель по координатам inXInt, inYInt, после чего нажать (вниз) клавишу мыши и не отпускать до выполнения соответсвующей команды (см. Up). Если координаты inXInt, inYInt не переданы - нажатие происходит на тех координатах X/Y, на которых указатель мыши находится. + + !ВНИМАНИЕ! Отсчет координат inXInt, inYInt начинается с левого верхнего края рабочей области (экрана). + + .. code-block:: python + + # Mouse: Взаимодействие с мышью + from pyOpenRPA.Robot import Mouse + Mouse.Down() #Опустить левую клавишу мыши + + :param inXInt: Целевая позиция указателя мыши по оси X (горизонтальная ось). + :type inXInt: int, опциональный + :param inYInt: Целевая позиция указателя мыши по оси Y (вертикальная ось). + :type inYInt: int, опциональный + :param inButtonStr: Номер кнопки, которую требуется нажать. Возможные варианты: 'left', 'middle', 'right' или 1, 2, 3. В остальных случаях инициирует исключение ValueError. По умолчанию 'left' + :type inButtonStr: str, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Mouse (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + mouseDown(x=inXInt, y=inYInt, button = inButtonStr) + time.sleep(inWaitAfterSecFloat) + +def Up(inXInt:int=None, inYInt:int=None, inButtonStr:str='left', inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Отпустить (вверх) клавишу мыши. Если координаты inXInt, inYInt не переданы - нажатие происходит на тех координатах X/Y, на которых указатель мыши находится. + + !ВНИМАНИЕ! Отсчет координат inXInt, inYInt начинается с левого верхнего края рабочей области. + + .. code-block:: python + + # Mouse: Взаимодействие с мышью + from pyOpenRPA.Robot import Mouse + Mouse.Up(inButtonStr:str='right') #Поднять правую клавишу мыши + + :param inXInt: Целевая позиция указателя мыши по оси X (горизонтальная ось). + :type inXInt: int, опциональный + :param inYInt: Целевая позиция указателя мыши по оси Y (вертикальная ось). + :type inYInt: int, опциональный + :param inButtonStr: Номер кнопки, которую требуется поднять. Возможные варианты: 'left', 'middle', 'right' или 1, 2, 3. В остальных случаях инициирует исключение ValueError. По умолчанию 'left' + :type inButtonStr: str, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Mouse (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + mouseUp(x=inXInt, y=inYInt, button = inButtonStr) + time.sleep(inWaitAfterSecFloat) + +def MoveTo(inXInt=None, inYInt=None, inMoveDurationSecFloat:float=0.0, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Переместить указатель мыши на позицию inXInt, inYInt за время inMoveDurationSecFloat. + + !ВНИМАНИЕ! Отсчет координат inXInt, inYInt начинается с левого верхнего края рабочей области (экрана). + + .. code-block:: python + + # Mouse: Взаимодействие с мышью + from pyOpenRPA.Robot import Mouse + Mouse.MoveTo(inXInt=100, inYInt=200) #Переместить указатель мыши по координатам: X(гор) 100, Y(вер) 200 + + :param inXInt: Целевая позиция указателя мыши по оси X (горизонтальная ось). + :type inXInt: int, опциональный + :param inYInt: Целевая позиция указателя мыши по оси Y (вертикальная ось). + :type inYInt: int, опциональный + :param inMoveDurationSecFloat: Время перемещения указателя мыши, По умолчанию 0.0 (моментальное перемещение) + :type inMoveDurationSecFloat: float, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Mouse (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + moveTo(x=inXInt, y=inYInt, duration=inMoveDurationSecFloat) + time.sleep(inWaitAfterSecFloat) + +def ScrollVertical(inScrollClickCountInt, inXInt=None, inYInt=None, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Переместить указатель мыши на позицию inXInt, inYInt и выполнить вертикальную прокрутку (скроллинг) колесом мыши на количество щелчков inScrollClickCountInt. + + !ВНИМАНИЕ! Отсчет координат inXInt, inYInt начинается с левого верхнего края рабочей области (экрана). + + .. code-block:: python + + # Mouse: Взаимодействие с мышью + from pyOpenRPA.Robot import Mouse + Mouse.ScrollVertical(100, inXInt=100, inYInt=200) #Крутить колесо мыши вниз на 100 кликов по координатам: X(гор) 100, Y(вер) 200 + Mouse.ScrollVertical(-100) #Крутить колесо мыши вверх на 100 кликов по текущим координатам указателя мыши. + + :param inScrollClickCountInt: Количество щелчок колеса мыши, которое требуется !вертикально! прокрутить. Аргумент может принимать как положительное (прокрутка вниз), так и отрицательное (прокрутка вверх) значения + :type inScrollClickCountInt: int, обязательный + :param inXInt: Целевая позиция указателя мыши по оси X (горизонтальная ось). + :type inXInt: int, опциональный + :param inYInt: Целевая позиция указателя мыши по оси Y (вертикальная ось). + :type inYInt: int, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Mouse (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + vscroll(inScrollClickCountInt, x=inXInt, y=inYInt) + time.sleep(inWaitAfterSecFloat) + +def ScrollHorizontal(inScrollClickCountInt, inXInt=None, inYInt=None, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """!ТОЛЬКО ДЛЯ LINUX! Переместить указатель мыши на позицию inXInt, inYInt и выполнить горизонтальную прокрутку (скроллинг) виртуальным колесом мыши на количество щелчков inScrollClickCountInt. + + !ВНИМАНИЕ! Отсчет координат inXInt, inYInt начинается с левого верхнего края рабочей области (экрана). + + .. code-block:: python + + # Mouse: Взаимодействие с мышью + from pyOpenRPA.Robot import Mouse + Mouse.ScrollHorizontal(100, inXInt=100, inYInt=200) #Крутить колесо мыши вниз на 100 кликов по координатам: X(гор) 100, Y(вер) 200 + Mouse.ScrollHorizontal(-100) #Крутить колесо мыши вверх на 100 кликов по текущим координатам указателя мыши. + + :param inScrollClickCountInt: Количество щелчок колеса мыши, которое требуется !горизонтально! прокрутить. Аргумент может принимать как положительное (прокрутка вправо), так и отрицательное (прокрутка влево) значения + :type inScrollClickCountInt: int, обязательный + :param inXInt: Целевая позиция указателя мыши по оси X (горизонтальная ось). + :type inXInt: int, опциональный + :param inYInt: Целевая позиция указателя мыши по оси Y (вертикальная ось). + :type inYInt: int, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Mouse (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + hscroll(inScrollClickCountInt, x=inXInt, y=inYInt) + time.sleep(inWaitAfterSecFloat) diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/README.md b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/README.md index f5f30305..4ae5e05c 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/README.md +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/README.md @@ -43,16 +43,5 @@ Resources\WPy64-3720\python-3.7.2.amd64\python.exe ] -# Open RPA Wiki -- [Home](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/home) -- [04. Desktop app access (win32 & ui automation)](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/04.-Desktop-app-access-(win32-&-ui-automation)) - -#Dependencies -* Python 3 x32 [psutil, pywinauto, wmi, PIL, keyboard, pyautogui, win32api (pywin32), selenium, openCV, tesseract, requests, lxml, PyMuPDF] -* Python 3 x64 [psutil, pywinauto, wmi, PIL, keyboard, pyautogui, win32api (pywin32), selenium, openCV, tesseract, requests, lxml, PyMuPDF] -* pywinauto (Windows GUI automation) -* Semantic UI CSS framework -* JsRender by https://www.jsviews.com (switch to Handlebars) -* Handlebars - -Created by Unicode Labs (Ivan Maslov) \ No newline at end of file + +Created by pyOpenRPA LLC (Ivan Maslov) \ No newline at end of file diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py index e084d515..fa101c2b 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py @@ -29,7 +29,7 @@ import copy #TODO В перспективе нужно реализовать алгоритм определения разрядности не в Robot.py, а в UIDesktop.py, тк начинают появляться функции, на входе в которые еще неизвестна разрядность элемента + селектор может охватить сразу два элемента из 2-х разных разрядностей - обрабатываться это должно непосредственно при выполнении #################################### -#Info: GUI module of the Robot app (OpenRPA - Robot) +#Info: GUI module of the Robot app (pyOpenRPA - Robot) #################################### # GUI Module - interaction with Desktop application @@ -99,19 +99,27 @@ mDefaultPywinautoBackend="win32" # "rich_text" - наименование rich_text # } #] -################ -#return: List of UI Object -#inElement - Входной элемент - показатель, что не требуется выполнять коннект к процессу -#inFlagRaiseException - Флаг True - выкинуть ошибку в случае обнаружении пустого списка -#old name - PywinautoExtElementsGet + +#old:PywinautoExtElementsGet def UIOSelector_Get_UIOList (inSpecificationList,inElement=None,inFlagRaiseException=True): ''' - Get the UIO list by the selector + Получить список UIO объектов по UIO селектору + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lDemoBaseUIOList = UIDesktop.UIOSelector_Get_UIOList(lDemoBaseUIOSelector) #Получить список UIO объектов, которые удовлетворяют требованиям UIO селектора. В нашем примере либо [], либо [UIO объект] - :param inSpecificationList: UIO Selector - :param inElement: Входной элемент - показатель, что не требуется выполнять коннект к процессу - :param inFlagRaiseException: Флаг True - выкинуть ошибку в случае обнаружении пустого списка - :return: + :param inSpecificationList: UIO Селектор, который определяет критерии поиска UI элементов + :type inSpecificationList: list, обязательный + :param inElement: Родительский элемент, от которого выполнить поиск UIO объектов по заданному UIO селектору. Если аргумент не задан, платформа выполнит поиск UIO объектов среди всех доступных приложений windows, которые запущены на текущей сессии + :type inElement: UIO объект, опциональный + :param inFlagRaiseException: True - формировать ошибку exception, если платформа не обнаружина ни одного UIO объекта по заданному UIO селектору. False - обратный случай. По умолчанию True + :type inFlagRaiseException: bool, опциональный + :return: Список UIO объектов, которые удовлетворяют условиям UIO селектора ''' #Создать копию входного листа, чтобы не менять массив в других верхнеуровневых функциях inSpecificationList=copy.deepcopy(inSpecificationList) @@ -235,20 +243,26 @@ def UIOSelector_Get_UIOList (inSpecificationList,inElement=None,inFlagRaiseExcep raise pywinauto.findwindows.ElementNotFoundError("Robot can't find element by the UIOSelector") return lResultList -################################################################################################# -#Get first (in more than one) UIO (UI Object) -#inSpecificationList - UIOSelector -#inElement - Входной элемент - показатель, что не требуется выполнять коннект к процессу -#inFlagRaiseException - Флаг True - выкинуть ошибку в случае обнаружении пустого списка -#old name - PywinautoExtElementGet +#old:PywinautoExtElementGet def UIOSelector_Get_UIO (inSpecificationList,inElement=None,inFlagRaiseException=True): ''' - Get the pywinauto object by the UIO selector. + Получить список UIO объект по UIO селектору. Если критериям UIO селектора удовлетворяет несколько UIO объектов - вернуть первый из списка + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lDemoBaseUIOList = UIDesktop.UIOSelector_Get_UIO(lDemoBaseUIOSelector) #Получить 1-й UIO объект, которые удовлетворяет требованиям UIO селектора. В нашем примере либо None, либо UIO объект - :param inSpecificationList: - :param inElement: - :param inFlagRaiseException: - :return: + :param inSpecificationList: UIO Селектор, который определяет критерии поиска UI элементов + :type inSpecificationList: list, обязательный + :param inElement: Родительский элемент, от которого выполнить поиск UIO объектов по заданному UIO селектору. Если аргумент не задан, платформа выполнит поиск UIO объектов среди всех доступных приложений windows, которые запущены на текущей сессии + :type inElement: UIO объект, опциональный + :param inFlagRaiseException: True - формировать ошибку exception, если платформа не обнаружина ни одного UIO объекта по заданному UIO селектору. False - обратный случай. По умолчанию True + :type inFlagRaiseException: bool, опциональный + :return: UIO объект, которые удовлетворяют условиям UIO селектора, или None ''' lResult=None #Получить родительский объект если на вход ничего не поступило @@ -259,17 +273,25 @@ def UIOSelector_Get_UIO (inSpecificationList,inElement=None,inFlagRaiseException if lResult is None and inFlagRaiseException: raise pywinauto.findwindows.ElementNotFoundError("Robot can't find element by the UIOSelector") return lResult -################################################################################################# -#Check if UIO exist (Identified by the UIOSelector) -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! -#UIOSelector -#old name - - + +#old:- def UIOSelector_Exist_Bool (inUIOSelector): ''' - Check if object is exist by the UIO selector. + Проверить существование хотя бы 1-го UIO объекта по заданному UIO селектору + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lDemoBaseUIOExistBool = UIDesktop.UIOSelector_Exist_Bool(lDemoBaseUIOSelector) # Получить булевый результат проверки существования UIO объекта - :param inUIOSelector: - :return: True - Object is exist. False - else case + :param inUIOSelector: UIO Селектор, который определяет критерии поиска UIO объектов + :type inUIOSelector: list, обязательный + :return: True - существует хотя бы 1 UIO объект. False - не существует ни одного UIO объекта по заданному UIO селектору ''' lResult=False #Check the bitness @@ -294,27 +316,34 @@ def UIOSelector_Exist_Bool (inUIOSelector): else: lResult = lPIPEResponseDict["Result"] return lResult -################################################################################################# -#Wait for UIO is appear (at least one of them or all at the same time) -#inSpecificationListList - List of the UIOSelector -#inWaitSecs - Время ожидания объекта в секундах -#inFlagWaitAllInMoment - доп. условие - ожидать появление всех UIOSelector одновременно -#return: [0,1,2] - index of UIOSpecification, which is appear -#old name - - -#####Внимание##### -##Функция ожидания появления элементов (тк элементы могут быть недоступны, неизвестно в каком фреймворке каждый из них может появиться) -def UIOSelectorsSecs_WaitAppear_List (inSpecificationListList,inWaitSecs,inFlagWaitAllInMoment=False): + +#old: - +def UIOSelectorsSecs_WaitAppear_List (inSpecificationListList,inWaitSecs=86400.0,inFlagWaitAllInMoment=False): ''' - Wait for many UI object will appear in GUI for inWaitSecs seconds. + Ожидать появление хотя бы 1-го / всех UIO объектов по заданным UIO селекторам + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python - :param inSpecificationListList: UIOSelector list. - Example: [ + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lNotepadOKSelector = [{"title":"notepad"},{"title":"OK"}] + lNotepadCancelSelector = [{"title":"notepad"},{"title":"Cancel"}] + lDemoBaseUIOExistList = UIDesktop.UIOSelectorsSecs_WaitAppear_List([lDemoBaseUIOSelector, lNotepadOKSelector, lNotepadCancelSelector]) # Ожидать появление UIO объекта + + :param inSpecificationListList: Список UIO селекторов, которые определяют критерии поиска UIO объектов + Пример: [ [{"title":"notepad"},{"title":"OK"}], [{"title":"notepad"},{"title":"Cancel"}] ] - :param inWaitSecs: Float value (seconds) for wait UI element appear in GUI - :param inFlagWaitAllInMoment: True - Wait all UI objects from the UIOSelector list to be appeared - :return: List of index, which UI object UIO will be appeared. Example: [1] # Appear only UI object with UIO selector: [{"title":"notepad"},{"title":"Cancel"}] + :type inSpecificationListList: list, обязательный + :param inWaitSecs: Количество секунд, которые отвести на ожидание UIO объектов. По умолчанию 24 часа (86400 секунд) + :type inWaitSecs: float, необязательный + :param inFlagWaitAllInMoment: True - Ожидать до того момента, пока не появятся все запрашиваемые UIO объекты на рабочей области + :return: Список индексов, которые указывают на номер входящих UIO селекторов, которые были обнаружены на рабочей области. Пример: [0,2] ''' lResultFlag=False lSecsSleep = 1 #Настроечный параметр @@ -345,29 +374,36 @@ def UIOSelectorsSecs_WaitAppear_List (inSpecificationListList,inWaitSecs,inFlagW lSecsDone=lSecsDone+lSecsSleep time.sleep(lSecsSleep) return lResultList -################################################################################################# -#Wait for UIO is Disappear (at least one of them or all at the same time) -#inSpecificationListList - List of the UIOSelector -#inWaitSecs - Время ожидания пропажи объекта в секундах -#inFlagWaitAllInMoment - доп. условие - ожидать пропажу всех UIOSelector одновременно -#return: [0,1,2] - index of UIOSpecification, which is Disappear -#old name - - -#####Внимание##### -##Функция ожидания пропажи элементов (тк элементы могут быть недоступны, неизвестно в каком фреймворке каждый из них может появиться) -def UIOSelectorsSecs_WaitDisappear_List (inSpecificationListList,inWaitSecs,inFlagWaitAllInMoment=False): + +#old: - +def UIOSelectorsSecs_WaitDisappear_List (inSpecificationListList,inWaitSecs=86400.0,inFlagWaitAllInMoment=False): ''' - Wait for many UI object will disappear in GUI for inWaitSecs seconds. + Ожидать исчезновение хотя бы 1-го / всех UIO объектов по заданным UIO селекторам + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lNotepadOKSelector = [{"title":"notepad"},{"title":"OK"}] + lNotepadCancelSelector = [{"title":"notepad"},{"title":"Cancel"}] + lDemoBaseUIOExistList = UIDesktop.UIOSelectorsSecs_WaitDisappear_List([lDemoBaseUIOSelector, lNotepadOKSelector, lNotepadCancelSelector]) # Ожидать исчезновение UIO объектов - :param inSpecificationListList: UIOSelector list. - Example: [ + :param inSpecificationListList: Список UIO селекторов, которые определяют критерии поиска UIO объектов + Пример: [ [{"title":"notepad"},{"title":"OK"}], [{"title":"notepad"},{"title":"Cancel"}] ] - :param inWaitSecs: Float value (seconds) for wait UI element disappear in GUI - :param inFlagWaitAllInMoment: True - Wait all UI objects from the UIOSelector list to be disappeared. - :return: List of index, which UI object UIO will be disappeared. Example: [1] # Disappear only UI object with UIO selector: [{"title":"notepad"},{"title":"Cancel"}] - :return: + :type inSpecificationListList: list, обязательный + :param inWaitSecs: Количество секунд, которые отвести на ожидание исчезновения UIO объектов. По умолчанию 24 часа (86400 секунд) + :type inWaitSecs: float, необязательный + :param inFlagWaitAllInMoment: True - Ожидать до того момента, пока не исчезнут все запрашиваемые UIO объекты на рабочей области + :return: Список индексов, которые указывают на номер входящих UIO селекторов, которые были обнаружены на рабочей области. Пример: [0,2] ''' + lResultFlag=False lSecsSleep = 1 #Настроечный параметр lSecsDone = 0 @@ -397,56 +433,77 @@ def UIOSelectorsSecs_WaitDisappear_List (inSpecificationListList,inWaitSecs,inFl lSecsDone=lSecsDone+lSecsSleep time.sleep(lSecsSleep) return lResultList -################################################################################################# -#Wait for UIO is appear (at least one of them or all at the same time) -#inSpecificationList - UIOSelector -#inWaitSecs - Время ожидания объекта в секундах -#return: Bool - True - UIO is appear -#old name - - + +#old: - def UIOSelectorSecs_WaitAppear_Bool (inSpecificationList,inWaitSecs): ''' - Wait for UI object will appear in GUI for inWaitSecs seconds. + Ожидать появление 1-го UIO объекта по заданному UIO селектору + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lDemoBaseUIOExistBool = UIDesktop.UIOSelectorSecs_WaitAppear_Bool(lDemoBaseUIOSelector) # Ожидать появление UIO объекта - :param inSpecificationList: UIOSelector. Example: [{"title":"notepad"},{"title":"OK"}] - :param inWaitSecs: Float value (seconds) for wait UI element appear in GUI - :return: True - UI object will appear. False - else case + :param inSpecificationList: UIO селектор, который определяет критерии поиска UIO объекта + :type inSpecificationList: list, обязательный + :param inWaitSecs: Количество секунд, которые отвести на ожидание UIO объекта. По умолчанию 24 часа (86400 секунд) + :type inWaitSecs: float, необязательный + :return: True - UIO объект был обнаружен. False - обратная ситуациая ''' lWaitAppearList=UIOSelectorsSecs_WaitAppear_List([inSpecificationList],inWaitSecs) lResult=False if len(lWaitAppearList)>0: lResult=True return lResult -################################################################################################# -#Wait for UIO is disappear (at least one of them or all at the same time) -#inSpecificationList - UIOSelector -#inWaitSecs - Время ожидания пропажи объекта в секундах -#return: Bool - True - UIO is Disappear + #old name - - def UIOSelectorSecs_WaitDisappear_Bool (inSpecificationList,inWaitSecs): ''' - Wait for UI object will disappear in GUI for inWaitSecs seconds. + Ожидать исчезновение 1-го UIO объекта по заданному UIO селектору + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lDemoBaseUIOExistBool = UIDesktop.UIOSelectorSecs_WaitDisappear_Bool(lDemoBaseUIOSelector) # Ожидать исчезновение UIO объекта - :param inSpecificationList: UIOSelector. - Example: [{"title":"notepad"},{"title":"OK"}] - :param inWaitSecs: Float value (seconds) for wait UI element disappear in GUI - :return: True - UI object will disappear. False - else case + :param inSpecificationList: UIO селектор, который определяет критерии поиска UIO объекта + :type inSpecificationList: list, обязательный + :param inWaitSecs: Количество секунд, которые отвести на исчезновение UIO объекта. По умолчанию 24 часа (86400 секунд) + :type inWaitSecs: float, необязательный + :return: True - UIO объект был обнаружен. False - обратная ситуациая ''' lWaitDisappearList=UIOSelectorsSecs_WaitDisappear_List([inSpecificationList],inWaitSecs) lResult=False if len(lWaitDisappearList)>0: lResult=True return lResult -################################################################################################# -#Get process bitness (32 or 64) -#inSpecificationList - UIOSelector -#old name - None -#return None (if Process not found), int 32, or int 64 + +#old: - def UIOSelector_Get_BitnessInt (inSpecificationList): ''' - Detect process bitness by the UI Object UIO Selector. + Определить разрядность приложения по UIO селектору. Вернуть результат в формате целого числа (64 или 32) + + .. code-block:: python - :param inSpecificationList: UIOSelector. Example: [{"title":"notepad"},{"title":"OK"}] - :return: int 32 or int 64 + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lDemoBaseBitInt = UIDesktop.UIOSelector_Get_BitnessInt(lDemoBaseUIOSelector) # Определить разрядность приложения, в котором обнаружен UIO объект по селектору + + :param inSpecificationList: UIO селектор, который определяет критерии поиска UIO объекта + :type inSpecificationList: list, обязательный + :return: None - UIO объект не обнаружен; 64 (int) - разрядность приложения равна 64 битам; 32 (int) - разрядность приложения равна 32 битам ''' lResult=None #Получить объект Application (Для проверки разрядности) @@ -457,18 +514,24 @@ def UIOSelector_Get_BitnessInt (inSpecificationList): else: lResult=32 return lResult -################################################################################################# -#Get process bitness ("32" or "64") -#inSpecificationList - UIOSelector -#old name - None -#return None (if Process not found), int 32, or int 64 + +#old: - def UIOSelector_Get_BitnessStr (inSpecificationList): - ''' - Detect process bitness by the UI Object UIO Selector. + """ + Определить разрядность приложения по UIO селектору. Вернуть результат в формате строки ("64" или "32") - :param inSpecificationList: UIOSelector. Example: [{"title":"notepad"},{"title":"OK"}] - :return: str "32" or str "64" - ''' + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lDemoBaseBitStr = UIDesktop.UIOSelector_Get_BitnessStr(lDemoBaseUIOSelector) # Определить разрядность приложения, в котором обнаружен UIO объект по селектору + + :param inSpecificationList: UIO селектор, который определяет критерии поиска UIO объекта + :type inSpecificationList: list, обязательный + :return: None - UIO объект не обнаружен; "64" (str) - разрядность приложения равна 64 битам; "32" (str) - разрядность приложения равна 32 битам + """ lResult=None #Получить объект Application (Для проверки разрядности) lRootElement=PWASpecification_Get_PWAApplication(inSpecificationList) @@ -478,28 +541,40 @@ def UIOSelector_Get_BitnessStr (inSpecificationList): else: lResult="32" return lResult -################################################################################################# -#Get OS bitness (32 or 64) -#old name - None -#return int 32, or int 64 + +#old: - def Get_OSBitnessInt (): ''' - Detect OS bitness. + Определить разрядность робота, в котором запускается данная функция - :return: int 32 or int 64 + .. code-block:: python + + from pyOpenRPA.Robot import UIDesktop + lRobotBitInt = UIDesktop.Get_OSBitnessInt() # Определить разрядность робота, в котором была вызвана это функция + + :return: 64 (int) - разрядность приложения равна 64 битам; 32 (int) - разрядность приложения равна 32 битам ''' lResult=32 if pywinauto.sysinfo.is_x64_OS(): lResult=64 return lResult -################################################################################################# +#old: - def UIOSelector_SafeOtherGet_Process(inUIOSelector): - ''' - Safe get other process or None if destination app is the other/same bitness + """ + Получить процесс робота другой разрядности (если приложение UIO объекта выполняется в другой разрядности). Функция возвращает None, если разрядность робота совпадает с разрядностью приложения UIO объекта, либо если при инициализации робота не устанавливался интерпретатор другой разрядности. - :param inUIOSelector: UIO Selector of the UI object - :return: None or process (of the other bitness) - ''' + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lOtherBitnessProcess = UIDesktop.UIOSelector_SafeOtherGet_Process(lDemoBaseUIOSelector) # Вернуть процесс робота, схожей разрядности + + :param inUIOSelector: UIO селектор, который определяет критерии поиска UIO объекта + :type inUIOSelector: list, обязательный + :return: Процесс робота схожей разрядности + """ #Default value lResult = None #Go check bitness if selector exists @@ -509,15 +584,44 @@ def UIOSelector_SafeOtherGet_Process(inUIOSelector): if lUIOSelectorAppBitness and Utils.ProcessBitness.mSettingsDict["BitnessProcessCurrent"] != lUIOSelectorAppBitness: lResult = Utils.ProcessBitness.OtherProcessGet() return lResult -################################################################################################## +#old: GetControl def PWASpecification_Get_UIO(inControlSpecificationArray): - ''' - #Backend def selection - attribute "backend" ("win32" || "uia") in 1-st list element - #old name - GetControl + """ + Получить UIO объект по PWA (pywinauto) селектору. (https://pywinauto.readthedocs.io/en/latest/code/pywinauto.findwindows.html). Мы рекомендуем использовать метод UIOSelector_UIO_Get, так как UIO селектор обладает большей функциональностью. - :param inControlSpecificationArray: List of dict, dict in pywinauto.find_windows notation - :return: list of UIO object - ''' + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIOObject = UIDesktop.PWASpecification_Get_UIO(lDemoBaseUIOSelector) # Получить UIO объект по PWA селектору + + :param inControlSpecificationArray: PWA селектор, который определяет критерии поиска UIO объекта + Допустимые ключи PWA селектора: + + - class_name содержимое атрибута class UIO объекта + - class_name_re содержимое атрибута class UIO объекта, которое удовлетворяет установленному рег. выражению + - process идентификатор процесса, в котором находится UIO объект + - title содержимое атрибута title UIO объекта + - title_re содержимое атрибута title UIO объекта, которое удовлетворяет установленному рег. выражению + - top_level_only признак поиска только на верхнем уровне приложения. По умолчанию True + - visible_only признак поиска только среди видимых UIO объектов. По умолчанию True + - enabled_only признак поиска только среди разблокированных UIO объектов. По умолчанию False + - best_match содержимое атрибута title UIO объекта максимально приближено к заданному + - handle идентификатор handle искомого UIO объекта + - ctrl_index индекс UIO объекта среди всех дочерних объектов в списке родительского + - found_index индекс UIO объекта среди всех обнаруженных + - predicate_func пользовательская функция проверки соответсвия UIO элемента + - active_only признак поиска только среди активных UIO объектов. По умолчанию False + - control_id идентификатор control_id искомого UIO объекта + - control_type тип элемента (применимо, если backend == "uia") + - auto_id идентификатор auto_id искомого UIO объекта (применимо, если backend == "uia") + - framework_id идентификатор framework_id искомого UIO объекта (применимо, если backend == "uia") + - backend вид технологии подключения к поиску UIO объекта ("uia" или "win32") + :type inControlSpecificationArray: list, обязательный + :return: UIO объект + """ #Определение backend lBackend=mDefaultPywinautoBackend if "backend" in inControlSpecificationArray[0]: @@ -563,14 +667,44 @@ def PWASpecification_Get_UIO(inControlSpecificationArray): #Добавить объект в результирующий массив lResultList.append(lTempObject) return lResultList -################################################################################################## + def PWASpecification_Get_PWAApplication(inControlSpecificationArray): - ''' - #Backend selection - attribute "backend" ("win32" || "uia") in 1-st list element + """ + Получить значение атрибута backend по PWA (pywinauto) селектору. Мы рекомендуем использовать метод UIOSelector_UIO_Get, так как UIO селектор обладает большей функциональностью. - :param inControlSpecificationArray: List of dict, dict in pywinauto.find_windows notation - :return: process application object - ''' + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lBackendStr = UIDesktop.PWASpecification_Get_PWAApplication(lDemoBaseUIOSelector) # Получить backend по PWA селектору + + :param inControlSpecificationArray: PWA селектор, который определяет критерии поиска UIO объекта + Допустимые ключи PWA селектора: + + - class_name содержимое атрибута class UIO объекта + - class_name_re содержимое атрибута class UIO объекта, которое удовлетворяет установленному рег. выражению + - process идентификатор процесса, в котором находится UIO объект + - title содержимое атрибута title UIO объекта + - title_re содержимое атрибута title UIO объекта, которое удовлетворяет установленному рег. выражению + - top_level_only признак поиска только на верхнем уровне приложения. По умолчанию True + - visible_only признак поиска только среди видимых UIO объектов. По умолчанию True + - enabled_only признак поиска только среди разблокированных UIO объектов. По умолчанию False + - best_match содержимое атрибута title UIO объекта максимально приближено к заданному + - handle идентификатор handle искомого UIO объекта + - ctrl_index индекс UIO объекта среди всех дочерних объектов в списке родительского + - found_index индекс UIO объекта среди всех обнаруженных + - predicate_func пользовательская функция проверки соответсвия UIO элемента + - active_only признак поиска только среди активных UIO объектов. По умолчанию False + - control_id идентификатор control_id искомого UIO объекта + - control_type тип элемента (применимо, если backend == "uia") + - auto_id идентификатор auto_id искомого UIO объекта (применимо, если backend == "uia") + - framework_id идентификатор framework_id искомого UIO объекта (применимо, если backend == "uia") + - backend вид технологии подключения к поиску UIO объекта ("uia" или "win32") + :type inControlSpecificationArray: list, обязательный + :return: "win32" или "uia" + """ inControlSpecificationArray=copy.deepcopy(inControlSpecificationArray) #Определение backend lBackend=mDefaultPywinautoBackend @@ -600,16 +734,23 @@ def PWASpecification_Get_PWAApplication(inControlSpecificationArray): #Скорректировано из-за недопонимания структуры lTempObject=lRPAApplication return lTempObject - -########################################################################################################### +#old: AutomationSearchMouseElement def UIOSelector_SearchChildByMouse_UIO(inElementSpecification): - ''' - UIOSelector (see description on the top of the document) - #old name - AutomationSearchMouseElement + """ + Инициировать визуальный поиск UIO объекта с помощью указателя мыши. При наведении указателя мыши UIO объект выделяется зеленой рамкой. Остановить режим поиска можно с помощью зажима клавиши ctrl left на протяжении нескольких секунд. После этого в веб окне студии будет отображено дерево расположения искомого UIO объекта. - :param inElementSpecification: UIOSelector of the UI Object - :return: pywinauto element wrapper instance or None - ''' + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIO = UIDesktop.UIOSelector_SearchChildByMouse_UIO(lDemoBaseUIOSelector) # Инициировать поиск дочернего UIO объекта, который расположен внутри lDemoBaseUIOSelector. + + :param inElementSpecification: UIO селектор, который определяет критерии поиска родительского UIO объекта, в котором будет производиться поиск дочернего UIO объекта + :type inElementSpecification: list, обязательный + :return: UIO объект или None (если UIO не был обнаружен) + """ lGUISearchElementSelected=None #Настройка - частота обновления подсвечивания lTimeSleepSeconds=0.4 @@ -647,15 +788,26 @@ def UIOSelector_SearchChildByMouse_UIO(inElementSpecification): #Вернуть результат поиска return lElementFoundedList -#################################################################################################### -#old name - AutomationSearchMouseElementHierarchy +#old: - AutomationSearchMouseElementHierarchy def UIOSelector_SearchChildByMouse_UIOTree(inUIOSelector): - ''' - !!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! + """ + Получить список уровней UIO объекта с указнием всех имеющихся атрибутов по входящему UIO селектору. + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lBackendStr = UIDesktop.UIOSelector_SearchChildByMouse_UIOTree(lDemoBaseUIOSelector) # Получить список атрибутов всех родительских элементов lDemoBaseUIOSelector. + + :param inUIOSelector: UIO селектор, который определяет UIO объект, для которого будет произведено извлечение всех атрибутов на всех уровнях. + :type inUIOSelector: list, обязательный + :return: list, список атрибутов на каждом уровне UIO объекта + """ - :param inUIOSelector: UIOSelector of the UI Object - :return: ? - ''' lItemInfo = [] #Check the bitness lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector) @@ -715,10 +867,24 @@ def UIOSelector_SearchChildByMouse_UIOTree(inUIOSelector): lItemInfo = lPIPEResponseDict["Result"] #Вернуть результат return lItemInfo -#################################################################################################### -#inElement- UIO (UI Object) #old name - PywinautoExtElementCtrlIndexGet def UIO_GetCtrlIndex_Int(inElement): + """ + Получить индекс UIO объекта inElement в списке родительского UIO объекта. + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIO = UIDesktop.UIOSelector_Get_UIO(lDemoBaseUIOSelector) # Получить UIO объект по UIO селектору. + lUIOIndexInt = UIDesktop.UIO_GetCtrlIndex_Int(lUIO) # Получить индекс UIO объекта в списке у родительского UIO объекта. + + :param inElement: UIO объект, для которого требуется определить индекс в списке родительского UIO объекта. + :type inElement: list, обязательный + :return: int, индекс UIO объекта в списке родительского UIO объекта + """ lResult = None #Выполнить алгоритм, если есть Element if inElement is not None: @@ -747,12 +913,27 @@ def UIO_GetCtrlIndex_Int(inElement): #Вернуть результат return lResult -#################################################################################################### -# Get the UIO Info list for the selected criteria -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! -#inSpecificationList - UIOSelector -#old name - PywinautoExtElementsGetInfo +#old: - PywinautoExtElementsGetInfo def UIOSelector_Get_UIOInfoList (inUIOSelector, inElement=None): + """ + Техническая функция: Получить список параметров последних уровней UIO селектора по UIO объектам, которые удовлетворяют входящим inUIOSelector, поиск по которым будет производится от уровня inElement. + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIOInfoList = UIDesktop.UIOSelector_Get_UIOInfoList(lDemoBaseUIOSelector) # Получить словарь параметров по UIO селектору. + + :param inUIOSelector: UIO селектор, который определяет UIO объект, для которого будет произведено извлечение всех атрибутов на всех уровнях. + :type inUIOSelector: list, обязательный + :param inElement: UIO объект, от которого выполнить поиск дочерних UIO объектов по UIO селектору inUIOSelector. По умолчанию None - поиск среди всех приложений. + :type inElement: UIO объект, необязательный + :return: dict, пример: {"title":None,"rich_text":None,"process_id":None,"process":None,"handle":None,"class_name":None,"control_type":None,"control_id":None,"rectangle":{"left":None,"top":None,"right":None,"bottom":None}, 'runtime_id':None} + """ #Check the bitness lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector) if lSafeOtherProcess is None: @@ -778,17 +959,25 @@ def UIOSelector_Get_UIOInfoList (inUIOSelector, inElement=None): lResultList = lPIPEResponseDict["Result"] return lResultList -#################################################################################################### -#Try to restore (maximize) window, if it's was minimized -#(особенность uia backend - он не может прицепиться к окну, если оно свернуто) -#inSpecificationList - UIOSelector -#old name - PywinautoExtTryToRestore +#old: - PywinautoExtTryToRestore def UIOSelector_TryRestore_Dict(inSpecificationList): """ - Try to restore (maximize) window, if it's minimized. (!IMPORTANT! When use UIA framework minimized windows doesn't appear by the UIOSelector. You need to try restore windows and after that try to get UIO) + Восстановить окно приложения на экране по UIO селектору inSpecificationList, если оно было свернуто. Функция обернута в try .. except - ошибок не возникнет. + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ УЖЕ ИСПОЛЬЗУЕТСЯ В РЯДЕ ДРУГИХ ФУНКЦИЙ ТАК КАК АДРЕССАЦИЯ ПО UIA FRAMEWORK НЕДОСТУПНА, ЕСЛИ ПРИЛОЖЕНИЕ СВЕРНУТО. + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + UIDesktop.UIOSelector_TryRestore_Dict(lDemoBaseUIOSelector) # Попытка восстановления свернутого окна по UIO селектору. - :param inSpecificationList: UIOSelector - List of items, which contains condition attributes - :return: + :param inSpecificationList: UIO селектор, который определяет UIO объект, для которого будет произведено извлечение всех атрибутов на всех уровнях. + :type inSpecificationList: list, обязательный """ lResult={} try: @@ -802,17 +991,24 @@ def UIOSelector_TryRestore_Dict(inSpecificationList): except Exception: True==False return lResult -#################################################################################################### -#Get the list of the UI object activities -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! -#inControlSpecificationArray - UIOSelector -#old name - ElementActionGetList + +#old: - ElementActionGetList def UIOSelector_Get_UIOActivityList (inUIOSelector): """ - Get the list of the UI object activities + Получить список доступных действий/функций по UIO селектору inUIOSelector. Описание возможных активностей см. ниже. + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python - :param inUIOSelector: UIOSelector - List of items, which contains condition attributes - :return: + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lActivityList = UIDesktop.UIOSelector_Get_UIOActivityList(lDemoBaseUIOSelector) # Получить список активностей по UIO селектору. + + :param inUIOSelector: UIO селектор, который определяет UIO объект, для которого будет представлен перечень доступных активностей. + :type inUIOSelector: list, обязательный """ #Check the bitness lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector) @@ -845,21 +1041,30 @@ def UIOSelector_Get_UIOActivityList (inUIOSelector): lResult = lPIPEResponseDict["Result"] return lResult -#################################################################################################### -#Run the activity in UIO (UI Object) -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! -#inUIOSelector -#inActionName - UIOActivity (name) from Pywinauto -#old name - ElementRunAction +#old: - ElementRunAction def UIOSelectorUIOActivity_Run_Dict(inUIOSelector, inActionName, inArgumentList=None, inkwArgumentObject=None): """ - Run the activity in UIO (UI Object) + Выполнить активность inActionName над UIO объектом, полученным с помощью UIO селектора inUIOSelector. Описание возможных активностей см. ниже. + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) - :param inUIOSelector: UIOSelector - List of items, which contains condition attributes - :param inActionName: UIOActivity (name) activity name string from Pywinauto - :param inArgumentList: - :param inkwArgumentObject: - :return: + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lActivityResult = UIDesktop.UIOSelectorUIOActivity_Run_Dict(lDemoBaseUIOSelector, "click") # выполнить действие над UIO объектом с помощью UIO селектора. + + :param inUIOSelector: UIO селектор, который определяет UIO объект, для которого будет представлен перечень доступных активностей. + :type inUIOSelector: list, обязательный + :param inActionName: наименование активности, которую требуется выполнить над UIO объектом + :type inActionName: str, обязательный + :param inArgumentList: список передаваемых неименованных аргументов в функцию inActionName + :type inArgumentList: list, необязательный + :param inkwArgumentObject: словарь передаваемых именованных аргументов в функцию inActionName + :type inkwArgumentObject: dict, необязательный + :return: возвращает результат запускаемой функции с наименованием inActionName над UIO объектом """ if inArgumentList is None: inArgumentList=[] # 2021 02 22 Minor fix by Ivan Maslov if inkwArgumentObject is None: inkwArgumentObject={} # 2021 02 22 Minor fix by Ivan Maslov @@ -905,16 +1110,57 @@ def UIOSelectorUIOActivity_Run_Dict(inUIOSelector, inActionName, inArgumentList= lResult = lPIPEResponseDict["Result"] return lResult -#################################################################################################### -#Get the UIO dict of the attributes -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! #old name - ElementGetInfo def UIOSelector_Get_UIOInfo(inUIOSelector): """ - Get the UIO dict of the attributes + Получить свойства UIO объекта (element_info), по заданному UIO селектору. Ниже представлен перечень возвращаемых свойств. + + Для backend = win32: + + - automation_id (int) + - class_name (str) + - control_id (int) + - control_type (str) + - full_control_type (str) + - enabled (bool) + - handle (int) + - name (str) + - parent (object/UIO) + - process_id (int) + - rectangle (object/rect) + - rich_text (str) + - visible (bool) + + Для backend = uia: - :param inUIOSelector: UIOSelector - List of items, which contains condition attributes - :return: + - automation_id (int) + - class_name (str) + - control_id (int) + - control_type (str) + - enabled (bool) + - framework_id (int) + - handle (int) + - name (str) + - parent (object/UIO) + - process_id (int) + - rectangle (object/rect) + - rich_text (str) + - runtime_id (int) + - visible (bool) + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIOElementInfoDict = UIDesktop.UIOSelector_Get_UIOInfo(lDemoBaseUIOSelector) #Получить свойства над UIO объектом с помощью UIO селектора. + + :param inUIOSelector: UIO селектор, который определяет UIO объект, для которого будет представлен перечень доступных активностей. + :type inUIOSelector: list, обязательный + :return: словарь свойств element_info: Пример {"control_id": ..., "process_id": ...} """ #Check the bitness lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector) @@ -945,12 +1191,28 @@ def UIOSelector_Get_UIOInfo(inUIOSelector): else: lResultList = lPIPEResponseDict["Result"] return lResultList -#################################################################################################### -#Search child UIO by the: Parent UIO, X, Y -#inHierarchyList: [{"index":<>,"element":<>}] - technical argument for internal purpose -#result -List of dict [{"index":<>,"element":<>}] -- list of element hierarchy specifications -#old name - GUISearchElementByRootXY +#old: - GUISearchElementByRootXY def UIOXY_SearchChild_ListDict(inRootElement,inX,inY,inHierarchyList=None): + """ + Техническая функция: Получить иерархию вложенности UIO объекта по заданным корневому UIO объекту, координатам X и Y. + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIO = UIDesktop.UIOSelector_Get_UIO(lDemoBaseUIOSelector) # Получить UIO объект с помощью UIO селектора + lUIOHierarchyList = UIDesktop.UIOXY_SearchChild_ListDict(lUIO, 100, 200) # Получить UIO объект с помощью UIO селектора родительского элемента и координат X / Y + + :param inRootElement: родительский UIO объект, полученный ранее с помощью UIO селектора. + :type inRootElement: object UIO, обязательный + :param inX: родительский UIO объект, полученный ранее с помощью UIO селектора. + :type inX: int, обязательный + :param inY: родительский UIO объект, полученный ранее с помощью UIO селектора. + :type inY: int, обязательный + :return: Список словарей - уровней UIO объектов + """ if inHierarchyList is None: inHierarchyList = [] #Инициализация результирующего значения lResultElement = None @@ -1035,21 +1297,27 @@ def UIOXY_SearchChild_ListDict(inRootElement,inX,inY,inHierarchyList=None): False == False return lResultHierarchyList -################################################################################################### -#Get list of child UIO's by Parent UIOSelector -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! -#inControlSpecificationArray- UIOSelector -#old name - ElementGetChildElementList +#old: - ElementGetChildElementList def UIOSelector_GetChildList_UIOList(inUIOSelector=None, inBackend=mDefaultPywinautoBackend): """ - Get list of child UIO's by the parent UIOSelector + Получить список дочерних UIO объектов по входящему UIO селектору inUIOSelector. + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) - :param inUIOSelector: UIOSelector - List of items, which contains condition attributes - :param inBackend: "win32" or "uia" - :return: - """ + .. code-block:: python + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIOList = UIDesktop.UIOSelector_GetChildList_UIOList(lDemoBaseUIOSelector) # Получить список дочерних UIO объектов с помощью UIO селектора + :param inUIOSelector: родительский UIO объект, полученный ранее с помощью UIO селектора. + :type inUIOSelector: list, обязательный + :param inBackend: вид backend "win32" или "uia". По умолчанию mDefaultPywinautoBackend ("win32") + :type inBackend: str, необязательный + :return: список дочерних UIO объектов + """ if inUIOSelector is None: inUIOSelector = [] #mRobotLogger.info(f"File!!!!") #mRobotLogger.info(f"inSelector:{str(inUIOSelector)}, inBackend:{str(inBackend)}") @@ -1099,12 +1367,24 @@ def UIOSelector_GetChildList_UIOList(inUIOSelector=None, inBackend=mDefaultPywin lResultList = lPIPEResponseDict["Result"] return lResultList -#################################################################################################### -#Подготовить массив для обращшения к поиску элемементов -#inControlSpecificationArray - UIOSelector (can be dirty) -#old name 1 - ElementSpecificationArraySearchPrepare -#old name 2 - ElementSpecificationListNormalize +#old1: - ElementSpecificationArraySearchPrepare +#old2: - ElementSpecificationListNormalize def UIOSelector_SearchUIONormalize_UIOSelector (inControlSpecificationArray): + """ + Нормализовать UIO селектор для дальнейшего использования в функциях поиск UIO объекта. Если недопустимых атрибутов не присутствует, то оставить как есть. + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelectorDitry = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lDemoBaseUIOSelectorClean = UIDesktop.UIOSelector_SearchUIONormalize_UIOSelector(lDemoBaseUIOSelectorDitry) # Очистить UIO селектор от недопустимых ключей для дальнейшего использования + + :param inControlSpecificationArray: UIO селектор, который определяет UIO объект, для которого будет представлен перечень доступных активностей. + :type inControlSpecificationArray: list, обязательный + :return: нормализованный UIO селектор + """ lResult=[] #Циклический обход for lSpecificationItem in inControlSpecificationArray: @@ -1172,12 +1452,25 @@ def UIOSelector_SearchUIONormalize_UIOSelector (inControlSpecificationArray): lResult.append(lSpecificationItemNew) #Вернуть результат return lResult -#################################################################################################### -#Подготовить массив для обращшения к поиску процесса (отличается от поиска элемента, тк данная функция нужна для нормализации спецификации для подключения к процессу с окнами) -#inControlSpecificationArray - UIOSelector (can be dirty) + #old name 1 - ElementSpecificationArraySearchPrepare #old name 2 - ElementSpecificationListNormalize def UIOSelector_SearchProcessNormalize_UIOSelector (inControlSpecificationArray): + """ + Нормализовать UIO селектор для дальнейшего использования в функциях поиска процесса, в котором находится искомый UIO объект. Если недопустимых атрибутов не присутствует, то оставить как есть. + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelectorDitry = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lDemoBaseUIOSelectorClean = UIDesktop.UIOSelector_SearchProcessNormalize_UIOSelector(lDemoBaseUIOSelectorDitry) # Очистить UIO селектор от недопустимых ключей для дальнейшего использования + + :param inControlSpecificationArray: UIO селектор, который определяет UIO объект, для которого будет представлен перечень доступных активностей. + :type inControlSpecificationArray: list, обязательный + :return: нормализованный UIO селектор + """ lResult=[] #Циклический обход for lSpecificationItem in inControlSpecificationArray: @@ -1250,11 +1543,25 @@ def UIOSelector_SearchProcessNormalize_UIOSelector (inControlSpecificationArray) lResult.append(lSpecificationItemNew) #Вернуть результат return lResult -#################################################################################################### -#Transfer UI object element info (pywinauto) to UIOInfo (dict of attributes) -#inElementInfo - UIOEI -#old name - ElementInfoExportObject + +#old: - ElementInfoExportObject def UIOEI_Convert_UIOInfo(inElementInfo): + """ + Техническая функция: Дообогащение словаря с параметрами UIO объекта по заданному UIO.element_info + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIO = UIDesktop.UIOSelector_Get_UIO(lDemoBaseUIOSelector) # Получить UIO объект по UIO селектору. + lUIOProcessInfoDict = UIDesktop.UIOEI_Convert_UIOInfo(lUIO.element_info) + + :param inElementInfo: экземпляр класса UIO.element_info, для которого требуется дообогатить словарь с параметрами (в дальнейшем можно использовать как элемент UIO селектора). + :type inElementInfo: object, обязательный + :return: dict, пример: {"title":None,"rich_text":None,"process_id":None,"process":None,"handle":None,"class_name":None,"control_type":None,"control_id":None,"rectangle":{"left":None,"top":None,"right":None,"bottom":None}, 'runtime_id':None} + """ #Подготовить выходную структуру данных lResult = {"title":None,"rich_text":None,"process_id":None,"process":None,"handle":None,"class_name":None,"control_type":None,"control_id":None,"rectangle":{"left":None,"top":None,"right":None,"bottom":None}, 'runtime_id':None} #Проверка name @@ -1322,10 +1629,21 @@ def UIOEI_Convert_UIOInfo(inElementInfo): #Вернуть результат return lResult -################################################################################################### -#Get list of top level -#old name - GetRootElementList +#old: - GetRootElementList def BackendStr_GetTopLevelList_UIOInfo(inBackend=mDefaultPywinautoBackend): + """ + Получить список UIOInfo словарей - процессы, которые запущены в рабочей сессии и готовы для взаимодействия с роботом через backend inBackend + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + lAppList = UIDesktop.BackendStr_GetTopLevelList_UIOInfo() # Очистить UIO селектор от недопустимых ключей для дальнейшего использования + + :param inBackend: вид backend, который планируется использовать для взаимодействия с UIO объектами + :type inBackend: list, обязательный + :return: список UIOInfo словарей + """ #Получить список объектов lResultList=pywinauto.findwindows.find_elements(top_level_only=True,backend=inBackend) lResultList2=[] @@ -1334,16 +1652,23 @@ def BackendStr_GetTopLevelList_UIOInfo(inBackend=mDefaultPywinautoBackend): lResultList2.append(UIOEI_Convert_UIOInfo(lI)) return lResultList2 -################################################################################################### -#Highlight the UI object -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! -#old name - ElementDrawOutlineNew +#old: - ElementDrawOutlineNew def UIOSelector_Highlight(inUIOSelector): """ - Highlight (draw outline) the element (in app) by the UIO selector. + Подсветить на несколько секунд на экране зеленой рамкой UIO объект, который соответствует входящему UIO селектору inUIOSelector - :param inUIOSelector: UIOSelector - List of items, which contains condition attributes - :return: + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + UIDesktop.UIOSelector_Highlight(lDemoBaseUIOSelector) # Подсветить UIO объект по UIO селектору + + :param inUIOSelector: UIO селектор, который определяет UIO объект, для которого будет представлен перечень доступных активностей. + :type inUIOSelector: list, обязательный """ #Check the bitness lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector) @@ -1364,17 +1689,23 @@ def UIOSelector_Highlight(inUIOSelector): else: return lPIPEResponseDict["Result"] return True - -################################################################################################### -#inSpecificationArray - UIOSelector -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! -#old name - ElementDrawOutlineNewFocus +#old: - ElementDrawOutlineNewFocus def UIOSelector_FocusHighlight(inUIOSelector): """ - Set focus and highlight (draw outline) the element (in app) by the UIO selector. + Установить фокус и подсветить на несколько секунд на экране зеленой рамкой UIO объект, который соответствует входящему UIO селектору inUIOSelector + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) - :param inUIOSelector: UIOSelector - List of items, which contains condition attributes - :return: + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + UIDesktop.UIOSelector_FocusHighlight(lDemoBaseUIOSelector) # Установить фокус и подсветить UIO объект по UIO селектору + + :param inUIOSelector: UIO селектор, который определяет UIO объект, для которого будет представлен перечень доступных активностей. + :type inUIOSelector: list, обязательный """ #Check the bitness @@ -1397,9 +1728,29 @@ def UIOSelector_FocusHighlight(inUIOSelector): return lPIPEResponseDict["Result"] return True -################################################################################################### -#old name - draw_outline_new +#old: - draw_outline_new def UIO_Highlight(lWrapperObject,colour='green',thickness=2,fill=win32defines.BS_NULL,rect=None,inFlagSetFocus=False): + """ + Выполнить подсветку UIO объекта на экране + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIO = UIDesktop.UIOSelector_Get_UIO(lDemoBaseUIOSelector) # Получить UIO объект по UIO селектору + UIDesktop.UIO_Highlight(lUIO) # Подсветить UIO объект по UIO селектору зеленым цветом с толщиной подсветки 2 px. + + :param lWrapperObject: UIO объект, который будет подсвечен + :type lWrapperObject: object UIO, обязательный + :param colour: цвет подсветки UIO объекта. Варианты: 'red', 'green', 'blue'. По умолчанию 'green' + :type colour: str, необязательный + :param thickness: толщина подсветки UIO объекта. По умолчанию 2 + :type thickness: int, необязательный + :param inFlagSetFocus: признак установки фокуса на UIO объект перед подсветкой. По умолчанию False + :type inFlagSetFocus: bool, необязательный + """ if lWrapperObject is not None: """ Draw an outline around the window. @@ -1449,10 +1800,27 @@ def UIO_Highlight(lWrapperObject,colour='green',thickness=2,fill=win32defines.BS # delete the Display context that we created win32functions.DeleteDC(dc) -################################################################################################### -#Аналог подсвечивания + установка фокуса -#old name - draw_outline_new_focus +#old: - draw_outline_new_focus def UIO_FocusHighlight(lWrapperObject,colour='green',thickness=2,fill=win32defines.BS_NULL,rect=None): + """ + Установить фокус и выполнить подсветку UIO объекта на экране + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIO = UIDesktop.UIOSelector_Get_UIO(lDemoBaseUIOSelector) # Получить UIO объект по UIO селектору + UIDesktop.UIO_FocusHighlight(lUIO) # Установить фокус и подсветить UIO объект по UIO селектору зеленым цветом с толщиной подсветки 2 px. + + :param lWrapperObject: UIO объект, который будет подсвечен + :type lWrapperObject: object UIO, обязательный + :param colour: цвет подсветки UIO объекта. Варианты: 'red', 'green', 'blue'. По умолчанию 'green' + :type colour: str, необязательный + :param thickness: толщина подсветки UIO объекта. По умолчанию 2 + :type thickness: int, необязательный + """ UIO_Highlight(lWrapperObject,'green',2,win32defines.BS_NULL,None,True) #Определить разрядность процесса diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/__init__.py b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/__init__.py index 8c4b3aa6..fc97568b 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/__init__.py +++ b/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA/__init__.py @@ -1,9 +1,9 @@ r""" -The OpenRPA package (from UnicodeLabs) +The pyOpenRPA package """ -__version__ = 'v1.2.12' +__version__ = 'v1.2.13' __all__ = [] -__author__ = 'Ivan Maslov ' +__author__ = 'Ivan Maslov ' #from .Core import Robot \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/INSTALLER b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/INSTALLER similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/INSTALLER rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/INSTALLER diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/METADATA b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/METADATA similarity index 99% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/METADATA rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/METADATA index ee047299..be5fb345 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/METADATA +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pyOpenRPA -Version: 1.2.12 +Version: 1.2.13 Summary: First open source RPA platform for business Home-page: https://pyopenrpa.ru/ Author: Ivan Maslov diff --git a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/RECORD b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/RECORD similarity index 96% rename from Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/RECORD rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/RECORD index 4f6a71f0..a559ce98 100644 --- a/Resources/WPy32-3720/python-3.7.2/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/RECORD +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/RECORD @@ -1,9 +1,9 @@ -pyOpenRPA-1.2.12.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pyOpenRPA-1.2.12.dist-info/METADATA,sha256=AmdWISfrdsF9DvjBrn42JJUXBb-TLln5OFBWKxX0VaE,4111 -pyOpenRPA-1.2.12.dist-info/RECORD,, -pyOpenRPA-1.2.12.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pyOpenRPA-1.2.12.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 -pyOpenRPA-1.2.12.dist-info/top_level.txt,sha256=RPzwQXgYBRo_m5L3ZLs6Voh8aEkMeT29Xsul1w1qE0g,10 +pyOpenRPA-1.2.13.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pyOpenRPA-1.2.13.dist-info/METADATA,sha256=HrNqM4-bPHXjqazFT4215H6pPafnYdCqattouxZIzVc,4111 +pyOpenRPA-1.2.13.dist-info/RECORD,, +pyOpenRPA-1.2.13.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pyOpenRPA-1.2.13.dist-info/WHEEL,sha256=qB97nP5e4MrOsXW5bIU5cUn_KSVr10EV0l-GCHG9qNs,97 +pyOpenRPA-1.2.13.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 @@ -26,9 +26,9 @@ pyOpenRPA/LICENSE.pdf,sha256=HEqffy8FIWpylw0zF7k-Wgwd8ppWQT9s9EGBgKV-6G8,321175 pyOpenRPA/Orchestrator/BackwardCompatibility.py,sha256=ABr0RugbBsIGdL5GE_EFC9QndSaKjvrjawvluhUNuMY,37795 pyOpenRPA/Orchestrator/ControlPanel.py,sha256=OzS8HjG__8OZgqhajr8L8owyugXPuSLWHLtXuKdEP78,103 pyOpenRPA/Orchestrator/Core.py,sha256=OHa3mSC3_wRAizqrWBVjlR6ln4-xVVvBpOSnWl6qVvY,529 -pyOpenRPA/Orchestrator/Managers/ControlPanel.py,sha256=BgtLjb6PR6kTlOjPLCg2YGP458LS9JOaYEfNurhS0nk,16544 +pyOpenRPA/Orchestrator/Managers/ControlPanel.py,sha256=XpmN_LB--phNq4VpsbdWHJC6ybIt7jWBsl6HKfxHP1I,16550 pyOpenRPA/Orchestrator/Managers/Git.py,sha256=dgXx2UzSwiEev4ov2hBbb-5MhXVhFKWZo2lmr19QSCQ,12582 -pyOpenRPA/Orchestrator/Managers/Process.py,sha256=7T_qofdkRJHdPQbaiEsTDOboImSf2N6d_Ku513rURkw,41369 +pyOpenRPA/Orchestrator/Managers/Process.py,sha256=DYX1pBK4gaxcfmDj-1OaLNyk83D_R_7ztZyt0SHWoik,41377 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,, @@ -81,7 +81,7 @@ pyOpenRPA/Orchestrator/Web/Index.js,sha256=YACiZAvjr6NmFlDhQu6urkJp49BX7L8WJU9p- pyOpenRPA/Orchestrator/Web/Index.xhtml,sha256=5JUAs5rEiU0XtHM9QO6EdNMBGt-W6QOVGY7xJ_HLPFM,19257 pyOpenRPA/Orchestrator/Web/__pycache__/Basic.cpython-37.pyc,, pyOpenRPA/Orchestrator/Web/favicon.ico,sha256=6S8XwSQ_3FXPpaX6zYkf8uUewVXO9bHnrrDHEoWrEgw,112922 -pyOpenRPA/Orchestrator/__Orchestrator__.py,sha256=Zud6HTAHSsfTJVrszML5EjGTqlA7k5qhthZTsSD1pX8,151055 +pyOpenRPA/Orchestrator/__Orchestrator__.py,sha256=rlM-j8LK4BdcPfI8KNMOi1Rq-Ht8kCLs6WYsPBZgDTU,203081 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,, @@ -270,15 +270,15 @@ pyOpenRPA/Resources/Web/Semantic-UI-CSS-master/themes/default/assets/fonts/outli pyOpenRPA/Resources/Web/Semantic-UI-CSS-master/themes/default/assets/images/flags.png,sha256=lNXH8WYTAcSm3Ekdct1VmgYgzZF6gm8N8bAju5bqnd0,28123 pyOpenRPA/Resources/Web/jQuery/jquery-3.1.1.min.js,sha256=HPMOWdIdSuVgr3FD9ZE-_MgiK8qk_MdQjrgCtfqp6U4,86713 pyOpenRPA/Resources/Web/pyOpenRPA_logo.png,sha256=7rulXo_C57xJQEaYWmAkChxXb6xbDW2zq-werzVbDbc,4899 -pyOpenRPA/Robot/Clipboard.py,sha256=q76X8L21zJwcwdoJJNPeCEwAV30xS6ylHP1WwvtxoWI,722 -pyOpenRPA/Robot/Keyboard.py,sha256=k_5uNh7UWq5F4TKGbe4LpJwqWgUrftNieWm51HOgOBI,22 -pyOpenRPA/Robot/Mouse.py,sha256=tBW9yteyEv9znJePOfbZcU3YqxX42wyu4Wc09fVaO0c,23 +pyOpenRPA/Robot/Clipboard.py,sha256=ntvXqnJpgmTPnehrjfVibrM72-AYLrqOn-CI2xVOaDs,1577 +pyOpenRPA/Robot/Keyboard.py,sha256=6Ah71EaETse2_nPiz8EPW_fZBlhpaZg5WZ6tWZ2wC9U,17898 +pyOpenRPA/Robot/Mouse.py,sha256=Wvai_tpanqREj5jA4tFEl_-0L45cpk41cX5_Ex68mBg,16079 pyOpenRPA/Robot/OrchestratorConnector.py,sha256=JUtdiUXCruqUqBD19gJBl9jk_b-tpWWx_v3MfBoKzoQ,20445 -pyOpenRPA/Robot/README.md,sha256=e2hKh7Tx6DAsX6jY_hBDhguL1L2Wiv6iugDB5otMzIA,2293 +pyOpenRPA/Robot/README.md,sha256=bwiTAygxuMZzBlwpsndw2QgxA2smIjUyOPZnsnR341k,1623 pyOpenRPA/Robot/Screen.py,sha256=tBW9yteyEv9znJePOfbZcU3YqxX42wyu4Wc09fVaO0c,23 pyOpenRPA/Robot/SettingsTemplate.py,sha256=Rp5XPeV2I4tCS2uf4Zkqm_ERJ6pZMg4-e5_lMqGJYLk,1453 pyOpenRPA/Robot/Test.py,sha256=qXr990nXiFZX5SNv6QN9GLb_U4HZRmJnbZR2qSnwilY,2878 -pyOpenRPA/Robot/UIDesktop.py,sha256=EllVup0umNNFqcQrrO6pffdoTBzc5Y-jEKrY0oO7joU,82938 +pyOpenRPA/Robot/UIDesktop.py,sha256=y0lHHtn-Cd7I1rUQGgBYfZQpfcrGBAfMST9F5aPIxtM,124815 pyOpenRPA/Robot/UIWeb.py,sha256=NFH0brDKEmWWOJxMzO7404K5lJ4LaDn5XMnkoH13Y64,22 pyOpenRPA/Robot/Utils/JSONNormalize.py,sha256=aIuVzuZDazhxkCOzoOjfhHVz66mp2FWdfPv5E7KWF5Y,3890 pyOpenRPA/Robot/Utils/ProcessBitness.py,sha256=WlKL-DklGaoTnchtapOTM_ydxSB4yOeo9lcG3zr2VME,4524 @@ -364,6 +364,6 @@ pyOpenRPA/Tools/__pycache__/License.cpython-37.pyc,, pyOpenRPA/Tools/__pycache__/StopSafe.cpython-37.pyc,, pyOpenRPA/Tools/__pycache__/Usage.cpython-37.pyc,, pyOpenRPA/Tools/__pycache__/__init__.cpython-37.pyc,, -pyOpenRPA/__init__.py,sha256=fmC6rG7L4TIer8c0qUyp-Ypv2d7C2TBucEjIg7Wwip4,175 +pyOpenRPA/__init__.py,sha256=Q9zi3T0F5hLslWv3SoO1EvZt17wEU5fq3JJ59uqdtg8,156 pyOpenRPA/__pycache__/__init__.cpython-37.pyc,, pyOpenRPA/test.txt,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/REQUESTED b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/REQUESTED similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/REQUESTED rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/REQUESTED diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/WHEEL b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/WHEEL similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/WHEEL rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/WHEEL diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/top_level.txt b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/top_level.txt similarity index 100% rename from Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.12.dist-info/top_level.txt rename to Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA-1.2.13.dist-info/top_level.txt diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/ControlPanel.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/ControlPanel.py index cef4acd4..599eed11 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/ControlPanel.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/ControlPanel.py @@ -39,6 +39,7 @@ class ControlPanel(): 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") diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/Process.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/Process.py index 276e4adc..ff47c075 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/Process.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/Managers/Process.py @@ -22,6 +22,7 @@ class Process(): - 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) @@ -35,6 +36,7 @@ class Process(): 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 diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/__Orchestrator__.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/__Orchestrator__.py index b47d891d..dca95b25 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/__Orchestrator__.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Orchestrator/__Orchestrator__.py @@ -41,13 +41,13 @@ gSettingsDict = None def AgentActivityItemAdd(inHostNameStr, inUserStr, inActivityItemDict, inGSettings=None): """ - Add activity in AgentDict. Check if item is created + Добавить активность в словарь активностей выбранного Агента - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: Agent host name - :param inUserStr: User login, where agent is based - :param inActivityItemDict: ActivityItem - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inActivityItemDict: Активность (ActivityItem). См. функцию ProcessorActivityitemCreate + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -72,11 +72,11 @@ def AgentActivityItemAdd(inHostNameStr, inUserStr, inActivityItemDict, inGSettin def AgentActivityItemExists(inHostNameStr, inUserStr, inGUIDStr, inGSettings = None): """ - Check by GUID if ActivityItem has exists in request list. If exist - the result response has not been recieved from the agent + Выполнить проверку, что активность (ActivityItem) была отправлена на сторону Агента. - :param inGSettings: Global settings dict (singleton) - :param inGUIDStr: GUID String of the ActivityItem - :return: True - ActivityItem is exist in AgentDict ; False - else case + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inGUIDStr: ГУИД (GUID) активности (ActivityItem) + :return: True - Активность присутствует ; False - Активность еще не была отправлена на сторону Агента """ # Check if GUID is exists in dict - has been recieved inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -92,11 +92,11 @@ def AgentActivityItemExists(inHostNameStr, inUserStr, inGUIDStr, inGSettings = N def AgentActivityItemReturnExists(inGUIDStr, inGSettings = None): """ - Check by GUID if ActivityItem has been executed and result has come to the Orchestrator + Выполнить проверку, что активность (ActivityItem) была выполнена на стороне Агента и результат был получен на стороне Оркестратора. - :param inGSettings: Global settings dict (singleton) - :param inGUIDStr: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! - :return: True - result has been received from the Agent to orc; False - else case + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inGUIDStr: ГУИД (GUID) активности (ActivityItem) + :return: True - Активность присутствует; False - Активность еще не была выполнена на стороне Агента """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -106,14 +106,15 @@ def AgentActivityItemReturnExists(inGUIDStr, inGSettings = None): def AgentActivityItemReturnGet(inGUIDStr, inCheckIntervalSecFloat = 0.5, inGSettings=None): """ - Work synchroniously! Wait while result will be recieved. Get the result of the ActivityItem execution on the Agent side. Before this please check by the def AgentActivityItemReturnExists that result has come to the Orchestrator - - !ATTENTION! Use only after Orchestrator initialization! Before orchestrator init exception will be raised. + Ожидает появления результата по активности (ActivityItem). Возвращает результат выполнения активности. + + !ВНИМАНИЕ! Замораживает поток, пока не будет получен результат. + !ВНИМАНИЕ! Запускать следует после того как будет инициализировано ядро Оркестратора (см. функцию OrchestratorInitWait), иначе будет инициирована ошибка. - :param inGSettings: Global settings dict (singleton) - :param inGUIDStr: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! - :param inCheckIntervalSecFloat: Interval in sec of the check Activity Item result - :return: Result of the ActivityItem executed on the Agent side anr transmitted to the Orchestrator. IMPORTANT! ONLY JSON ENABLED Types CAN BE TRANSMITTED TO ORCHESTRATOR! + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inGUIDStr: ГУИД (GUID) активности (ActivityItem) + :param inCheckIntervalSecFloat: Интервал в секундах, с какой частотой выполнять проверку результата. По умолчанию 0.5 + :return: Результат выполнения активности. !ВНИМАНИЕ! Возвращаются только то результаты, которые могут быть интерпретированы в JSON формате. """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings #Check if Orchestrator has been initialized - else raise exception @@ -128,17 +129,17 @@ def AgentActivityItemReturnGet(inGUIDStr, inCheckIntervalSecFloat = 0.5, inGSett def 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 + Отправка команды командной строки на сессию, где работает pyOpenRPA.Agent. Результат выполнения команды можно выводить в лог оркестратора. - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: Agent host name in upper case (example "RPA01", "RPA_99" and so on). Active agent session you can see on the orchestrator dashboard as Orchestrator admin - :param inUserStr: Agent user name in upper case (example "UserRPA"). Active agent session you can see on the orchestrator dashboard as Orchestrator admin - :param inCMDStr: command to execute on the Agent session - :param inRunAsyncBool: True - Agent processor don't wait execution; False - Agent processor wait cmd execution - :param inSendOutputToOrchestratorLogsBool: True - catch cmd execution output and send it to the Orchestrator logs; Flase - else case; Default True - :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: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inCMDStr: Команда для исполнения на стороне сессии Агента + :param inRunAsyncBool: True - Агент не ожидает окончания выполнения команды. !ВНИМАНИЕ! Логирование в такой ситуации будет невозможно; False - Агент ожидает окончания выполнения операции. + :param inSendOutputToOrchestratorLogsBool: True - отправлять весь вывод от команды в логи Оркестратора; Flase - Не отправлять; Default True + :param inCMDEncodingStr: Кодировка DOS среды, в которой исполняется команда. Если некорректно установить кодировку - русские символы будут испорчены. По умолчанию установлена "cp1251" + :param inCaptureBool: True - не запускать приложение как отдельное. Результат выполнения команды будет выводиться в окне Агента (если окно Агента присутствует на экране). False - команда будет запущена в отдельном DOS окне. + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lActivityItemDict = { @@ -153,9 +154,11 @@ def AgentOSCMD(inHostNameStr, inUserStr, inCMDStr, inRunAsyncBool=True, inSendOu def AgentOSLogoff(inHostNameStr, inUserStr): """ - Logoff the agent user session + Выполнить операцию logoff на стороне пользователя. - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet() # Set the global settings lCMDStr = "shutdown /l" @@ -171,16 +174,17 @@ def AgentOSLogoff(inHostNameStr, inUserStr): def 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 - Thread safe - you can call def even if you dont init the orchestrator - def will be executed later + Отправить файл по адресу inOrchestratorFilePathStr со стороны Оркестратора и сохранить по адресу inAgentFilePathStr на стороне Агента. + Поддерживает передачу крупных файлов (более 2-х Гб.). Функция является синхронной - не закончит свое выполнение, пока файл не будет передан полностью. - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: - :param inFileDataBytes: - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + !ВНИМАНИЕ - ПОТОКОБЕЗОПАСНАЯ! Вы можете вызвать эту функцию до инициализации ядра Оркестратора. Оркестратор добавит эту функцию в процессорную очередь на исполение. Если вам нужен результат функции, то необходимо сначала убедиться в том, что ядро Оркестратора было инициализированно (см. функцию OrchestratorInitWait). + + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inOrchestratorFilePathStr: Полный путь к передаваемому файлу на стороне Оркестратора. + :param inAgentFilePathStr: Полный путь к локации, в которую требуется сохранить передаваемый файл. + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -237,14 +241,14 @@ def AgentOSFileSend(inHostNameStr, inUserStr, inOrchestratorFilePathStr, inAgent def AgentOSFileBinaryDataBytesCreate(inHostNameStr, inUserStr, inFilePathStr, inFileDataBytes, inGSettings=None): """ - Create binary file by the base64 string by the pyOpenRPA.Agent daemon process (safe for JSON transmition) + Создать бинарный файл, который будет расположен по адресу inFilePathStr на стороне Агента с содержимым inFileDataBytes - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: - :param inFileDataBytes: - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inFilePathStr: Полный путь к сохраняемому файлу на стороне Агента. + :param inFileDataBytes: Строка байт (b'') для отправки в создаваемый файл на стороне Агента. + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lFileDataBase64Str = base64.b64encode(inFileDataBytes).decode("utf-8") @@ -261,14 +265,14 @@ def AgentOSFileBinaryDataBytesCreate(inHostNameStr, inUserStr, inFilePathStr, in def AgentOSFileBinaryDataBase64StrCreate(inHostNameStr, inUserStr, inFilePathStr, inFileDataBase64Str, inGSettings=None): """ - Create binary file by the base64 string by the pyOpenRPA.Agent daemon process (safe for JSON transmission) - - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: - :param inFileDataBase64Str: - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + Создать бинарный файл, который будет расположен по адресу inFilePathStr на стороне Агента с содержимым, декодированным с формата base64: inFileDataBase64Str + + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inFilePathStr: Полный путь к сохраняемому файлу на стороне Агента. + :param inFileDataBase64Str: Строка в формате base64 для отправки в создаваемый файл на стороне Агента. + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lActivityItemDict = { @@ -284,14 +288,14 @@ def AgentOSFileBinaryDataBase64StrCreate(inHostNameStr, inUserStr, inFilePathStr def AgentOSFileBinaryDataBase64StrAppend(inHostNameStr, inUserStr, inFilePathStr, inFileDataBase64Str, inGSettings = None): """ - Append binary file by the base64 string by the pyOpenRPA.Agent daemon process (safe for JSON transmission) - - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: - :param inFileDataBase64Str: - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + Добавить бинарную информацию в существующий бинарный файл, который будет расположен по адресу inFilePathStr на стороне Агента с содержимым, декодированным с формата base64: inFileDataBase64Str + + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inFilePathStr: Полный путь к сохраняемому файлу на стороне Агента. + :param inFileDataBase64Str: Строка в формате base64 для отправки в создаваемый файл на стороне Агента. + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lActivityItemDict = { @@ -308,15 +312,15 @@ def AgentOSFileBinaryDataBase64StrAppend(inHostNameStr, inUserStr, inFilePathStr # Send text file to Agent (string) def AgentOSFileTextDataStrCreate(inHostNameStr, inUserStr, inFilePathStr, inFileDataStr, inEncodingStr = "utf-8",inGSettings=None): """ - Create text file by the string by the pyOpenRPA.Agent daemon process - - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: - :param inFileDataStr: - :param inEncodingStr: - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + Создать текстовый файл, который будет расположен по адресу inFilePathStr на стороне Агента с содержимым inFileDataStr в кодировке inEncodingStr + + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inFilePathStr: Полный путь к сохраняемому файлу на стороне Агента. + :param inFileDataStr: Строка для отправки в создаваемый файл на стороне Агента. + :param inEncodingStr: Кодировка текстового файла. По умолчанию utf-8 + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lActivityItemDict = { @@ -331,13 +335,13 @@ def AgentOSFileTextDataStrCreate(inHostNameStr, inUserStr, inFilePathStr, inFile def AgentOSFileBinaryDataBase64StrReceive(inHostNameStr, inUserStr, inFilePathStr, inGSettings = None): """ - Read binary file and encode in base64 to transmit (safe for JSON transmition) + Выполнить чтение бинарного файла и получить содержимое в формате base64 (строка) - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: File path to read - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inFilePathStr: Путь к бинарному файлу на чтение на стороне Агента + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lActivityItemDict = { @@ -353,13 +357,14 @@ def AgentOSFileBinaryDataBase64StrReceive(inHostNameStr, inUserStr, inFilePathSt def AgentOSFileBinaryDataReceive(inHostNameStr, inUserStr, inFilePathStr): """ - Read binary file from agent (synchronious) - - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: File path to read - :return: file data bytes + Чтение бинарного файла на стороне Агента по адресу inFilePathStr. + + !ВНИМАНИЕ - СИНХРОННАЯ! Функция не завершится, пока не будет получен результат чтения на стороне Агента. + + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inFilePathStr: Путь к бинарному файлу, который требуется прочитать на стороне Агента + :return: Строка байт (b'') - содержимое бинарного файла """ lFileDataBytes = None inGSettings = GSettingsGet() # Set the global settings @@ -391,14 +396,16 @@ def AgentOSFileBinaryDataReceive(inHostNameStr, inUserStr, inFilePathStr): def AgentOSFileTextDataStrReceive(inHostNameStr, inUserStr, inFilePathStr, inEncodingStr="utf-8", inGSettings = None): """ - Read text file in the agent GUI session - - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :param inFilePathStr: File path to read - :param inEncodingStr: Text file encoding. Default 'utf-8' - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + Чтение текстового файла на стороне Агента по адресу inFilePathStr. По ГИУД с помощью функции AgentActivityItemReturnGet можно будет получить текстовую строку данных, которые были расположены в файле. + + !ВНИМАНИЕ - АСИНХРОННАЯ! Функция завершится сразу, не дожидаясь окончания выполнения операции на стороне Агента. + + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inFilePathStr: Путь к бинарному файлу, который требуется прочитать на стороне Агента + :param inEncodingStr: Кодировка текстового файла. По умолчанию utf-8 + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lActivityItemDict = { @@ -413,12 +420,14 @@ def AgentOSFileTextDataStrReceive(inHostNameStr, inUserStr, inFilePathStr, inEnc def AgentProcessWOExeUpperUserListGet(inHostNameStr, inUserStr, inGSettings = None): """ - Return the process list only for the current user (where Agent is running) without .EXE in upper case. Can use in ActivityItem from Orchestrator to Agent + Получить список процессов, которые выполняется на сессии Агента. Все процессы фиксируются без постфикса .exe, а также в верхнем регистре. + + ПРИМЕР РЕЗУЛЬТАТА, КОТОРЫЙ МОЖНО ПОЛУЧИТЬ ПО ГУИД ЧЕРЕЗ ФУНКЦИЮ AgentActivityItemReturnGet: ["ORCHESTRATOR", "AGENT", "CHROME", "EXPLORER", ...] - :param inGSettings: Global settings dict (singleton) - :param inHostNameStr: - :param inUserStr: - :return: GUID String of the ActivityItem - you can wait (sync or async) result by this guid! + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления + :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lActivityItemDict = { @@ -432,22 +441,22 @@ def AgentProcessWOExeUpperUserListGet(inHostNameStr, inUserStr, inGSettings = No return AgentActivityItemAdd(inGSettings=inGSettings, inHostNameStr=inHostNameStr, inUserStr=inUserStr, inActivityItemDict=lActivityItemDict) # OS DEFS - def OSLogoff(): """ - Logoff the current orchestrator session + Выполнить отключение сессии, на которой выполняется Оркестратор. + :return: """ os.system("shutdown /l") def OSCredentialsVerify(inUserStr, inPasswordStr, inDomainStr=""): ## """ - Verify user credentials in windows. Return bool + Выполнить верификацию доменного (локального) пользователя по паре логин/пароль - :param inUserStr: - :param inPasswordStr: - :param inDomainStr: - :return: True - Credentials are actual; False - Credentials are not actual + :param inUserStr: Наименование пользователя + :param inPasswordStr: Пароль + :param inDomainStr: Домен. Если домена нет - не указывать или "" + :return: True - Учетные данные верны; False - Учетные данные представлены некорректно """ try: hUser = win32security.LogonUser( @@ -461,12 +470,13 @@ def OSCredentialsVerify(inUserStr, inPasswordStr, inDomainStr=""): ## def OSRemotePCRestart(inHostStr, inForceBool=True, inLogger = None): """ - Send signal via power shell to restart remote PC - ATTENTION: Orchestrator user need to have restart right on the Remote machine to restart PC. + Отправить сигнал на удаленную перезагрузку операционной системы. + + !ВНИМАНИЕ! Перезапуск будет принят, если учетная запись имеет полномочия на перезапуск на соответсвующей машине. - :param inLogger: logger to log powershell result in logs - :param inHostStr: PC hostname which you need to restart. - :param inForceBool: True - send signal to force retart PC; False - else case + :param inHostStr: Имя хоста, который требуется перезагрузить + :param inForceBool: True - принудительная перезагрузка; False - мягкая перезагрузка (дождаться окончания выполнения всех операций). По умолчанию True + :param inLogger: Логгер, в который отправлять информацию о результате выполнения команды :return: """ if inLogger is None: inLogger = OrchestratorLoggerGet() @@ -476,12 +486,12 @@ def OSRemotePCRestart(inHostStr, inForceBool=True, inLogger = None): def OSCMD(inCMDStr, inRunAsyncBool=True, inLogger = None): """ - OS send command in shell locally + Отправить команду на выполнение на сессию, где выполняется Оркестратор. - :param inCMDStr: - :param inRunAsyncBool: - :param inLogger: - :return: CMD result string + :param inCMDStr: Команда на отправку + :param inRunAsyncBool: True - выполнить команду в асинхронном режиме (не дожидаться окончания выполнения программы и не захватывать результат выполнения); False - Ждать окончания выполнения и захватывать результат + :param inLogger: Логгер, в который отправлять информацию о результате выполнения команды + :return: Строка результата выполнения команды. Если inRunAsyncBool = False """ if inLogger is None: inLogger = OrchestratorLoggerGet() lResultStr = "" @@ -521,9 +531,9 @@ def OSCMD(inCMDStr, inRunAsyncBool=True, inLogger = None): def OrchestratorRestart(inGSettings=None): """ - Orchestrator restart + Перезапуск Оркестратора с сохранением информации о запущенных RDP сессиях. - :param inGSettings: Global settings dict (singleton) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings OrchestratorSessionSave(inGSettings=inGSettings) # Dump RDP List in file json @@ -536,27 +546,27 @@ def OrchestratorRestart(inGSettings=None): def OrchestratorLoggerGet() -> logging.Logger: """ - Get the logger from the Orchestrator + Получить логгер Оркестратора - :return: + :return: Логгер """ return GSettingsGet().get("Logger",None) def OrchestratorScheduleGet() -> schedule: """ - Get the schedule (schedule.readthedocs.io) from the Orchestrator - - Fro example you can use: + Базовый объект расписания, который можно использовать для запуска / остановки роботов. + Подробнее про объект schedule и его примеры использования см. по адресу: schedule.readthedocs.io .. code-block:: python - # One schedule threaded + + # Однопоточный schedule Orchestrator.OrchestratorScheduleGet().every(5).seconds.do(lProcess.StatusCheckStart) - #New schedule thread # See def description Orchestrator.OrchestratorThreadStart + #Многопоточный schedule. cм. описание Orchestrator.OrchestratorThreadStart Orchestrator.OrchestratorScheduleGet().every(5).seconds.do(Orchestrator.OrchestratorThreadStart,lProcess.StatusCheckStart) - :return: schedule module. Example see here https://schedule.readthedocs.io/en/stable/examples.html + :return: schedule объект """ if GSettingsGet().get("SchedulerDict",{}).get("Schedule",None) is None: GSettingsGet()["SchedulerDict"]["Schedule"]=schedule @@ -564,12 +574,12 @@ def OrchestratorScheduleGet() -> schedule: def OrchestratorThreadStart(inDef, *inArgList, **inArgDict): """ - Execute def in new thread and pass some args with list and dict types + Запустить функцию в отдельном потоке. В таком случае получить результат выполнения функции можно только через общие переменные. (Например через GSettings) - :param inDef: Python Def - :param inArgList: args as list - :param inArgDict: args as dict - :return: threading.Thread object + :param inDef: Python функция + :param inArgList: Список неименованных аргументов функции inDef + :param inArgDict: Словарь именованных аргументов функции inDef + :return: threading.Thread экземпляр """ lDefThread = threading.Thread(target=inDef,args=inArgList,kwargs=inArgDict) lDefThread.start() @@ -577,9 +587,9 @@ def OrchestratorThreadStart(inDef, *inArgList, **inArgDict): def OrchestratorIsAdmin(): """ - Check if Orchestrator process is running as administrator + Проверить, запущен ли Оркестратор с правами администратора. Права администратора нужны Оркестратору только для контроля графической сессии, на которой он запущен. Если эти права выделить индивидуально, то права администратора будут необязательны. - :return: True - run as administrator; False - not as administrator + :return: True - Запущен с правами администратора; False - Не запущен с правами администратора """ try: return ctypes.windll.shell32.IsUserAnAdmin() @@ -587,17 +597,20 @@ def OrchestratorIsAdmin(): return False def OrchestratorIsInited() -> bool: - """Check if Orchestrator initial actions were processed + """ + Проверить, было ли проинициализировано ядро Оркестратора - :return: True - orc is already inited; False - else + :return: True - Ядро Оркестратора было проинициализировано; False - Требуется время на инициализацию :rtype: bool """ return Core.IsOrchestratorInitialized(inGSettings=GSettingsGet()) def OrchestratorInitWait() -> None: - """Wait thread while orc will process initial action. - ATTENTION: DO NOT CALL THIS DEF IN THREAD WHERE ORCHESTRATOR MUST BE INITIALIZED - INFINITE LOOP + """ + Ожидать инициализацию ядра Оркестратора + + !ВНИМАНИЕ!: НИ В КОЕМ СЛУЧАЕ НЕ ЗАПУСКАТЬ ЭТУ ФУНКЦИЮ В ОСНОВНОМ ПОТОКЕ, ГДЕ ПРОИСХОДИТ ИНИЦИАЛИЗАЦИЯ ЯДРА ОРКЕСТРАТОРА - ВОЗНИКНЕТ ВЕЧНЫЙ ЦИКЛ """ lIntervalSecFloat = 0.5 while not OrchestratorIsInited(): @@ -606,9 +619,9 @@ def OrchestratorInitWait() -> None: def OrchestratorRerunAsAdmin(): """ - Check if not admin - then rerun orchestrator as administrator + Перезапустить Оркестратор с правами локального администратора. Права администратора нужны Оркестратору только для контроля графической сессии, на которой он запущен. Если эти права выделить индивидуально, то права администратора будут необязательны. - :return: True - run as administrator; False - not as administrator + :return: True - Запущен с правами администратора; False - Не запущен с правами администратора """ if not OrchestratorIsAdmin(): # Re-run the program with admin rights @@ -618,19 +631,21 @@ def OrchestratorRerunAsAdmin(): def 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! + Выполнить поиск и инициализацию пользовательских .py файлов в Оркестраторе (например панелей управления роботов) + + Добавляет инициализированный модуль в пространство sys.modules как imported (имя модуля = имя файла без расширения). + .. code-block:: python - # USAGE VAR 1 (without the def auto call) - # Autoinit control panels starts with CP_ + # ВАРИАНТ ИСПОЛЬЗОВАНИЯ 1 (инициализация модуля py без вызова каких-либо функций внутри) + # автоинициализация всех .py файлов, с префиксом CP_, которые расположены в папке ControlPanel 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_ + # ВАРИАНТ ИСПОЛЬЗОВАНИЯ 2 (инициализация модуля py с вызовом функции внутри) - преимущественно для обратной совместимости старых версий панелей управления < 1.2.7 + # автоинициализация всех .py файлов, с префиксом CP_, которые расположены в папке ControlPanel Orchestrator.OrchestratorPySearchInit(inGlobPatternStr="ControlPanel\\CP_*.py", inDefStr="SettingsUpdate", inDefArgNameGSettingsStr="inGSettings") - # INFO: The code above will replace the code below + # ДЛЯ СПРАВКИ & ИСТОРИИ: Код выше позволил отказаться от блока кода ниже для каждого .py файла ## !!! For Relative import !!! CP Version Check try: sys.path.insert(0,os.path.abspath(os.path.join(r""))) @@ -639,12 +654,11 @@ def OrchestratorPySearchInit(inGlobPatternStr, inDefStr = None, inDefArgNameGSet except Exception as e: gSettings["Logger"].exception(f"Exception when init CP. See below.") - - :param inGlobPatternStr: example"..\\*\\*\\*X64*.cmd" - :param inDefStr: OPTIONAL The string name of the def. For backward compatibility if you need to auto call some def from initialized module - :param inDefArgNameGSettingsStr: OPTIONAL The name of the GSettings argument in def (if exists) - :param inAsyncInitBool: OPTIONAL True - init py modules in many threads - parallel execution. False (default) - sequence execution - :return: { "ModuleNameStr":{"PyPathStr": "", "Module": ...}, ...} + :param inGlobPatternStr: Пример "..\\*\\*\\*_CP*.py" + :param inDefStr: ОПЦИОНАЛЬНО Строковое наименование функции. Преимущественно для обратной совместимости + :param inDefArgNameGSettingsStr: ОПЦИОНАЛЬНО Наименование аргумента, в который требуется передать GSettings (если необходимо) + :param inAsyncInitBool: ОПЦИОНАЛЬНО True - Инициализация py модулей в отдельных параллельных потоках - псевдопараллельное выполнение. False - последовательная инициализация + :return: Сведения об инициализированных модулях в структуре: { "ModuleNameStr":{"PyPathStr": "", "Module": ...}, ...} """ # # # # # # # # @@ -688,16 +702,19 @@ def OrchestratorPySearchInit(inGlobPatternStr, inDefStr = None, inDefArgNameGSet def OrchestratorSessionSave(inGSettings=None): """ - Orchestrator session save in file - (from version 1.2.7) + Сохранить состояние Оркестратора (для дальнейшего восстановления в случае перезапуска): + + - RDP сессий, которые контролирует Оркестратор + - Хранилища DataStorage в глобальном словаре настроек GSettings. DataStorage поддерживает хранение объектов Python + + (до версии 1.2.7) _SessionLast_GSettings.pickle (binary) - (above the version 1.2.7) + (начиная с версии 1.2.7) _SessionLast_RDPList.json (encoding = "utf-8") _SessionLast_StorageDict.pickle (binary) - :param inGSettings: Global settings dict (singleton) - :return: True every time + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lL = inGSettings["Logger"] @@ -730,16 +747,19 @@ def OrchestratorSessionSave(inGSettings=None): def OrchestratorSessionRestore(inGSettings=None): """ - Check _SessioLast... files in working directory. if exist - load into gsettings - (from version 1.2.7) + Восстановить состояние Оркестратора, если ранее состояние Оркестратора было сохранено с помощью функции OrchestratorSessionSave: + + - RDP сессий, которые контролирует Оркестратор + - Хранилища DataStorage в глобальном словаре настроек GSettings. DataStorage поддерживает хранение объектов Python + + (до версии 1.2.7) _SessionLast_GSettings.pickle (binary) - (above the version 1.2.7) + (начиная с версии 1.2.7) _SessionLast_RDPList.json (encoding = "utf-8") _SessionLast_StorageDict.pickle (binary) - :param inGSettings: Global settings dict (singleton) - :return: + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lL = inGSettings.get("Logger",None) @@ -776,33 +796,47 @@ def OrchestratorSessionRestore(inGSettings=None): def UACKeyListCheck(inRequest, inRoleKeyList) -> bool: """ - Check is client is has access for the key list + Проверить права доступа для пользователя запроса по списку ключей до права. + + .. code-block:: python + + # ВАРИАНТ ИСПОЛЬЗОВАНИЯ 1 (инициализация модуля py без вызова каких-либо функций внутри) + # автоинициализация всех .py файлов, с префиксом CP_, которые расположены в папке ControlPanel + Orchestrator.UACKeyListCheck(inRequest=lRequest, inRoleKeyList=["ROBOT1","DISPLAY_DASHBOARD"]) - :param inRequest: request handler (from http.server import BaseHTTPRequestHandler) - :param inRoleKeyList: - :return: bool + :param inRequest: Экземпляр request (from http.server import BaseHTTPRequestHandler) + :param inRoleKeyList: Список ключей, права доступа к которому требуется проверить + :return: True - Пользователь обладает соответствующим правом; False - Пользователь не обладает соответствующим правом """ return inRequest.UACClientCheck(inRoleKeyList=inRoleKeyList) def UACUserDictGet(inRequest) -> dict: """ - Return user UAC hierarchy dict of the inRequest object. Empty dict - superuser access + Вернуть UAC (User Access Control) словарб доступов для пользователя, который отправил запрос. Пустой словарь - супердоступ (доступ ко всему) - :param inRequest: request handler (from http.server import BaseHTTPRequestHandler) - :return: user UAC hierarchy dict + :param inRequest: Экземпляр request (from http.server import BaseHTTPRequestHandler) + :return: Словарь доступов пользователя. Пустой словарь - супердоступ (доступ ко всему) """ return inRequest.UserRoleHierarchyGet() # get the Hierarchy def UACUpdate(inADLoginStr, inADStr="", inADIsDefaultBool=True, inURLList=None, inRoleHierarchyAllowedDict=None, inGSettings = None): """ - Update user access (UAC) - - :param inGSettings: Global settings dict (singleton) - :param inADLoginStr: - :param inADStr: - :param inADIsDefaultBool: - :param inURLList: - :param inRoleHierarchyAllowedDict: + Дообогащение словаря доступа UAC пользователя inADStr\\inADLoginStr. Если ранее словарь не устанавливался, то по умолчанию он {}. Далее идет дообогащение теми ключами, которые присутствуют в inRoleHierarchyAllowedDict + + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inADLoginStr: Логин пользователя + :param inADStr: Домен пользователя. Если пусто - локальный компьютер или домен по-умолчанию, который настроен в ОС + :param inADIsDefaultBool: True - домен настроен по умолчанию; False - домен требуется обязательно указывать + :param inURLList: Список разрешенных URL для пользователя. Для добавления URL рекомендуем использовать функции WebURLConnectDef, WebURLConnectFile, WebURLConnectFolder + Формат: { + "Method": "GET" || "POST", + "URL": "/GetScreenshot", + "MatchType": "BeginWith" || "Equal" || "EqualCase" || "Contains" || "EqualNoParam", + "ResponseDefRequestGlobal": Функция python || "ResponseFilePath": Путь к файлу || "ResponseFolderPath": Путь к папке, в которой искать файлы, + "ResponseContentType": пример MIME "image/png", + "UACBool":False - не выполнять проверку прав доступа по запросу, + "UseCacheBool": True - кэшировать ответ}, + :param inRoleHierarchyAllowedDict: Словарь доступа пользователя UAC. Пустой словарь - полный доступ """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lUserTurple = (inADStr.upper(),inADLoginStr.upper()) # Create turple key for inGSettings["ServerDict"]["AccessUsers"]["RuleDomainUserDict"] @@ -831,10 +865,10 @@ def UACUpdate(inADLoginStr, inADStr="", inADIsDefaultBool=True, inURLList=None, def UACSuperTokenUpdate(inSuperTokenStr, inGSettings=None): """ - Add supertoken for the all access (it is need for the robot communication without human) + Добавить супертокен (полный доступ). Супертокены используются для подключения к Оркестратору по API - :param inGSettings: Global settings dict (singleton) - :param inSuperTokenStr: + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inSuperTokenStr: Кодовая строковая комбинация, которая будет предоставлять доступ роботу / агенту для взаимодействия с Оркестратором по API """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lLoginStr = "SUPERTOKEN" @@ -846,31 +880,26 @@ def UACSuperTokenUpdate(inSuperTokenStr, inGSettings=None): # # # # # # # # # # # # # # # # # # # # # # # # OrchestratorWeb defs # # # # # # # # # # # # # # # # # # # # # # # - def WebURLIndexChange(inURLIndexStr:str ="/"): - """Change the index page of the orchestrator if you dont want the '/' (main) path + """ + Изменить адрес главной страницы Оркестратора. По умолчанию '/' - :param inURLIndexStr: New url for the index page of the orchestrator, defaults to "/" - :type inURLIndexStr: str, optional + :param inURLIndexStr: Новый адрес главной страницы Оркестратора. + :type inURLIndexStr: str, опционально """ GSettingsGet()["ServerDict"]["URLIndexStr"] = inURLIndexStr def WebURLConnectDef(inMethodStr, inURLStr, inMatchTypeStr, inDef, inContentTypeStr="application/octet-stream", inGSettings = None, inUACBool = None): """ - Connect URL to DEF - "inMethodStr":"GET|POST", - "inURLStr": "/index", #URL of the request - "inMatchTypeStr": "", #"BeginWith|Contains|Equal|EqualCase", - "inContentTypeStr": "", #HTTP Content-type - "inDef": None #Function with str result - - :param inGSettings: Global settings dict (singleton) - :param inMethodStr: "GET|POST", - :param inURLStr: example "/index", #URL of the request - :param inMatchTypeStr: #"BeginWith|Contains|Equal|EqualCase", - :param inDef: def arg allowed list: 2:[inRequest, inGSettings], 1: [inRequest], 0: [] - :param inContentTypeStr: default: "application/octet-stream" - :param inUACBool: default: None; True - check user access before do this URL item. None - get Server flag if ask user + Подключить функцию Python к URL. + + :param inMethodStr: Метод доступа по URL "GET" || "POST" + :param inURLStr: URL адрес. Пример "/index" + :param inMatchTypeStr: Тип соответсвия строки URL с inURLStr: "BeginWith" || "Contains" || "Equal" || "EqualCase" || "EqualNoParam" + :param inDef: Функция Python. Допускаются функции, которые принимают следующие наборы параметров: 2:[inRequest, inGSettings], 1: [inRequest], 0: [] + :param inContentTypeStr: МИМЕ тип. По умолчанию: "application/octet-stream" + :param inUACBool: True - Выполнять проверку прав доступа пользователя перед отправкой ответа; False - не выполнять проверку прав доступа пользователя + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lURLItemDict = { @@ -889,20 +918,15 @@ def WebURLConnectDef(inMethodStr, inURLStr, inMatchTypeStr, inDef, inContentType def WebURLConnectFolder(inMethodStr, inURLStr, inMatchTypeStr, inFolderPathStr, inGSettings = None, inUACBool = None, inUseCacheBool= False): """ - Connect URL to Folder - "inMethodStr":"GET|POST", - "inURLStr": "/Folder/", #URL of the request - "inMatchTypeStr": "", #"BeginWith|Contains|Equal|EqualCase", - "inFolderPathStr": "", #Absolute or relative path - "inUACBool" - - :param inGSettings: Global settings dict (singleton) - :param inMethodStr: - :param inURLStr: - :param inMatchTypeStr: - :param inFolderPathStr: - :param inUACBool: default: None; True - check user access before do this URL item. None - get Server flag if ask user - :param inUseCacheBool: True - cache this page - dont open ever + Подключить папку к URL. + + :param inMethodStr: Метод доступа по URL "GET" || "POST" + :param inURLStr: URL адрес. Пример "/index" + :param inMatchTypeStr: Тип соответсвия строки URL с inURLStr: "BeginWith" || "Contains" || "Equal" || "EqualCase" || "EqualNoParam" + :param inFolderPathStr: Путь к папке на диске, в которой искать файл и возвращать пользователю по HTTP + :param inUACBool: True - Выполнять проверку прав доступа пользователя перед отправкой ответа; False - не выполнять проверку прав доступа пользователя + :param inUseCacheBool: True - выполнить кэширование страницы, чтобы в следющих запросах открыть быстрее; False - не кэшировать + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check if last symbol is "/" - append if not exist @@ -925,20 +949,18 @@ def WebURLConnectFolder(inMethodStr, inURLStr, inMatchTypeStr, inFolderPathStr, def WebURLConnectFile(inMethodStr, inURLStr, inMatchTypeStr, inFilePathStr, inContentTypeStr=None, inGSettings = None, inUACBool = None, inUseCacheBool = False): """ - Connect URL to File - "inMethodStr":"GET|POST", - "inURLStr": "/index", #URL of the request - "inMatchTypeStr": "", #"BeginWith|Contains|Equal|EqualCase", - "inFolderPathStr": "", #Absolute or relative path - - :param inGSettings: Global settings dict (singleton) - :param inMethodStr: - :param inURLStr: - :param inMatchTypeStr: - :param inFilePathStr: - :param inContentTypeStr: If none - autodetect - :param inUACBool: default: None; True - check user access before do this URL item. None - get Server flag if ask user - :param inUseCacheBool: True - cache this page - dont open ever + + Подключить файл к URL. + + :param inMethodStr: Метод доступа по URL "GET" || "POST" + :param inURLStr: URL адрес. Пример "/index" + :param inMatchTypeStr: Тип соответсвия строки URL с inURLStr: "BeginWith" || "Contains" || "Equal" || "EqualCase" || "EqualNoParam" + :param inFilePathStr: Путь к файлу на диске, который возвращать пользователю по HTTP + :param inContentTypeStr: МИМЕ тип. Если None - выполнить автоматическое определение + :param inUACBool: True - Выполнять проверку прав доступа пользователя перед отправкой ответа; False - не выполнять проверку прав доступа пользователя + :param inUseCacheBool: True - выполнить кэширование страницы, чтобы в следющих запросах открыть быстрее; False - не кэшировать + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lURLItemDict = { @@ -956,13 +978,13 @@ def WebURLConnectFile(inMethodStr, inURLStr, inMatchTypeStr, inFilePathStr, inCo def WebListenCreate(inServerKeyStr="Default", inAddressStr="", inPortInt=80, inCertFilePEMPathStr=None, inKeyFilePathStr=None, inGSettings = None): """ - Create listen interface for the web server - - :param inGSettings: Global settings dict (singleton) - :param inAddressStr: IP interface to listen - :param inPortInt: Port int to listen for HTTP default is 80; for HTTPS default is 443 - :param inCertFilePEMPathStr: Path to .pem (base 64) certificate. Required for SSL connection. ATTENTION - do not use certificate with password - :param inKeyFilePathStr: Path to the private key file + Настроить веб-сервер Оркестратора. + + :param inAddressStr: IP адрес для прослушивания. Если "", то прослушивать запросы со всех сетевых карт. Если "127.0.0.1", то слушать запросы только с той ОС, на которой работает Оркестратор + :param inPortInt: Номер порта для прослушивания. Если HTTP - 80; Если HTTPS - 443. По умолчанию 80. Допускается установка других портов + :param inCertFilePEMPathStr: Путь файлу сертификата, сгенерированного в .pem (base64) формате. Обязателен при использовании защищенного HTTPS/SSL соединения. + :param inKeyFilePathStr: Путь к файлу закрытого ключа в base64 формате + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) :return: """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -977,13 +999,13 @@ def WebListenCreate(inServerKeyStr="Default", inAddressStr="", inPortInt=80, inC def WebCPUpdate(inCPKeyStr, inHTMLRenderDef=None, inJSONGeneratorDef=None, inJSInitGeneratorDef=None, inGSettings = None): """ - Add control panel HTML, JSON generator or JS when page init + Добавить панель управления робота в Оркестратор. Для панели управления открыт доступ для использования функции-генератора HTML, генератора JSON данных, генератора JS кода. - :param inGSettings: Global settings dict (singleton) - :param inCPKeyStr: - :param inHTMLRenderDef: - :param inJSONGeneratorDef: - :param inJSInitGeneratorDef: + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inCPKeyStr: Текстовый ключ панели управления. Ключ для каждой панели управления должен быть уникальным! + :param inHTMLRenderDef: Функция Python для генерации HTML кода. Для использования Jinja2 шаблонов HTML см. pyOpenRPA.Orchestrator.Managers.ControlPanel + :param inJSONGeneratorDef: Функция Python для генерации JSON контейнера для отправки на клиентскую часть Оркестратора + :param inJSInitGeneratorDef: Функция Python для генерации JS кода для отправки на клиентскую часть Оркестратора """ lCPManager = Managers.ControlPanel(inControlPanelNameStr=inCPKeyStr, inRefreshHTMLJinja2TemplatePathStr=None) # CASE HTMLRender @@ -996,11 +1018,11 @@ def WebCPUpdate(inCPKeyStr, inHTMLRenderDef=None, inJSONGeneratorDef=None, inJSI def WebAuditMessageCreate(inRequest=None, inOperationCodeStr="-", inMessageStr="-"): """ - Create message string with request user details (IP, Login etc...). Very actual for IT security in big company. - + Создание сообщения ИТ аудита с такими сведениями как (Домен, IP, логин и тд.). Данная функция особенно актуальна в том случае, если требуется реализовать дополнительные меры контроля ИТ системы. + .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lWebAuditMessageStr = Orchestrator.WebAuditMessageCreate( @@ -1008,13 +1030,13 @@ def WebAuditMessageCreate(inRequest=None, inOperationCodeStr="-", inMessageStr=" inOperationCodeStr = "OP_CODE_1", inMessageStr="Success"): - # Log the WebAudit message + # Логгирование сообщения lLogger.info(lWebAuditMessageStr) - :param inRequest: HTTP request handler. Optional if call def from request thread - :param inOperationCodeStr: operation code in string format (actual for IT audit in control panels) - :param inMessageStr: additional message after - :return: format "WebAudit :: DOMAIN\\USER@101.121.123.12 :: operation code :: message" + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :param inOperationCodeStr: Код операции, который принят в компании в соответствии с регламентными процедурами + :param inMessageStr: Дополнительное сообщение, которое необходимо отправить в сообщение об ИТ аудите + :return: Формат сообщения: "WebAudit :: DOMAIN\\USER@101.121.123.12 :: operation code :: message" """ try: if inRequest is None: inRequest = WebRequestGet() @@ -1030,10 +1052,10 @@ def WebAuditMessageCreate(inRequest=None, inOperationCodeStr="-", inMessageStr=" def WebRequestParseBodyBytes(inRequest=None): """ - Extract the body in bytes from the request + Извлечь данные в байт виде из тела (body) HTTP запроса. - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: Bytes or None + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :return: Строка байт b'' или None (если тело запроса было пустым) """ if inRequest is None: inRequest = WebRequestGet() lBodyBytes=None @@ -1044,40 +1066,40 @@ def WebRequestParseBodyBytes(inRequest=None): def WebRequestParseBodyStr(inRequest=None): """ - Extract the body in str from the request + Извлечь данные в виде строки из тела (body) HTTP запроса. - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: str or None + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :return: Текстовая строка '' или None (если тело запроса было пустым) """ if inRequest is None: inRequest = WebRequestGet() return WebRequestParseBodyBytes(inRequest=inRequest).decode('utf-8') def WebRequestParseBodyJSON(inRequest=None): """ - Extract the body in dict/list from the request + Извлечь из тела (body) запроса HTTP JSON данные и преобразовать в Dict / List структуры языка Python. - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: dict or list + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :return: Словарь (dict), список (list) или None (если тело запроса было пустым) """ if inRequest is None: inRequest = WebRequestGet() return json.loads(WebRequestParseBodyStr(inRequest=inRequest)) def WebRequestParsePath(inRequest=None): """ - Parse the request - extract the url. Example: /pyOpenRPA/Debugging/DefHelper/... + Извлечь декодированный URL путь из HTTP запроса пользователя в формате строки. - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: Str, Example: /pyOpenRPA/Debugging/DefHelper/... + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :return: str, пример: /pyOpenRPA/Debugging/DefHelper """ if inRequest is None: inRequest = WebRequestGet() return urllib.parse.unquote(inRequest.path) def WebRequestParseFile(inRequest=None): """ - Parse the request - extract the file (name, body in bytes) + Извлечь файл (наименование + содержимое в виде строки байт b'') из HTTP запроса пользователя. - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: (FileNameStr, FileBodyBytes) or (None, None) + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :return: Кортеж формата (FileNameStr, FileBodyBytes) or (None, None), если файл не был обнаружен """ if inRequest is None: inRequest = WebRequestGet() lResultTurple=(None,None) @@ -1099,21 +1121,26 @@ def WebRequestParseFile(inRequest=None): return lResultTurple -def WebRequestResponseSend(inResponeStr, inRequest=None): +def WebRequestResponseSend(inResponeStr, inRequest=None, inContentTypeStr: str = None, inHeadersDict: dict = None): """ - Send response for the request + Установить ответ на HTTP запрос пользователя. - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: + :param inResponeStr: Тело ответа (строка) + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :param inContentTypeStr: МИМЕ тип. Пример: "html/text" + :param inHeadersDict: Словарь (dict) ключей, которые добавить в headers HTTP ответа на запрос пользователя """ if inRequest is None: inRequest = WebRequestGet() inRequest.OpenRPAResponseDict["Body"] = bytes(inResponeStr, "utf8") + if inHeadersDict is not None: + inRequest.OpenRPAResponseDict["Headers"].update(inHeadersDict) + if inContentTypeStr is not None: + inRequest.OpenRPAResponseDict["Headers"]["Content-type"] = inContentTypeStr def WebRequestGet(): """ - Return the web request instance if current thread was created by web request from client. else return None - + Вернуть экземпляр HTTP запроса, если функция вызвана в потоке, который был порожден для отработки HTTP запроса пользователя. """ lCurrentThread = threading.current_thread() if hasattr(lCurrentThread, "request"): @@ -1121,10 +1148,10 @@ def WebRequestGet(): def WebUserInfoGet(inRequest=None): """ - Return User info about request + Информация о пользователе, который отправил HTTP запрос. - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: {"DomainUpperStr": "", "UserNameUpperStr": ""} + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :return: Сведения в формате {"DomainUpperStr": "PYOPENRPA", "UserNameUpperStr": "IVAN.MASLOV"} """ if inRequest is None: inRequest = WebRequestGet() lDomainUpperStr = inRequest.OpenRPA["Domain"].upper() @@ -1133,11 +1160,11 @@ def WebUserInfoGet(inRequest=None): def WebUserIsSuperToken(inRequest = None, inGSettings = None): """ - Return bool if request is authentificated with supetoken (token which is never expires) + Проверить, авторизован ли HTTP запрос с помощью супер токена (токен, который не истекает). - :param inRequest: inRequest from the server. Optional if call def from request thread - :param inGSettings: Global settings dict (singleton) - :return: bool True - is supertoken; False - is not supertoken + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: True - является супертокеном; False - не является супертокеном """ if inRequest is None: inRequest = WebRequestGet() inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -1148,10 +1175,10 @@ def WebUserIsSuperToken(inRequest = None, inGSettings = None): def WebUserUACHierarchyGet(inRequest = None): """ - Return User UAC Hierarchy DICT Return {...} + Вернуть словарь доступа UAC в отношении пользователя, который выполнил HTTP запрос inRequest - :param inRequest: inRequest from the server. Optional if call def from request thread - :return: UAC Dict {} + :param inRequest: Экземпляр HTTP request. Опционален, если сообщение фиксируется из под потока, который был инициирован запросом пользователя + :return: UAC словарь доступа или {}, что означает полный доступ """ if inRequest is None: inRequest = WebRequestGet() return inRequest.UserRoleHierarchyGet() @@ -1171,10 +1198,10 @@ if __name__ == "pyOpenRPA.Orchestrator.__Orchestrator__" and "pyOpenRPA.Orchestr def GSettingsGet(inGSettings=None): """ - Get the GSettings from the singleton module. + Вернуть глобальный словарь настроек Оркестратора. Во время выполнения программы глобальный словарь настроек существует в единственном экземпляре (синглтон) - :param inGSettings: You can pass some GSettings to check if it equal to base gsettings. If not equal - def will merge it - :return: GSettings + :param inGSettings: Дополнительный словарь настроек, который необходимо добавить в основной глобальный словарь настроек Оркестратора (синглтон) + :return: Глобальный словарь настроек GSettings """ global GSettings # identify the global variable # Merge dictionaries if some new dictionary has come @@ -1184,12 +1211,13 @@ def GSettingsGet(inGSettings=None): def GSettingsKeyListValueSet(inValue, inKeyList=None, inGSettings = None): """ - Set value in GSettings by the key list + Установить значение из глобального словаря настроек Оркестратора GSettings по списку ключей. + + Пример: Для того, чтобы установить значение для ключа car в словаре {"complex":{"car":"green"}, "simple":"HELLO"}, необходимо передать список ключей: ["complex", "car"] - :param inGSettings: Global settings dict (singleton) - :param inValue: - :param inKeyList: - :return: bool + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inValue: Значение для установки в глобальный словарь настроек Оркестратора GSettings + :param inKeyList: Список ключей, по адресу которого установить значение в GSettings """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inKeyList is None: inKeyList = [] @@ -1206,11 +1234,11 @@ def GSettingsKeyListValueSet(inValue, inKeyList=None, inGSettings = None): def GSettingsKeyListValueGet(inKeyList=None, inGSettings = None): """ - Get the value from the GSettings by the key list + Получить значение из глобального словаря настроек Оркестратора GSettings по списку ключей. - :param inGSettings: Global settings dict (singleton) - :param inKeyList: - :return: value any type + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inKeyList: Список ключей, по адресу которого получить значение из GSettings + :return: Значение (тип данных определяется форматом хранения в GSettings) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inKeyList is None: inKeyList = [] @@ -1226,11 +1254,11 @@ def GSettingsKeyListValueGet(inKeyList=None, inGSettings = None): def GSettingsKeyListValueAppend(inValue, inKeyList=None, inGSettings = None): """ - Append value in GSettings by the key list + Применить операцию .append к обьекту, расположенному по адресу списка ключей inKeyList в глобальном словаре настроек Оркестратора GSettings. Пример: Добавить значение в конец списка (list). .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.GSettingsKeyListValueAppend( @@ -1246,10 +1274,9 @@ def GSettingsKeyListValueAppend(inValue, inKeyList=None, inGSettings = None): # } #} - :param inGSettings: Global settings dict (singleton) - :param inValue: Any value to be appended in gSettings Dict by the key list - :param inKeyList: List of the nested keys (see example) - :return: True every time + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inValue: Значение для установки в глобальный словарь настроек Оркестратора GSettings + :param inKeyList: Список ключей, по адресу которого выполнить добавление в конец списка (list) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inKeyList is None: inKeyList = [] @@ -1266,11 +1293,11 @@ def GSettingsKeyListValueAppend(inValue, inKeyList=None, inGSettings = None): def GSettingsKeyListValueOperatorPlus(inValue, inKeyList=None, inGSettings = None): """ - Execute plus operation between 2 lists (1:inValue and 2:gSettings by the inKeyList) + Применить оператор сложения (+) к обьекту, расположенному по адресу списка ключей inKeyList в глобальном словаре настроек Оркестратора GSettings. Пример: соединить 2 списка (list). .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.GSettingsKeyListValueOperatorPlus( @@ -1289,10 +1316,9 @@ def GSettingsKeyListValueOperatorPlus(inValue, inKeyList=None, inGSettings = Non # } #} - :param inGSettings: Global settings dict (singleton) - :param inValue: List with values to be merged with list in gSettings - :param inKeyList: List of the nested keys (see example) - :return: True every time + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inValue: Значение для установки в глобальный словарь настроек Оркестратора GSettings + :param inKeyList: Список ключей, по адресу которого выполнить добавление в конец списка (list) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inKeyList is None: inKeyList = [] @@ -1309,19 +1335,19 @@ def GSettingsKeyListValueOperatorPlus(inValue, inKeyList=None, inGSettings = Non def StorageRobotExists(inRobotNameStr): """ - Check if robot storage exists + Проверить, существует ли ключ inRobotNameStr в хранилище пользовательской информации StorageDict (GSettings > StarageDict) - :param inRobotNameStr: Robot name (case sensitive) - :return: True - robot storage exist; False - does not exist + :param inRobotNameStr: Наименование (ключ) робота. !ВНИМАНИЕ! Наименование чувствительно к регистру + :return: True - ключ робота присутствует в хранилище; False - отсутствует """ return inRobotNameStr in GSettingsGet()["StorageDict"] def StorageRobotGet(inRobotNameStr): """ - Get the robot storage by the robot name. If Robot storage is not exist - function will create it + Получить содержимое по ключу робота inRobotNameStr в хранилище пользовательской информации StorageDict (GSettings > StarageDict) - :param inRobotNameStr: Robot name (case sensitive) - :return: Dict + :param inRobotNameStr: Наименование (ключ) робота. !ВНИМАНИЕ! Наименование чувствительно к регистру + :return: Значение или структура, которая расположена по адресу (GSettings > StarageDict > inRobotNameStr) """ if inRobotNameStr not in GSettingsGet()["StorageDict"]: GSettingsGet()["StorageDict"][inRobotNameStr]={} @@ -1329,9 +1355,9 @@ def StorageRobotGet(inRobotNameStr): def ProcessorAliasDefCreate(inDef, inAliasStr=None, inGSettings = None): """ - 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 can't transmit Python def object out of the Python environment) - Deprecated. See ActivityItemDefAliasCreate + Создать синоним (текстовый ключ) для инициации выполнения функции в том случае, если запрос на выполнения пришел из вне (передача функций невозможна). + + Старая версия. Новую версию см. ActivityItemDefAliasCreate .. code-block:: python @@ -1346,18 +1372,19 @@ def ProcessorAliasDefCreate(inDef, inAliasStr=None, inGSettings = None): inAliasStr="TestDefAlias") # Now you can call TestDef by the alias from var lAliasStr with help of ActivityItem (key Def = lAliasStr) - :param inGSettings: Global settings dict (singleton) - :param inDef: Def - :param inAliasStr: String alias for associated def - :return: str Alias string (Alias can be regenerated if previous alias was occupied) + + :param inDef: функция Python + :param inAliasStr: Строковый ключ (синоним), который можно будет использовать в Активности (ActivityItem) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: Строковый ключ, который был назначен. Ключ может быть изменен, если входящий текстовый ключ был уже занят. """ return ActivityItemDefAliasCreate(inDef=inDef, inAliasStr=inAliasStr, inGSettings = inGSettings) def ProcessorAliasDefUpdate(inDef, inAliasStr, inGSettings = None): """ - Update 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 can't transmit Python def object out of the Python environment) - Deprecated. See ActivityItemDefAliasUpdate + Обновить синоним (текстовый ключ) для инициации выполнения функции в том случае, если запрос на выполнения пришел из вне (передача функций невозможна). + + Старая версия. Новую версию см. ActivityItemDefAliasUpdate .. code-block:: python @@ -1372,20 +1399,20 @@ def ProcessorAliasDefUpdate(inDef, inAliasStr, inGSettings = None): inAliasStr="TestDefAlias") # Now you can call TestDef by the alias "TestDefAlias" with help of ActivityItem (key Def = "TestDefAlias") - :param inGSettings: Global settings dict (singleton) - :param inDef: Def - :param inAliasStr: String alias for associated def - :return: str Alias string + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inDef: функция Python + :param inAliasStr: Строковый ключ (синоним), который можно будет использовать в Активности (ActivityItem) + :return: Строковый ключ, который был назначен. Ключ будет тем же, если входящий текстовый ключ был уже занят. """ return ActivityItemDefAliasUpdate(inDef=inDef, inAliasStr=inAliasStr, inGSettings = inGSettings) # ActivityItem defs def ActivityItemHelperDefList(inDefQueryStr=None): """ - Create list of the available Def names in activity item. You can use query def filter via arg inDefQueryStr + Получить список синонимов (текстовых ключей), доступных для использования в Активностях (ActivityItem). - :param inDefStr: - :return: ["ActivityItemDefAliasUpdate", "ActivityItemDefAliasCreate", etc...] + :param inDefStr: Часть текстового ключ (начало / середина / конец) + :return: Список доступных ключей в формате: ["ActivityItemDefAliasUpdate", "ActivityItemDefAliasCreate", etc...] """ lResultList = [] if inDefQueryStr is not None: # do search alg @@ -1399,10 +1426,17 @@ def ActivityItemHelperDefList(inDefQueryStr=None): def ActivityItemHelperDefAutofill(inDef): """ - Detect def by the name and prepare the activity item dict with values. + Анализ аргументов функции по синониму (текстовому ключу). - :param inDef: - :return: + :param inDef: Часть текстового ключ (начало / середина / конец) + :return: Преднастроенная структура активности (ActivityItem) + { + "Def": None, + "ArgList": [], + "ArgDict": {}, + "ArgGSettingsStr": None, + "ArgLoggerStr": None + } """ lResultDict = { "Def": None, @@ -1431,14 +1465,14 @@ def ActivityItemHelperDefAutofill(inDef): def ActivityItemCreate(inDef, inArgList=None, inArgDict=None, inArgGSettingsStr=None, inArgLoggerStr=None, inGUIDStr = None, inThreadBool = False): """ - Create activity item. Activity item can be used as list item in ProcessorActivityItemAppend or in Processor.ActivityListExecute. + Создать Активность (ActivityItem). Активность можно использовать в ProcessorActivityItemAppend или в Processor.ActivityListExecute или в функциях работы с Агентами. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator - # EXAMPLE 1 + # ВАРИАНТ 1 def TestDef(inArg1Str, inGSettings, inLogger): pass lActivityItem = Orchestrator.ActivityItemCreate( @@ -1456,7 +1490,7 @@ def ActivityItemCreate(inDef, inArgList=None, inArgDict=None, inArgGSettingsStr= # "ArgLogger": "inLogger" # } - # EXAMPLE 2 + # ВАРИАНТ 2 def TestDef(inArg1Str): pass Orchestrator.ActivityItemDefAliasUpdate( @@ -1478,14 +1512,23 @@ def ActivityItemCreate(inDef, inArgList=None, inArgDict=None, inArgGSettingsStr= # "ArgLogger": None # } - :param inDef: def link or def alias (look gSettings["Processor"]["AliasDefDict"]) - :param inArgList: Args list for the Def - :param inArgDict: Args dict for the def - :param inArgGSettingsStr: Name of def argument of the GSettings dict - :param inArgLoggerStr: Name of def argument of the logging object - :param inGUIDStr: GUID which you can specify. If None the GUID will be generated - :param inThreadBool: True - execute ActivityItem in new thread; False - in processor thread - :return: {} + :param inDef: Функция Python или синоним (текстовый ключ) + :param inArgList: Список (list) неименованных аргументов к функции + :param inArgDict: Словарь (dict) именованных аргументов к функции + :param inArgGSettingsStr: Текстовое наименование аргумента GSettings (если требуется передавать) + :param inArgLoggerStr: Текстовое наименование аргумента logger (если требуется передавать) + :param inGUIDStr: ГУИД идентификатор активности (ActivityItem). Если ГУИД не указан, то он будет сгенерирован автоматически + :param inThreadBool: True - выполнить ActivityItem в новом потоке; False - выполнить последовательно в общем потоке процессорной очереди + :return: + lActivityItemDict= { + "Def":inDef, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "ArgList":inArgList, # Args list + "ArgDict":inArgDict, # Args dictionary + "ArgGSettings": inArgGSettingsStr, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": inArgLoggerStr, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "GUIDStr": inGUIDStr, + "ThreadBool": inThreadBool + } """ # Work about GUID in Activity items if inGUIDStr is None: @@ -1506,12 +1549,11 @@ def ActivityItemCreate(inDef, inArgList=None, inArgDict=None, inArgGSettingsStr= def ActivityItemDefAliasCreate(inDef, inAliasStr=None, inGSettings = None): """ - 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 can't transmit Python def object out of the Python environment) - + Создать синоним (текстовый ключ) для инициации выполнения функции в том случае, если запрос на выполнения пришел из вне (передача функций невозможна). + .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator def TestDef(): @@ -1522,10 +1564,10 @@ def ActivityItemDefAliasCreate(inDef, inAliasStr=None, inGSettings = None): inAliasStr="TestDefAlias") # Now you can call TestDef by the alias from var lAliasStr with help of ActivityItem (key Def = lAliasStr) - :param inGSettings: Global settings dict (singleton) - :param inDef: Def - :param inAliasStr: String alias for associated def - :return: str Alias string (Alias can be regenerated if previous alias was occupied) + :param inDef: функция Python + :param inAliasStr: Строковый ключ (синоним), который можно будет использовать в Активности (ActivityItem) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: Строковый ключ, который был назначен. Ключ может быть изменен, если входящий текстовый ключ был уже занят. """ #TODO Pay attention - New alias can be used too - need to create more complex algorythm to create new alias! inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -1540,9 +1582,7 @@ def ActivityItemDefAliasCreate(inDef, inAliasStr=None, inGSettings = None): def ActivityItemDefAliasModulesLoad(): """ - Load all def from sys.modules... in ActivityItem def alias dict - - :return: None + Загрузить все функции из импортированных модулей sys.modules в ActivityItem синонимы - полезно для отладки со стороны панели управления. """ lL = OrchestratorLoggerGet() lL.info(f"ActivityItem aliases: start to load sys.modules") @@ -1560,9 +1600,8 @@ def ActivityItemDefAliasModulesLoad(): def ActivityItemDefAliasUpdate(inDef, inAliasStr, inGSettings = None): """ - Update 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 can't transmit Python def object out of the Python environment) - + Обновить синоним (текстовый ключ) для инициации выполнения функции в том случае, если запрос на выполнения пришел из вне (передача функций невозможна). + .. code-block:: python # USAGE @@ -1576,10 +1615,10 @@ def ActivityItemDefAliasUpdate(inDef, inAliasStr, inGSettings = None): inAliasStr="TestDefAlias") # Now you can call TestDef by the alias "TestDefAlias" with help of ActivityItem (key Def = "TestDefAlias") - :param inGSettings: Global settings dict (singleton) - :param inDef: Def - :param inAliasStr: String alias for associated def - :return: str Alias string + :param inDef: функция Python + :param inAliasStr: Строковый ключ (синоним), который можно будет использовать в Активности (ActivityItem) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: Строковый ключ, который был назначен. Ключ будет тем же, если входящий текстовый ключ был уже занят. """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if callable(inDef): inGSettings["ProcessorDict"]["AliasDefDict"][inAliasStr] = inDef @@ -1590,14 +1629,16 @@ def ActivityItemDefAliasUpdate(inDef, inAliasStr, inGSettings = None): def ProcessorActivityItemCreate(inDef, inArgList=None, inArgDict=None, inArgGSettingsStr=None, inArgLoggerStr=None, inGUIDStr = None, inThreadBool = False): """ - Create activity item. Activity item can be used as list item in ProcessorActivityItemAppend or in Processor.ActivityListExecute. - Deprecated. See ActivityItemCreate + Создать Активность (ActivityItem). Активность можно использовать в ProcessorActivityItemAppend или в Processor.ActivityListExecute или в функциях работы с Агентами. + + Старая версия. Новую версию см. в ActivityItemCreate + .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator - # EXAMPLE 1 + # ВАРИАНТ 1 def TestDef(inArg1Str, inGSettings, inLogger): pass lActivityItem = Orchestrator.ProcessorActivityItemCreate( @@ -1615,7 +1656,7 @@ def ProcessorActivityItemCreate(inDef, inArgList=None, inArgDict=None, inArgGSet # "ArgLogger": "inLogger" # } - # EXAMPLE 2 + # ВАРИАНТ 2 def TestDef(inArg1Str): pass Orchestrator.ProcessorAliasDefUpdate( @@ -1637,22 +1678,31 @@ def ProcessorActivityItemCreate(inDef, inArgList=None, inArgDict=None, inArgGSet # "ArgLogger": None # } - :param inDef: def link or def alias (look gSettings["Processor"]["AliasDefDict"]) - :param inArgList: Args list for the Def - :param inArgDict: Args dict for the def - :param inArgGSettingsStr: Name of def argument of the GSettings dict - :param inArgLoggerStr: Name of def argument of the logging object - :param inGUIDStr: GUID which you can specify. If None the GUID will be generated - :param inThreadBool: True - execute ActivityItem in new thread; False - in processor thread - :return: {} + :param inDef: Функция Python или синоним (текстовый ключ) + :param inArgList: Список (list) неименованных аргументов к функции + :param inArgDict: Словарь (dict) именованных аргументов к функции + :param inArgGSettingsStr: Текстовое наименование аргумента GSettings (если требуется передавать) + :param inArgLoggerStr: Текстовое наименование аргумента logger (если требуется передавать) + :param inGUIDStr: ГУИД идентификатор активности (ActivityItem). Если ГУИД не указан, то он будет сгенерирован автоматически + :param inThreadBool: True - выполнить ActivityItem в новом потоке; False - выполнить последовательно в общем потоке процессорной очереди + :return: + lActivityItemDict= { + "Def":inDef, # def link or def alias (look gSettings["Processor"]["AliasDefDict"]) + "ArgList":inArgList, # Args list + "ArgDict":inArgDict, # Args dictionary + "ArgGSettings": inArgGSettingsStr, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "ArgLogger": inArgLoggerStr, # Name of GSettings attribute: str (ArgDict) or index (for ArgList) + "GUIDStr": inGUIDStr, + "ThreadBool": inThreadBool + } """ return ActivityItemCreate(inDef=inDef, inArgList=inArgList, inArgDict=inArgDict, inArgGSettingsStr=inArgGSettingsStr, inArgLoggerStr=inArgLoggerStr, inGUIDStr=inGUIDStr, inThreadBool=inThreadBool) def ProcessorActivityItemAppend(inGSettings = None, inDef=None, inArgList=None, inArgDict=None, inArgGSettingsStr=None, inArgLoggerStr=None, inActivityItemDict=None): """ - Create and add activity item in processor queue. - + Добавить активность (ActivityItem) в процессорную очередь. + .. code-block:: python # USAGE @@ -1688,14 +1738,16 @@ def ProcessorActivityItemAppend(inGSettings = None, inDef=None, inArgList=None, inActivityItemDict = lActivityItem) # Activity have been already append in the processor queue - :param inGSettings: Global settings dict (singleton) - :param inDef: def link or def alias (look gSettings["Processor"]["AliasDefDict"]) - :param inArgList: Args list for the Def - :param inArgDict: Args dict for the Def - :param inArgGSettingsStr: Name of def argument of the GSettings dict - :param inArgLoggerStr: Name of def argument of the logging object - :param inActivityItemDict: Fill if you already have ActivityItemDict (don't fill inDef, inArgList, inArgDict, inArgGSettingsStr, inArgLoggerStr) - :return ActivityItem GUIDStr + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inDef: Функция Python или синоним (текстовый ключ) + :param inArgList: Список (list) неименованных аргументов к функции + :param inArgDict: Словарь (dict) именованных аргументов к функции + :param inArgGSettingsStr: Текстовое наименование аргумента GSettings (если требуется передавать) + :param inArgLoggerStr: Текстовое наименование аргумента logger (если требуется передавать) + :param inGUIDStr: ГУИД идентификатор активности (ActivityItem). Если ГУИД не указан, то он будет сгенерирован автоматически + :param inThreadBool: True - выполнить ActivityItem в новом потоке; False - выполнить последовательно в общем потоке процессорной очереди + :param inActivityItemDict: Альтернативный вариант заполнения, если уже имеется Активность (ActivityItem). В таком случае не требуется заполнять аргументы inDef, inArgList, inArgDict, inArgGSettingsStr, inArgLoggerStr + :return ГУИД активности (ActivityItem) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inActivityItemDict is None: @@ -1727,18 +1779,20 @@ def ProcessorActivityItemAppend(inGSettings = None, inDef=None, inArgList=None, ## Process defs def ProcessIsStarted(inProcessNameWOExeStr): # Check if process is started """ - Check if there is any running process that contains the given name processName. + Проверить, запущен ли процесс, который в наименовании содержит inProcessNameWOExeStr. + !ВНИМАНИЕ! ПРОВЕРЯЕТ ВСЕ ПРОЦЕССЫ ОПЕРАЦИОННОЙ СИСТЕМЫ. И ДРУГИХ ПОЛЬЗОВАТЕЛЬСКИХ СЕССИЙ, ЕСЛИ ОНИ ЗАПУЩЕНЫ НА ЭТОЙ МАШИНЕ. + .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lProcessIsStartedBool = Orchestrator.ProcessIsStarted(inProcessNameWOExeStr = "notepad") # lProcessIsStartedBool is True - notepad.exe is running on the Orchestrator machine - :param inProcessNameWOExeStr: Process name WithOut (WO) '.exe' postfix. Example: "notepad" (not "notepad.exe") - :return: True - process is running on the orchestrator machine; False - process is not running on the orchestrator machine + :param inProcessNameWOExeStr: Наименование процесса без расширения .exe (WO = WithOut = Без) Пример: Для проверки процесса блокнота нужно указывать "notepad", не "notepad.exe" + :return: True - Процесс запущен на ОС ; False - Процесс не запущен на ОС, где работает Оркестратор """ #Iterate over the all the running process for proc in psutil.process_iter(): @@ -1752,11 +1806,13 @@ def ProcessIsStarted(inProcessNameWOExeStr): # Check if process is started def ProcessStart(inPathStr, inArgList, inStopProcessNameWOExeStr=None): """ - Start process locally. Extra feature: Use inStopProcessNameWOExeStr to stop the execution if current process is running. + Запуск процесса на сессии Оркестратора, если на ОС не запущен процесс inStopProcessNameWOExeStr. + + !ВНИМАНИЕ! ПРИ ПРОВЕРКЕ РАНЕЕ ЗАПУЩЕННЫХ ПРОЦЕССОВ ПРОВЕРЯЕТ ВСЕ ПРОЦЕССЫ ОПЕРАЦИОННОЙ СИСТЕМЫ. И ДРУГИХ ПОЛЬЗОВАТЕЛЬСКИХ СЕССИЙ, ЕСЛИ ОНИ ЗАПУЩЕНЫ НА ЭТОЙ МАШИНЕ. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.ProcessStart( @@ -1765,10 +1821,9 @@ def ProcessStart(inPathStr, inArgList, inStopProcessNameWOExeStr=None): inStopProcessNameWOExeStr = "notepad") # notepad.exe will be started if no notepad.exe is active on the machine - :param inPathStr: Command to send in CMD - :param inArgList: List of the arguments for the CMD command. Example: ["test.txt"] - :param inStopProcessNameWOExeStr: Trigger: stop execution if process is running. Process name WithOut (WO) '.exe' postfix. Example: "notepad" (not "notepad.exe") - :return: None - nothing is returned. If process will not start -exception will be raised + :param inPathStr: Путь к файлу запускаемого процесса + :param inArgList: Список аргументов, передаваемых в запускаемый процесс. Пример: ["test.txt"] + :param inStopProcessNameWOExeStr: Доп. контроль: Не запускать процесс, если обнаружен запущенный процесс под наименованием inStopProcessNameWOExeStr без расширения .exe (WO = WithOut = Без) """ lStartProcessBool = True if inStopProcessNameWOExeStr is not None: #Check if process running @@ -1789,11 +1844,11 @@ def ProcessStart(inPathStr, inArgList, inStopProcessNameWOExeStr=None): def ProcessStop(inProcessNameWOExeStr, inCloseForceBool, inUserNameStr = "%username%"): """ - Stop process on the orchestrator machine. You can set user session on the machine and set flag about to force close process. + Остановить процесс на ОС, где работает Оркестратор, под учетной записью inUserNameStr. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.ProcessStop( @@ -1802,10 +1857,9 @@ def ProcessStop(inProcessNameWOExeStr, inCloseForceBool, inUserNameStr = "%usern inUserNameStr = "USER_99") # Will close process "notepad.exe" on the user session "USER_99" (!ATTENTION! if process not exists no exceptions will be raised) - :param inProcessNameWOExeStr: Process name WithOut (WO) '.exe' postfix. Example: "notepad" (not "notepad.exe") - :param inCloseForceBool: True - do force close. False - send signal to safe close (!ATTENTION! - Safe close works only in orchestrator session. Win OS doens't allow to send safe close signal between GUI sessions) - :param inUserNameStr: User name which is has current process to close. Default value is close process on the Orchestrator session - :return: None + :param inProcessNameWOExeStr: Наименование процесса без расширения .exe (WO = WithOut = Без). Пример: Для проверки процесса блокнота нужно указывать "notepad", не "notepad.exe" + :param inCloseForceBool: True - принудительно завершить процесс. False - отправить сигнал на безопасное отключение (!ВНИМАНИЕ! - ОС не позволяет отправлять сигнал на безопасное отключение на другую сесиию - только на той, где работает Оркестратор) + :param inUserNameStr: Наименование пользователя, под именем которого искать процесс для остановки. По умолчанию "%username%" - искать процесс на текущей сессии """ # Support input arg if with .exe lProcessNameWExeStr = inProcessNameWOExeStr @@ -1826,30 +1880,32 @@ def ProcessStop(inProcessNameWOExeStr, inCloseForceBool, inUserNameStr = "%usern def ProcessListGet(inProcessNameWOExeList=None): """ - Return process list on the orchestrator machine sorted by Memory Usage. You can determine the list of the processes you are interested - def will return the list about it. + Вернуть список процессов, запущенных на ОС, где работает Оркестратор. В списке отсортировать процессы по количеству используемой оперативной памяти. Также можно указать перечень процессов, которые интересуют - функция будет показывать активные из них. + + !ВНИМАНИЕ! ДЛЯ ПОЛУЧЕНИЯ СПИСКА ВСЕХ ПРОЦЕССОВ ОС НЕОБХОДИМО ЗАПУСКАТЬ ОРКЕСТРАТОР С ПРАВАМИ АДМИНИСТРАТОРА. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lProcessList = Orchestrator.ProcessListGet() # Return the list of the process on the machine. # !ATTENTION! RUn orchestrator as administrator to get all process list on the machine. - :param inProcessNameWOExeList: - :return: { - "ProcessWOExeList": ["notepad","..."], - "ProcessWOExeUpperList": ["NOTEPAD","..."], - "ProcessDetailList": [ - { - 'pid': 412, - 'username': "DESKTOP\\USER", - 'name': 'notepad.exe', - 'vms': 13.77767775, - 'NameWOExeUpperStr': 'NOTEPAD', - 'NameWOExeStr': "'notepad'"}, - {...}] + :param inProcessNameWOExeList: Список процессов, среди которых искать активные. Если параметр не указывать - вернет перечень всех доступных процессов + :return: Сведения о запущенных процессах в следующем формате { + "ProcessWOExeList": ["notepad","..."], + "ProcessWOExeUpperList": ["NOTEPAD","..."], + "ProcessDetailList": [ + { + 'pid': 412, # Идентификатор процесса + 'username': "DESKTOP\\USER", + 'name': 'notepad.exe', + 'vms': 13.77767775, # В Мб + 'NameWOExeUpperStr': 'NOTEPAD', + 'NameWOExeStr': "'notepad'"}, + {...}] """ if inProcessNameWOExeList is None: inProcessNameWOExeList = [] @@ -1884,19 +1940,18 @@ def ProcessListGet(inProcessNameWOExeList=None): def ProcessDefIntervalCall(inDef, inIntervalSecFloat, inIntervalAsyncBool=False, inDefArgList=None, inDefArgDict=None, inDefArgGSettingsNameStr=None, inDefArgLoggerNameStr=None, inExecuteInNewThreadBool=True, inLogger=None, inGSettings = None): """ - Use this procedure if you need to run periodically some def. Set def, args, interval and enjoy :) - - :param inGSettings: global settings - :param inDef: def link, which will be called with interval inIntervalSecFloat - :param inIntervalSecFloat: Interval in seconds between call - :param inIntervalAsyncBool: False - wait interval before next call after the previous iteration result; True - wait interval after previous iteration call - :param inDefArgList: List of the args in def. Default None (empty list) - :param inDefArgDict: Dict of the args in def. Default None (empty dict) - :param inDefArgGSettingsNameStr: Name of the GSettings arg name for def (optional) - :param inDefArgLoggerNameStr: Name of the Logger arg name for def (optional). If Use - please check fill of the inLogger arg. - :param inExecuteInNewThreadBool: True - create new thread for the periodic execution; False - execute in current thread. Default: True - :param inLogger: logging def if some case is appear - :return: + Периодический вызов функции Python. + + :param inDef: Функция Python, которую потребуется периодически вызывать + :param inIntervalSecFloat: Интервал между вызовами функции в сек. + :param inIntervalAsyncBool: False - ожидать интервал inIntervalSecFloat только после окончания выполнения предыдущей итерации; True - Ожидать интервал сразу после запуска итерации + :param inDefArgList: Список (list) неименованных аргументов для передачи в функцию. По умолчанию None + :param inDefArgDict: Словарь (dict) именованных аргументов для передачи в функцию. По умолчанию None + :param inDefArgGSettingsNameStr: Наименование аргумента глобального словаря настроек Оркестратора GSettings (опционально) + :param inDefArgLoggerNameStr: Наименование аргумента логгера Оркестратора (опционально) + :param inExecuteInNewThreadBool: True - периодический вызов выполнять в отдельном потоке (не останавливать выполнение текущего потока); False - Выполнение периодического вызова в текущем потоке, в котором была вызвана функция ProcessDefIntervalCall. По умолчанию: True + :param inLogger: Логгер для фиксации сообщений выполнения функции (опционально) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inLogger is None: inLogger = OrchestratorLoggerGet() @@ -1965,15 +2020,15 @@ def ProcessDefIntervalCall(inDef, inIntervalSecFloat, inIntervalAsyncBool=False, # Python def - start module function def PythonStart(inModulePathStr, inDefNameStr, inArgList=None, inArgDict=None, inLogger = None): """ - Import module and run def in the Orchestrator process. + Импорт модуля и выполнение функции в процессе Оркестратора. .. note:: - Import module will be each time when PythonStart def will be called. + Импорт модуля inModulePathStr будет происходить каждый раз в вызовом функции PythonStart. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.PythonStart( @@ -1981,12 +2036,11 @@ def PythonStart(inModulePathStr, inDefNameStr, inArgList=None, inArgDict=None, i inDefNameStr="TestDef") # Import module in Orchestrator process and call def "TestDef" from module "ModuleToCall.py" - :param inModulePathStr: Absolute or relative (working directory of the orchestrator process) path to the importing module .py - :param inDefNameStr: Def name in module - :param inArgList: List of the arguments for callable def - :param inArgDict: Dict of the named arguments for callable def - :param inLogger: Logger instance to log some information when PythonStart def is running - :return: None + :param inModulePathStr: Абсолютный или относительный путь (относительно рабочей директории процесса Оркестратора), по которому расположен импортируемый .py файл + :param inDefNameStr: Наименование функции в модуле .py + :param inArgList: Список (list) неименованных аргументов для передачи в функцию. По умолчанию None + :param inArgDict: Словарь (dict) именованных аргументов для передачи в функцию. По умолчанию None + :param inLogger: Логгер для фиксации сообщений выполнения функции (опционально) """ if inLogger is None: inLogger = OrchestratorLoggerGet() if inArgList is None: inArgList=[] @@ -2001,17 +2055,16 @@ def PythonStart(inModulePathStr, inDefNameStr, inArgList=None, inArgDict=None, i # # # # # # # # # # # # # # # # # # # # # # # # Scheduler # # # # # # # # # # # # # # # # # # # # # # # - def SchedulerActivityTimeAddWeekly(inTimeHHMMStr="23:55:", inWeekdayList=None, inActivityList=None, inGSettings = None): """ - Add activity item list in scheduler. You can set weekday list and set time when launch. Activity list will be executed at planned time/day. + Добавить активность по расписанию. Допускается указание времени и дней недели, в которые производить запуск. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator - # EXAMPLE 1 + # ВАРИАНТ 1 def TestDef(inArg1Str): pass lActivityItem = Orchestrator.ProcessorActivityItemCreate( @@ -2027,11 +2080,10 @@ def SchedulerActivityTimeAddWeekly(inTimeHHMMStr="23:55:", inWeekdayList=None, i inActivityList = [lActivityItem]) # Activity will be executed at 04:34 Wednesday (2), thursday (3), friday (4) - :param inGSettings: Global settings dict (singleton) - :param inTimeHHMMStr: Activation time from "00:00" to "23:59". Example: "05:29" - :param inWeekdayList: Week day list to initiate activity list. Use int from 0 (monday) to 6 (sunday) as list items. Example: [0,1,2,3,4]. Default value is everyday ([0,1,2,3,4,5,6]) - :param inActivityList: Activity list structure - :return: None + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inTimeHHMMStr: Время запуска активности. Допускаются значения от "00:00" до "23:59". Example: "05:29" + :param inWeekdayList: Список (list) дней недели, в которые выполнять запуск список активностей (ActivityItem list). 0 (понедельник) - 6 (воскресенье). Пример: [0,1,2,3,4]. По умолчанию устанавливается каждый день [0,1,2,3,4,5,6] + :param inActivityList: Список активностей (ActivityItem list) на исполнение """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inWeekdayList is None: inWeekdayList=[0,1,2,3,4,5,6] @@ -2052,11 +2104,11 @@ def SchedulerActivityTimeAddWeekly(inTimeHHMMStr="23:55:", inWeekdayList=None, i def RDPTemplateCreate(inLoginStr, inPasswordStr, inHostStr="127.0.0.1", inPortInt = 3389, inWidthPXInt = 1680, inHeightPXInt = 1050, inUseBothMonitorBool = False, inDepthBitInt = 32, inSharedDriveList=None, inRedirectClipboardBool=True): """ - Create RDP connect dict item/ Use it connect/reconnect (Orchestrator.RDPSessionConnect) + Создать шаблон подключения RDP (dict). Данный шаблон далее можно использовать в Orchestrator.RDPSessionConnect .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lRDPItemDict = Orchestrator.RDPTemplateCreate( @@ -2068,49 +2120,38 @@ def RDPTemplateCreate(inLoginStr, inPasswordStr, inHostStr="127.0.0.1", inPortIn inHeightPXInt = 1050, inUseBothMonitorBool = False, inDepthBitInt = 32, - inSharedDriveList=None) - # lRDPTemplateDict= { # Init the configuration item - # "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 - # } - - :param inLoginStr: User/Robot Login, example "USER_99" - :param inPasswordStr: Password, example "USER_PASS_HERE" - :param inHostStr: Host address, example "77.77.22.22" - :param inPortInt: RDP Port, example "3389" (default) - :param inWidthPXInt: Width of the remote desktop in pixels, example 1680 - :param inHeightPXInt: Height of the remote desktop in pixels, example 1050 - :param inUseBothMonitorBool: True - connect to the RDP with both monitors. False - else case - :param inDepthBitInt: Remote desktop bitness. Available: 32 or 24 or 16 or 15, example 32 - :param inSharedDriveList: Host local disc to connect to the RDP session. Example: ["c", "d"] - :param inRedirectClipboardBool: # True - share clipboard to RDP; False - else + inSharedDriveList=None, + inRedirectClipboardBool=False) + + :param inLoginStr: Логин учетной записи, на которую будет происходить вход по RDP + :param inPasswordStr: Пароль учетной записи, на которую будет происходить вход по RDP. !ВНИМАНИЕ! Пароль нигде не сохраняется - конфиденциальность обеспечена + :param inHostStr: Имя хоста, к которому планируется подключение по RDP. Пример "77.77.22.22" + :param inPortInt: RDP порт, по которому будет происходить подключение. По умолчанию 3389 (стандартный порт RDP) + :param inWidthPXInt: Разрешение ширины RDP графической сессии в пикселях. По умолчанию 1680 + :param inHeightPXInt: Разрешение высоты RDP графической сессии в пикселях. По умолчанию 1050 + :param inUseBothMonitorBool: True - Использовать все подключенные мониторы на RDP сессии; False - Использовать только один монитор на подключенной RDP сессии + :param inDepthBitInt: Глубина цвета на удаленной RDP графической сессии. Допустимые варианты: 32 || 24 || 16 || 15. По умолчанию 32 + :param inSharedDriveList: Перечень общих дисков, доступ к которым предоставить на сторону удаленной RDP сессии. Пример: ["c", "d"] + :param inRedirectClipboardBool: True - Синхронизировать буфер обмена между сессией Оркестратора и удаленной RDP сессией; False - Не синхронизировать буфер обмена. По умолчанию True (в целях обратной совместимости). !ВНИМАНИЕ! Для учетных записей роботов мы рекомендуем не синхронизировать буфер обмена, так как это может привести к ошибкам роботов, которые работают с клавиатурой и буфером обмена :return: { - "Host": inHostStr, # Host address, example "77.77.22.22" - "Port": str(inPortInt), # RDP Port, example "3389" - "Login": inLoginStr, # Login, example "test" - "Password": inPasswordStr, # Password, example "test" + "Host": inHostStr, # Адрес хоста, пример "77.77.22.22" + "Port": str(inPortInt), # RDP порт, пример "3389" + "Login": inLoginStr, # Логин УЗ, пример "test" + "Password": inPasswordStr, # Пароль УЗ, пример "test" "Screen": { - "Width": inWidthPXInt, # Width of the remote desktop in pixels, example 1680 - "Height": inHeightPXInt, # Height of the remote desktop in pixels, example 1050 - # "640x480" or "1680x1050" or "FullScreen". If Resolution not exists set full screen, example - "FlagUseAllMonitors": inUseBothMonitorBool, # True or False, example False - "DepthBit": str(inDepthBitInt) # "32" or "24" or "16" or "15", example "32" + "Width": inWidthPXInt, # Разрешение ширины RDP графической сессии в пикселях. По умолчанию 1680 + "Height": inHeightPXInt, Разрешение высоты RDP графической сессии в пикселях. По умолчанию 1050 + "FlagUseAllMonitors": inUseBothMonitorBool, + "DepthBit": str(inDepthBitInt) }, - "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 "" + "SharedDriveList": inSharedDriveList, + "RedirectClipboardBool": True, + ###### PROGRAM VARIABLE ############ + "SessionHex": "77777sdfsdf77777dsfdfsf77777777", "SessionIsWindowExistBool": False, - # Flag if the RDP window is exist, old name "FlagSessionIsActive". Check every n seconds , example False "SessionIsWindowResponsibleBool": False, - # Flag if RDP window is responsible (recieve commands). Check every nn seconds. If window is Responsible - window is Exist too , example False - "SessionIsIgnoredBool": False # Flag to ignore RDP window False - dont ignore, True - ignore, example False + "SessionIsIgnoredBool": False } """ @@ -2144,27 +2185,22 @@ def RDPTemplateCreate(inLoginStr, inPasswordStr, inHostStr="127.0.0.1", inPortIn # TODO Search dublicates in GSettings RDPlist ! # Return list if dublicates def RDPSessionDublicatesResolve(inGSettings): - """ - DEVELOPING Search duplicates in GSettings RDPlist - !def is developing! - - :param inGSettings: Global settings dict (singleton) - :return: - """ pass #for lItemKeyStr in inGSettings["RobotRDPActive"]["RDPList"]: # lItemDict = inGSettings["RobotRDPActive"]["RDPList"][lItemKeyStr] def RDPSessionConnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inHostStr=None, inPortStr=None, inLoginStr=None, inPasswordStr=None, inGSettings = None, inRedirectClipboardBool=True): """ - Create new RDPSession in RobotRDPActive. Attention - activity will be ignored if RDP key is already exists - 2 way of the use - Var 1 (Main stream): inGSettings, inRDPSessionKeyStr, inRDPTemplateDict - Var 2 (Backward compatibility): inGSettings, inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPasswordStr + Выполнить подключение к RDP и следить за стабильностью соединения со стороны Оркестратора. + !ВНИМАНИЕ! - Подключение будет проигнорировано, если соединение по таком RDP ключу уже было инициализировано ранее. + + 2 способа использования функции: + ВАРИАНТ 1 (ОСНОВНОЙ): inGSettings, inRDPSessionKeyStr, inRDPTemplateDict. Для получения inRDPTemplateDict см. функцию Orchestrator.RDPTemplateCreate + ВАРИАНТ 2 (ОБРАТНАЯ СОВМЕСТИМОСТЬ ДО ВЕРСИИ 1.1.20): inGSettings, inRDPSessionKeyStr, inHostStr, inPortStr, inLoginStr, inPasswordStr .. code-block:: python - # USAGE + # ПРИМЕР (ВАРИАНТ 1) from pyOpenRPA import Orchestrator lRDPItemDict = Orchestrator.RDPTemplateCreate( @@ -2176,15 +2212,15 @@ def RDPSessionConnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inHostStr=None inRDPSessionKeyStr = "RDPKey", inRDPTemplateDict = lRDPItemDict) # Orchestrator will create RDP session by the lRDPItemDict configuration - - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inRDPTemplateDict: RDP configuration dict with settings (see def Orchestrator.RDPTemplateCreate) - :param inHostStr: Backward compatibility from Orchestrator v 1.1.20. Use inRDPTemplateDict - :param inPortStr: Backward compatibility from Orchestrator v 1.1.20. Use inRDPTemplateDict - :param inLoginStr: Backward compatibility from Orchestrator v 1.1.20. Use inRDPTemplateDict - :param inPasswordStr: Backward compatibility from Orchestrator v 1.1.20. Use inRDPTemplateDict - :return: True every time :) + + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inRDPTemplateDict: Конфигурационный словарь (dict) RDP подключения (см. функцию Orchestrator.RDPTemplateCreate) + :param inLoginStr: Логин учетной записи, на которую будет происходить вход по RDP. Обратная совместимость до версии v 1.1.20. Мы рекомендуем использовать inRDPTemplateDict (см. функцию Orchestrator.RDPTemplateCreate) + :param inPasswordStr: Пароль учетной записи, на которую будет происходить вход по RDP. !ВНИМАНИЕ! Пароль нигде не сохраняется - конфиденциальность обеспечена. Обратная совместимость до версии v 1.1.20. Мы рекомендуем использовать inRDPTemplateDict (см. функцию Orchestrator.RDPTemplateCreate) + :param inHostStr: Имя хоста, к которому планируется подключение по RDP. Пример "77.77.22.22". Обратная совместимость до версии v 1.1.20. Мы рекомендуем использовать inRDPTemplateDict (см. функцию Orchestrator.RDPTemplateCreate) + :param inPortInt: RDP порт, по которому будет происходить подключение. По умолчанию 3389 (стандартный порт RDP). Обратная совместимость до версии v 1.1.20. Мы рекомендуем использовать inRDPTemplateDict (см. функцию Orchestrator.RDPTemplateCreate) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inRedirectClipboardBool: True - Синхронизировать буфер обмена между сессией Оркестратора и удаленной RDP сессией; False - Не синхронизировать буфер обмена. По умолчанию True (в целях обратной совместимости). !ВНИМАНИЕ! Для учетных записей роботов мы рекомендуем не синхронизировать буфер обмена, так как это может привести к ошибкам роботов, которые работают с клавиатурой и буфером обмена """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check thread @@ -2217,11 +2253,11 @@ def RDPSessionConnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inHostStr=None def RDPSessionDisconnect(inRDPSessionKeyStr, inBreakTriggerProcessWOExeList = None, inGSettings = None): """ - Disconnect the RDP session and stop monitoring it. + Выполнить отключение RDP сессии и прекратить мониторить его активность. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.RDPSessionDisconnect( @@ -2229,14 +2265,9 @@ def RDPSessionDisconnect(inRDPSessionKeyStr, inBreakTriggerProcessWOExeList = No inRDPSessionKeyStr = "RDPKey") # Orchestrator will disconnect RDP session and will stop to monitoring current RDP - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inBreakTriggerProcessWOExeList: List of the processes, which will stop the execution. Example ["notepad"] - - .. note:: - - Orchestrator look processes on the current machine - :return: True every time + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inBreakTriggerProcessWOExeList: Список процессов, наличие которых в диспетчере задач приведет к прерыванию задачи по остановке RDP соединения. Пример ["notepad"] + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inBreakTriggerProcessWOExeList is None: inBreakTriggerProcessWOExeList = [] @@ -2265,11 +2296,11 @@ def RDPSessionDisconnect(inRDPSessionKeyStr, inBreakTriggerProcessWOExeList = No def RDPSessionReconnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inGSettings = None): """ - Reconnect the RDP session + Выполнить переподключение RDP сессии и продолжить мониторить его активность. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lRDPItemDict = Orchestrator.RDPTemplateCreate( @@ -2282,10 +2313,9 @@ def RDPSessionReconnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inGSettings inRDPTemplateDict = inRDPTemplateDict) # Orchestrator will reconnect RDP session and will continue to monitoring current RDP - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inRDPTemplateDict: RDP configuration dict with settings (see def Orchestrator.RDPTemplateCreate) - :return: + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inRDPTemplateDict: Конфигурационный словарь (dict) RDP подключения (см. функцию Orchestrator.RDPTemplateCreate) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check thread @@ -2312,11 +2342,11 @@ def RDPSessionReconnect(inRDPSessionKeyStr, inRDPTemplateDict=None, inGSettings def RDPSessionMonitorStop(inRDPSessionKeyStr, inGSettings = None): """ - Stop monitoring the RDP session by the Orchestrator process. Current def don't kill RDP session - only stop to track it (it can give ) - + Прекратить мониторить активность RDP соединения со стороны Оркестратора. Данная функция не уничтожает активное RDP соединение. + .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.RDPSessionMonitorStop( @@ -2324,9 +2354,8 @@ def RDPSessionMonitorStop(inRDPSessionKeyStr, inGSettings = None): inRDPSessionKeyStr = "RDPKey") # Orchestrator will stop the RDP monitoring - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :return: True every time :> + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lResult = True @@ -2335,11 +2364,11 @@ def RDPSessionMonitorStop(inRDPSessionKeyStr, inGSettings = None): def RDPSessionLogoff(inRDPSessionKeyStr, inBreakTriggerProcessWOExeList = None, inGSettings = None): """ - Logoff the RDP session from the Orchestrator process (close all apps in session when logoff) + Выполнить отключение (logoff) на RDP сессии и прекратить мониторить активность со стороны Оркестратора. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.RDPSessionLogoff( @@ -2348,10 +2377,11 @@ def RDPSessionLogoff(inRDPSessionKeyStr, inBreakTriggerProcessWOExeList = None, inBreakTriggerProcessWOExeList = ['Notepad']) # Orchestrator will logoff the RDP session - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inBreakTriggerProcessWOExeList: List of the processes, which will stop the execution. Example ["notepad"] - :return: True - logoff is successful + + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inBreakTriggerProcessWOExeList: Список процессов, наличие которых в диспетчере задач приведет к прерыванию задачи по остановке RDP соединения. Пример ["notepad"] + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: True - Отключение прошло успешно; False - были зафиксированы ошибки при отключении. """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings if inBreakTriggerProcessWOExeList is None: inBreakTriggerProcessWOExeList = [] @@ -2382,13 +2412,6 @@ def RDPSessionLogoff(inRDPSessionKeyStr, inBreakTriggerProcessWOExeList = None, return lResult def RDPSessionResponsibilityCheck(inRDPSessionKeyStr, inGSettings = None): - """ - DEVELOPING, MAYBE NOT USEFUL Check RDP Session responsibility TODO NEED DEV + TEST - - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :return: True every time - """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check thread if not Core.IsProcessorThread(inGSettings=inGSettings): @@ -2427,11 +2450,13 @@ def RDPSessionResponsibilityCheck(inRDPSessionKeyStr, inGSettings = None): def RDPSessionProcessStartIfNotRunning(inRDPSessionKeyStr, inProcessNameWEXEStr, inFilePathStr, inFlagGetAbsPathBool=True, inGSettings = None): """ - Start process in RDP if it is not running (check by the arg inProcessNameWEXEStr) + Выполнить запуск процесса на RDP сессии через графические UI инструменты (без Агента). + + !ВНИМАНИЕ! Данная функция может работать нестабильно из-за использования графических элементов UI при работе с RDP. Мы рекомендуем использовать конструкцию взаимодействия Оркестратора с Агентом. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator Orchestrator.RDPSessionProcessStartIfNotRunning( @@ -2442,12 +2467,11 @@ def RDPSessionProcessStartIfNotRunning(inRDPSessionKeyStr, inProcessNameWEXEStr, inFlagGetAbsPathBool = True) # Orchestrator will start the process in RDP session - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inProcessNameWEXEStr: Process name with extension (.exe). This arg allow to check the process is running. Example: "Notepad.exe" - :param inFilePathStr: Path to run process if it is not running. - :param inFlagGetAbsPathBool: True - get abs path from the relative path in inFilePathStr. False - else case - :return: True every time :) + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inProcessNameWEXEStr: Наименование процесса с расширением .exe (WEXE - WITH EXE - С EXE). Параметр позволяет не допустить повторного запуска процесса, если он уже был запущен. Example: "Notepad.exe" + :param inFilePathStr: Путь к файлу запуска процесса на стороне RDP сессии + :param inFlagGetAbsPathBool: True - Преобразовать относительный путь inFilePathStr в абсолютный с учетом рабочей директории Оркестратора; False - Не выполнять преобразований + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check thread @@ -2474,11 +2498,13 @@ def RDPSessionProcessStartIfNotRunning(inRDPSessionKeyStr, inProcessNameWEXEStr, def RDPSessionCMDRun(inRDPSessionKeyStr, inCMDStr, inModeStr="CROSSCHECK", inGSettings = None): """ - Send CMD command to the RDP session "RUN" window + Отправить CMD команду на удаленную сесиию через RDP окно (без Агента). + + !ВНИМАНИЕ! Данная функция может работать нестабильно из-за использования графических элементов UI при работе с RDP. Мы рекомендуем использовать конструкцию взаимодействия Оркестратора с Агентом. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lResultDict = Orchestrator.RDPSessionCMDRun( @@ -2486,18 +2512,18 @@ def RDPSessionCMDRun(inRDPSessionKeyStr, inCMDStr, inModeStr="CROSSCHECK", inGSe inRDPSessionKeyStr = "RDPKey", inModeStr = 'LISTEN') # Orchestrator will send CMD to RDP and return the result (see return section) - - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inCMDStr: Any CMD string - :param inModeStr: Variants: - "LISTEN" - Get result of the cmd command in result; - "CROSSCHECK" - Check if the command was successfully sent - "RUN" - Run without crosscheck and get clipboard - :return: # OLD > True - CMD was executed successfully + + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inCMDStr: Команда CMD, которую отправить на удаленную сессию + :param inModeStr: По умолчанию "CROSSCHECK". Варианты: + "LISTEN" - Получить результат выполнения операции. Внимание! необходим общий буфер обмена с сессией Оркестратора! + "CROSSCHECK" - Выполнить проверку, что операция была выполнена (без получения результата отработки CMD команды). Внимание! необходим общий буфер обмена с сессией Оркестратора! + "RUN" - Не получать результат и не выполнять проверку + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :return: Результат выполнения операции в соответсвии с параметрами инициализации функции. Выходная структура: { - "OutStr": <> # Result string - "IsResponsibleBool": True|False # Flag is RDP is responsible - works only when inModeStr = CROSSCHECK + "OutStr": <> # Результат выполнения CMD (если inModeStr = "LISTEN") + "IsResponsibleBool": True|False # True - RDP приняло команду; False - обратная связь не была получена (если inModeStr = "CROSSCHECK") } """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings @@ -2528,11 +2554,13 @@ def RDPSessionCMDRun(inRDPSessionKeyStr, inCMDStr, inModeStr="CROSSCHECK", inGSe def RDPSessionProcessStop(inRDPSessionKeyStr, inProcessNameWEXEStr, inFlagForceCloseBool, inGSettings = None): """ - Send CMD command to the RDP session "RUN" window. + Отправка CMD команды в RDP окне на остановку процесса (без Агента). + + !ВНИМАНИЕ! Данная функция может работать нестабильно из-за использования графических элементов UI при работе с RDP. Мы рекомендуем использовать конструкцию взаимодействия Оркестратора с Агентом. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lResultDict = Orchestrator.RDPSessionProcessStop( @@ -2542,11 +2570,11 @@ def RDPSessionProcessStop(inRDPSessionKeyStr, inProcessNameWEXEStr, inFlagForceC inFlagForceCloseBool = True) # Orchestrator will send CMD to RDP and return the result (see return section) - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inProcessNameWEXEStr: Process name to kill. Example: 'notepad.exe' - :param inFlagForceCloseBool: True - force close the process. False - safe close the process - :return: True every time + + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inProcessNameWEXEStr: Наименование процесса, который требуется выключить с расширением .exe (WEXE - WITH EXE - С EXE). Пример: "Notepad.exe" + :param inFlagForceCloseBool: True - Принудительное отключение. False - Отправка сигнала на безопасное отключение (если процесс поддерживает) + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check thread @@ -2574,11 +2602,15 @@ def RDPSessionProcessStop(inRDPSessionKeyStr, inProcessNameWEXEStr, inFlagForceC def RDPSessionFileStoredSend(inRDPSessionKeyStr, inHostFilePathStr, inRDPFilePathStr, inGSettings = None): """ - Send file from Orchestrator session to the RDP session using shared drive in RDP (see RDP Configuration Dict, Shared drive) + Отправка файла со стороны Оркестратора на сторону RDP сессии через UI инструменты RDP окна (без Агента). + + !ВНИМАНИЕ! Данная функция может работать нестабильно из-за использования графических элементов UI при работе с RDP. Мы рекомендуем использовать конструкцию взаимодействия Оркестратора с Агентом. + + !ВНИМАНИЕ! Для работы функции требуется открыть доступ по RDP к тем дискам, с которых будет производится копирование файла. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lResultDict = Orchestrator.RDPSessionFileStoredSend( @@ -2588,11 +2620,10 @@ def RDPSessionFileStoredSend(inRDPSessionKeyStr, inHostFilePathStr, inRDPFilePat inRDPFilePathStr = "C:\\RPA\\TESTDIR\\Test.py") # Orchestrator will send CMD to RDP and return the result (see return section) - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inHostFilePathStr: Relative or absolute path to the file location on the Orchestrator side. Example: "TESTDIR\\Test.py" - :param inRDPFilePathStr: !Absolute! path to the destination file location on the RDP side. Example: "C:\\RPA\\TESTDIR\\Test.py" - :return: True every time + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inHostFilePathStr: Откуда взять файл. Относительный или абсолютный путь к файлу на стороне Оркестратора. Пример: "TESTDIR\\Test.py" + :param inRDPFilePathStr: Куда скопировать файл. !Абсолютный! путь на стороне RDP сессии. Пример: "C:\\RPA\\TESTDIR\\Test.py" + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check thread @@ -2619,11 +2650,15 @@ def RDPSessionFileStoredSend(inRDPSessionKeyStr, inHostFilePathStr, inRDPFilePat def RDPSessionFileStoredRecieve(inRDPSessionKeyStr, inRDPFilePathStr, inHostFilePathStr, inGSettings = None): """ - Recieve file from RDP session to the Orchestrator session using shared drive in RDP (see RDP Configuration Dict, Shared drive) + Получение файла со стороны RDP сессии на сторону Оркестратора через UI инструменты RDP окна (без Агента). + + !ВНИМАНИЕ! Данная функция может работать нестабильно из-за использования графических элементов UI при работе с RDP. Мы рекомендуем использовать конструкцию взаимодействия Оркестратора с Агентом. + + !ВНИМАНИЕ! Для работы функции требуется открыть доступ по RDP к тем дискам, с которых будет производится копирование файла. .. code-block:: python - # USAGE + # ПРИМЕР from pyOpenRPA import Orchestrator lResultDict = Orchestrator.RDPSessionFileStoredRecieve( @@ -2633,11 +2668,10 @@ def RDPSessionFileStoredRecieve(inRDPSessionKeyStr, inRDPFilePathStr, inHostFile inRDPFilePathStr = "C:\\RPA\\TESTDIR\\Test.py") # Orchestrator will send CMD to RDP and return the result (see return section) - :param inGSettings: Global settings dict (singleton) - :param inRDPSessionKeyStr: RDP Session string key - need for the further identification - :param inRDPFilePathStr: !Absolute! path to the destination file location on the RDP side. Example: "C:\\RPA\\TESTDIR\\Test.py" - :param inHostFilePathStr: Relative or absolute path to the file location on the Orchestrator side. Example: "TESTDIR\\Test.py" - :return: True every time + :param inRDPSessionKeyStr: Ключ RDP сессии - необходим для дальнейшей идентификации + :param inRDPFilePathStr: Откуда скопировать файл. !Абсолютный! путь на стороне RDP сессии. Пример: "C:\\RPA\\TESTDIR\\Test.py" + :param inHostFilePathStr: Куда скопировать файл. Относительный или абсолютный путь к файлу на стороне Оркестратора. Пример: "TESTDIR\\Test.py" + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings # Check thread @@ -2665,13 +2699,8 @@ def RDPSessionFileStoredRecieve(inRDPSessionKeyStr, inRDPFilePathStr, inHostFile # # # # # Start orchestrator # # # # # # # # # # # # # # # # # # # # # # # +#HIDDEN Interval gSettings auto cleaner def to clear some garbage. def GSettingsAutocleaner(inGSettings=None): - """ - HIDDEN Interval gSettings auto cleaner def to clear some garbage. - - :param inGSettings: Global settings dict (singleton) - :return: None - """ inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings while True: time.sleep(inGSettings["Autocleaner"]["IntervalSecFloat"]) # Wait for the next iteration @@ -2700,23 +2729,15 @@ def GSettingsAutocleaner(inGSettings=None): from .. import __version__ # Get version from the package def Start(inDumpRestoreBool = True, inRunAsAdministratorBool = True): - """ - Start the orchestrator threads execution - - :param inDumpRestoreBool: True - restore data from the dumo - :param inRunAsAdministratorBool: True - rerun as admin if not - :return: - """ Orchestrator(inDumpRestoreBool = True, inRunAsAdministratorBool = True) def Orchestrator(inGSettings=None, inDumpRestoreBool = True, inRunAsAdministratorBool = True): """ - Main def to start orchestrator + Инициализация ядра Оркестратора (всех потоков) - :param inGSettings: - :param inDumpRestoreBool: - :param inRunAsAdministratorBool: - :return: + :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) + :param inDumpRestoreBool: True - Восстановить информацию о RDP сессиях и StorageDict; False - не восстанавливать + :param inRunAsAdministratorBool: True - Проверить права администратратора и обеспечить их; False - Не обеспечивать права администратора """ lL = inGSettings["Logger"] # https://stackoverflow.com/questions/130763/request-uac-elevation-from-within-a-python-script @@ -2801,8 +2822,6 @@ def Orchestrator(inGSettings=None, inDumpRestoreBool = True, inRunAsAdministrato lRobotRDPActiveThread.start() # Start the thread execution. if lL: lL.info("Robot RDP active has been started") #Logging - - # Init autocleaner in another thread lAutocleanerThread = threading.Thread(target= GSettingsAutocleaner, kwargs={"inGSettings":gSettingsDict}) lAutocleanerThread.daemon = True # Run the thread in daemon mode. diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Clipboard.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Clipboard.py index 12b43186..279e699b 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Clipboard.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Clipboard.py @@ -4,17 +4,42 @@ import win32clipboard #################################### # GUI Module - interaction with Windows clipboard -################ -###ClipboardGet -################ +def Get(): + """ + Получить текстовое содержимое буфера обмена. + + .. code-block:: python + + # Clipboard: Взаимодействие с буфером + from pyOpenRPA.Robot import Clipboard + lClipStr = Clipboard.Get() + + :return: Текстовое содержимое буфера обмена + :rtype: str + """ + return ClipboardGet() + +def Set(inTextStr:str): + """ + Установить текстовое содержимое в буфер обмена. + + .. code-block:: python + + # Clipboard: Взаимодействие с буфером + from pyOpenRPA.Robot import Clipboard + lClipStr = Clipboard.Set(inTextStr="HELLO WORLD") + + :param inTextStr: Текстовое содержимое для установки в буфера обмена + :type inTextStr: str + """ + ClipboardSet(inText=inTextStr) + def ClipboardGet(): win32clipboard.OpenClipboard() lResult = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT) win32clipboard.CloseClipboard() return lResult -################ -###ClipboardSet -################ + def ClipboardSet(inText): win32clipboard.OpenClipboard() win32clipboard.EmptyClipboard() diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Keyboard.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Keyboard.py index b6a278fc..d6cbacc5 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Keyboard.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Keyboard.py @@ -1 +1,344 @@ -from keyboard import * \ No newline at end of file +from keyboard import * +import time + +# Настройки модуля Keyboard +WAIT_AFTER_SEC_FLOAT = 0.4 # Время, которое ожидать после выполнения любой операции модуля Keyboard. Настройка является единой для всех участов кода, использующих модуль Keyboard. Если для некоторой функции требуется изменить данное время ожидания, то в отношении этой функции можно применить соответсвующий аргумент. + +# ШЕСТНАДЦАТИРИЧНЫЙ СКАН-КОД В РУССКОЙ РАСКЛАДКЕ (НЕЗАВИСИМО ОТ ВЫБРАННОГО ЯЗЫКА НА КЛАВИАТУРЕ) +# ОТОБРАЖЕНИЕ СКАН КОДОВ НА КЛАВИАТУРЕ https://snipp.ru/handbk/scan-codes + +KEY_RUS_Ф = 0x1E #A +KEY_RUS_И = 0x30 #B +KEY_RUS_С = 0x2E #C +KEY_RUS_В = 0x20 #D +KEY_RUS_У = 0x12 #E +KEY_RUS_А = 0x21 #F +KEY_RUS_П = 0x22 #G +KEY_RUS_Р = 0x23 #H +KEY_RUS_Ш = 0x17 #I +KEY_RUS_О = 0x24 #J +KEY_RUS_Л = 0x25 #K +KEY_RUS_Д = 0x26 #L +KEY_RUS_Ь = 0x32 #M +KEY_RUS_Т = 0x31 #N +KEY_RUS_Щ = 0x18 #O +KEY_RUS_З = 0x19 #P +KEY_RUS_Й = 0x10 #Q +KEY_RUS_К = 0x13 #R +KEY_RUS_Ы = 0x1F #S +KEY_RUS_Е = 0x14 #T +KEY_RUS_Г = 0x16 #U +KEY_RUS_М = 0x2F #V +KEY_RUS_Ц = 0x11 #W +KEY_RUS_Ч = 0x2D #X +KEY_RUS_Н = 0x15 #Y +KEY_RUS_Я = 0x2C #Z +KEY_RUS_Ё = 0x29 #~ +KEY_RUS_Ж = 0x27 #: +KEY_RUS_Б = 0x33 #< +KEY_RUS_Ю = 0x34 #> +KEY_RUS_Х = 0x1A #[ +KEY_RUS_Ъ = 0x1B #] +KEY_RUS_Э = 0x28 #' + +KEY_ENG_A = 0x1E #A +KEY_ENG_B = 0x30 #B +KEY_ENG_C = 0x2E #C +KEY_ENG_D = 0x20 #D +KEY_ENG_E = 0x12 #E +KEY_ENG_F = 0x21 #F +KEY_ENG_G = 0x22 #G +KEY_ENG_H = 0x23 #H +KEY_ENG_I = 0x17 #I +KEY_ENG_J = 0x24 #J +KEY_ENG_K = 0x25 #K +KEY_ENG_L = 0x26 #L +KEY_ENG_M = 0x32 #M +KEY_ENG_N = 0x31 #N +KEY_ENG_O = 0x18 #O +KEY_ENG_P = 0x19 #P +KEY_ENG_Q = 0x10 #Q +KEY_ENG_R = 0x13 #R +KEY_ENG_S = 0x1F #S +KEY_ENG_T = 0x14 #T +KEY_ENG_U = 0x16 #U +KEY_ENG_V = 0x2F #V +KEY_ENG_W = 0x11 #W +KEY_ENG_X = 0x2D #X +KEY_ENG_Y = 0x15 #Y +KEY_ENG_Z = 0x2C #Z + + +KEY_HOT_NUMPAD_0 = 0x52 +KEY_HOT_NUMPAD_1 = 0x4F +KEY_HOT_NUMPAD_2 = 0x50 +KEY_HOT_NUMPAD_3 = 0x51 +KEY_HOT_NUMPAD_4 = 0x4B +KEY_HOT_NUMPAD_5 = 0x4C +KEY_HOT_NUMPAD_6 = 0x4D +KEY_HOT_NUMPAD_7 = 0x47 +KEY_HOT_NUMPAD_8 = 0x48 +KEY_HOT_NUMPAD_9 = 0x49 +KEY_HOT_NUMPAD_ASTERISK = 0x37 #* +KEY_HOT_NUMPAD_PLUS = 0x4E +KEY_HOT_NUMPAD_MINUS = 0x4A +KEY_HOT_NUMPAD_DELETE = 0x53 +KEY_HOT_NUMPAD_SOLIDUS = 0x35 #/ +KEY_HOT_NUMPAD_ENTER = 0x11c + +KEY_HOT_F1 = 0x3B +KEY_HOT_F2 = 0x3C +KEY_HOT_F3 = 0x3D +KEY_HOT_F4 = 0x3E +KEY_HOT_F5 = 0x3F +KEY_HOT_F6 = 0x40 +KEY_HOT_F7 = 0x41 +KEY_HOT_F8 = 0x42 +KEY_HOT_F9 = 0x43 +KEY_HOT_F10 = 0x44 +KEY_HOT_F11 = 0x57 +KEY_HOT_F12 = 0x58 +KEY_HOT_F13 = 0x7C +KEY_HOT_F14 = 0x7D +KEY_HOT_F15 = 0x7E +KEY_HOT_F16 = 0x7F +KEY_HOT_F17 = 0x80 +KEY_HOT_F18 = 0x81 +KEY_HOT_F19 = 0x82 +KEY_HOT_F20 = 0x83 +KEY_HOT_F21 = 0x84 +KEY_HOT_F22 = 0x85 +KEY_HOT_F23 = 0x86 +KEY_HOT_F24 = 0x87 + +KEY_HOT_TILDE = 0x29 #~ +KEY_HOT_COLON = 0x27 #: +KEY_HOT_PLUS = 0x0D #+ +KEY_HOT_MINUS = 0x0C #- +KEY_HOT_LESS_THAN = 0x33 #< , +KEY_HOT_GREATER_THAN = 0x34 #> . +KEY_HOT_SOLIDUS = 0x35 #/ ? +KEY_HOT_SQUARE_BRACKET_LEFT = 0x1A #[ +KEY_HOT_SQUARE_BRACKET_RIGHT = 0x1B #] +KEY_HOT_APOSTROPHE = 0x28 #' " +KEY_HOT_VERTICAL_LINE = 0x2B #| \ + +KEY_HOT_ESC = 0x1 +KEY_HOT_BACKSPACE = 0x0E +KEY_HOT_TAB = 0x0F +KEY_HOT_ENTER = 0x1C +KEY_HOT_CONTEXT_MENU = 0x15D +KEY_HOT_SHIFT_LEFT = 0x2A +KEY_HOT_SHIFT_RIGHT = 0x36 +KEY_HOT_CTRL_LEFT = 0x1D +KEY_HOT_CTRL_RIGHT = 0x11D +KEY_HOT_ALT_LEFT = 0x38 +KEY_HOT_ALT_RIGHT = 0x138 +KEY_HOT_WIN_LEFT = 57435 #OLD AND DONT WORK 0x5B +KEY_HOT_WIN_RIGHT = 57436 #OLD AND DONT WORK 0x5C +KEY_HOT_CAPS_LOCK = 0x3A +KEY_HOT_NUM_LOCK = 0x45 +KEY_HOT_SCROLL_LOCK = 0x46 +KEY_HOT_END = 0x4F +KEY_HOT_HOME = 0x47 +KEY_HOT_SPACE = 0x39 +KEY_HOT_PAGE_UP = 0x49 +KEY_HOT_PAGE_DOWN = 0x51 +KEY_HOT_CLEAR = 0x4C +KEY_HOT_LEFT = 0x4B +KEY_HOT_UP = 0x48 +KEY_HOT_RIGHT = 0x4D +KEY_HOT_DOWN = 0x50 +KEY_HOT_PRINT_SCREEN = 0x137 +KEY_HOT_INSERT = 0x52 +KEY_HOT_DELETE = 0x53 + +KEY_HOT_0 = 0xB +KEY_HOT_1 = 0x2 +KEY_HOT_2 = 0x3 +KEY_HOT_3 = 0x4 +KEY_HOT_4 = 0x5 +KEY_HOT_5 = 0x6 +KEY_HOT_6 = 0x7 +KEY_HOT_7 = 0x8 +KEY_HOT_8 = 0x9 +KEY_HOT_9 = 0xA + +def Write(inTextStr:str, inDelayFloat:float=0, inRestoreStateAfterBool:bool=True, inExactBool:bool=None, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """ + Печатает текст, который был передан в переменной inTextStr (поддерживает передачу в одной строке символов разного языка). Не зависит от текущей раскладки клавиатуры! Посылает искусственные клавишные события в ОС, моделируя печать данного текста. Знаки, не доступные на клавиатуре, напечатаны как явный unicode знаки, использующие определенную для ОС функциональность, такие как alt+codepoint. + Чтобы гарантировать текстовую целостность, все в настоящее время нажатые ключи выпущены прежде текст напечатан, и модификаторы восстановлены впоследствии. + + ВНИМАНИЕ! ПЕЧАТАЕТ ЛЮБУЮ СТРОКУ, ДАЖЕ В СОЧЕТАНИИ НЕСКОЛЬКИХ ЯЗЫКОВ ОДНОВРЕМЕННО. ДЛЯ РАБОТЫ С ГОРЯЧИМИ КЛАВИШАМИ ИСПОЛЬЗУЙ ФУНКЦИЮ Send, Up, Down, HotkeyCombination + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + Keyboard.Write("Привет мой милый мир! Hello my dear world!") + + :param inTextStr: Текст, отправляемый на печать. Не зависит от текущей раскладки клавиатуры! + :type inTextStr: str + :param inDelayFloat: Число секунд, которое ожидать между нажатиями. По умолчанию 0 + :type inDelayFloat: float, опциональный + :param inRestoreStateAfterBool: Может использоваться, чтобы восстановить регистр нажатых ключей после того, как текст напечатан, т.е. нажимает ключи, которые были выпущены в начало. + :type inRestoreStateAfterBool: bool, опциональный + :param inExactBool: Печатает все знаки как явный unicode. Необязательный параметр + :type inExactBool: bool, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Keyboard (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + write(text=inTextStr, delay=inDelayFloat, restore_state_after=inRestoreStateAfterBool, exact=inExactBool) + time.sleep(inWaitAfterSecFloat) + +def HotkeyCombination(*inKeyList, inDelaySecFloat = 0.3,inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Получает перечень клавиш для одновременного нажатия. Между нажатиями программа ожидания время inDelaySecFloat + ВНИМАНИЕ! НЕ ЗАВИСИТ ОТ ТЕКУЩЕЙ РАСКЛАДКИ КЛАВИАТУРЫ + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + Keyboard.HotkeyCombination(Keyboard.KEY_HOT_CTRL_LEFT,Keyboard.KEY_ENG_A) # Ctrl + a + Keyboard.HotkeyCombination(Keyboard.KEY_HOT_CTRL_LEFT,Keyboard.KEY_ENG_C) # Ctrl + c + Keyboard.HotkeyCombination(Keyboard.KEY_HOT_CTRL_LEFT,Keyboard.KEY_ENG_A) + Keyboard.HotkeyCombination(Keyboard.KEY_HOT_ALT_LEFT,Keyboard.KEY_HOT_TAB, Keyboard.KEY_HOT_TAB) + + :param inKeyList: Список клавиш для одновременного нажатия. Перечень клавиш см. в разделе "Коды клавиш". Пример: KEY_HOT_CTRL_LEFT,KEY_ENG_A + :param inDelaySecFloat: Интервал между нажатиями. Необходим в связи с тем, что операционной системе требуется время на реакцию на нажатие клавиш, по умолчанию: 0.3 + :type inDelaySecFloat: float, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Keyboard (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + for l_key_item in inKeyList: + if l_key_item == inKeyList[-1]: + send(l_key_item) + else: + press(l_key_item) + time.sleep(inDelaySecFloat) + lRevKeyList = list(reversed(inKeyList)) + for l_key_item in lRevKeyList: + if l_key_item == lRevKeyList[0]: + pass + else: + release(l_key_item) + time.sleep(inDelaySecFloat) + time.sleep(inWaitAfterSecFloat) + +def HotkeyCtrlA_CtrlC(inWaitAfterSecFloat:float=0.4) -> None: + """Выполнить выделение текста, после чего скопировать его в буфер обмена + ВНИМАНИЕ! НЕ ЗАВИСИТ ОТ ТЕКУЩЕЙ РАСКЛАДКИ КЛАВИАТУРЫ + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + Keyboard.HotkeyCtrlA_CtrlC() # Отправить команды: выделить все, скопировать в буфер обмена + + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Keyboard (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + HotkeyCombination(KEY_HOT_CTRL_LEFT,KEY_ENG_A) # Ctrl + a + HotkeyCombination(KEY_HOT_CTRL_LEFT,KEY_ENG_C) # Ctrl + c + time.sleep(inWaitAfterSecFloat) + +def Send(inKeyInt:int, inDoPressBool:bool=True, inDoReleaseBool:bool=True,inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT) -> None: + """ + Имитация нажатия/отпускания любой физической клавиши. Посылает событие в операционную систему, которые выполняет нажатие и отпускание данной клавиши + + ВНИМАНИЕ! ПРИ ПОПЫТКЕ ПЕЧАТИ ТЕКСТА БУДЕТ УЧИТЫВАТЬ ТЕКУЩУЮ РАСКЛАДКУ КЛАВИАТУРЫ. ДЛЯ ПЕЧАТИ ТЕКСТА ИСПОЛЬЗУЙ Write! + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + Keyboard.Send(Keyboard.KEY_ENG_A) # Нажать клавишу A. Если будет активна русская раскладка, то будет выведена буква ф. + + :param inKeyInt: Перечень клавиш см. в разделе "Коды клавиш". Пример: KEY_HOT_CTRL_LEFT,KEY_ENG_A + :type inKeyInt: int + :param inDoPressBool: Выполнить событие нажатия клавиши, По умолчанию True + :type inDoPressBool: bool, опциональный + :param inDoReleaseBool: Выполнить событие отпускания клавиши, По умолчанию True + :type inDoReleaseBool: bool, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Keyboard (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + send(hotkey=inKeyInt, do_press=inDoPressBool, do_release=inDoReleaseBool) + time.sleep(inWaitAfterSecFloat) + +def Up(inKeyInt:int, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT) -> None: + """ + Отпустить (поднять) клавишу. Если клавиша уже была поднята, то ничего не произойдет. + + ВНИМАНИЕ! ПРИ ПОПЫТКЕ ПЕЧАТИ ТЕКСТА БУДЕТ УЧИТЫВАТЬ ТЕКУЩУЮ РАСКЛАДКУ КЛАВИАТУРЫ. ДЛЯ ПЕЧАТИ ТЕКСТА ИСПОЛЬЗУЙ Write! + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + Keyboard.Up(Keyboard.KEY_ENG_A) # Отпустить клавишу A. + + :param inKeyInt: Перечень клавиш см. в разделе "Коды клавиш". Пример: KEY_HOT_CTRL_LEFT, KEY_ENG_A + :type inKeyInt: int + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Keyboard (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + send(hotkey=inKeyInt, do_press=False, do_release=True) + time.sleep(inWaitAfterSecFloat) + +def Down(inKeyInt:int, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT) -> None: + """ + Нажать (опустить) клавишу. Если клавиша уже была опущена, то ничего не произойдет. + + ВНИМАНИЕ! ПРИ ПОПЫТКЕ ПЕЧАТИ ТЕКСТА БУДЕТ УЧИТЫВАТЬ ТЕКУЩУЮ РАСКЛАДКУ КЛАВИАТУРЫ. ДЛЯ ПЕЧАТИ ТЕКСТА ИСПОЛЬЗУЙ Write! + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + Keyboard.Down(Keyboard.KEY_ENG_A) # Отпустить клавишу A. + + :param inKeyInt: Перечень клавиш см. в разделе "Коды клавиш". Пример: KEY_HOT_CTRL_LEFT, KEY_ENG_A + :type inKeyInt: int + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Keyboard (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + send(hotkey=inKeyInt, do_press=True, do_release=False) + time.sleep(inWaitAfterSecFloat) + +def IsDown(inKeyInt:int) -> bool: + """ + Проверить, опущена ли клавиша. Вернет True если опущена; False если поднята. + + ВНИМАНИЕ! ПРИ ПОПЫТКЕ ПЕЧАТИ ТЕКСТА БУДЕТ УЧИТЫВАТЬ ТЕКУЩУЮ РАСКЛАДКУ КЛАВИАТУРЫ. ДЛЯ ПЕЧАТИ ТЕКСТА ИСПОЛЬЗУЙ Write! + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + lKeyAIsPressedBool = Keyboard.IsDown(Keyboard.KEY_ENG_A) # Проверить, опущена ли клавиша A. + + :param inKeyInt: Перечень клавиш см. в разделе "Коды клавиш". Пример: KEY_HOT_CTRL_LEFT, KEY_ENG_A + :type inKeyInt: int + """ + return is_pressed(inKeyInt) + +def Wait(inKeyInt:int,inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Блокирует осуществление программы, пока данная обозначенная клавиша не будет нажата. + ВНИМАНИЕ! НЕ ЗАВИСИТ ОТ ТЕКУЩЕЙ РАСКЛАДКИ КЛАВИАТУРЫ. ОЖИДАЕТ НАЖАТИЕ СООТВЕТСВУЮЩЕЙ ФИЗИЧЕСКОЙ КЛАВИШИ + + .. code-block:: python + + # Keyboard: Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Keyboard + Keyboard.Wait(Keyboard.KEY_ENG_A) # Ждать нажатие клавиши A. + + :param inKeyInt: Перечень клавиш см. в разделе "Коды клавиш". Пример: KEY_HOT_CTRL_LEFT,KEY_ENG_A + :type inKeyInt: int + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Keyboard (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + wait(hotkey=inKeyInt) + time.sleep(inWaitAfterSecFloat) + +key_to_scan_codes("win") # 2022 06 10 Люблю смотреть скан код клавиши Виндовс :) \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Mouse.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Mouse.py index 49af0760..e693a900 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Mouse.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/Mouse.py @@ -1 +1,173 @@ -from pyautogui import * \ No newline at end of file +from pyautogui import * +import time + +WAIT_AFTER_SEC_FLOAT = 0.4 # Настройка модуля Mouse: Время, которое ожидать после выполнения любой операции модуля Mouse. Настройка является единой для всех участов кода, использующих модуль Mouse. Если для некоторой функции требуется изменить данное время ожидания, то в отношении этой функции можно применить соответсвующий аргумент. + +def Click(inXInt:int=None, inYInt:int=None, inClickCountInt:int=1, inIntervalSecFloat:float=0.0, inButtonStr:str='left', inMoveDurationSecFloat:float=0.0, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Нажатие (вниз) кнопки мыши и затем немедленно выпуск (вверх) её. Допускается следующая параметризация. Если не указаны inXInt и inYInt - клик производится по месту нахождения указателя мыши. + + !ВНИМАНИЕ! Отсчет координат inXInt, inYInt начинается с левого верхнего края рабочей области (экрана). + + .. code-block:: python + + # Mouse: Взаимодействие с мышью + from pyOpenRPA.Robot import Mouse + Mouse.Click(100,150) #Выполнить нажатие левой клавиши мыши на экране по координатам: X(гор) 100px, Y(вер) 150px. + + :param inXInt: Целевая позиция указателя мыши по оси X (горизонтальная ось). + :type inXInt: int, опциональный + :param inYInt: Целевая позиция указателя мыши по оси Y (вертикальная ось). + :type inYInt: int, опциональный + :param inClickCountInt: Количество нажатий (вниз и вверх) кнопкой мыши, По умолчанию 1 + :type inClickCountInt: int, опциональный + :param inIntervalSecFloat: Интервал ожидания в секундах между нажатиями, По умолчанию 0.0 + :type inIntervalSecFloat: float, опциональный + :param inButtonStr: Номер кнопки, которую требуется нажать. Возможные варианты: 'left', 'middle', 'right' или 1, 2, 3. В остальных случаях инициирует исключение ValueError. По умолчанию 'left' + :type inButtonStr: str, опциональный + :param inMoveDurationSecFloat: Время перемещения указателя мыши, По умолчанию 0.0 (моментальное перемещение) + :type inMoveDurationSecFloat: float, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Mouse (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + click(x=inXInt, y=inYInt, clicks=inClickCountInt, interval=inIntervalSecFloat, button=inButtonStr, duration=inMoveDurationSecFloat) + time.sleep(inWaitAfterSecFloat) + +def ClickDouble(inXInt:int=None, inYInt:int=None, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Двойное нажатие левой клавиши мыши. Данное действие аналогично вызову функции (см. ниже). + + !ВНИМАНИЕ! Отсчет координат inXInt, inYInt начинается с левого верхнего края рабочей области (экрана). + + .. code-block:: python + + # Mouse: Взаимодействие с мышью + from pyOpenRPA.Robot import Mouse + Mouse.ClickDouble(100,150) #Выполнить двойное нажатие левой клавиши мыши на экране по координатам: X(гор) 100px, Y(вер) 150px. + + :param inXInt: Целевая позиция указателя мыши по оси X (горизонтальная ось). + :type inXInt: int, опциональный + :param inYInt: Целевая позиция указателя мыши по оси Y (вертикальная ось). + :type inYInt: int, опциональный + :param inButtonStr: Номер кнопки, которую требуется нажать. Возможные варианты: 'left', 'middle', 'right' или 1, 2, 3. В остальных случаях инициирует исключение ValueError. По умолчанию 'left' + :type inButtonStr: str, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Mouse (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + doubleClick(x=inXInt, y=inYInt) + time.sleep(inWaitAfterSecFloat) + +def Down(inXInt:int=None, inYInt:int=None, inButtonStr:str='left', inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Переместить указатель по координатам inXInt, inYInt, после чего нажать (вниз) клавишу мыши и не отпускать до выполнения соответсвующей команды (см. Up). Если координаты inXInt, inYInt не переданы - нажатие происходит на тех координатах X/Y, на которых указатель мыши находится. + + !ВНИМАНИЕ! Отсчет координат inXInt, inYInt начинается с левого верхнего края рабочей области (экрана). + + .. code-block:: python + + # Mouse: Взаимодействие с мышью + from pyOpenRPA.Robot import Mouse + Mouse.Down() #Опустить левую клавишу мыши + + :param inXInt: Целевая позиция указателя мыши по оси X (горизонтальная ось). + :type inXInt: int, опциональный + :param inYInt: Целевая позиция указателя мыши по оси Y (вертикальная ось). + :type inYInt: int, опциональный + :param inButtonStr: Номер кнопки, которую требуется нажать. Возможные варианты: 'left', 'middle', 'right' или 1, 2, 3. В остальных случаях инициирует исключение ValueError. По умолчанию 'left' + :type inButtonStr: str, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Mouse (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + mouseDown(x=inXInt, y=inYInt, button = inButtonStr) + time.sleep(inWaitAfterSecFloat) + +def Up(inXInt:int=None, inYInt:int=None, inButtonStr:str='left', inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Отпустить (вверх) клавишу мыши. Если координаты inXInt, inYInt не переданы - нажатие происходит на тех координатах X/Y, на которых указатель мыши находится. + + !ВНИМАНИЕ! Отсчет координат inXInt, inYInt начинается с левого верхнего края рабочей области. + + .. code-block:: python + + # Mouse: Взаимодействие с мышью + from pyOpenRPA.Robot import Mouse + Mouse.Up(inButtonStr:str='right') #Поднять правую клавишу мыши + + :param inXInt: Целевая позиция указателя мыши по оси X (горизонтальная ось). + :type inXInt: int, опциональный + :param inYInt: Целевая позиция указателя мыши по оси Y (вертикальная ось). + :type inYInt: int, опциональный + :param inButtonStr: Номер кнопки, которую требуется поднять. Возможные варианты: 'left', 'middle', 'right' или 1, 2, 3. В остальных случаях инициирует исключение ValueError. По умолчанию 'left' + :type inButtonStr: str, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Mouse (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + mouseUp(x=inXInt, y=inYInt, button = inButtonStr) + time.sleep(inWaitAfterSecFloat) + +def MoveTo(inXInt=None, inYInt=None, inMoveDurationSecFloat:float=0.0, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Переместить указатель мыши на позицию inXInt, inYInt за время inMoveDurationSecFloat. + + !ВНИМАНИЕ! Отсчет координат inXInt, inYInt начинается с левого верхнего края рабочей области (экрана). + + .. code-block:: python + + # Mouse: Взаимодействие с мышью + from pyOpenRPA.Robot import Mouse + Mouse.MoveTo(inXInt=100, inYInt=200) #Переместить указатель мыши по координатам: X(гор) 100, Y(вер) 200 + + :param inXInt: Целевая позиция указателя мыши по оси X (горизонтальная ось). + :type inXInt: int, опциональный + :param inYInt: Целевая позиция указателя мыши по оси Y (вертикальная ось). + :type inYInt: int, опциональный + :param inMoveDurationSecFloat: Время перемещения указателя мыши, По умолчанию 0.0 (моментальное перемещение) + :type inMoveDurationSecFloat: float, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Mouse (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + moveTo(x=inXInt, y=inYInt, duration=inMoveDurationSecFloat) + time.sleep(inWaitAfterSecFloat) + +def ScrollVertical(inScrollClickCountInt, inXInt=None, inYInt=None, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """Переместить указатель мыши на позицию inXInt, inYInt и выполнить вертикальную прокрутку (скроллинг) колесом мыши на количество щелчков inScrollClickCountInt. + + !ВНИМАНИЕ! Отсчет координат inXInt, inYInt начинается с левого верхнего края рабочей области (экрана). + + .. code-block:: python + + # Mouse: Взаимодействие с мышью + from pyOpenRPA.Robot import Mouse + Mouse.ScrollVertical(100, inXInt=100, inYInt=200) #Крутить колесо мыши вниз на 100 кликов по координатам: X(гор) 100, Y(вер) 200 + Mouse.ScrollVertical(-100) #Крутить колесо мыши вверх на 100 кликов по текущим координатам указателя мыши. + + :param inScrollClickCountInt: Количество щелчок колеса мыши, которое требуется !вертикально! прокрутить. Аргумент может принимать как положительное (прокрутка вниз), так и отрицательное (прокрутка вверх) значения + :type inScrollClickCountInt: int, обязательный + :param inXInt: Целевая позиция указателя мыши по оси X (горизонтальная ось). + :type inXInt: int, опциональный + :param inYInt: Целевая позиция указателя мыши по оси Y (вертикальная ось). + :type inYInt: int, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Mouse (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + vscroll(inScrollClickCountInt, x=inXInt, y=inYInt) + time.sleep(inWaitAfterSecFloat) + +def ScrollHorizontal(inScrollClickCountInt, inXInt=None, inYInt=None, inWaitAfterSecFloat:float=WAIT_AFTER_SEC_FLOAT): + """!ТОЛЬКО ДЛЯ LINUX! Переместить указатель мыши на позицию inXInt, inYInt и выполнить горизонтальную прокрутку (скроллинг) виртуальным колесом мыши на количество щелчков inScrollClickCountInt. + + !ВНИМАНИЕ! Отсчет координат inXInt, inYInt начинается с левого верхнего края рабочей области (экрана). + + .. code-block:: python + + # Mouse: Взаимодействие с мышью + from pyOpenRPA.Robot import Mouse + Mouse.ScrollHorizontal(100, inXInt=100, inYInt=200) #Крутить колесо мыши вниз на 100 кликов по координатам: X(гор) 100, Y(вер) 200 + Mouse.ScrollHorizontal(-100) #Крутить колесо мыши вверх на 100 кликов по текущим координатам указателя мыши. + + :param inScrollClickCountInt: Количество щелчок колеса мыши, которое требуется !горизонтально! прокрутить. Аргумент может принимать как положительное (прокрутка вправо), так и отрицательное (прокрутка влево) значения + :type inScrollClickCountInt: int, обязательный + :param inXInt: Целевая позиция указателя мыши по оси X (горизонтальная ось). + :type inXInt: int, опциональный + :param inYInt: Целевая позиция указателя мыши по оси Y (вертикальная ось). + :type inYInt: int, опциональный + :param inWaitAfterSecFloat: Количество секунд, которые ожидать после выполнения операции. По умолчанию установлено в настройках модуля Mouse (базовое значение 0.4) + :type inWaitAfterSecFloat: float, опциональный + """ + hscroll(inScrollClickCountInt, x=inXInt, y=inYInt) + time.sleep(inWaitAfterSecFloat) diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/README.md b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/README.md index f5f30305..4ae5e05c 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/README.md +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/README.md @@ -43,16 +43,5 @@ Resources\WPy64-3720\python-3.7.2.amd64\python.exe ] -# Open RPA Wiki -- [Home](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/home) -- [04. Desktop app access (win32 & ui automation)](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/04.-Desktop-app-access-(win32-&-ui-automation)) - -#Dependencies -* Python 3 x32 [psutil, pywinauto, wmi, PIL, keyboard, pyautogui, win32api (pywin32), selenium, openCV, tesseract, requests, lxml, PyMuPDF] -* Python 3 x64 [psutil, pywinauto, wmi, PIL, keyboard, pyautogui, win32api (pywin32), selenium, openCV, tesseract, requests, lxml, PyMuPDF] -* pywinauto (Windows GUI automation) -* Semantic UI CSS framework -* JsRender by https://www.jsviews.com (switch to Handlebars) -* Handlebars - -Created by Unicode Labs (Ivan Maslov) \ No newline at end of file + +Created by pyOpenRPA LLC (Ivan Maslov) \ No newline at end of file diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py index e084d515..fa101c2b 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/Robot/UIDesktop.py @@ -29,7 +29,7 @@ import copy #TODO В перспективе нужно реализовать алгоритм определения разрядности не в Robot.py, а в UIDesktop.py, тк начинают появляться функции, на входе в которые еще неизвестна разрядность элемента + селектор может охватить сразу два элемента из 2-х разных разрядностей - обрабатываться это должно непосредственно при выполнении #################################### -#Info: GUI module of the Robot app (OpenRPA - Robot) +#Info: GUI module of the Robot app (pyOpenRPA - Robot) #################################### # GUI Module - interaction with Desktop application @@ -99,19 +99,27 @@ mDefaultPywinautoBackend="win32" # "rich_text" - наименование rich_text # } #] -################ -#return: List of UI Object -#inElement - Входной элемент - показатель, что не требуется выполнять коннект к процессу -#inFlagRaiseException - Флаг True - выкинуть ошибку в случае обнаружении пустого списка -#old name - PywinautoExtElementsGet + +#old:PywinautoExtElementsGet def UIOSelector_Get_UIOList (inSpecificationList,inElement=None,inFlagRaiseException=True): ''' - Get the UIO list by the selector + Получить список UIO объектов по UIO селектору + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lDemoBaseUIOList = UIDesktop.UIOSelector_Get_UIOList(lDemoBaseUIOSelector) #Получить список UIO объектов, которые удовлетворяют требованиям UIO селектора. В нашем примере либо [], либо [UIO объект] - :param inSpecificationList: UIO Selector - :param inElement: Входной элемент - показатель, что не требуется выполнять коннект к процессу - :param inFlagRaiseException: Флаг True - выкинуть ошибку в случае обнаружении пустого списка - :return: + :param inSpecificationList: UIO Селектор, который определяет критерии поиска UI элементов + :type inSpecificationList: list, обязательный + :param inElement: Родительский элемент, от которого выполнить поиск UIO объектов по заданному UIO селектору. Если аргумент не задан, платформа выполнит поиск UIO объектов среди всех доступных приложений windows, которые запущены на текущей сессии + :type inElement: UIO объект, опциональный + :param inFlagRaiseException: True - формировать ошибку exception, если платформа не обнаружина ни одного UIO объекта по заданному UIO селектору. False - обратный случай. По умолчанию True + :type inFlagRaiseException: bool, опциональный + :return: Список UIO объектов, которые удовлетворяют условиям UIO селектора ''' #Создать копию входного листа, чтобы не менять массив в других верхнеуровневых функциях inSpecificationList=copy.deepcopy(inSpecificationList) @@ -235,20 +243,26 @@ def UIOSelector_Get_UIOList (inSpecificationList,inElement=None,inFlagRaiseExcep raise pywinauto.findwindows.ElementNotFoundError("Robot can't find element by the UIOSelector") return lResultList -################################################################################################# -#Get first (in more than one) UIO (UI Object) -#inSpecificationList - UIOSelector -#inElement - Входной элемент - показатель, что не требуется выполнять коннект к процессу -#inFlagRaiseException - Флаг True - выкинуть ошибку в случае обнаружении пустого списка -#old name - PywinautoExtElementGet +#old:PywinautoExtElementGet def UIOSelector_Get_UIO (inSpecificationList,inElement=None,inFlagRaiseException=True): ''' - Get the pywinauto object by the UIO selector. + Получить список UIO объект по UIO селектору. Если критериям UIO селектора удовлетворяет несколько UIO объектов - вернуть первый из списка + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lDemoBaseUIOList = UIDesktop.UIOSelector_Get_UIO(lDemoBaseUIOSelector) #Получить 1-й UIO объект, которые удовлетворяет требованиям UIO селектора. В нашем примере либо None, либо UIO объект - :param inSpecificationList: - :param inElement: - :param inFlagRaiseException: - :return: + :param inSpecificationList: UIO Селектор, который определяет критерии поиска UI элементов + :type inSpecificationList: list, обязательный + :param inElement: Родительский элемент, от которого выполнить поиск UIO объектов по заданному UIO селектору. Если аргумент не задан, платформа выполнит поиск UIO объектов среди всех доступных приложений windows, которые запущены на текущей сессии + :type inElement: UIO объект, опциональный + :param inFlagRaiseException: True - формировать ошибку exception, если платформа не обнаружина ни одного UIO объекта по заданному UIO селектору. False - обратный случай. По умолчанию True + :type inFlagRaiseException: bool, опциональный + :return: UIO объект, которые удовлетворяют условиям UIO селектора, или None ''' lResult=None #Получить родительский объект если на вход ничего не поступило @@ -259,17 +273,25 @@ def UIOSelector_Get_UIO (inSpecificationList,inElement=None,inFlagRaiseException if lResult is None and inFlagRaiseException: raise pywinauto.findwindows.ElementNotFoundError("Robot can't find element by the UIOSelector") return lResult -################################################################################################# -#Check if UIO exist (Identified by the UIOSelector) -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! -#UIOSelector -#old name - - + +#old:- def UIOSelector_Exist_Bool (inUIOSelector): ''' - Check if object is exist by the UIO selector. + Проверить существование хотя бы 1-го UIO объекта по заданному UIO селектору + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lDemoBaseUIOExistBool = UIDesktop.UIOSelector_Exist_Bool(lDemoBaseUIOSelector) # Получить булевый результат проверки существования UIO объекта - :param inUIOSelector: - :return: True - Object is exist. False - else case + :param inUIOSelector: UIO Селектор, который определяет критерии поиска UIO объектов + :type inUIOSelector: list, обязательный + :return: True - существует хотя бы 1 UIO объект. False - не существует ни одного UIO объекта по заданному UIO селектору ''' lResult=False #Check the bitness @@ -294,27 +316,34 @@ def UIOSelector_Exist_Bool (inUIOSelector): else: lResult = lPIPEResponseDict["Result"] return lResult -################################################################################################# -#Wait for UIO is appear (at least one of them or all at the same time) -#inSpecificationListList - List of the UIOSelector -#inWaitSecs - Время ожидания объекта в секундах -#inFlagWaitAllInMoment - доп. условие - ожидать появление всех UIOSelector одновременно -#return: [0,1,2] - index of UIOSpecification, which is appear -#old name - - -#####Внимание##### -##Функция ожидания появления элементов (тк элементы могут быть недоступны, неизвестно в каком фреймворке каждый из них может появиться) -def UIOSelectorsSecs_WaitAppear_List (inSpecificationListList,inWaitSecs,inFlagWaitAllInMoment=False): + +#old: - +def UIOSelectorsSecs_WaitAppear_List (inSpecificationListList,inWaitSecs=86400.0,inFlagWaitAllInMoment=False): ''' - Wait for many UI object will appear in GUI for inWaitSecs seconds. + Ожидать появление хотя бы 1-го / всех UIO объектов по заданным UIO селекторам + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python - :param inSpecificationListList: UIOSelector list. - Example: [ + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lNotepadOKSelector = [{"title":"notepad"},{"title":"OK"}] + lNotepadCancelSelector = [{"title":"notepad"},{"title":"Cancel"}] + lDemoBaseUIOExistList = UIDesktop.UIOSelectorsSecs_WaitAppear_List([lDemoBaseUIOSelector, lNotepadOKSelector, lNotepadCancelSelector]) # Ожидать появление UIO объекта + + :param inSpecificationListList: Список UIO селекторов, которые определяют критерии поиска UIO объектов + Пример: [ [{"title":"notepad"},{"title":"OK"}], [{"title":"notepad"},{"title":"Cancel"}] ] - :param inWaitSecs: Float value (seconds) for wait UI element appear in GUI - :param inFlagWaitAllInMoment: True - Wait all UI objects from the UIOSelector list to be appeared - :return: List of index, which UI object UIO will be appeared. Example: [1] # Appear only UI object with UIO selector: [{"title":"notepad"},{"title":"Cancel"}] + :type inSpecificationListList: list, обязательный + :param inWaitSecs: Количество секунд, которые отвести на ожидание UIO объектов. По умолчанию 24 часа (86400 секунд) + :type inWaitSecs: float, необязательный + :param inFlagWaitAllInMoment: True - Ожидать до того момента, пока не появятся все запрашиваемые UIO объекты на рабочей области + :return: Список индексов, которые указывают на номер входящих UIO селекторов, которые были обнаружены на рабочей области. Пример: [0,2] ''' lResultFlag=False lSecsSleep = 1 #Настроечный параметр @@ -345,29 +374,36 @@ def UIOSelectorsSecs_WaitAppear_List (inSpecificationListList,inWaitSecs,inFlagW lSecsDone=lSecsDone+lSecsSleep time.sleep(lSecsSleep) return lResultList -################################################################################################# -#Wait for UIO is Disappear (at least one of them or all at the same time) -#inSpecificationListList - List of the UIOSelector -#inWaitSecs - Время ожидания пропажи объекта в секундах -#inFlagWaitAllInMoment - доп. условие - ожидать пропажу всех UIOSelector одновременно -#return: [0,1,2] - index of UIOSpecification, which is Disappear -#old name - - -#####Внимание##### -##Функция ожидания пропажи элементов (тк элементы могут быть недоступны, неизвестно в каком фреймворке каждый из них может появиться) -def UIOSelectorsSecs_WaitDisappear_List (inSpecificationListList,inWaitSecs,inFlagWaitAllInMoment=False): + +#old: - +def UIOSelectorsSecs_WaitDisappear_List (inSpecificationListList,inWaitSecs=86400.0,inFlagWaitAllInMoment=False): ''' - Wait for many UI object will disappear in GUI for inWaitSecs seconds. + Ожидать исчезновение хотя бы 1-го / всех UIO объектов по заданным UIO селекторам + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lNotepadOKSelector = [{"title":"notepad"},{"title":"OK"}] + lNotepadCancelSelector = [{"title":"notepad"},{"title":"Cancel"}] + lDemoBaseUIOExistList = UIDesktop.UIOSelectorsSecs_WaitDisappear_List([lDemoBaseUIOSelector, lNotepadOKSelector, lNotepadCancelSelector]) # Ожидать исчезновение UIO объектов - :param inSpecificationListList: UIOSelector list. - Example: [ + :param inSpecificationListList: Список UIO селекторов, которые определяют критерии поиска UIO объектов + Пример: [ [{"title":"notepad"},{"title":"OK"}], [{"title":"notepad"},{"title":"Cancel"}] ] - :param inWaitSecs: Float value (seconds) for wait UI element disappear in GUI - :param inFlagWaitAllInMoment: True - Wait all UI objects from the UIOSelector list to be disappeared. - :return: List of index, which UI object UIO will be disappeared. Example: [1] # Disappear only UI object with UIO selector: [{"title":"notepad"},{"title":"Cancel"}] - :return: + :type inSpecificationListList: list, обязательный + :param inWaitSecs: Количество секунд, которые отвести на ожидание исчезновения UIO объектов. По умолчанию 24 часа (86400 секунд) + :type inWaitSecs: float, необязательный + :param inFlagWaitAllInMoment: True - Ожидать до того момента, пока не исчезнут все запрашиваемые UIO объекты на рабочей области + :return: Список индексов, которые указывают на номер входящих UIO селекторов, которые были обнаружены на рабочей области. Пример: [0,2] ''' + lResultFlag=False lSecsSleep = 1 #Настроечный параметр lSecsDone = 0 @@ -397,56 +433,77 @@ def UIOSelectorsSecs_WaitDisappear_List (inSpecificationListList,inWaitSecs,inFl lSecsDone=lSecsDone+lSecsSleep time.sleep(lSecsSleep) return lResultList -################################################################################################# -#Wait for UIO is appear (at least one of them or all at the same time) -#inSpecificationList - UIOSelector -#inWaitSecs - Время ожидания объекта в секундах -#return: Bool - True - UIO is appear -#old name - - + +#old: - def UIOSelectorSecs_WaitAppear_Bool (inSpecificationList,inWaitSecs): ''' - Wait for UI object will appear in GUI for inWaitSecs seconds. + Ожидать появление 1-го UIO объекта по заданному UIO селектору + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lDemoBaseUIOExistBool = UIDesktop.UIOSelectorSecs_WaitAppear_Bool(lDemoBaseUIOSelector) # Ожидать появление UIO объекта - :param inSpecificationList: UIOSelector. Example: [{"title":"notepad"},{"title":"OK"}] - :param inWaitSecs: Float value (seconds) for wait UI element appear in GUI - :return: True - UI object will appear. False - else case + :param inSpecificationList: UIO селектор, который определяет критерии поиска UIO объекта + :type inSpecificationList: list, обязательный + :param inWaitSecs: Количество секунд, которые отвести на ожидание UIO объекта. По умолчанию 24 часа (86400 секунд) + :type inWaitSecs: float, необязательный + :return: True - UIO объект был обнаружен. False - обратная ситуациая ''' lWaitAppearList=UIOSelectorsSecs_WaitAppear_List([inSpecificationList],inWaitSecs) lResult=False if len(lWaitAppearList)>0: lResult=True return lResult -################################################################################################# -#Wait for UIO is disappear (at least one of them or all at the same time) -#inSpecificationList - UIOSelector -#inWaitSecs - Время ожидания пропажи объекта в секундах -#return: Bool - True - UIO is Disappear + #old name - - def UIOSelectorSecs_WaitDisappear_Bool (inSpecificationList,inWaitSecs): ''' - Wait for UI object will disappear in GUI for inWaitSecs seconds. + Ожидать исчезновение 1-го UIO объекта по заданному UIO селектору + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lDemoBaseUIOExistBool = UIDesktop.UIOSelectorSecs_WaitDisappear_Bool(lDemoBaseUIOSelector) # Ожидать исчезновение UIO объекта - :param inSpecificationList: UIOSelector. - Example: [{"title":"notepad"},{"title":"OK"}] - :param inWaitSecs: Float value (seconds) for wait UI element disappear in GUI - :return: True - UI object will disappear. False - else case + :param inSpecificationList: UIO селектор, который определяет критерии поиска UIO объекта + :type inSpecificationList: list, обязательный + :param inWaitSecs: Количество секунд, которые отвести на исчезновение UIO объекта. По умолчанию 24 часа (86400 секунд) + :type inWaitSecs: float, необязательный + :return: True - UIO объект был обнаружен. False - обратная ситуациая ''' lWaitDisappearList=UIOSelectorsSecs_WaitDisappear_List([inSpecificationList],inWaitSecs) lResult=False if len(lWaitDisappearList)>0: lResult=True return lResult -################################################################################################# -#Get process bitness (32 or 64) -#inSpecificationList - UIOSelector -#old name - None -#return None (if Process not found), int 32, or int 64 + +#old: - def UIOSelector_Get_BitnessInt (inSpecificationList): ''' - Detect process bitness by the UI Object UIO Selector. + Определить разрядность приложения по UIO селектору. Вернуть результат в формате целого числа (64 или 32) + + .. code-block:: python - :param inSpecificationList: UIOSelector. Example: [{"title":"notepad"},{"title":"OK"}] - :return: int 32 or int 64 + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lDemoBaseBitInt = UIDesktop.UIOSelector_Get_BitnessInt(lDemoBaseUIOSelector) # Определить разрядность приложения, в котором обнаружен UIO объект по селектору + + :param inSpecificationList: UIO селектор, который определяет критерии поиска UIO объекта + :type inSpecificationList: list, обязательный + :return: None - UIO объект не обнаружен; 64 (int) - разрядность приложения равна 64 битам; 32 (int) - разрядность приложения равна 32 битам ''' lResult=None #Получить объект Application (Для проверки разрядности) @@ -457,18 +514,24 @@ def UIOSelector_Get_BitnessInt (inSpecificationList): else: lResult=32 return lResult -################################################################################################# -#Get process bitness ("32" or "64") -#inSpecificationList - UIOSelector -#old name - None -#return None (if Process not found), int 32, or int 64 + +#old: - def UIOSelector_Get_BitnessStr (inSpecificationList): - ''' - Detect process bitness by the UI Object UIO Selector. + """ + Определить разрядность приложения по UIO селектору. Вернуть результат в формате строки ("64" или "32") - :param inSpecificationList: UIOSelector. Example: [{"title":"notepad"},{"title":"OK"}] - :return: str "32" or str "64" - ''' + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lDemoBaseBitStr = UIDesktop.UIOSelector_Get_BitnessStr(lDemoBaseUIOSelector) # Определить разрядность приложения, в котором обнаружен UIO объект по селектору + + :param inSpecificationList: UIO селектор, который определяет критерии поиска UIO объекта + :type inSpecificationList: list, обязательный + :return: None - UIO объект не обнаружен; "64" (str) - разрядность приложения равна 64 битам; "32" (str) - разрядность приложения равна 32 битам + """ lResult=None #Получить объект Application (Для проверки разрядности) lRootElement=PWASpecification_Get_PWAApplication(inSpecificationList) @@ -478,28 +541,40 @@ def UIOSelector_Get_BitnessStr (inSpecificationList): else: lResult="32" return lResult -################################################################################################# -#Get OS bitness (32 or 64) -#old name - None -#return int 32, or int 64 + +#old: - def Get_OSBitnessInt (): ''' - Detect OS bitness. + Определить разрядность робота, в котором запускается данная функция - :return: int 32 or int 64 + .. code-block:: python + + from pyOpenRPA.Robot import UIDesktop + lRobotBitInt = UIDesktop.Get_OSBitnessInt() # Определить разрядность робота, в котором была вызвана это функция + + :return: 64 (int) - разрядность приложения равна 64 битам; 32 (int) - разрядность приложения равна 32 битам ''' lResult=32 if pywinauto.sysinfo.is_x64_OS(): lResult=64 return lResult -################################################################################################# +#old: - def UIOSelector_SafeOtherGet_Process(inUIOSelector): - ''' - Safe get other process or None if destination app is the other/same bitness + """ + Получить процесс робота другой разрядности (если приложение UIO объекта выполняется в другой разрядности). Функция возвращает None, если разрядность робота совпадает с разрядностью приложения UIO объекта, либо если при инициализации робота не устанавливался интерпретатор другой разрядности. - :param inUIOSelector: UIO Selector of the UI object - :return: None or process (of the other bitness) - ''' + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"},{"title":"DEMO", "depth_start": 5, "depth_end": 5}] + lOtherBitnessProcess = UIDesktop.UIOSelector_SafeOtherGet_Process(lDemoBaseUIOSelector) # Вернуть процесс робота, схожей разрядности + + :param inUIOSelector: UIO селектор, который определяет критерии поиска UIO объекта + :type inUIOSelector: list, обязательный + :return: Процесс робота схожей разрядности + """ #Default value lResult = None #Go check bitness if selector exists @@ -509,15 +584,44 @@ def UIOSelector_SafeOtherGet_Process(inUIOSelector): if lUIOSelectorAppBitness and Utils.ProcessBitness.mSettingsDict["BitnessProcessCurrent"] != lUIOSelectorAppBitness: lResult = Utils.ProcessBitness.OtherProcessGet() return lResult -################################################################################################## +#old: GetControl def PWASpecification_Get_UIO(inControlSpecificationArray): - ''' - #Backend def selection - attribute "backend" ("win32" || "uia") in 1-st list element - #old name - GetControl + """ + Получить UIO объект по PWA (pywinauto) селектору. (https://pywinauto.readthedocs.io/en/latest/code/pywinauto.findwindows.html). Мы рекомендуем использовать метод UIOSelector_UIO_Get, так как UIO селектор обладает большей функциональностью. - :param inControlSpecificationArray: List of dict, dict in pywinauto.find_windows notation - :return: list of UIO object - ''' + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIOObject = UIDesktop.PWASpecification_Get_UIO(lDemoBaseUIOSelector) # Получить UIO объект по PWA селектору + + :param inControlSpecificationArray: PWA селектор, который определяет критерии поиска UIO объекта + Допустимые ключи PWA селектора: + + - class_name содержимое атрибута class UIO объекта + - class_name_re содержимое атрибута class UIO объекта, которое удовлетворяет установленному рег. выражению + - process идентификатор процесса, в котором находится UIO объект + - title содержимое атрибута title UIO объекта + - title_re содержимое атрибута title UIO объекта, которое удовлетворяет установленному рег. выражению + - top_level_only признак поиска только на верхнем уровне приложения. По умолчанию True + - visible_only признак поиска только среди видимых UIO объектов. По умолчанию True + - enabled_only признак поиска только среди разблокированных UIO объектов. По умолчанию False + - best_match содержимое атрибута title UIO объекта максимально приближено к заданному + - handle идентификатор handle искомого UIO объекта + - ctrl_index индекс UIO объекта среди всех дочерних объектов в списке родительского + - found_index индекс UIO объекта среди всех обнаруженных + - predicate_func пользовательская функция проверки соответсвия UIO элемента + - active_only признак поиска только среди активных UIO объектов. По умолчанию False + - control_id идентификатор control_id искомого UIO объекта + - control_type тип элемента (применимо, если backend == "uia") + - auto_id идентификатор auto_id искомого UIO объекта (применимо, если backend == "uia") + - framework_id идентификатор framework_id искомого UIO объекта (применимо, если backend == "uia") + - backend вид технологии подключения к поиску UIO объекта ("uia" или "win32") + :type inControlSpecificationArray: list, обязательный + :return: UIO объект + """ #Определение backend lBackend=mDefaultPywinautoBackend if "backend" in inControlSpecificationArray[0]: @@ -563,14 +667,44 @@ def PWASpecification_Get_UIO(inControlSpecificationArray): #Добавить объект в результирующий массив lResultList.append(lTempObject) return lResultList -################################################################################################## + def PWASpecification_Get_PWAApplication(inControlSpecificationArray): - ''' - #Backend selection - attribute "backend" ("win32" || "uia") in 1-st list element + """ + Получить значение атрибута backend по PWA (pywinauto) селектору. Мы рекомендуем использовать метод UIOSelector_UIO_Get, так как UIO селектор обладает большей функциональностью. - :param inControlSpecificationArray: List of dict, dict in pywinauto.find_windows notation - :return: process application object - ''' + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lBackendStr = UIDesktop.PWASpecification_Get_PWAApplication(lDemoBaseUIOSelector) # Получить backend по PWA селектору + + :param inControlSpecificationArray: PWA селектор, который определяет критерии поиска UIO объекта + Допустимые ключи PWA селектора: + + - class_name содержимое атрибута class UIO объекта + - class_name_re содержимое атрибута class UIO объекта, которое удовлетворяет установленному рег. выражению + - process идентификатор процесса, в котором находится UIO объект + - title содержимое атрибута title UIO объекта + - title_re содержимое атрибута title UIO объекта, которое удовлетворяет установленному рег. выражению + - top_level_only признак поиска только на верхнем уровне приложения. По умолчанию True + - visible_only признак поиска только среди видимых UIO объектов. По умолчанию True + - enabled_only признак поиска только среди разблокированных UIO объектов. По умолчанию False + - best_match содержимое атрибута title UIO объекта максимально приближено к заданному + - handle идентификатор handle искомого UIO объекта + - ctrl_index индекс UIO объекта среди всех дочерних объектов в списке родительского + - found_index индекс UIO объекта среди всех обнаруженных + - predicate_func пользовательская функция проверки соответсвия UIO элемента + - active_only признак поиска только среди активных UIO объектов. По умолчанию False + - control_id идентификатор control_id искомого UIO объекта + - control_type тип элемента (применимо, если backend == "uia") + - auto_id идентификатор auto_id искомого UIO объекта (применимо, если backend == "uia") + - framework_id идентификатор framework_id искомого UIO объекта (применимо, если backend == "uia") + - backend вид технологии подключения к поиску UIO объекта ("uia" или "win32") + :type inControlSpecificationArray: list, обязательный + :return: "win32" или "uia" + """ inControlSpecificationArray=copy.deepcopy(inControlSpecificationArray) #Определение backend lBackend=mDefaultPywinautoBackend @@ -600,16 +734,23 @@ def PWASpecification_Get_PWAApplication(inControlSpecificationArray): #Скорректировано из-за недопонимания структуры lTempObject=lRPAApplication return lTempObject - -########################################################################################################### +#old: AutomationSearchMouseElement def UIOSelector_SearchChildByMouse_UIO(inElementSpecification): - ''' - UIOSelector (see description on the top of the document) - #old name - AutomationSearchMouseElement + """ + Инициировать визуальный поиск UIO объекта с помощью указателя мыши. При наведении указателя мыши UIO объект выделяется зеленой рамкой. Остановить режим поиска можно с помощью зажима клавиши ctrl left на протяжении нескольких секунд. После этого в веб окне студии будет отображено дерево расположения искомого UIO объекта. - :param inElementSpecification: UIOSelector of the UI Object - :return: pywinauto element wrapper instance or None - ''' + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIO = UIDesktop.UIOSelector_SearchChildByMouse_UIO(lDemoBaseUIOSelector) # Инициировать поиск дочернего UIO объекта, который расположен внутри lDemoBaseUIOSelector. + + :param inElementSpecification: UIO селектор, который определяет критерии поиска родительского UIO объекта, в котором будет производиться поиск дочернего UIO объекта + :type inElementSpecification: list, обязательный + :return: UIO объект или None (если UIO не был обнаружен) + """ lGUISearchElementSelected=None #Настройка - частота обновления подсвечивания lTimeSleepSeconds=0.4 @@ -647,15 +788,26 @@ def UIOSelector_SearchChildByMouse_UIO(inElementSpecification): #Вернуть результат поиска return lElementFoundedList -#################################################################################################### -#old name - AutomationSearchMouseElementHierarchy +#old: - AutomationSearchMouseElementHierarchy def UIOSelector_SearchChildByMouse_UIOTree(inUIOSelector): - ''' - !!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! + """ + Получить список уровней UIO объекта с указнием всех имеющихся атрибутов по входящему UIO селектору. + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lBackendStr = UIDesktop.UIOSelector_SearchChildByMouse_UIOTree(lDemoBaseUIOSelector) # Получить список атрибутов всех родительских элементов lDemoBaseUIOSelector. + + :param inUIOSelector: UIO селектор, который определяет UIO объект, для которого будет произведено извлечение всех атрибутов на всех уровнях. + :type inUIOSelector: list, обязательный + :return: list, список атрибутов на каждом уровне UIO объекта + """ - :param inUIOSelector: UIOSelector of the UI Object - :return: ? - ''' lItemInfo = [] #Check the bitness lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector) @@ -715,10 +867,24 @@ def UIOSelector_SearchChildByMouse_UIOTree(inUIOSelector): lItemInfo = lPIPEResponseDict["Result"] #Вернуть результат return lItemInfo -#################################################################################################### -#inElement- UIO (UI Object) #old name - PywinautoExtElementCtrlIndexGet def UIO_GetCtrlIndex_Int(inElement): + """ + Получить индекс UIO объекта inElement в списке родительского UIO объекта. + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIO = UIDesktop.UIOSelector_Get_UIO(lDemoBaseUIOSelector) # Получить UIO объект по UIO селектору. + lUIOIndexInt = UIDesktop.UIO_GetCtrlIndex_Int(lUIO) # Получить индекс UIO объекта в списке у родительского UIO объекта. + + :param inElement: UIO объект, для которого требуется определить индекс в списке родительского UIO объекта. + :type inElement: list, обязательный + :return: int, индекс UIO объекта в списке родительского UIO объекта + """ lResult = None #Выполнить алгоритм, если есть Element if inElement is not None: @@ -747,12 +913,27 @@ def UIO_GetCtrlIndex_Int(inElement): #Вернуть результат return lResult -#################################################################################################### -# Get the UIO Info list for the selected criteria -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! -#inSpecificationList - UIOSelector -#old name - PywinautoExtElementsGetInfo +#old: - PywinautoExtElementsGetInfo def UIOSelector_Get_UIOInfoList (inUIOSelector, inElement=None): + """ + Техническая функция: Получить список параметров последних уровней UIO селектора по UIO объектам, которые удовлетворяют входящим inUIOSelector, поиск по которым будет производится от уровня inElement. + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIOInfoList = UIDesktop.UIOSelector_Get_UIOInfoList(lDemoBaseUIOSelector) # Получить словарь параметров по UIO селектору. + + :param inUIOSelector: UIO селектор, который определяет UIO объект, для которого будет произведено извлечение всех атрибутов на всех уровнях. + :type inUIOSelector: list, обязательный + :param inElement: UIO объект, от которого выполнить поиск дочерних UIO объектов по UIO селектору inUIOSelector. По умолчанию None - поиск среди всех приложений. + :type inElement: UIO объект, необязательный + :return: dict, пример: {"title":None,"rich_text":None,"process_id":None,"process":None,"handle":None,"class_name":None,"control_type":None,"control_id":None,"rectangle":{"left":None,"top":None,"right":None,"bottom":None}, 'runtime_id':None} + """ #Check the bitness lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector) if lSafeOtherProcess is None: @@ -778,17 +959,25 @@ def UIOSelector_Get_UIOInfoList (inUIOSelector, inElement=None): lResultList = lPIPEResponseDict["Result"] return lResultList -#################################################################################################### -#Try to restore (maximize) window, if it's was minimized -#(особенность uia backend - он не может прицепиться к окну, если оно свернуто) -#inSpecificationList - UIOSelector -#old name - PywinautoExtTryToRestore +#old: - PywinautoExtTryToRestore def UIOSelector_TryRestore_Dict(inSpecificationList): """ - Try to restore (maximize) window, if it's minimized. (!IMPORTANT! When use UIA framework minimized windows doesn't appear by the UIOSelector. You need to try restore windows and after that try to get UIO) + Восстановить окно приложения на экране по UIO селектору inSpecificationList, если оно было свернуто. Функция обернута в try .. except - ошибок не возникнет. + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ УЖЕ ИСПОЛЬЗУЕТСЯ В РЯДЕ ДРУГИХ ФУНКЦИЙ ТАК КАК АДРЕССАЦИЯ ПО UIA FRAMEWORK НЕДОСТУПНА, ЕСЛИ ПРИЛОЖЕНИЕ СВЕРНУТО. + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + UIDesktop.UIOSelector_TryRestore_Dict(lDemoBaseUIOSelector) # Попытка восстановления свернутого окна по UIO селектору. - :param inSpecificationList: UIOSelector - List of items, which contains condition attributes - :return: + :param inSpecificationList: UIO селектор, который определяет UIO объект, для которого будет произведено извлечение всех атрибутов на всех уровнях. + :type inSpecificationList: list, обязательный """ lResult={} try: @@ -802,17 +991,24 @@ def UIOSelector_TryRestore_Dict(inSpecificationList): except Exception: True==False return lResult -#################################################################################################### -#Get the list of the UI object activities -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! -#inControlSpecificationArray - UIOSelector -#old name - ElementActionGetList + +#old: - ElementActionGetList def UIOSelector_Get_UIOActivityList (inUIOSelector): """ - Get the list of the UI object activities + Получить список доступных действий/функций по UIO селектору inUIOSelector. Описание возможных активностей см. ниже. + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python - :param inUIOSelector: UIOSelector - List of items, which contains condition attributes - :return: + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lActivityList = UIDesktop.UIOSelector_Get_UIOActivityList(lDemoBaseUIOSelector) # Получить список активностей по UIO селектору. + + :param inUIOSelector: UIO селектор, который определяет UIO объект, для которого будет представлен перечень доступных активностей. + :type inUIOSelector: list, обязательный """ #Check the bitness lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector) @@ -845,21 +1041,30 @@ def UIOSelector_Get_UIOActivityList (inUIOSelector): lResult = lPIPEResponseDict["Result"] return lResult -#################################################################################################### -#Run the activity in UIO (UI Object) -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! -#inUIOSelector -#inActionName - UIOActivity (name) from Pywinauto -#old name - ElementRunAction +#old: - ElementRunAction def UIOSelectorUIOActivity_Run_Dict(inUIOSelector, inActionName, inArgumentList=None, inkwArgumentObject=None): """ - Run the activity in UIO (UI Object) + Выполнить активность inActionName над UIO объектом, полученным с помощью UIO селектора inUIOSelector. Описание возможных активностей см. ниже. + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) - :param inUIOSelector: UIOSelector - List of items, which contains condition attributes - :param inActionName: UIOActivity (name) activity name string from Pywinauto - :param inArgumentList: - :param inkwArgumentObject: - :return: + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lActivityResult = UIDesktop.UIOSelectorUIOActivity_Run_Dict(lDemoBaseUIOSelector, "click") # выполнить действие над UIO объектом с помощью UIO селектора. + + :param inUIOSelector: UIO селектор, который определяет UIO объект, для которого будет представлен перечень доступных активностей. + :type inUIOSelector: list, обязательный + :param inActionName: наименование активности, которую требуется выполнить над UIO объектом + :type inActionName: str, обязательный + :param inArgumentList: список передаваемых неименованных аргументов в функцию inActionName + :type inArgumentList: list, необязательный + :param inkwArgumentObject: словарь передаваемых именованных аргументов в функцию inActionName + :type inkwArgumentObject: dict, необязательный + :return: возвращает результат запускаемой функции с наименованием inActionName над UIO объектом """ if inArgumentList is None: inArgumentList=[] # 2021 02 22 Minor fix by Ivan Maslov if inkwArgumentObject is None: inkwArgumentObject={} # 2021 02 22 Minor fix by Ivan Maslov @@ -905,16 +1110,57 @@ def UIOSelectorUIOActivity_Run_Dict(inUIOSelector, inActionName, inArgumentList= lResult = lPIPEResponseDict["Result"] return lResult -#################################################################################################### -#Get the UIO dict of the attributes -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! #old name - ElementGetInfo def UIOSelector_Get_UIOInfo(inUIOSelector): """ - Get the UIO dict of the attributes + Получить свойства UIO объекта (element_info), по заданному UIO селектору. Ниже представлен перечень возвращаемых свойств. + + Для backend = win32: + + - automation_id (int) + - class_name (str) + - control_id (int) + - control_type (str) + - full_control_type (str) + - enabled (bool) + - handle (int) + - name (str) + - parent (object/UIO) + - process_id (int) + - rectangle (object/rect) + - rich_text (str) + - visible (bool) + + Для backend = uia: - :param inUIOSelector: UIOSelector - List of items, which contains condition attributes - :return: + - automation_id (int) + - class_name (str) + - control_id (int) + - control_type (str) + - enabled (bool) + - framework_id (int) + - handle (int) + - name (str) + - parent (object/UIO) + - process_id (int) + - rectangle (object/rect) + - rich_text (str) + - runtime_id (int) + - visible (bool) + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIOElementInfoDict = UIDesktop.UIOSelector_Get_UIOInfo(lDemoBaseUIOSelector) #Получить свойства над UIO объектом с помощью UIO селектора. + + :param inUIOSelector: UIO селектор, который определяет UIO объект, для которого будет представлен перечень доступных активностей. + :type inUIOSelector: list, обязательный + :return: словарь свойств element_info: Пример {"control_id": ..., "process_id": ...} """ #Check the bitness lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector) @@ -945,12 +1191,28 @@ def UIOSelector_Get_UIOInfo(inUIOSelector): else: lResultList = lPIPEResponseDict["Result"] return lResultList -#################################################################################################### -#Search child UIO by the: Parent UIO, X, Y -#inHierarchyList: [{"index":<>,"element":<>}] - technical argument for internal purpose -#result -List of dict [{"index":<>,"element":<>}] -- list of element hierarchy specifications -#old name - GUISearchElementByRootXY +#old: - GUISearchElementByRootXY def UIOXY_SearchChild_ListDict(inRootElement,inX,inY,inHierarchyList=None): + """ + Техническая функция: Получить иерархию вложенности UIO объекта по заданным корневому UIO объекту, координатам X и Y. + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIO = UIDesktop.UIOSelector_Get_UIO(lDemoBaseUIOSelector) # Получить UIO объект с помощью UIO селектора + lUIOHierarchyList = UIDesktop.UIOXY_SearchChild_ListDict(lUIO, 100, 200) # Получить UIO объект с помощью UIO селектора родительского элемента и координат X / Y + + :param inRootElement: родительский UIO объект, полученный ранее с помощью UIO селектора. + :type inRootElement: object UIO, обязательный + :param inX: родительский UIO объект, полученный ранее с помощью UIO селектора. + :type inX: int, обязательный + :param inY: родительский UIO объект, полученный ранее с помощью UIO селектора. + :type inY: int, обязательный + :return: Список словарей - уровней UIO объектов + """ if inHierarchyList is None: inHierarchyList = [] #Инициализация результирующего значения lResultElement = None @@ -1035,21 +1297,27 @@ def UIOXY_SearchChild_ListDict(inRootElement,inX,inY,inHierarchyList=None): False == False return lResultHierarchyList -################################################################################################### -#Get list of child UIO's by Parent UIOSelector -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! -#inControlSpecificationArray- UIOSelector -#old name - ElementGetChildElementList +#old: - ElementGetChildElementList def UIOSelector_GetChildList_UIOList(inUIOSelector=None, inBackend=mDefaultPywinautoBackend): """ - Get list of child UIO's by the parent UIOSelector + Получить список дочерних UIO объектов по входящему UIO селектору inUIOSelector. + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) - :param inUIOSelector: UIOSelector - List of items, which contains condition attributes - :param inBackend: "win32" or "uia" - :return: - """ + .. code-block:: python + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIOList = UIDesktop.UIOSelector_GetChildList_UIOList(lDemoBaseUIOSelector) # Получить список дочерних UIO объектов с помощью UIO селектора + :param inUIOSelector: родительский UIO объект, полученный ранее с помощью UIO селектора. + :type inUIOSelector: list, обязательный + :param inBackend: вид backend "win32" или "uia". По умолчанию mDefaultPywinautoBackend ("win32") + :type inBackend: str, необязательный + :return: список дочерних UIO объектов + """ if inUIOSelector is None: inUIOSelector = [] #mRobotLogger.info(f"File!!!!") #mRobotLogger.info(f"inSelector:{str(inUIOSelector)}, inBackend:{str(inBackend)}") @@ -1099,12 +1367,24 @@ def UIOSelector_GetChildList_UIOList(inUIOSelector=None, inBackend=mDefaultPywin lResultList = lPIPEResponseDict["Result"] return lResultList -#################################################################################################### -#Подготовить массив для обращшения к поиску элемементов -#inControlSpecificationArray - UIOSelector (can be dirty) -#old name 1 - ElementSpecificationArraySearchPrepare -#old name 2 - ElementSpecificationListNormalize +#old1: - ElementSpecificationArraySearchPrepare +#old2: - ElementSpecificationListNormalize def UIOSelector_SearchUIONormalize_UIOSelector (inControlSpecificationArray): + """ + Нормализовать UIO селектор для дальнейшего использования в функциях поиск UIO объекта. Если недопустимых атрибутов не присутствует, то оставить как есть. + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelectorDitry = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lDemoBaseUIOSelectorClean = UIDesktop.UIOSelector_SearchUIONormalize_UIOSelector(lDemoBaseUIOSelectorDitry) # Очистить UIO селектор от недопустимых ключей для дальнейшего использования + + :param inControlSpecificationArray: UIO селектор, который определяет UIO объект, для которого будет представлен перечень доступных активностей. + :type inControlSpecificationArray: list, обязательный + :return: нормализованный UIO селектор + """ lResult=[] #Циклический обход for lSpecificationItem in inControlSpecificationArray: @@ -1172,12 +1452,25 @@ def UIOSelector_SearchUIONormalize_UIOSelector (inControlSpecificationArray): lResult.append(lSpecificationItemNew) #Вернуть результат return lResult -#################################################################################################### -#Подготовить массив для обращшения к поиску процесса (отличается от поиска элемента, тк данная функция нужна для нормализации спецификации для подключения к процессу с окнами) -#inControlSpecificationArray - UIOSelector (can be dirty) + #old name 1 - ElementSpecificationArraySearchPrepare #old name 2 - ElementSpecificationListNormalize def UIOSelector_SearchProcessNormalize_UIOSelector (inControlSpecificationArray): + """ + Нормализовать UIO селектор для дальнейшего использования в функциях поиска процесса, в котором находится искомый UIO объект. Если недопустимых атрибутов не присутствует, то оставить как есть. + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelectorDitry = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lDemoBaseUIOSelectorClean = UIDesktop.UIOSelector_SearchProcessNormalize_UIOSelector(lDemoBaseUIOSelectorDitry) # Очистить UIO селектор от недопустимых ключей для дальнейшего использования + + :param inControlSpecificationArray: UIO селектор, который определяет UIO объект, для которого будет представлен перечень доступных активностей. + :type inControlSpecificationArray: list, обязательный + :return: нормализованный UIO селектор + """ lResult=[] #Циклический обход for lSpecificationItem in inControlSpecificationArray: @@ -1250,11 +1543,25 @@ def UIOSelector_SearchProcessNormalize_UIOSelector (inControlSpecificationArray) lResult.append(lSpecificationItemNew) #Вернуть результат return lResult -#################################################################################################### -#Transfer UI object element info (pywinauto) to UIOInfo (dict of attributes) -#inElementInfo - UIOEI -#old name - ElementInfoExportObject + +#old: - ElementInfoExportObject def UIOEI_Convert_UIOInfo(inElementInfo): + """ + Техническая функция: Дообогащение словаря с параметрами UIO объекта по заданному UIO.element_info + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIO = UIDesktop.UIOSelector_Get_UIO(lDemoBaseUIOSelector) # Получить UIO объект по UIO селектору. + lUIOProcessInfoDict = UIDesktop.UIOEI_Convert_UIOInfo(lUIO.element_info) + + :param inElementInfo: экземпляр класса UIO.element_info, для которого требуется дообогатить словарь с параметрами (в дальнейшем можно использовать как элемент UIO селектора). + :type inElementInfo: object, обязательный + :return: dict, пример: {"title":None,"rich_text":None,"process_id":None,"process":None,"handle":None,"class_name":None,"control_type":None,"control_id":None,"rectangle":{"left":None,"top":None,"right":None,"bottom":None}, 'runtime_id':None} + """ #Подготовить выходную структуру данных lResult = {"title":None,"rich_text":None,"process_id":None,"process":None,"handle":None,"class_name":None,"control_type":None,"control_id":None,"rectangle":{"left":None,"top":None,"right":None,"bottom":None}, 'runtime_id':None} #Проверка name @@ -1322,10 +1629,21 @@ def UIOEI_Convert_UIOInfo(inElementInfo): #Вернуть результат return lResult -################################################################################################### -#Get list of top level -#old name - GetRootElementList +#old: - GetRootElementList def BackendStr_GetTopLevelList_UIOInfo(inBackend=mDefaultPywinautoBackend): + """ + Получить список UIOInfo словарей - процессы, которые запущены в рабочей сессии и готовы для взаимодействия с роботом через backend inBackend + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + lAppList = UIDesktop.BackendStr_GetTopLevelList_UIOInfo() # Очистить UIO селектор от недопустимых ключей для дальнейшего использования + + :param inBackend: вид backend, который планируется использовать для взаимодействия с UIO объектами + :type inBackend: list, обязательный + :return: список UIOInfo словарей + """ #Получить список объектов lResultList=pywinauto.findwindows.find_elements(top_level_only=True,backend=inBackend) lResultList2=[] @@ -1334,16 +1652,23 @@ def BackendStr_GetTopLevelList_UIOInfo(inBackend=mDefaultPywinautoBackend): lResultList2.append(UIOEI_Convert_UIOInfo(lI)) return lResultList2 -################################################################################################### -#Highlight the UI object -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! -#old name - ElementDrawOutlineNew +#old: - ElementDrawOutlineNew def UIOSelector_Highlight(inUIOSelector): """ - Highlight (draw outline) the element (in app) by the UIO selector. + Подсветить на несколько секунд на экране зеленой рамкой UIO объект, который соответствует входящему UIO селектору inUIOSelector - :param inUIOSelector: UIOSelector - List of items, which contains condition attributes - :return: + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + UIDesktop.UIOSelector_Highlight(lDemoBaseUIOSelector) # Подсветить UIO объект по UIO селектору + + :param inUIOSelector: UIO селектор, который определяет UIO объект, для которого будет представлен перечень доступных активностей. + :type inUIOSelector: list, обязательный """ #Check the bitness lSafeOtherProcess = UIOSelector_SafeOtherGet_Process(inUIOSelector) @@ -1364,17 +1689,23 @@ def UIOSelector_Highlight(inUIOSelector): else: return lPIPEResponseDict["Result"] return True - -################################################################################################### -#inSpecificationArray - UIOSelector -#!!!!!Safe call is included (you can set activity and UIDesktop will choose the bitness and return the result)!!!!! -#old name - ElementDrawOutlineNewFocus +#old: - ElementDrawOutlineNewFocus def UIOSelector_FocusHighlight(inUIOSelector): """ - Set focus and highlight (draw outline) the element (in app) by the UIO selector. + Установить фокус и подсветить на несколько секунд на экране зеленой рамкой UIO объект, который соответствует входящему UIO селектору inUIOSelector + + !ВНИМАНИЕ! ДАННАЯ ФУНКЦИОНАЛЬНОСТЬ В АВТОМАТИЧЕСКОМ РЕЖИМЕ ПОДДЕРЖИВАЕТ ВСЕ РАЗРЯДНОСТИ ПРИЛОЖЕНИЙ (32|64), КОТОРЫЕ ЗАПУЩЕНЫ В СЕСИИ. PYTHON x64 ИМЕЕТ ВОЗМОЖНОСТЬ ВЗЗАИМОДЕЙСТВИЯ С x32 UIO ОБЪЕКТАМИ, НО МЫ РЕКОМЕНДУЕМ ДОПОЛНИТЕЛЬНО ИСПОЛЬЗОВАТЬ ИНТЕРПРЕТАТОР PYTHON x32 (ПОДРОБНЕЕ СМ. ФУНКЦИЮ Configure()) - :param inUIOSelector: UIOSelector - List of items, which contains condition attributes - :return: + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + UIDesktop.UIOSelector_FocusHighlight(lDemoBaseUIOSelector) # Установить фокус и подсветить UIO объект по UIO селектору + + :param inUIOSelector: UIO селектор, который определяет UIO объект, для которого будет представлен перечень доступных активностей. + :type inUIOSelector: list, обязательный """ #Check the bitness @@ -1397,9 +1728,29 @@ def UIOSelector_FocusHighlight(inUIOSelector): return lPIPEResponseDict["Result"] return True -################################################################################################### -#old name - draw_outline_new +#old: - draw_outline_new def UIO_Highlight(lWrapperObject,colour='green',thickness=2,fill=win32defines.BS_NULL,rect=None,inFlagSetFocus=False): + """ + Выполнить подсветку UIO объекта на экране + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIO = UIDesktop.UIOSelector_Get_UIO(lDemoBaseUIOSelector) # Получить UIO объект по UIO селектору + UIDesktop.UIO_Highlight(lUIO) # Подсветить UIO объект по UIO селектору зеленым цветом с толщиной подсветки 2 px. + + :param lWrapperObject: UIO объект, который будет подсвечен + :type lWrapperObject: object UIO, обязательный + :param colour: цвет подсветки UIO объекта. Варианты: 'red', 'green', 'blue'. По умолчанию 'green' + :type colour: str, необязательный + :param thickness: толщина подсветки UIO объекта. По умолчанию 2 + :type thickness: int, необязательный + :param inFlagSetFocus: признак установки фокуса на UIO объект перед подсветкой. По умолчанию False + :type inFlagSetFocus: bool, необязательный + """ if lWrapperObject is not None: """ Draw an outline around the window. @@ -1449,10 +1800,27 @@ def UIO_Highlight(lWrapperObject,colour='green',thickness=2,fill=win32defines.BS # delete the Display context that we created win32functions.DeleteDC(dc) -################################################################################################### -#Аналог подсвечивания + установка фокуса -#old name - draw_outline_new_focus +#old: - draw_outline_new_focus def UIO_FocusHighlight(lWrapperObject,colour='green',thickness=2,fill=win32defines.BS_NULL,rect=None): + """ + Установить фокус и выполнить подсветку UIO объекта на экране + + .. code-block:: python + + # UIDesktop: Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIDesktop + # 1С: UIO Селектор выбора базы + lDemoBaseUIOSelector = [{"title":"Запуск 1С:Предприятия","class_name":"V8TopLevelFrameTaxiStarter","backend":"uia"}] + lUIO = UIDesktop.UIOSelector_Get_UIO(lDemoBaseUIOSelector) # Получить UIO объект по UIO селектору + UIDesktop.UIO_FocusHighlight(lUIO) # Установить фокус и подсветить UIO объект по UIO селектору зеленым цветом с толщиной подсветки 2 px. + + :param lWrapperObject: UIO объект, который будет подсвечен + :type lWrapperObject: object UIO, обязательный + :param colour: цвет подсветки UIO объекта. Варианты: 'red', 'green', 'blue'. По умолчанию 'green' + :type colour: str, необязательный + :param thickness: толщина подсветки UIO объекта. По умолчанию 2 + :type thickness: int, необязательный + """ UIO_Highlight(lWrapperObject,'green',2,win32defines.BS_NULL,None,True) #Определить разрядность процесса diff --git a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/__init__.py b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/__init__.py index 8c4b3aa6..fc97568b 100644 --- a/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/__init__.py +++ b/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pyOpenRPA/__init__.py @@ -1,9 +1,9 @@ r""" -The OpenRPA package (from UnicodeLabs) +The pyOpenRPA package """ -__version__ = 'v1.2.12' +__version__ = 'v1.2.13' __all__ = [] -__author__ = 'Ivan Maslov ' +__author__ = 'Ivan Maslov ' #from .Core import Robot \ No newline at end of file diff --git a/Sources/GuideSphinx/01_HowToInstall.rst b/Sources/GuideSphinx/01_HowToInstall.rst index ad09df6c..21abf39c 100644 --- a/Sources/GuideSphinx/01_HowToInstall.rst +++ b/Sources/GuideSphinx/01_HowToInstall.rst @@ -2,25 +2,37 @@ 1. Первый запуск #################################### -Are you ready to install the pyOpenRPA solution on your machine? +Готовы испытать всю мощь перспективных технологий? -Ok, we start. -**Do the following operations:** +Будет очень интересно - начинаем! -- Download the pyOpenRPA package from master branch on GitLab [Download ZIP](https://gitlab.com/UnicodeLabs/OpenRPA/-/archive/master/OpenRPA-master.zip) -- Unzip the package +**Для начала необходимо выполнить следующие действия:** -**Installation has been completed :)** +- Скачать пакет pyOpenRPA c главной страницы https://pyopenrpa.ru/ +- Распаковать пакет куда угодно! + +**ВСЁ - Развертывание pyOpenRPA завершено! :)** ************************************************** -How to check installation +Проверить, что pyOpenRPA развернута корректно? ************************************************** -- Run portable python (built in the pyOpenRPA) +В папке pyOpenRPA запустить интерпретатор Python - - x32 python (GIT\\Resources\\WPy32-3720\\python-3.7.2\\python.exe) - - x64 python (GIT\\Resources\\WPy64-3720\\python-3.7.2.amd64\\python.exe) +- x32 Python (GIT\\Resources\\WPy32-3720\\python-3.7.2\\python.exe) +- x64 Python (GIT\\Resources\\WPy64-3720\\python-3.7.2.amd64\\python.exe) -**The pyOpenRPA has been successfully installed if the portable python 3.7.2 was started without any exceptions (see screenshot).** +**Платформа pyOpenRPA успешно развернута корректно. если интерпретаторы python 3.7.2 были запущены без проблем (см. скриншот).** .. image:: /img/cb5dec8cecafa7d64f6cd14b2672acce.png - :alt: cb5dec8cecafa7d64f6cd14b2672acce.png \ No newline at end of file + :alt: cb5dec8cecafa7d64f6cd14b2672acce.png + +****************************** +Быстрая навигация +****************************** + +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ \ No newline at end of file diff --git a/Sources/GuideSphinx/03_Copyrights_Contacts.rst b/Sources/GuideSphinx/03_Copyrights_Contacts.rst index f9a277f8..bb91f77f 100644 --- a/Sources/GuideSphinx/03_Copyrights_Contacts.rst +++ b/Sources/GuideSphinx/03_Copyrights_Contacts.rst @@ -80,4 +80,15 @@ pyOpenRPA - роботы Вам помогут! - Handlebars, v4.1.2, лицензия MIT, https://github.com/handlebars-lang/handlebars.js/blob/master/LICENSE - jinja2, v2.11.2, лицензия BSD 3-Clause, https://github.com/pallets/jinja/blob/main/LICENSE.rst - JupiterNotebook v6.1.4, лицензия BSD 3-Clause, https://github.com/jupyter/notebook/blob/main/LICENSE -- schedule, v1.1.0, лицензия MIT, https://github.com/dbader/schedule/blob/master/LICENSE.txt \ No newline at end of file +- schedule, v1.1.0, лицензия MIT, https://github.com/dbader/schedule/blob/master/LICENSE.txt + +****************************** +Быстрая навигация +****************************** + +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ \ No newline at end of file diff --git a/Sources/GuideSphinx/Agent/02_Defs.rst b/Sources/GuideSphinx/Agent/02_Defs.rst index 64850fbb..8801b5d3 100644 --- a/Sources/GuideSphinx/Agent/02_Defs.rst +++ b/Sources/GuideSphinx/Agent/02_Defs.rst @@ -1,5 +1,5 @@ #################################### -2. Defs +2. Функции #################################### ************************************************** @@ -11,13 +11,3 @@ pyOpenRPA.Agent.__Agent__ .. automodule:: pyOpenRPA.Agent.__Agent__ :members: :autosummary: - - -********** -References -********** - -`reStructuredText`_ - -.. target-notes:: -.. _`reStructuredText`: http://docutils.sourceforge.net/rst.html diff --git a/Sources/GuideSphinx/Orchestrator/01_Orchestrator.rst b/Sources/GuideSphinx/Orchestrator/01_Orchestrator.rst index f15992ed..09d195ee 100644 --- a/Sources/GuideSphinx/Orchestrator/01_Orchestrator.rst +++ b/Sources/GuideSphinx/Orchestrator/01_Orchestrator.rst @@ -1,83 +1,75 @@ +.. _module.orchestrator.dscription: + #################################### -1. Description +1. Описание #################################### -pyOpenRPA Orchestrator is the executable process. +************************************ +Общее +************************************ -The features of the orchestrator is: +Модуль оркестратор - это координирующее звено, которое обеспечивает бесперебойную работа массива роботов. Этот массив может состоять как из одного так и из тысячи роботов RPA. -- Centralized/decentralized user control interface (applicable and for business users and for technical users). Web based, support desktop, tablet, phone. -- Automatized robots control (customized algorithms, robots scheduling) -- Source code mega flexibility: Light Orchestrator architecture is good for own customization +**Основные возможности** -************************************ -Global settings dict concept -************************************ -pyOpenRPA project is complex tool which consist of several executable modules such as Robot, Orchestrator, Studio, +- Запуск / пауза / безопасная остановка / принудительная остановка робота +- Интеллектуальное расписание +- Просмотр состояния графических сессий роботов через панель управления +- Удаленное администрирование сессий оркестратора и робота +- Среда отладки функциональности через панель управления оркестратора +- Консолидированное хранилище логов, доступное для просмотра через панель управления +- Ролевая модель разграничения доступа +- Функциональность очередей для координации роботов -Because of module compexity, we use 1 init arg - inGSettings -inGSettings is a complex dictionary which has all reqired parameters for the module execution. +************************************************************************ +Концепция единого глобального словаря настроек (GSettings) +************************************************************************ -The description of the GSettings you can find in executable module details. +pyOpenRPA - это сложное решение, которое направлено на упрощение жизни пользователей и разработчиков роботов. -************************************ -Orchestrator how to configure -************************************ +Для того, чтобы предлагать рынку гибкое, адаптивное и надежное решение, одним из архитектурных решений был выбран подхъод хранения !ВСЕЙ! конфигурационной информации в едином словаре, который мы называем GSettings. +GSettings - это многоуровневая и иерархичная структура, которая позволяет произвести широкую кастомизацию под свои нужды, и в то же время быть открытой к внедрению новых возможностей. -To init pyOpenRPA Orchestrator instance use script: +Ознакомиться со структурой GSettings можно по ссылке: :ref:`module.orchestrator.gsettings` -from pyOpenRPA import Orchestrator # Import orchestrator main -gSettings = SettingsTemplate.Create(inModeStr="BASIC") # Create GSettings with basic configuration -Orchestrator.Orchestrator(inGSettings=gSettings) # Call the orchestrator def +Мы не рекомендуем вносить изменения напрямую в GSettings, хоть мы и оставляем такую возможность. Для корректировки функциональности Вы можете воспользоваться соответствующей функцией в модуле Оркестратора (см. здесь: :ref:`module.orchestrator.defs`) -gSettings structure +Используя специальные функции модуля Оркестратора вы существенно увеличиваете шансы бесшовного перехода на новые версии pyOpenRPA, если вам это потребуется. ************************************ -Orchestrator architecture +Архитектура ************************************ -Orchestrator has several source code components: - -- User/robot activity consolidated queue single thread (Processor) -- User/robot activity asynchonus many threads (Processor) -- Scheduler single thread (main) -- RDP keep active many thread -- Autocleaner single thread -- GUI keep active single thread -- HTTP web server single thread (create user socket threads) -- +Оркестратор состоит из следующих основных потоков: -Below you can find more information about all of the component. +- Процессорная очередь активностей (ActivityItem) (Processor) +- Функциональность асинхронного исполнения активностей (ActivityItem) (Processor) +- Поток интеллектуального расписания (main) +- Поток контроля активности RDP сессий +- Поток сбора мусорных данных +- Поток контроля графической сессии на учетной записи, где работает Оркестратор +- Поток веб-сервера Оркестратора -*************************** -Component Processor -*************************** -Sync - Append activity list to consolidated processor queue. Execution goes sequency by the activity list order -Async - Create New thread to execute the activity list +Ознакомиться с возможностями и функциями оркестратора можно по ссылке: :ref:`module.orchestrator.defs` -- Activity list -List of the activity item +Дорогие коллеги! -- Activity item +Мы знаем, что с pyOpenRPA вы сможете существенно улучшить качество вашего бизнеса. Платформа роботизации pyOpenRPA - это разработка, которая дает возможность делать виртуальных сотрудников (программных роботов RPA) выгодными, начиная от эффекта всего в **10 тыс. руб.** И управлять ими будете только Вы! -Activity item is universal mechanism to execute different algorythms from any sources. -The core feature of the Activity is to call python defs with args and kwargs. -If you need to init do some activity you can write some python def, then create Activity item with current def. -ATTENTION: In some cases (such as web transmition), when you can't transmit python def as object you can use symbolic names for python defs. It is apply you to init all of you want from the web UI. +Если у вас останутся вопросы, то вы всегда можете обратиться в центр поддержки клиентов pyOpenRPA. Контакты: :ref:`3.-Copyrights-&-Contacts` -?Why i cant transmit python def from the web -Because the WEB space is not the Python executable space. Interaction between it spaces create by JSON protocol. So, we know than JSON apply int, float, str, bool, None, list, dict - that is all. +pyOpenRPA - роботы помогут! -.. note:: +****************************** +Быстрая навигация +****************************** - Example - { - "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) - }# Pay attention! Do not left comma symbol after the end of the dict - it can be interpretated like a turple.. +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ \ No newline at end of file diff --git a/Sources/GuideSphinx/Orchestrator/02_Defs.rst b/Sources/GuideSphinx/Orchestrator/02_Defs.rst index 9b804f54..4c3b7646 100644 --- a/Sources/GuideSphinx/Orchestrator/02_Defs.rst +++ b/Sources/GuideSphinx/Orchestrator/02_Defs.rst @@ -1,20 +1,26 @@ +.. _module.orchestrator.defs: + #################################### 2. Функции #################################### +************************************************** +Общее +************************************************** + Раздел содержит всю необходимую информацию о функциях pyOpenRPA.Orchestrator При необходимости вы всегда можете обратиться в центр поддержки клиентов pyOpenRPA. Контакты: :ref:`3.-Copyrights-&-Contacts` ************************************************** -Что такое активность (ActivityItem) +Что такое активность (ActivityItem)? ************************************************** Архитектура pyOpenRPA позволяет обмениваться сообщениями о выполнении функций через механизм активностей (ActivityItem). На стороне Агента и Оркестратора реализована процессорная очередь, которая последовательно выполняет поставленные активности. Результат этих активностей сообщается инициатору (см. функции группы Agent... в Оркестраторе) ************************************************** -pyOpenRPA.Orchestrator.__Orchestrator__ +Функции ************************************************** .. code-block:: python @@ -29,50 +35,50 @@ pyOpenRPA.Orchestrator.__Orchestrator__ -Группа функций Agent... -###################### +**Группа функций Agent...** + Взаимодействие между Оркестратором и Агентом, который развертнут на других графических сессиях, где будет происходить запуск робота. -Группа функций GSettings... -###################### +**Группа функций GSettings...** + Вспомогательные функции для работы с глобальным словарем настроек Оркестратора -Группа функций Storage... -###################### +**Группа функций Storage...** + Функции для взаимодействия со специальным хранилищем переменных, предназначенного для хранения информации от роботов. !ВНИМАНИЕ! Данное хранилище сохраняется при перезагрузке Оркестратора из панели управления. -Группа функций OS... -###################### +**Группа функций OS...** + Функции взаимодействия с командной строкой на сессии, где запущен Оркестратор. -Группа функций Process... -###################### +**Группа функций Process...** + Запуск / остановка процессов на сессии Оркестратора. -Группа функций Processor... -###################### +**Группа функций Processor...** + Функции взаимодействия с процессорной очередью. Если требуется выполнить синхронизацию нескольких разных задач, то можно их отправлять в процессорную очередь. -Группа функций Python... -###################### +**Группа функций Python...** + Функции взаимодействия с Python модулями. -Группа функций RDPSession... -###################### +**Группа функций RDPSession...** + Запуск, отключение, перезапуск, отправка CMD команд, раскрыть на весь экран на RDP сессию -Группа функций Web... -###################### +**Группа функций Web...** + Управление веб-сервером Оркестратора. -Группа функций UAC... -###################### +**Группа функций UAC...** + Управление ролевой моделью доступа пользователей к панели управления Оркестратора. Актуально для подключения бизнес-пользователей. -Группа функций Scheduler... -###################### +**Группа функций Scheduler...** + Установка расписания на различные активности. @@ -81,10 +87,13 @@ pyOpenRPA.Orchestrator.__Orchestrator__ :autosummary: -************************************************** -pyOpenRPA.Orchestrator.Web.Basic -************************************************** +****************************** +Быстрая навигация +****************************** -.. automodule:: pyOpenRPA.Orchestrator.Web.Basic - :members: - :autosummary: \ No newline at end of file +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ diff --git a/Sources/GuideSphinx/Orchestrator/03_gSettingsTemplate.rst b/Sources/GuideSphinx/Orchestrator/03_gSettingsTemplate.rst index 4efe8d47..f67a6ee5 100644 --- a/Sources/GuideSphinx/Orchestrator/03_gSettingsTemplate.rst +++ b/Sources/GuideSphinx/Orchestrator/03_gSettingsTemplate.rst @@ -1,9 +1,29 @@ -.. _gSettingsTemplate: -************************ -3. gSettings Template -************************ +.. _module.orchestrator.gsettings: -gSettings structure +############################################# +3. Настройки GSettings (шаблон) +############################################# + +****************************** +Общее +****************************** +Ниже представлена структура единого глобального словаря настроек GSettings + +****************************** +Структура +****************************** .. include:: ../../pyOpenRPA/Orchestrator/SettingsTemplate.py - :literal: \ No newline at end of file + :literal: + + +****************************** +Быстрая навигация +****************************** + +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ \ No newline at end of file diff --git a/Sources/GuideSphinx/Orchestrator/04_HowToUse.rst b/Sources/GuideSphinx/Orchestrator/04_HowToUse.rst index 392bc9cf..c92f98b6 100644 --- a/Sources/GuideSphinx/Orchestrator/04_HowToUse.rst +++ b/Sources/GuideSphinx/Orchestrator/04_HowToUse.rst @@ -1,8 +1,17 @@ -************************ -4. How to use -************************ +################################# +4. Как использовать? +################################# -You need to run orchestrator process? +****************************** +Как запустить? +****************************** + +Хотите выполнить запуск Оркестратора? + +**Для этого достаточно (выбрать одно):** + +- запустить .cmd файл, расположенный в папке pyOpenRPA по адресу: Orchestrator\pyOpenRPA.Orchestrator_x64.cmd +- в свой .py скрипт добавить следующий код (см. ниже) .. code-block:: python @@ -13,7 +22,23 @@ You need to run orchestrator process? Orchestrator.Orchestrator(inGSettings=gSettings) -If you need more configurations - so you can see here: +****************************** +Параметры настройки +****************************** + +Также вы можете выполнить более тонкую настройку параметров Оркестратора. Ниже пример такой настройки: .. include:: ../../../Orchestrator/OrchestratorSettings.py :literal: + + +****************************** +Быстрая навигация +****************************** + +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ \ No newline at end of file diff --git a/Sources/GuideSphinx/Orchestrator/05_UAC.rst b/Sources/GuideSphinx/Orchestrator/05_UAC.rst index e7f5e58a..334a47a1 100644 --- a/Sources/GuideSphinx/Orchestrator/05_UAC.rst +++ b/Sources/GuideSphinx/Orchestrator/05_UAC.rst @@ -1,21 +1,23 @@ #################################### -5. UAC - User Access Control +5. Права доступа пользователей UAC #################################### ***************** -About +Описание ***************** -Orchestrator has mega feature - user access control (UAC). This feature allow you to manipulate access of the web UI for the all users! +Оркестратор обладает уникальным и гибким механизмом контроля и распределения прав доступа пользователей (UAC - User Access Control). Концепция pyOpenRPA заключается в том, что настройка доступа должна быть максимально функциональной, но при этом удобной в использовании. -If you need to give admin rights - you don't customize UAC dict. +Если требуется дать все права доступа - не нужно ничего редактировать - они будут по умолчанию. -If you need to give some little rights for user only for one robot in orchestrator web panel - you can set the following properties in UAC dict. +Если нужно внести корректировки - вы можете указать лишь те ключи доступа, которые потребуются пользователю. -To work with UAC you can use defs ``Orchestrator.UAC`` group. +Также UAC механизм распределения прав доступа отлично интегрируется со сторонними системами безопасности, которые уже используются в компаниях, например Active Directory и другие. -!!!ATTENTION!!! +Функции по работе с UAC представлены в группе ``Orchestrator.UAC`` в разделе описания функций: :ref:`module.orchestrator.defs`. -Need practice example to work with UAC! - too hard to understand +Если у вас останутся вопросы, то вы всегда можете обратиться в центр поддержки клиентов pyOpenRPA. Контакты: :ref:`3.-Copyrights-&-Contacts` + +pyOpenRPA - роботы помогут! *************************************************** UAC Dict for Orchestrator WEB UI rights @@ -55,4 +57,16 @@ UAC Dict for pyOpenRPA Orchestrator WEB UI rights. "ActivityListExecuteBool": True, # Execute activity at the current thread "ActivityListAppendProcessorQueueBool": True # Append activity to the processor queue } - } \ No newline at end of file + } + + +****************************** +Быстрая навигация +****************************** + +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ \ No newline at end of file diff --git a/Sources/GuideSphinx/Orchestrator/06_Defs Managers.rst b/Sources/GuideSphinx/Orchestrator/06_Defs Managers.rst deleted file mode 100644 index 060b8528..00000000 --- a/Sources/GuideSphinx/Orchestrator/06_Defs Managers.rst +++ /dev/null @@ -1,52 +0,0 @@ -#################################### -6. Defs Managers -#################################### - -************************************************** -Process (General) -************************************************** - -.. code-block:: python - - # EXAMPLE - from pyOpenRPA.Orchestrator import Orchestrator - lProcess = Orchestrator.Managers.Process(inAgentHostNameStr="PC-DESKTOP",inAgentUserNameStr="ND", inProcessNameWOExeStr="notepad",inStartCMDStr="notepad") - - -.. automodule:: pyOpenRPA.Orchestrator.Managers.Process - :members: - :autosummary: - - -************************************************** -Process (Details) -************************************************** - -.. automodule:: pyOpenRPA.Orchestrator.Managers.Process - :members: - :autosummary: - - -************************************************** -ControlPanel (General) -************************************************** - -.. code-block:: python - - # EXAMPLE - from pyOpenRPA.Orchestrator import Orchestrator - lCP = Orchestrator.Managers.ControlPanel(inControlPanelNameStr="TestTTT",inRefreshHTMLJinja2TemplatePathStr="ControlPanel\\test.html", inJinja2TemplateRefreshBool = True) - - -.. automodule:: pyOpenRPA.Orchestrator.Managers.ControlPanel - :members: - :autosummary: - - -************************************************** -ControlPanel (Details) -************************************************** - -.. automodule:: pyOpenRPA.Orchestrator.Managers.ControlPanel - :members: - :autosummary: diff --git a/Sources/GuideSphinx/Robot/01_Robot.rst b/Sources/GuideSphinx/Robot/01_Robot.rst index 301b1c1f..1e591111 100644 --- a/Sources/GuideSphinx/Robot/01_Robot.rst +++ b/Sources/GuideSphinx/Robot/01_Robot.rst @@ -1,30 +1,45 @@ .. _module.robot.description: -************************ +#################################### 1. Описание -************************ +#################################### +****************************** +Общее +****************************** Модуль обеспечивает всю необходимую функциональность для создания любого программного робота RPA. Модуль робота поставляется в качестве библиотеки Python, что позволяет с легкостью интегрировать его в другие проекты перспективных технологий. **Содержит** -- Уровень доступа к элементам локального приложения (win32, UI automation), и веб приложения +- **Уровень доступа к элементам локального приложения (win32, UI automation), и веб приложения** - UIDesktop: инструменты взаимодействия с элементами локального приложения (взаимодействие с ОС через протоколы win32, UI automation). Перейти к описанию функций: :ref:`module.robot.uidesktop` - UIWeb: инструменты взаимодействия с элементами веб приложения. Перейти к описанию функций: :ref:`module.robot.uiweb` -- Уровень доступа к текстовым каналам передачи данных (клавиатура, буфер обмена) +- **Уровень доступа к текстовым каналам передачи данных (клавиатура, буфер обмена)** - Keyboard: инструменты взаимодействия с клавиатурой. Перейти к описанию функций: :ref:`module.robot.keyboard` - Clipboard: инструменты взаимодействия с буфером обмена. Перейти к описанию функций: :ref:`module.robot.clipboard` -- Уровень доступа к графическим каналам передачи данных (мышь, экран) +- **Уровень доступа к графическим каналам передачи данных (мышь, экран)** - Mouse: инструменты взаимодействия с мышью. Перейти к описанию функций: :ref:`module.robot.mouse` - Image: инструменты взаимодействия с эраном рабочего стола. Перейти к описанию функций: :ref:`module.robot.image` -Ниже преставлен пример использования инструментов робота. +Дорогие коллеги! + +Мы знаем, что с pyOpenRPA вы сможете существенно улучшить качество вашего бизнеса. Платформа роботизации pyOpenRPA - это разработка, которая дает возможность делать виртуальных сотрудников (программных роботов RPA) выгодными, начиная от эффекта всего в **10 тыс. руб.** И управлять ими будете только Вы! + +Если у вас останутся вопросы, то вы всегда можете обратиться в центр поддержки клиентов pyOpenRPA. Контакты: :ref:`3.-Copyrights-&-Contacts` + +pyOpenRPA - роботы помогут! + +****************************** +Примеры +****************************** + +**Ниже преставлен пример использования инструментов робота.** .. code-block:: python @@ -110,4 +125,15 @@ Mouse.mouseDown(x-30,y+90) Mouse.moveTo(x+40,y+130) Mouse.moveTo(x+105,y+90) - Mouse.mouseUp() \ No newline at end of file + Mouse.mouseUp() + +****************************** +Быстрая навигация +****************************** + +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ \ No newline at end of file diff --git a/Sources/GuideSphinx/Robot/02_uidesktop.rst b/Sources/GuideSphinx/Robot/02_uidesktop.rst index 7482f590..7ef19ae8 100644 --- a/Sources/GuideSphinx/Robot/02_uidesktop.rst +++ b/Sources/GuideSphinx/Robot/02_uidesktop.rst @@ -1,276 +1,185 @@ .. _module.robot.uidesktop: #################################### -2. UIDesktop +2. Функции UIDesktop #################################### ************************ Общее ************************ +Здесь представлено описание всех функций, которые используются для взаимодействия с UI интерфейсами локальных приложений. -Here you can find the functions description for interaction with desktop GUI applications +**Функции в модуле UIDesktop именуются по следующему принципу:** +<Входящий аргумент>_<действие>_<исходящий аргумент - если присутствует> +**Термины и определения:** -************************ -UIO объект -************************ - -************************ -UIO селектор -************************ - +- **UIO:** Объект пользовательского интерфейса +- **UIOSelector:** Селектор (адрес) одного и/или более UIO объектов. Селектор представлен в формате списка (list) словарей (dict) атрибутивных критериев. -************************************************ -UIO свойства и методы (общие) -************************************************ +************************************************** +Описание функций +************************************************** -- process_id() -Return the ID of process that owns this window -- window_text() -Window text of the element -Quite a few contorls have other text that is visible, for example Edit controls usually have an empty string for window_text but still have text displayed in the edit window. - -- windowclasses= [] - -- writable_props -Build the list of the default properties to be written. - -Derived classes may override or extend this list depending on how much control they need. -- rectangle() -Return the rectangle of element: {"top", "left", "right", "bottom"} -The rectangle() is the rectangle of the element on the screen. Coordinates are given from the top left of the screen. -This method returns a RECT structure, Which has attributes - top, left, right, bottom. and has methods width() and height(). See win32structures.RECT for more information. +.. automodule:: pyOpenRPA.Robot.UIDesktop + :members: + :autosummary: -- right_click_input(coords=(None, None)) -Right click at the specified coords +************************ +Селектор UIO +************************ -- click_input(button='left', coords=(None, None), button_down=True, button_up=True, double=False, wheel_dist=0, use_log=True, pressed='', absolute=False, key_down=True, key_up=True) -Click at the specified coordinates -button The mouse button to click. One of ‘left’, ‘right’, ‘middle’ or ‘x’ (Default: ‘left’, ‘move’ is a special case) -coords The coordinates to click at.(Default: the center of the control) -double Whether to perform a double click or not (Default: False) -wheel_dist The distance to move the mouse wheel (default: 0) -NOTES: -This is different from click method in that it requires the control to be visible on the screen but performs a more realistic ‘click’ simulation. -This method is also vulnerable if the mouse is moved by the user as that could easily move the mouse off the control before the click_input has finished. - -- double_click_input(button='left', coords=(None, None)) -Double click at the specified coordinates - -- press_mouse_input(button='left', coords=(None, None), pressed='', absolute=True, key_down=True, key_up=True) -Press a mouse button using SendInput - -- press_mouse_input(button='left', coords=(None, None), pressed='', absolute=True, key_down=True, key_up=True) -Press a mouse button using SendInput - -- drag_mouse_input(dst=(0, 0), src=None, button='left', pressed='', absolute=True) -Click on src, drag it and drop on dst -dst is a destination wrapper object or just coordinates. -src is a source wrapper object or coordinates. If src is None the self is used as a source object. -button is a mouse button to hold during the drag. It can be “left”, “right”, “middle” or “x” -pressed is a key on the keyboard to press during the drag. -absolute specifies whether to use absolute coordinates for the mouse pointer locations - -- wheel_mouse_input(coords=(None, None), wheel_dist=1, pressed='') -Do mouse wheel - -- draw_outline(colour='green', thickness=2, fill=, rect=None) -Draw an outline around the window. -colour can be either an integer or one of ‘red’, ‘green’, ‘blue’ (default ‘green’) -thickness thickness of rectangle (default 2) -fill how to fill in the rectangle (default BS_NULL) -rect the coordinates of the rectangle to draw (defaults to the rectangle of the control) - -- element_info -Read-only property to get ElementInfo object - -- from_point(x, y) -Get wrapper object for element at specified screen coordinates (x, y) - -- get_properties() -Return the properties of the control as a dictionary. - -- is_child(parent) -Return True if this element is a child of ‘parent’. -An element is a child of another element when it is a direct of the other element. An element is a direct descendant of a given element if the parent element is the the chain of parent elements for the child element. - -- is_dialog() -Return True if the control is a top level window - -- is_enabled() -Whether the element is enabled or not -Checks that both the top level parent (probably dialog) that owns this element and the element itself are both enabled. -If you want to wait for an element to become enabled (or wait for it to become disabled) use Application.wait('visible') or Application.wait_not('visible'). -If you want to raise an exception immediately if an element is not enabled then you can use the BaseWrapper.verify_enabled(). BaseWrapper.VerifyReady() raises if the window is not both visible and enabled. - - -- is_visible() -Whether the element is visible or not -Checks that both the top level parent (probably dialog) that owns this element and the element itself are both visible. -If you want to wait for an element to become visible (or wait for it to become hidden) use Application.wait('visible') or Application.wait_not('visible'). -If you want to raise an exception immediately if an element is not visible then you can use the BaseWrapper.verify_visible(). BaseWrapper.verify_actionable() raises if the element is not both visible and enabled. - -- parent() -Return the parent of this element -Note that the parent of a control is not necesarily a dialog or other main window. A group box may be the parent of some radio buttons for example. -To get the main (or top level) window then use BaseWrapper.top_level_parent(). - -- root() -Return wrapper for root element (desktop) - -- set_focus() -Set the focus to this element - -- texts() -Return the text for each item of this control -It is a list of strings for the control. It is frequently overridden to extract all strings from a control with multiple items. -It is always a list with one or more strings: -The first element is the window text of the control -Subsequent elements contain the text of any items of the control (e.g. items in a listbox/combobox, tabs in a tabcontrol) - -- type_keys(keys, pause=None, with_spaces=False, with_tabs=False, with_newlines=False, turn_off_numlock=True, set_foreground=True, vk_packet=True) -Type keys to the element using keyboard.send_keys -Ограниченная функциональность. Для более полной функциональности рекомендуем ознакомится с pyOpenPRA.Robot.Keyboard -This uses the re-written keyboard python module where you can find documentation on what to use for the keys. - -- was_maximized() -Indicate whether the window was maximized before minimizing or not - -************************************************************* -UIO свойства и методы (дополнение для win32 элементов) -************************************************************* -Кнопка (Button || CheckBox || RadioButton || GroupBox) - -- check() -Check a checkbox - -- get_check_state() -Return the check state of the checkbox -The check state is represented by an integer 0 - unchecked 1 - checked 2 - indeterminate -The following constants are defined in the win32defines module BST_UNCHECKED = 0 BST_CHECKED = 1 BST_INDETERMINATE = 2 - -- click(button='left', pressed='', coords=(0, 0), double=False, absolute=False) -Click the Button control -- is_checked() -Return True if checked, False if not checked, None if indeterminate -- is_dialog() -Buttons are never dialogs so return False -- set_check_indeterminate() -Set the checkbox to indeterminate -- uncheck() -Uncheck a checkbox -- friendly_class_name() -Return the friendly class name of the button - -Windows controls with the class “Button” can look like different controls based on their style. They can look like the following controls: - -Buttons, this method returns “Button” -CheckBoxes, this method returns “CheckBox” -RadioButtons, this method returns “RadioButton” -GroupBoxes, this method returns “GroupBox” - - -Поле выбора нескольких значений из списка (ComboBox) - -- dropped_rect() -Get the dropped rectangle of the combobox -- friendlyclassname= 'ComboBox' -- get_properties() -Return the properties of the control as a dictionary -item_count() -Return the number of items in the combobox -- item_data(item) -Returns the item data associated with the item if any -- item_texts() -Return the text of the items of the combobox -- select(item) -Select the ComboBox item -item can be either a 0 based index of the item to select or it can be the string that you want to select -- selected_index() -Return the selected index -- selected_text() -Return the selected text -- texts() -Return the text of the items in the combobox -- windowclasses= ['ComboBox', 'WindowsForms\\d*\\.COMBOBOX\\..*', '.*ComboBox'] - -Поле ввода (Edit) - -- friendlyclassname= 'Edit' -- get_line(line_index) -Return the line specified -- line_count() -Return how many lines there are in the Edit -- line_length(line_index) -Return how many characters there are in the line -- select(start=0, end=None) -Set the edit selection of the edit control -- selection_indices() -The start and end indices of the current selection -- set_edit_text(text, pos_start=None, pos_end=None) -Set the text of the edit control -- set_text(text, pos_start=None, pos_end=None) -Set the text of the edit control -- set_window_text(text, append=False) -Override set_window_text for edit controls because it should not be used for Edit controls. -Edit Controls should either use set_edit_text() or type_keys() to modify the contents of the edit control. -- text_block() -Get the text of the edit control -- texts() -Get the text of the edit control -- windowclasses= ['Edit', '.*Edit', 'TMemo', 'WindowsForms\\d*\\.EDIT\\..*', 'ThunderTextBox', 'ThunderRT6TextBox'] - - -Поле выбора 1-го значения из списка (ListBox) - -- friendlyclassname= 'ListBox' -- get_item_focus() -Return the index of current selection in a ListBox -- is_single_selection() -Check whether the listbox has single selection mode. -- item_count() -Return the number of items in the ListBox -- item_data(i) -Return the item_data if any associted with the item -- item_rect(item) -Return the rect of the item -- item_texts() -Return the text of the items of the listbox -- select(item, select=True) -Select the ListBox item -item can be either a 0 based index of the item to select or it can be the string that you want to select -- selected_indices() -The currently selected indices of the listbox -- set_item_focus(item) -Set the ListBox focus to the item at index -- texts() -Return the texts of the control -- windowclasses= ['ListBox', 'WindowsForms\\d*\\.LISTBOX\\..*', '.*ListBox'] - -Выпадающее меню (PopupMenu) - -- friendlyclassname= 'PopupMenu' -- is_dialog() -Return whether it is a dialog -- windowclasses= ['#32768'] - -Текст (Static) +Селектор UIO - адрес одного и/или более UIO объектов. Селектор представлен в формате списка (list) словарей (dict) атрибутивных критериев. Поддерживает формат JSON, что позволяет обеспечить удобство форматирования и передачи через web интерфейс студии / оркестратора. + +UIO селектор — это список характеристических словарей (спецификаций UIO). Данные спецификации UIO содержат условия, с помощью которых библиотека pyOpenRPA определит UIO, удовлетворяющий условиям, заданным в спецификации UIO. Индекс спецификации UIO в списке UIO селектора харакетризует уровень вложенности целевого UIO. Говоря другим языком, UIO селектор — это перечень условий, под которые может попасть 0, 1 или n UIO. + +Ниже приведен перечень атрибутов — условий, которые можно использовать в спецификациях UIO: + +**Формат селектора:** + +[ + { + + "depth_start" :: [int, начинается с 1] :: глубина, с которой начинается поиск (по умолчанию 1), + + "depth_end" :: [int, начинается с 1] :: глубина, до которой ведется поиск (по умолчанию 1), + + "ctrl_index" || "index" :: [int, начинается с 0] :: индекс UIO в списке у родительского UIO, + + "title" :: [str] :: идентичное наименование атрибута *title* искомого объекта UIO, + + "title_re" :: [str] :: регулярное выражение (python диалект) для отбора UIO, у которого атрибут *title* должен удовлетворять условию данного регулярного выражения, + + "rich_text" :: [str] :: идентичное наименование атрибута *rich_text* искомого объекта UIO, + + "rich_text_re" :: [str] :: регулярное выражение (python диалект) для отбора UIO, у которого атрибут *rich_text* должен удовлетворять условию данного регулярного выражения, + + "class_name" :: [str] :: идентичное наименование атрибута *class_name* искомого объекта UIO, + + "class_name_re" :: [str] :: регулярное выражение (python диалект) для отбора UIO, у которого атрибут *class_name* должен удовлетворять условию данного регулярного выражения, + + "friendly_class_name" :: [str] :: идентичное наименование атрибута *friendly_class_name* искомого объекта UIO, + + "friendly_class_name_re" :: [str] :: регулярное выражение (python диалект) для отбора UIO, у которого атрибут *friendly_class_name* должен удовлетворять условию данного регулярного выражения, + + "control_type" :: [str] :: идентичное наименование атрибута *control_type* искомого объекта UIO, + + "control_type_re" :: [str] :: регулярное выражение (python диалект) для отбора UIO, у которого атрибут *control_type* должен удовлетворять условию данного регулярного выражения, + + "is_enabled" :: [bool] :: признак, что UIO доступен для выполнения действий, + + "is_visible" :: [bool] :: признак, что UIO отображается на экране, + + "backend" :: [str, "win32" || "uia"] :: вид способа адресации к UIO (по умолчанию "win32"). Внимание! Данный атрибут может быть указан только для первого элемента списка UIO селектора. Для остальных элементов списка данный атрибут будет проигнорирован. + + }, + { ... спецификация UIO следующего уровня иерархии } +] + +**Пример UIO селектора:** +[ + {"class_name":"CalcFrame", "backend":"win32"}, # Спецификация UIO 1-го уровня вложенности + {"title":"Hex", "depth_start":3, "depth_end": 3} # Спецификация UIO 1+3-го уровня вложенности (так как установлены атрибуты depth_start|depth_stop, определяющие глубину поиска UIO) +] + + +**UIO объект - свойства и методы (общие)** + +- process_id(): Возвращает идентификатор процесса, которому принадлежит это окно +- window_text(): Текст окна элемента. Довольно много элементов управления имеют другой текст, который виден, например, элементы управления редактированием обычно имеют пустую строку для window_text, но все равно имеют текст, отображаемый в окне редактирования. +- rectangle(): Возвращает прямоугольник элемента: {"сверху", "слева", "справа", "снизу"} Прямоугольник() - это прямоугольник элемента на экране. Координаты указаны в левом верхнем углу экрана. Этот метод возвращает прямоугольную структуру, которая имеет атрибуты - top, left, right, bottom. и имеет методы width() и height(). См. раздел win32structures.Прямую кишку для получения дополнительной информации. +- right_click_input(coords=(None, None)): Щелкните правой кнопкой мыши на указанных координатах +- click_input(button='left', coords=(None, None), button_down=True, button_up=True, double=False, wheel_dist=0, use_log=True, pressed='', absolute=False, key_down=True, key_up=True): Щелкните по указанным координатам кнопкой мыши, чтобы щелкнуть. Один из "влево", "вправо", "посередине" или "x" (по умолчанию: "влево", "переместить" - это особый случай) определяет координаты, по которым нужно щелкнуть.(По умолчанию: центр элемента управления) дважды Укажите, следует ли выполнять двойной щелчок или нет (по умолчанию: False) wheel_dist Расстояние для перемещения колеса мыши (по умолчанию: 0) Внимание: Этот метод отличается от метода щелчка тем, что он требует, чтобы элемент управления был виден на экране, но выполняет более реалистичную симуляцию щелчка. Этот метод также уязвим, если пользователь перемещает мышь, поскольку это может легко переместить мышь с элемента управления до завершения click_input. +- double_click_input(button='left', coords=(None, None)): Дважды щелкните по указанным координатам +- press_mouse_input(button='left', coords=(None, None), pressed='', absolute=True, key_down=True, key_up=True): Нажмите кнопку мыши с помощью SendInput +- drag_mouse_input(dst=(0, 0), src=None, button='left', pressed='', absolute=True): Нажмите на src, перетащите его и перетащите на dst dst - это объект-оболочка назначения или просто координаты. src - это исходный объект-оболочка или координаты. Если src равен None, self используется в качестве исходного объекта. кнопка - это кнопка мыши, которую нужно удерживать во время перетаскивания. Это может быть “влево”, “вправо”, “посередине” или “x”. Нажата клавиша на клавиатуре, которую нужно нажимать во время перетаскивания. абсолютные указывает, следует ли использовать абсолютные координаты для расположения указателя мыши +- wheel_mouse_input(coords=(None, None), wheel_dist=1, pressed=''): Прокрутить колесо мыши +- draw_outline(colour='green', thickness=2, fill=, rect=None): Нарисуйте контур вокруг окна. цвет может быть либо целым числом, либо одним из "красного", "зеленого", "синего" (по умолчанию "зеленый") толщина толщина прямоугольника (по умолчанию 2) заливка как заполнить прямоугольник (по умолчанию BS_NULL) укажите координаты прямоугольника для рисования (по умолчанию используется прямоугольник элемента управления) +- element_info: Свойство, доступное только для чтения, для получения объекта ElementInfo +- from_point(x, y): Получить объект-оболочку для элемента в заданных координатах экрана (x, y) +- get_properties(): Возвращает свойства элемента управления в виде словаря. +- is_child(parent): Возвращает значение True, если этот элемент является дочерним элементом ‘parent’. Элемент является дочерним элементом другого элемента, когда он является прямым элементом другого элемента. Элемент является прямым потомком данного элемента, если родительский элемент является цепочкой родительских элементов для дочернего элемента. +- is_dialog(): Возвращает значение True, если элемент управления является окном верхнего уровня +- is_enabled(): Независимо от того, включен элемент или нет. Проверяет, что как родительский элемент верхнего уровня (возможно, диалоговое окно), которому принадлежит этот элемент, так и сам элемент включены.Если вы хотите дождаться, пока элемент станет включенным (или дождаться, пока он станет отключенным), используйте Application.wait('visible') или Application.wait_not('visible').Если вы хотите немедленно вызвать исключение, если элемент не включен, вы можете использовать BaseWrapper.verify_enabled(). Функция BaseWrapper.Verify Ready() вызывается, если окно одновременно не видно и не включено. +- is_visible(): Является ли элемент видимым или нет. Проверяет, видны ли как родительский элемент верхнего уровня (возможно, диалоговое окно), которому принадлежит этот элемент, так и сам элемент. Если вы хотите дождаться, пока элемент станет видимым (или дождаться, пока он станет скрытым), используйте Application.wait('visible') или Application.wait_not('visible'). Если вы хотите немедленно вызвать исключение, если элемент не виден, вы можете использовать BaseWrapper.verify_visible(). Базовая оболочка.verify_actible() вызывается, если элемент одновременно не виден и не включен. +- parent(): Возвращает родительский элемент этого элемента Обратите внимание, что родительским элементом элемента управления не обязательно является диалоговое окно или другое главное окно. Например, поле группы может быть родительским для некоторых переключателей. Чтобы получить главное (или окно верхнего уровня), затем используйте BaseWrapper.top_level_parent(). +- root(): Возвращаемая оболочка для корневого элемента (рабочий стол) +- set_focus(): Установить фокус на этот элемент +- texts(): Возвращает текст для каждого элемента этого элемента управления Это список строк для элемента управления. Часто переопределяется извлечение всех строк из элемента управления с несколькими элементами. Это всегда список с одной или несколькими строками: Первый элемент - это текст окна элемента управления Последующие элементы содержат текст любых элементов элемента управления (например, элементы в listbox/combobox, вкладки в tabcontrol) +- type_keys(keys, pause=None, with_spaces=False, with_tabs=False, with_newlines=False, turn_off_numlock=True, set_foreground=True, vk_packet=True): Введите ключи для элемента с помощью клавиатуры.send_keys. Ограниченная функциональность. Для более полной функциональности рекомендуем ознакомится с pyOpenPRA.Robot.Keyboard +- was_maximized(): Проверить, было ли окно развернуто перед сворачиванием или нет + +**UIO свойства и методы (дополнение к базовым методам для win32 элементов)** + +**Кнопка (Button || CheckBox || RadioButton || GroupBox)** + +- check(): Установить флажок +- uncheck(): Снять флажок +- get_check_state(): Вернуть состояние проверки флажка. Состояние проверки представлено целым числом 0 - непроверено 1 - проверено 2 - неопределенно. Следующие константы определены в модуле win32defines BST_UNCHECKED = 0 BST_CHECKED = 1 BST_INDETERMINATE = 2 +- click(button='left', pressed='', coords=(0, 0), double=False, absolute=False): Клик на кнопку управления +- is_checked(): Возвращает True, если флажок установлен, False, если флажок не установлен, None, если значение не определено +- is_dialog(): Кнопки никогда не являются диалоговыми окнами, поэтому возвращайте значение False +- set_check_indeterminate(): Установить флажок в положение неопределенный +- friendly_class_name(): Возвращает имя класса кнопки. Они могут выглядеть следующим образом: Кнопки, этот метод возвращает “Button”; Флажки, этот метод возвращает “флажок”; RadioButtons, этот метод возвращает “RadioButton”; GroupBoxes, этот метод возвращает “GroupBox” + +**Поле выбора нескольких значений из списка (ComboBox)** + +- friendlyclassname = 'ComboBox' +- windowclasses = ['ComboBox', 'WindowsForms\\d*\\.COMBOBOX\\..*', '.*ComboBox'] +- dropped_rect(): Получить выпадающий прямоугольник в поле со списком +- get_properties(): Возвращает свойства элемента управления в виде словаря +- item_count(): Возвращает количество элементов в поле со списком +- item_data(item): Возвращает данные элемента, связанные с элементом, если таковые имеются +- item_texts(): Возвращает текст элементов выпадающего списка +- select(item): Выбрать элемент со списком элемент может быть либо индексом элемента для выбора на основе 0, либо строкой, которую вы хотите выбрать +- selected_index(): Возвращает выбранный индекс +- selected_text():Возвращает выделенный текст +- texts(): Возвращает текст элементов в выпадающем списке + +**Поле ввода (Edit)** + +- friendlyclassname = 'Edit' +- windowclasses = ['Edit', '.*Edit', 'TMemo', 'WindowsForms\\d*\\.EDIT\\..*', 'ThunderTextBox', 'ThunderRT6TextBox'] +- get_line(line_index): Возвращает указанную строку +- line_count(): Возвращает, сколько строк есть в редактировании +- line_length(line_index): Возвращает количество символов в строке +- select(start=0, end=None): Установите выбор редактирования элемента управления редактированием +- selection_indices(): Начальный и конечный индексы текущего выбора +- set_edit_text(text, pos_start=None, pos_end=None): Задать текст элемента управления редактированием +- set_text(text, pos_start=None, pos_end=None): Задать текст элемента управления редактированием +- set_window_text(text, append=False): Переопределите set_window_text для элементов управления редактированием, поскольку он не должен использоваться для элементов управления редактированием. Элементы управления редактированием должны использовать либо set_edit_text(), либо type_keys() для изменения содержимого элемента управления редактированием. +- text_block(): Получить текст элемента управления редактированием +- texts(): Получить текст элемента управления редактированием + +**Поле выбора 1-го значения из списка (ListBox)** + +- friendlyclassname = 'ListBox' +- windowclasses = ['ListBox', 'WindowsForms\\d*\\.LISTBOX\\..*', '.*ListBox'] +- get_item_focus(): Возвращает индекс текущего выбора в списке +- is_single_selection(): Проверить, имеет ли поле списка режим одиночного выбора +- item_count(): Возвращает количество элементов в списке +- item_data(i): Возвращает item_data, если таковые имеются, связанные с элементом +- item_texts(): Возвращает текст элементов списка +- select(item, select=True): Выбрать элемент списка элемент может быть либо индексом элемента для выбора на основе 0, либо строкой, которую вы хотите выбрать +- selected_indices(): Выбранные в данный момент индексы списка +- set_item_focus(item): Установить фокус по элементу +- texts(): Получить текст элемента управления редактированием + +**Выпадающее меню (PopupMenu)** + +- friendlyclassname = 'PopupMenu' +- windowclasses = ['#32768'] +- is_dialog(): Возвращает, является ли это диалогом + +**Текст (Static)** - friendlyclassname= 'Static' - windowclasses= ['Static', 'WindowsForms\\d*\\.STATIC\\..*', 'TPanel', '.*StaticText'] -************************************************************* -UIO свойства и методы (дополнение для uia элементов) -************************************************************* - - - -************************************************ -Инициализация 2-х разрядностей для UIO -************************************************ +**Инициализация 2-х разрядностей для UIO** pyOpenRPA позволяет обеспечить максимальную совместимость со всеми приложениями, которые выполняются на компьютере. Мы рекомендуем разрабатывать робота под интерпретатором Python x64. В дополнение к нему Вы можете подключить Python x32 (см. ниже пример подключения). Если планируемый робот не будет взаимодействовать через pyOpenRPA.Robot.UIDesktop с другой разрядность, то эту настройку можно не применять. @@ -289,16 +198,13 @@ pyOpenRPA позволяет обеспечить максимальную со # Теперь при вызове функций pyOpenRPA.Robot.UIDesktop платформа pyOpenRPA будет отслеживать разрядность приложения и отправлять соответсвующий вызов на идентичную разрядность. -.. automodule:: pyOpenRPA.Robot.UIDesktop - :members: - :autosummary: - - -********** -Ссылки -********** - -`reStructuredText`_ +****************************** +Быстрая навигация +****************************** -.. target-notes:: -.. _`reStructuredText`: http://docutils.sourceforge.net/rst.html +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ diff --git a/Sources/GuideSphinx/Robot/03_uiweb.rst b/Sources/GuideSphinx/Robot/03_uiweb.rst index 80946577..fe8905ca 100644 --- a/Sources/GuideSphinx/Robot/03_uiweb.rst +++ b/Sources/GuideSphinx/Robot/03_uiweb.rst @@ -1,38 +1,31 @@ .. _module.robot.uiweb: #################################### -3. UIWeb +3. Функции UIWeb #################################### -Here you can find the functions description for interaction with desktop GUI applications +************************ +Общее +************************ -How to use both x32 and x64 python processes (it can be helpfully, if another app GUI is on another bitness than your app) +Документация к модулю будет опубликована в Июле 2022. По всем вопросам роботизации WEB приложений обращайтесь в центр поддержки клиентов pyOpenRPA. -.. code-block:: python - from pyOpenRPA.Robot import UIDesktop - #Section for robot init - lPyOpenRPA_SettingsDict = { - "Python32FullPath": "..\\Resources\\WPy32-3720\\python-3.7.2\\python.exe", #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe" - "Python64FullPath": "..\\Resources\\WPy64-3720\\python-3.7.2.amd64\\python.exe", #Set from user - "Python32ProcessName": "pyOpenRPA_UIDesktopX32.exe", #Config set once - "Python64ProcessName": "pyOpenRPA_UIDesktopX64.exe" #Config set once - } - # Init the pyOpenRPA configuration - UIDesktop.Utils.ProcessBitness.SettingsInit(lPyOpenRPA_SettingsDict) - # Now you can use pyOpenRPA with both bitness. +Дорогие коллеги! +Мы знаем, что с pyOpenRPA вы сможете существенно улучшить качество вашего бизнеса. Платформа роботизации pyOpenRPA - это разработка, которая дает возможность делать виртуальных сотрудников (программных роботов RPA) выгодными, начиная от эффекта всего в **10 тыс. руб.** И управлять ими будете только Вы! -.. automodule:: pyOpenRPA.Robot.UIDesktop - :members: - :autosummary: +Если у вас останутся вопросы, то вы всегда можете обратиться в центр поддержки клиентов pyOpenRPA. Контакты: :ref:`3.-Copyrights-&-Contacts` +pyOpenRPA - роботы помогут! -********** -References -********** +****************************** +Быстрая навигация +****************************** -`reStructuredText`_ - -.. target-notes:: -.. _`reStructuredText`: http://docutils.sourceforge.net/rst.html +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ diff --git a/Sources/GuideSphinx/Robot/04_keyboard.rst b/Sources/GuideSphinx/Robot/04_keyboard.rst index 3b9ef7b4..2c754580 100644 --- a/Sources/GuideSphinx/Robot/04_keyboard.rst +++ b/Sources/GuideSphinx/Robot/04_keyboard.rst @@ -1,9 +1,13 @@ .. _module.robot.keyboard: #################################### -4. Keyboard +4. Функции Keyboard #################################### +************************ +Общее +************************ + Клавиатура - это главный текстовый инструмент, который обладает 100% точностью передачи данных. С его помощью можно отправлять сообщения, ожидать нажатия и выполнять различные комбинации клавиш. На этой странице представлена вся необходимая информация по управлению клавиатурой со стороны программного робота RPA. В отличие от многих RPA платформ, pyOpenRPA обладает функциями, которые не зависят от текущей раскладки клавиатуры. За счет этого надежность и стабильность программного робота существенно возрастает. @@ -29,7 +33,7 @@ Коды клавиш см. ниже ************************************************** -Описание методов +Описание функций ************************************************** @@ -215,3 +219,15 @@ # Пример использования функции send from pyOpenRPA.Robot import Keyboard Keyboard.send(57) + +****************************** +Быстрая навигация +****************************** + +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ + diff --git a/Sources/GuideSphinx/Robot/05_clipboard.rst b/Sources/GuideSphinx/Robot/05_clipboard.rst index d733784a..641979c3 100644 --- a/Sources/GuideSphinx/Robot/05_clipboard.rst +++ b/Sources/GuideSphinx/Robot/05_clipboard.rst @@ -1,38 +1,24 @@ .. _module.robot.clipboard: #################################### -5. Clipboard +5. Функции Clipboard #################################### -Here you can find the functions description for interaction with desktop GUI applications +************************************************** +Описание функций +************************************************** -How to use both x32 and x64 python processes (it can be helpfully, if another app GUI is on another bitness than your app) - -.. code-block:: python - - from pyOpenRPA.Robot import UIDesktop - #Section for robot init - lPyOpenRPA_SettingsDict = { - "Python32FullPath": "..\\Resources\\WPy32-3720\\python-3.7.2\\python.exe", #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe" - "Python64FullPath": "..\\Resources\\WPy64-3720\\python-3.7.2.amd64\\python.exe", #Set from user - "Python32ProcessName": "pyOpenRPA_UIDesktopX32.exe", #Config set once - "Python64ProcessName": "pyOpenRPA_UIDesktopX64.exe" #Config set once - } - # Init the pyOpenRPA configuration - UIDesktop.Utils.ProcessBitness.SettingsInit(lPyOpenRPA_SettingsDict) - # Now you can use pyOpenRPA with both bitness. - - -.. automodule:: pyOpenRPA.Robot.UIDesktop +.. automodule:: pyOpenRPA.Robot.Clipboard :members: :autosummary: +****************************** +Быстрая навигация +****************************** -********** -References -********** - -`reStructuredText`_ - -.. target-notes:: -.. _`reStructuredText`: http://docutils.sourceforge.net/rst.html +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ diff --git a/Sources/GuideSphinx/Robot/06_mouse.rst b/Sources/GuideSphinx/Robot/06_mouse.rst index dab54f67..2574f755 100644 --- a/Sources/GuideSphinx/Robot/06_mouse.rst +++ b/Sources/GuideSphinx/Robot/06_mouse.rst @@ -1,38 +1,29 @@ .. _module.robot.mouse: #################################### -6. Mouse +6. Функции Mouse #################################### -Here you can find the functions description for interaction with desktop GUI applications - -How to use both x32 and x64 python processes (it can be helpfully, if another app GUI is on another bitness than your app) - -.. code-block:: python - - from pyOpenRPA.Robot import UIDesktop - #Section for robot init - lPyOpenRPA_SettingsDict = { - "Python32FullPath": "..\\Resources\\WPy32-3720\\python-3.7.2\\python.exe", #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe" - "Python64FullPath": "..\\Resources\\WPy64-3720\\python-3.7.2.amd64\\python.exe", #Set from user - "Python32ProcessName": "pyOpenRPA_UIDesktopX32.exe", #Config set once - "Python64ProcessName": "pyOpenRPA_UIDesktopX64.exe" #Config set once - } - # Init the pyOpenRPA configuration - UIDesktop.Utils.ProcessBitness.SettingsInit(lPyOpenRPA_SettingsDict) - # Now you can use pyOpenRPA with both bitness. +************************************************** +Общее +************************************************** +************************************************** +Описание функций +************************************************** .. automodule:: pyOpenRPA.Robot.Mouse :members: :autosummary: -********** -References -********** - -`reStructuredText`_ +****************************** +Быстрая навигация +****************************** -.. target-notes:: -.. _`reStructuredText`: http://docutils.sourceforge.net/rst.html +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ diff --git a/Sources/GuideSphinx/Robot/07_image.rst b/Sources/GuideSphinx/Robot/07_image.rst index 3a0959e7..0cf05269 100644 --- a/Sources/GuideSphinx/Robot/07_image.rst +++ b/Sources/GuideSphinx/Robot/07_image.rst @@ -1,38 +1,30 @@ .. _module.robot.image: #################################### -7. Image +7. Функции Image #################################### -Here you can find the functions description for interaction with desktop GUI applications +************************ +Общее +************************ -How to use both x32 and x64 python processes (it can be helpfully, if another app GUI is on another bitness than your app) +Документация к модулю будет опубликована в Июле 2022. По всем вопросам роботизации WEB приложений обращайтесь в центр поддержки клиентов pyOpenRPA. -.. code-block:: python +Дорогие коллеги! - from pyOpenRPA.Robot import UIDesktop - #Section for robot init - lPyOpenRPA_SettingsDict = { - "Python32FullPath": "..\\Resources\\WPy32-3720\\python-3.7.2\\python.exe", #Set from user: "..\\Resources\\WPy32-3720\\python-3.7.2\\OpenRPARobotGUIx32.exe" - "Python64FullPath": "..\\Resources\\WPy64-3720\\python-3.7.2.amd64\\python.exe", #Set from user - "Python32ProcessName": "pyOpenRPA_UIDesktopX32.exe", #Config set once - "Python64ProcessName": "pyOpenRPA_UIDesktopX64.exe" #Config set once - } - # Init the pyOpenRPA configuration - UIDesktop.Utils.ProcessBitness.SettingsInit(lPyOpenRPA_SettingsDict) - # Now you can use pyOpenRPA with both bitness. +Мы знаем, что с pyOpenRPA вы сможете существенно улучшить качество вашего бизнеса. Платформа роботизации pyOpenRPA - это разработка, которая дает возможность делать виртуальных сотрудников (программных роботов RPA) выгодными, начиная от эффекта всего в **10 тыс. руб.** И управлять ими будете только Вы! +Если у вас останутся вопросы, то вы всегда можете обратиться в центр поддержки клиентов pyOpenRPA. Контакты: :ref:`3.-Copyrights-&-Contacts` -.. automodule:: pyOpenRPA.Robot.UIDesktop - :members: - :autosummary: +pyOpenRPA - роботы помогут! +****************************** +Быстрая навигация +****************************** -********** -References -********** - -`reStructuredText`_ - -.. target-notes:: -.. _`reStructuredText`: http://docutils.sourceforge.net/rst.html +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ \ No newline at end of file diff --git a/Sources/GuideSphinx/Robot/08_HowToUse.rst b/Sources/GuideSphinx/Robot/08_HowToUse.rst index 5259e73b..5c23544e 100644 --- a/Sources/GuideSphinx/Robot/08_HowToUse.rst +++ b/Sources/GuideSphinx/Robot/08_HowToUse.rst @@ -2,225 +2,85 @@ 8. Как использовать? #################################### -The Robot tool is the main module for production process automation. It has no graphic/console interface. All low-level actions to OS are perfoming by the Robot tool in pyOpenRPA. +Модуль РОБОТ - это ключевое звено, которое отвечает за продуктивную роботизацию процесса. Данный модуль не имеет графический или консольный интерфейс - он подключается в качестве библиотеки в проект робота, что позволяет выполнять операции максимально быстро. А также позволяет с легкостью интегрировать робота в другие проекты. ************************************************** -How to execute RPA script +Как запустить скрипт робота? ************************************************** -You can use the robot by the several ways: -- In Python script -- In Studio script (n/a) +Запустить скрипт робота можно 2-мя способами: +- Скрипт Python (файл .py) +- Скрипт в Студии pyOpenRPA -Create python script + +Скрипт Python (файл .py) ############################################ -In order to use robot just add Robot tool folder in work directory and add line "import GUI" in your script. +Чтобы начать использовать модуль робота достаточно выполнить в файле скрипта соответсвующие команды импорта: .. code-block:: python import sys sys.path.append('../../') - import selenium # [Web app access](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/05.1.-Theory-&-practice:-Web-app-access-(Chrome,-Firefox,-Opera))
- import GUI # [Win32 & UI Automation access](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/05.2.-Theory-&-practice:-Desktop-app-UI-access-(win32-and-UI-automation-dlls))
- import pyautogui #[Screen capture/recognition](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/05.4.-Theory-&-practice:-Screen-capture-&-image-recognition) [#Mouse manipulation](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/05.3.-Theory-&-practice:-Keyboard-&-mouse-manipulation)
- import cv2 # [Computer vision](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/05.4.-Theory-&-practice:-Screen-capture-&-image-recognition)
- import keyboard #[Keyboard manipulation](https://gitlab.com/UnicodeLabs/OpenRPA/wikis/05.3.-Theory-&-practice:-Keyboard-&-mouse-manipulation)
- -Execute python script -############################################ + from pyOpenRPA.Robot import UIDesktop # Взаимодействие с UI объектами приложений + from pyOpenRPA.Robot import UIWeb # Взаимодействие с UI объектами веб приложений + from pyOpenRPA.Robot import Keyboard # Взаимодействие с клавиатурой + from pyOpenRPA.Robot import Clipboard # Взаимодействие с буфером обмена + from pyOpenRPA.Robot import Mouse # Взаимодействие с мышью + from pyOpenRPA.Robot import Image # Взаимодействие с графической сессией ОС -The pyOpenRPA is fully portable solution. It contains own python enviroment both 32 and 64 bit versions. So, you can execute your python script in several ways: -- Execute in python x32 (\OpenRPA\Resources\WPy32-3720\python-3.7.2) -- Execute in python x64 (\OpenRPA\Resources\WPy64-3720\python-3.7.2.amd64) -- Execute from .cmd file +Описание каждого из этих модулей представлены в разделе "МОДУЛЬ РОБОТ" -Execute in the Python x32 +Execute python script ############################################ -To execute your python script in x32 bit version just write in command line from x32 python directory: +pyOpenRPA - это максимально инкапсулированная платформа программной роботизаии RPA. Все необходимые зависимости находятся внутри нее, что позволяет копировать робота между ЭВМ максимально просто. -.. code-block:: python +Вы можете запустить скрипт робота RPA следующими способами: - cd "\OpenRPA\Resources\WPy32-3720\python-3.7.2" - python.exe "path to your python script.py" +- Запустить из интерпретатора Python x32 (Resources\WPy32-3720\python-3.7.2\python.exe) +- Запустить из интерпретатора Python x64 (Resources\WPy64-3720\python-3.7.2.amd64\python.exe) +- Запустить из под .cmd файла -Execute in the Python x64 +Запустить из интерпретатора Python x32 ############################################ - -To execute your python script in x32 bit version just write in command line from x32 python directory: +Для запуска срипта из интерпретатора Python x32 необходимо открыть командную строку (cmd), и выполнить следующие команды: .. code-block:: python - cd "\OpenRPA\Resources\WPy64-3720\python-3.7.2.amd64" - python.exe "path to your python script.py" + cd "Resources\WPy32-3720\python-3.7.2" # Установить рабочую директорию там, где находится интерпретатор Python + python.exe "path to your python script.py" # Запустить интерпретатор Python с файлом скрипта робота "path to your python script.py" -Execute from .cmd file +Запустить из интерпретатора Python x64 ############################################ - -In order to simplify the execution process you can write several code lines in file with the .cmd extension: +Для запуска срипта из интерпретатора Python x64 необходимо открыть командную строку (cmd), и выполнить следующие команды: .. code-block:: python - cd %~dp0 - copy /Y ..\Resources\WPy32-3720\python-3.7.2\python.exe ..\Resources\WPy32-3720\python-3.7.2\OpenRPAOrchestrator.exe - .\..\Resources\WPy32-3720\python-3.7.2\OpenRPAOrchestrator.exe orchestratorMain.py - pause >nul - - -Use in studio script (n/a) -############################################ -.. code-block:: python - - import sys - sys.path.append('../../') - import GUI - import keyboard - import subprocess - import time - - #Highlight the UI Object in Folder explorer - GUI.UIOSelector_FocusHighlight([{"class_name":"CabinetWClass","backend":"uia"},{"ctrl_index":2},{"ctrl_index":0},{"ctrl_index":2},{"ctrl_index":0}]) - - #Wait 2 seconds - time.sleep(3) - - #Loop: get child element of UI List - for lItem in GUI.UIOSelector_Get_UIO([{"class_name":"CabinetWClass","backend":"uia"},{"ctrl_index":2},{"ctrl_index":0},{"ctrl_index":2},{"ctrl_index":0}]).children(): - print(str(lItem)) - - - -Here you can find the docs and examples of the OpenRPA desktop (GUI) app access. - -**************************************************************************************************** -Desktop app UI access (win32 and UI automation dlls) -**************************************************************************************************** - -Definitions -############################################ - -- **UIO** - UI Object (class of pywinauto UI object) [pywinauto.base_wrapper] -- **UIOSelector** - List of dict (key attributes) -- **PWA** - PyWinAuto -- **PWASpecification** - List of dict (key attributes in pywinauto.find_window notation) -- **UIOTree** - Recursive Dict of Dict ... (UI Parent -> Child hierarchy) -- **UIOInfo** - Dict of UIO attributes -- **UIOActivity** - Activity of the UIO (UI object) from the Pywinauto module -- **UIOEI** - UI Object info object - - -What is UIO? -############################################ -UIO is a User Interface Object (pyOpenRPA terminology). For maximum compatibility, this instance is inherited from the object model developed in the [pywinauto library (click to get a list of available class functions)](https://pywinauto.readthedocs.io/en/latest/code/pywinauto.base_wrapper.html). - -This approach allows us to implement useful functionality that has already been successfully developed in other libraries, and Supplement it with the missing functionality. In our case, the missing functionality is the ability to dynamically access UIO objects using UIO selectors. + cd "Resources\WPy32-3720\python-3.7.2.amd64" # Установить рабочую директорию там, где находится интерпретатор Python + python.exe "path to your python script.py" # Запустить интерпретатор Python с файлом скрипта робота "path to your python script.py" - -UIOSelector structure & example +Запустить из под .cmd файла ############################################ -UIOSelector is the list of condition items for the UIO in GUI. Each item has condition attributes for detect applicable UIO. Here is the description of the available condition attributes in item. - -**Desciption** - -.. code-block:: python - - [ - { - "depth_start" :: [int, start from 1] :: the depth index, where to start check the condition list (default 1), - "depth_end" :: [int, start from 1] :: the depth index, where to stop check the condition list (default 1), - "ctrl_index" || "index" :: [int, starts from 0] :: the index of the UIO in parent UIO child list, - "title" :: [str] :: the condition for the UIO attribute *title*, - "title_re" :: [str] :: regular expression (python ver) for the condition for the UIO attribute *title*, - "rich_text" :: [str] :: the condition for the UIO attribute *rich_text*, - "rich_text_re" :: [str] :: regular expression (python ver) for the condition for the UIO attribute *rich_text*, - "class_name" :: [str] :: the condition for the UIO attribute *class_name*, - "class_name_re" :: [str] :: regular expression (python ver) for the condition for the UIO attribute *class_name*, - "friendly_class_name" :: [str] :: the condition for the UIO attribute *friendly_class_name*, - "friendly_class_name_re" :: [str] :: regular expression (python ver) for the condition for the UIO attribute *friendly_class_name*, - "control_type" :: [str] :: the condition for the UIO attribute *control_type*, - "control_type_re" :: [str] :: regular expression (python ver) for the condition for the UIO attribute *control_type*, - "is_enabled" :: [bool] :: the condition for the UIO attribute *is_enabled*. If UI object is enabled on GUI, - "is_visible" :: [bool] :: the condition for the UIO attribute *is_visible*. If UI object is visible on GUI, - "backend" :: [str, "win32" || "uia"] :: the method of UIO extraction (default "win32"). ATTENTION! Current option can be only for the first item of the UIO selector. For the next items this option will be implemented from the first item. - }, - { ... specification next level UIO } - ] -**The UIO selector example** +Упростить процесс запуска и свести инициализацию робота к одному нажатию можно с помощью средстве command shell и .cmd файла. -.. code-block:: python - - [ - {"class_name":"CalcFrame", "backend":"win32"}, # 1-st level UIO specification - {"title":"Hex", "depth_start":3, "depth_end": 3} # 3-rd level specification (because of attribute depth_start|depth_stop) - ] - -The UIDesktop module (OpenRPA/Robot/UIDesktop.py) -######################################################################################## -The UIDesktop is extension of the pywinauto module which provide access to the desktop apps by the **win32** and **ui automation** dll frameworks (big thx to the Microsoft :) ). +Для этого достаточно выбрать рабочую директорию робота, там создать текстовый .cmd файл, и прописать в нем следующий код: .. code-block:: python - # EXAMPLE 1 - from pyOpenRPA.Robot import UIDesktop - - UIDesktop.UIOSelector_Get_UIO( - inSpecificationList=[ - {"title":"notepad.exe"},{"title":"OK"}], - inElement=None, - inFlagRaiseException=True) - - -The UIDesktop module (OpenRPA/Robot/UIDesktop.py) -######################################################################################## -The UIDesktop is extension of the pywinauto module which provide access to the desktop apps by the **win32** and **ui automation** dll frameworks (big thx to the Microsoft :) ). - -*Naming convention: \\_\\_\*
- - -**************************************************************************************************** -Theory & practice. WEB app UI access (selenium) -**************************************************************************************************** - -About -############################################### -The pyOpenRPA support web app manipulation (by the Selenium lib). -More docs about selenium you can find here (https://selenium-python.readthedocs.io/) - -How to use -############################################### -To start use selenium just import selenium modules in the robot tool. Here is the example of the usage. - -.. code-block:: python - - from selenium import webdriver - from selenium.webdriver.common.keys import Keys - - driver = webdriver.Chrome() - driver.get("http://www.python.org") - assert "Python" in driver.title - elem = driver.find_element_by_name("q") - elem.clear() - elem.send_keys("pycon") - elem.send_keys(Keys.RETURN) - assert "No results found." not in driver.page_source - driver.close() - -**************************************************************************************************** -Theory & practice. Keyboard & mouse manipulation -**************************************************************************************************** - - -**************************************************************************************************** -Theory & practice. Screen capture & image recognition -**************************************************************************************************** - -How to automate image recognition on PC -########################################### - -Here you can find any ways you need to use in your business case: -- Find the exact match on the screen with the other image -- Use text recognition module (OCR) -- Use computer vision (CV) to identify the objects on screen/image/video -- Use artificial intelligence (AI) to make custom identification/classification/text recognition \ No newline at end of file + cd %~dp0 # Установить рабочую директорую там, где находится этот .cmd файл + copy /Y ..\Resources\WPy32-3720\python-3.7.2\python.exe ..\Resources\WPy32-3720\python-3.7.2\OpenRPAOrchestrator.exe # Выполнить компирование python.exe на другое наименование, чтобы изменить наименование процесса робота в диспетчере задач (без этой операции все роботы будут отображаться в диспетчере задач как python.exe) + .\..\Resources\WPy32-3720\python-3.7.2\OpenRPAOrchestrator.exe orchestratorMain.py # Выполнить инициализацию скрипта робота RPA + pause >nul # Не закрывать окно консоли после завершения работы скрипта робота + +****************************** +Быстрая навигация +****************************** + +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ \ No newline at end of file diff --git a/Sources/GuideSphinx/Robot/09_Dependencies.rst b/Sources/GuideSphinx/Robot/09_Dependencies.rst deleted file mode 100644 index ce74f304..00000000 --- a/Sources/GuideSphinx/Robot/09_Dependencies.rst +++ /dev/null @@ -1,10 +0,0 @@ -#################################### -9. Зависимости -#################################### - -Python 3 x32 [psutil, pywinauto, wmi, PIL, keyboard, pyautogui, win32api (pywin32), selenium, openCV, tesseract, requests, lxml, PyMuPDF] -Python 3 x64 [psutil, pywinauto, wmi, PIL, keyboard, pyautogui, win32api (pywin32), selenium, openCV, tesseract, requests, lxml, PyMuPDF] -pywinauto (Windows GUI automation) -Semantic UI CSS framework -JsRender by https://www.jsviews.com (switch to Handlebars) -Handlebars \ No newline at end of file diff --git a/Sources/GuideSphinx/Studio/01_Studio.rst b/Sources/GuideSphinx/Studio/01_Studio.rst index 45c773bb..fdfbf0c9 100644 --- a/Sources/GuideSphinx/Studio/01_Studio.rst +++ b/Sources/GuideSphinx/Studio/01_Studio.rst @@ -1,7 +1,32 @@ .. _module.studio.description: -************************ +#################################### 1. Описание +#################################### + +************************ +Общее ************************ -pyOpenRPA Studio is the executable process. +Модуль студии обеспечивает всю необходимую функциональность взаимодействия с UI объектами различных приложений, запущенных в сессии. + +В разделе :ref:`module.studio.how-to-use` вы найдете практическое руководство по работе с пользовательским интерфейсом студии, которая отрывается в веб браузере. + +Дорогие коллеги! + +Мы знаем, что с pyOpenRPA вы сможете существенно улучшить качество вашего бизнеса. Платформа роботизации pyOpenRPA - это разработка, которая дает возможность делать виртуальных сотрудников (программных роботов RPA) выгодными, начиная от эффекта всего в **10 тыс. руб.** И управлять ими будете только Вы! + +Если у вас останутся вопросы, то вы всегда можете обратиться в центр поддержки клиентов pyOpenRPA. Контакты: :ref:`3.-Copyrights-&-Contacts` + +pyOpenRPA - роботы помогут! + +****************************** +Быстрая навигация +****************************** + +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ \ No newline at end of file diff --git a/Sources/GuideSphinx/Studio/02_HowToUse.rst b/Sources/GuideSphinx/Studio/02_HowToUse.rst index 96761ba8..fb0c6678 100644 --- a/Sources/GuideSphinx/Studio/02_HowToUse.rst +++ b/Sources/GuideSphinx/Studio/02_HowToUse.rst @@ -1,126 +1,148 @@ +.. _module.studio.how-to-use: + #################################### 2. Как использовать? #################################### -Content -======= - -- `How to run <#how-to-run>`__ -- `UI Description <#ui-description>`__ -- `How to extract UI tree <#how-to-extract-ui-tree>`__ -- `How to search UI object by mouse - hover <#how-to-search-ui-object-by-mouse-hover>`__ -- `How to extract UI object - properties <#how-to-extract-ui-object-properties>`__ - -How to run -========== - -- For OS x32 -- Run (double click): OpenRPA\_32.cmd (for OS x32) -- For OS x64 -- Run (double click): OpenRPA\_64.cmd (for OS x64) -- Wait text "running server" in console. Default browser will be open - automatically -- **Attention!** The studio tool does not support the Internet explorer - (any version) for GUI rendering (lol) +.. _general: + +************************ +Общее +************************ + +- `Как запустить? <#how-to-run>`__ +- `Описание UI студии <#ui-description>`__ +- `Извлечь UI дерево <#how-to-extract-ui-tree>`__ +- `Поиск UI объекта по наведению мыши <#how-to-search-ui-object-by-mouse-hover>`__ +- `Извлечь свойства UI объекта <#how-to-extract-ui-object-properties>`__ + +.. _how-to-run: + +************************ +Как запустить? +************************ + +- Запустить файл Studio\pyOpenRPA.Studio_x64.cmd +- Ожидать текст в окне консоли: "running server". Браузер, установленный по умолчанию откроется автоматически +- **!ВНИМАНИЕ!** Студия поддерживает все версии браузеров, кроме Internet Explorer. .. image:: /img/504b98f76747f63900a2943532a946bb.png :alt: 504b98f76747f63900a2943532a946bb.png +.. _ui-description: -UI Description -============== +************************ +Описание UI студии +************************ -**The studio tool GUI contains of:** +**Интерфейс (UI) студии состоит из следующих компонентов:** -1. UI tree viewer -2. Selected UI object hierarchy list -3. Selected UI object property list -4. UIO selector editor -5. UIO action panel -6. Another Python activity panel -7. Action/activity list +1. Обозреватель UI дерева +2. Обозреватель иерархии выбранного UI объекта +3. Обозреватель свойств выбранного уровня UI объекта +4. Редактор UIO селектора +5. Панель активностей над UIO объектом +6. Панель других Python активностей +7. Список активностей -*Look it on the GUI screenshots are listed below* +*Ниже представлены скриншоты студии* -GUI Screenshot 1 +Скриншот 1 ---------------- .. image:: /img/d3d6ad14a7e50843bd89d2b14a092fee.png :alt: 504b98f76747f63900a2943532a946bb.png -GUI Screenshot 2 +Скриншот 2 ---------------- .. image:: /img/65b7d51c0a5b21e6b27dc23d4062d3ca.png :alt: 65b7d51c0a5b21e6b27dc23d4062d3ca.png -How to extract UI tree -====================== +.. _how-to-extract-ui-tree: + +************************ +Извлечь UI дерево +************************ -In order to extract the UI tree do the following: in ``UI tree viewer`` -choose the object you are interested and click the button "Expand". ## +Чтобы извлечь дерево пользовательского интерфейса выполните следующие действия: в ``UI Tree viewer`` выбрать интересующий UI объект и нажать кнопку ``Expand``. -Action: Click the button "Expand" +Действие: Нажать по кнопке "Expand" --------------------------------------- .. image:: /img/6effc376ff6ea928840674bd744caced.png :alt: 6effc376ff6ea928840674bd744caced.png -Result +Итог --------------------------------------- .. image:: /img/18b9ab36126c8c32168bf5bbb9330701.png :alt: 18b9ab36126c8c32168bf5bbb9330701.png -How to search UI object by mouse hover + --------------------------------------- -In order to search UI object do the -following: in ``UI tree viewer`` choose the parent object, where you are -want to search UI object, and click the button "Mouse search". The mouse -search mode will start. Turn mouse on the UI object you are interested -and wait when the studio will highlight the UI object. After the -hightlight hold the "Ctrl" key and wait 3 seconds. The interested UI -object will be shown in ``UI tree viewer``. - -Action: Click the button "Mouse search" + +.. _how-to-search-ui-object-by-mouse-hover: + +*********************************** +Поиск UI объекта по наведению мыши +*********************************** + +Чтобы выполнить поиск UI объекта пользовательского интерфейса, необходимо в ``UI tree viewer`` выбрать родительский UI объект, в котором вы хотите выполнить поиск, и нажать кнопку ``Mouse search``. + +Будет активирован режим поиск UI объекта по курсору мыши. Наведите курсор мыши на интересующий вас объект пользовательского интерфейса и дождитесь, когда студия выделит объект пользовательского интерфейса. После выделения цветов удерживайте клавишу "Ctrl" и подождите 3 секунды. Интересующий UI объект будет показан в ``UI tree viewer``. + +Действие: Нажать кнопку "Mouse search" --------------------------------------- .. image:: /img/84d7e4de0c840631f87cf7b325b53ad8.png :alt: 84d7e4de0c840631f87cf7b325b53ad8.png -Action: Turn mouse on the UI object you are interested and hold the "Ctrl" key for 3 seconds --------------------------------------------------------------------------------------------- +Действие: Навести курсор мыши на UI объект, который интересует и зажать клавишу "Ctrl" на 3 секунды +-------------------------------------------------------------------------------------------------------------- .. image:: /img/b7c38d622bf5b7afa5b26d1686d7302a.png :alt: b7c38d622bf5b7afa5b26d1686d7302a.png -Result: The interested UI object will be shown in ``UI tree viewer`` +Итог: Интересующий UI объект будет отображен в ``UI tree viewer`` -------------------------------------------------------------------- .. image:: /img/629bbf4db2c01b9c640194230949fcd2.png :alt: 629bbf4db2c01b9c640194230949fcd2.png -How to extract UI object properties -=================================== +.. _how-to-extract-ui-object-properties: + +*********************************** +Извлечь свойства UI объекта +*********************************** -In order to extract UI object properties do the following: in -``Selected UI object hierarchy list`` choose the UI object you are -interested and click it. The UI object property list will be shown in -``Selected UI object property list`` +Чтобы извлечь свойства UI объекта, необходимо в +``Selected UI object hierarchy list`` выбрать интересующий UI объект и щелкнуть по нему. Список свойств UI объекта будет отображен в ``Selected UI object property list`` -Action: Choose the UI object you are interested and click it +Действие: Choose the UI object you are interested and click it ------------------------------------------------------------------------------ .. image:: /img/2c27be5bdde20b5d062cbb40e74eaec5.png :alt: 2c27be5bdde20b5d062cbb40e74eaec5.png -Result: The UI object property list will be shown in ``Selected UI object property list`` +Итог: Свойства UI объекта будут отображены в ``Selected UI object property list`` ----------------------------------------------------------------------------------------- .. image:: /img/f235ae29099a713e0246cd574ac3a17c.png :alt: f235ae29099a713e0246cd574ac3a17c.png + +****************************** +Быстрая навигация +****************************** + +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ + + diff --git a/Sources/GuideSphinx/Tools/02_Defs.rst b/Sources/GuideSphinx/Tools/02_Defs.rst index e118c2ac..ca56fb6e 100644 --- a/Sources/GuideSphinx/Tools/02_Defs.rst +++ b/Sources/GuideSphinx/Tools/02_Defs.rst @@ -1,5 +1,5 @@ #################################### -2. Defs StopSafe +2. Функции StopSafe #################################### How to use StopSafe on the robot side diff --git a/Sources/GuideSphinx/index.rst b/Sources/GuideSphinx/index.rst index ba45c743..440bd076 100644 --- a/Sources/GuideSphinx/index.rst +++ b/Sources/GuideSphinx/index.rst @@ -51,9 +51,9 @@ pyOpenRPA - роботы помогут! **Для коммерческого использования:** -* Вариант 1: Подписка на премиальную техническую поддержку от вендора (ежемесячно от 66 900 руб. без НДС) -* Вариант 2: Покупка бессрочной лицензии на текущую версию pyOpenRPA и ниже (разовый платеж 299 000 руб. без НДС) -* Вариант 3: Покупка бессрочной лицензии на 1-го робота, который будет использовать текущую версию pyOpenPRA и ниже (разовый платеж 99 000 руб. без НДС) +* **Вариант 1:** Подписка на премиальную техническую поддержку от вендора (ежемесячно от 66 900 руб. без НДС) +* **Вариант 2:** Покупка бессрочной лицензии на текущую версию pyOpenRPA и ниже (разовый платеж 299 000 руб. без НДС) +* **Вариант 3:** Покупка бессрочной лицензии на 1-го робота, который будет использовать текущую версию pyOpenPRA и ниже (разовый платеж 99 000 руб. без НДС) Используя ПО pyOpenRPA Вы осознаете свою ответственность в случаях нарушения лицензионного законодательства и совершения неправомерных действий. @@ -244,4 +244,17 @@ Wiki структура :caption: ИНСТРУМЕНТЫ :glob: - Tools/* \ No newline at end of file + Tools/* + + + +****************************** +Быстрая навигация +****************************** + +- `Сообщество pyOpenRPA (telegram) `_ +- `Сообщество pyOpenRPA (tenchat) `_ +- `Сообщество pyOpenRPA (вконтакте) `_ +- `Презентация pyOpenRPA `_ +- `Портал pyOpenRPA `_ +- `Репозиторий pyOpenRPA `_ \ No newline at end of file diff --git a/Sources/GuideSphinx/make_RUS_Guide_PDF.cmd b/Sources/GuideSphinx/make_RUS_Guide_PDF.cmd new file mode 100644 index 00000000..31cfd772 --- /dev/null +++ b/Sources/GuideSphinx/make_RUS_Guide_PDF.cmd @@ -0,0 +1 @@ +"C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Resources\wkhtmltopdf\bin\wkhtmltopdf.exe" --javascript-delay 5000 --load-error-handling ignore --enable-local-file-access C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\index.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\01_HowToInstall.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\03_Copyrights_Contacts.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\Robot\01_Robot.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\Robot\02_uidesktop.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\Robot\03_uiweb.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\Robot\04_keyboard.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\Robot\05_clipboard.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\Robot\06_mouse.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\Robot\07_image.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\Robot\08_HowToUse.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\Studio\01_Studio.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\Studio\02_HowToUse.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\Orchestrator\01_Orchestrator.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\Orchestrator\02_Defs.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\Orchestrator\03_gSettingsTemplate.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\Orchestrator\04_HowToUse.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\html\Orchestrator\05_UAC.html C:\Abs\Archive\scopeSrcUL\pyOpenRPA\Wiki\RUS_Guide\pdf\pyOpenRPA_Guide_RUS.pdf \ No newline at end of file diff --git a/Sources/pyOpenRPA/Robot/Clipboard.py b/Sources/pyOpenRPA/Robot/Clipboard.py index 12b43186..279e699b 100644 --- a/Sources/pyOpenRPA/Robot/Clipboard.py +++ b/Sources/pyOpenRPA/Robot/Clipboard.py @@ -4,17 +4,42 @@ import win32clipboard #################################### # GUI Module - interaction with Windows clipboard -################ -###ClipboardGet -################ +def Get(): + """ + Получить текстовое содержимое буфера обмена. + + .. code-block:: python + + # Clipboard: Взаимодействие с буфером + from pyOpenRPA.Robot import Clipboard + lClipStr = Clipboard.Get() + + :return: Текстовое содержимое буфера обмена + :rtype: str + """ + return ClipboardGet() + +def Set(inTextStr:str): + """ + Установить текстовое содержимое в буфер обмена. + + .. code-block:: python + + # Clipboard: Взаимодействие с буфером + from pyOpenRPA.Robot import Clipboard + lClipStr = Clipboard.Set(inTextStr="HELLO WORLD") + + :param inTextStr: Текстовое содержимое для установки в буфера обмена + :type inTextStr: str + """ + ClipboardSet(inText=inTextStr) + def ClipboardGet(): win32clipboard.OpenClipboard() lResult = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT) win32clipboard.CloseClipboard() return lResult -################ -###ClipboardSet -################ + def ClipboardSet(inText): win32clipboard.OpenClipboard() win32clipboard.EmptyClipboard() diff --git a/Sources/pyOpenRPA/__init__.py b/Sources/pyOpenRPA/__init__.py index 8e4a392b..fc97568b 100644 --- a/Sources/pyOpenRPA/__init__.py +++ b/Sources/pyOpenRPA/__init__.py @@ -3,7 +3,7 @@ r""" The pyOpenRPA package """ -__version__ = 'v1.2.12' +__version__ = 'v1.2.13' __all__ = [] __author__ = 'Ivan Maslov ' #from .Core import Robot \ No newline at end of file diff --git a/Wiki/RUS_Guide/doctrees/01_HowToInstall.doctree b/Wiki/RUS_Guide/doctrees/01_HowToInstall.doctree index bf882b7d..de69ee25 100644 Binary files a/Wiki/RUS_Guide/doctrees/01_HowToInstall.doctree and b/Wiki/RUS_Guide/doctrees/01_HowToInstall.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/03_Copyrights_Contacts.doctree b/Wiki/RUS_Guide/doctrees/03_Copyrights_Contacts.doctree index ec2da502..d9166c6f 100644 Binary files a/Wiki/RUS_Guide/doctrees/03_Copyrights_Contacts.doctree and b/Wiki/RUS_Guide/doctrees/03_Copyrights_Contacts.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Agent/02_Defs.doctree b/Wiki/RUS_Guide/doctrees/Agent/02_Defs.doctree index 992c9a17..fa002a68 100644 Binary files a/Wiki/RUS_Guide/doctrees/Agent/02_Defs.doctree and b/Wiki/RUS_Guide/doctrees/Agent/02_Defs.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Orchestrator/01_Orchestrator.doctree b/Wiki/RUS_Guide/doctrees/Orchestrator/01_Orchestrator.doctree index 79801fef..76b0b691 100644 Binary files a/Wiki/RUS_Guide/doctrees/Orchestrator/01_Orchestrator.doctree and b/Wiki/RUS_Guide/doctrees/Orchestrator/01_Orchestrator.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Orchestrator/02_Defs.doctree b/Wiki/RUS_Guide/doctrees/Orchestrator/02_Defs.doctree index 0222e3db..2de72328 100644 Binary files a/Wiki/RUS_Guide/doctrees/Orchestrator/02_Defs.doctree and b/Wiki/RUS_Guide/doctrees/Orchestrator/02_Defs.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Orchestrator/03_gSettingsTemplate.doctree b/Wiki/RUS_Guide/doctrees/Orchestrator/03_gSettingsTemplate.doctree index 54b05c6b..c53558fb 100644 Binary files a/Wiki/RUS_Guide/doctrees/Orchestrator/03_gSettingsTemplate.doctree and b/Wiki/RUS_Guide/doctrees/Orchestrator/03_gSettingsTemplate.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Orchestrator/04_HowToUse.doctree b/Wiki/RUS_Guide/doctrees/Orchestrator/04_HowToUse.doctree index 755c16c0..71757177 100644 Binary files a/Wiki/RUS_Guide/doctrees/Orchestrator/04_HowToUse.doctree and b/Wiki/RUS_Guide/doctrees/Orchestrator/04_HowToUse.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Orchestrator/05_UAC.doctree b/Wiki/RUS_Guide/doctrees/Orchestrator/05_UAC.doctree index 2fafd1aa..6687a267 100644 Binary files a/Wiki/RUS_Guide/doctrees/Orchestrator/05_UAC.doctree and b/Wiki/RUS_Guide/doctrees/Orchestrator/05_UAC.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Orchestrator/06_Defs Managers.doctree b/Wiki/RUS_Guide/doctrees/Orchestrator/06_Defs Managers.doctree deleted file mode 100644 index 88349b6b..00000000 Binary files a/Wiki/RUS_Guide/doctrees/Orchestrator/06_Defs Managers.doctree and /dev/null differ diff --git a/Wiki/RUS_Guide/doctrees/Robot/01_Robot.doctree b/Wiki/RUS_Guide/doctrees/Robot/01_Robot.doctree index f4711a82..ad87f52b 100644 Binary files a/Wiki/RUS_Guide/doctrees/Robot/01_Robot.doctree and b/Wiki/RUS_Guide/doctrees/Robot/01_Robot.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Robot/02_Defs.doctree b/Wiki/RUS_Guide/doctrees/Robot/02_Defs.doctree deleted file mode 100644 index 480e5de9..00000000 Binary files a/Wiki/RUS_Guide/doctrees/Robot/02_Defs.doctree and /dev/null differ diff --git a/Wiki/RUS_Guide/doctrees/Robot/02_uidesktop.doctree b/Wiki/RUS_Guide/doctrees/Robot/02_uidesktop.doctree index 18a74312..62a57645 100644 Binary files a/Wiki/RUS_Guide/doctrees/Robot/02_uidesktop.doctree and b/Wiki/RUS_Guide/doctrees/Robot/02_uidesktop.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Robot/03_uiweb.doctree b/Wiki/RUS_Guide/doctrees/Robot/03_uiweb.doctree index aaccfbaf..8f31eab2 100644 Binary files a/Wiki/RUS_Guide/doctrees/Robot/03_uiweb.doctree and b/Wiki/RUS_Guide/doctrees/Robot/03_uiweb.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Robot/04_keyboard.doctree b/Wiki/RUS_Guide/doctrees/Robot/04_keyboard.doctree index 48124a9d..b43a3646 100644 Binary files a/Wiki/RUS_Guide/doctrees/Robot/04_keyboard.doctree and b/Wiki/RUS_Guide/doctrees/Robot/04_keyboard.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Robot/05_clipboard.doctree b/Wiki/RUS_Guide/doctrees/Robot/05_clipboard.doctree index 9c9e210f..ecdde6b8 100644 Binary files a/Wiki/RUS_Guide/doctrees/Robot/05_clipboard.doctree and b/Wiki/RUS_Guide/doctrees/Robot/05_clipboard.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Robot/06_mouse.doctree b/Wiki/RUS_Guide/doctrees/Robot/06_mouse.doctree index 6b2a2f34..601ef916 100644 Binary files a/Wiki/RUS_Guide/doctrees/Robot/06_mouse.doctree and b/Wiki/RUS_Guide/doctrees/Robot/06_mouse.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Robot/07_image.doctree b/Wiki/RUS_Guide/doctrees/Robot/07_image.doctree index 0d35bf3f..b3a07a6c 100644 Binary files a/Wiki/RUS_Guide/doctrees/Robot/07_image.doctree and b/Wiki/RUS_Guide/doctrees/Robot/07_image.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Robot/08_HowToUse.doctree b/Wiki/RUS_Guide/doctrees/Robot/08_HowToUse.doctree index f81a1b52..82eb31ef 100644 Binary files a/Wiki/RUS_Guide/doctrees/Robot/08_HowToUse.doctree and b/Wiki/RUS_Guide/doctrees/Robot/08_HowToUse.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Robot/09_Dependencies.doctree b/Wiki/RUS_Guide/doctrees/Robot/09_Dependencies.doctree deleted file mode 100644 index f8c220f1..00000000 Binary files a/Wiki/RUS_Guide/doctrees/Robot/09_Dependencies.doctree and /dev/null differ diff --git a/Wiki/RUS_Guide/doctrees/Studio/01_Studio.doctree b/Wiki/RUS_Guide/doctrees/Studio/01_Studio.doctree index 1ae92b00..a4aab303 100644 Binary files a/Wiki/RUS_Guide/doctrees/Studio/01_Studio.doctree and b/Wiki/RUS_Guide/doctrees/Studio/01_Studio.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Studio/02_HowToUse.doctree b/Wiki/RUS_Guide/doctrees/Studio/02_HowToUse.doctree index 49c895d6..8039cfeb 100644 Binary files a/Wiki/RUS_Guide/doctrees/Studio/02_HowToUse.doctree and b/Wiki/RUS_Guide/doctrees/Studio/02_HowToUse.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/Tools/02_Defs.doctree b/Wiki/RUS_Guide/doctrees/Tools/02_Defs.doctree index abcf297b..ba1d4c2c 100644 Binary files a/Wiki/RUS_Guide/doctrees/Tools/02_Defs.doctree and b/Wiki/RUS_Guide/doctrees/Tools/02_Defs.doctree differ diff --git a/Wiki/RUS_Guide/doctrees/environment.pickle b/Wiki/RUS_Guide/doctrees/environment.pickle index 87e75238..d7251631 100644 Binary files a/Wiki/RUS_Guide/doctrees/environment.pickle and b/Wiki/RUS_Guide/doctrees/environment.pickle differ diff --git a/Wiki/RUS_Guide/doctrees/index.doctree b/Wiki/RUS_Guide/doctrees/index.doctree index 8f396b29..be164731 100644 Binary files a/Wiki/RUS_Guide/doctrees/index.doctree and b/Wiki/RUS_Guide/doctrees/index.doctree differ diff --git a/Wiki/RUS_Guide/html/01_HowToInstall.html b/Wiki/RUS_Guide/html/01_HowToInstall.html index 1cd6d2ef..ef9bbd31 100644 --- a/Wiki/RUS_Guide/html/01_HowToInstall.html +++ b/Wiki/RUS_Guide/html/01_HowToInstall.html @@ -41,7 +41,7 @@ - + @@ -91,24 +91,22 @@

МОДУЛЬ РОБОТ

МОДУЛЬ СТУДИЯ

    @@ -117,20 +115,19 @@

МОДУЛЬ ОРКЕСТРАТОР

МОДУЛЬ АГЕНТ

ИНСТРУМЕНТЫ

@@ -200,35 +197,35 @@

1. Первый запуск

-

Are you ready to install the pyOpenRPA solution on your machine?

-

Ok, we start. -Do the following operations:

+

Готовы испытать всю мощь перспективных технологий?

+

Будет очень интересно - начинаем!

+

Для начала необходимо выполнить следующие действия:

-

Installation has been completed :)

-
-

How to check installation

+

ВСЁ - Развертывание pyOpenRPA завершено! :)

+
+

Проверить, что pyOpenRPA развернута корректно?

+

В папке pyOpenRPA запустить интерпретатор Python

    -
  • Run portable python (built in the pyOpenRPA)

    -
      -
    • x32 python (GIT\Resources\WPy32-3720\python-3.7.2\python.exe)

    • -
    • x64 python (GIT\Resources\WPy64-3720\python-3.7.2.amd64\python.exe)

    • -
    -
  • +
  • x32 Python (GIT\Resources\WPy32-3720\python-3.7.2\python.exe)

  • +
  • x64 Python (GIT\Resources\WPy64-3720\python-3.7.2.amd64\python.exe)

-

The pyOpenRPA has been successfully installed if the portable python 3.7.2 was started without any exceptions (see screenshot).

+

Платформа pyOpenRPA успешно развернута корректно. если интерпретаторы python 3.7.2 были запущены без проблем (см. скриншот).

cb5dec8cecafa7d64f6cd14b2672acce.png
-
-

System requirements

+
+

Быстрая навигация

-

.. v1.2.12 replace:: v1.2.12 - .. |author| replace:: Ivan Maslov <ivan.maslov@unicodelabs.ru>

+

.. v1.2.12 replace:: v1.2.12

@@ -239,7 +236,7 @@