from pyOpenRPA.Tools import CrossOS import os import sys import time import threading from pyOpenRPA import Orchestrator from pyOpenRPA.Orchestrator.Server import app from fastapi import Depends, Body from fastapi.responses import PlainTextResponse from fastapi.responses import FileResponse from fastapi.staticfiles import StaticFiles time.sleep(1.5) # Определить очередность в панели управления cp_path_str = CrossOS.PathJoinList(CrossOS.PathSplitList(__file__)[:-1]) # ПАПКА ПАНЕЛИ УПРАВЛЕНИЯ (АВТОИДЕНТИФИКАЦИЯ ПО ТЕКУЩЕМУ ФАЙЛУ) # # # # # # # # # # # # # # БЛОК # # # # # ПАРАМЕТРОВ # # # # # НАЧАЛО # # # # # # # # # # # # ПАРАМЕТРЫ АГЕНТА agent_hostname_str = "" # ЕСЛИ НЕ УКАЗЫВАТЬ - ОРКЕСТРАТОР БУДЕТ ЗАПУСКАТЬ ПРОЦЕСС НА СВОЕЙ УЗ agent_username_str = "" # ПАРАМЕТРЫ РОБОТА robot_logs_path_str = os.path.join(cp_path_str, "..", "..", "Logs") # ПУТЬ К ПАПКЕ С ЛОГАМИ ВИДА гггг_мм_дд.log robot_key_str = "SIMPLE_01" # КОД РОБОТА (ТЕКСТОВЫЙ ИДЕНТИФИКАТОР В ОБЩЕМ ПРОСТРАНСТВЕ ОРКЕСТРАТОРА) robot_start_path_str = "notepad" # ПУТЬ К ФАЙЛУ ЗАПУСКА ПРОЦЕССА robot_process_wo_exe_str = "notepad" # НАИМЕНОВАНИЕ ПРОЦЕССА РОБОТА !БЕЗ УПОМИНАНИЯ РАСШИРЕНИЯ .EXE! # ПАРАМЕТРЫ ДОПОЛНИТЕЛЬНЫЕ additional_folder_path_str = os.path.join(cp_path_str, "..", "..", "Readme") # ПУТЬ К ПАПКЕ С ДОПОЛНИТЕЛЬНЫМИ ДОКУМЕНТАМИ - ОТОБРАЖАЮТСЯ НА ПАНЕЛИ ЗАДАЧ howto_url_str = f"/{robot_key_str}/howto.docx" # URL ССЫЛКА НА ИНСТРУКЦИЮ. НАЧИНАТЬ ОБЯЗАТЕЛЬНО С / howto_path_str = os.path.join(cp_path_str, "how_to.docx") # ПУТЬ К ИНСТРУКЦИИ НА ДИСКЕ # # # # # # # # # # # # # # БЛОК # # # # # ПАРАМЕТРОВ # # # # # КОНЕЦ # # # # # # # # # # # # ПОДКЛЮЧЕНИЕ ПАПКИ С ПАНЕЛЬЮ УПРАВЛЕНИЯ. ДОСТУПНА БУДЕТ ПО URL f"/{robot_key_str}/folder" app.mount(f"/{robot_key_str}/folder", StaticFiles(directory=os.path.abspath(cp_path_str)), name=f"{robot_key_str}_folder") # ПОДКЛЮЧЕНИЕ ИНСТРУКЦИИ ПОЛЬЗОВАТЕЛЯ @app.get(path=howto_url_str,tags=[f"{robot_key_str}"]) def get_howto(): return FileResponse(os.path.abspath(howto_path_str)) # ПОДКЛЮЧЕНИЕ ПАПКИ С ЛОГАМИ app.mount(f"/{robot_key_str}/logs", StaticFiles(directory=os.path.abspath(robot_logs_path_str)), name=f"{robot_key_str}-logs") # ПОДКЛЮЧЕНИЕ ПАПКИ С ДОП. ДОКУМЕНТАМИ app.mount(f"/{robot_key_str}/additional", StaticFiles(directory=os.path.abspath(additional_folder_path_str)), name=f"{robot_key_str}-additional") def additional_files(): files = os.listdir(additional_folder_path_str) return files[::-1] # ПРОВЕРКА ПРОЦЕССА (ЗАПУЩЕН ИЛИ ОСТАНОВЛЕН) ВНИМАНИЕ! АСИНХРОННАЯ ПРОВЕРКА, ЧТОБЫ НЕ ЗАВИСАЛ ПОТОК ОБРАБОТКИ (СЕТЕВОЕ ВЗАИМОДЕЙСТВИЕ) robot_is_started_bool = False def robot_is_started(): global robot_is_started_bool if agent_hostname_str: process_list_guid_str = Orchestrator.AgentProcessWOExeUpperUserListGet( inHostNameStr=agent_hostname_str, inUserStr=agent_username_str) process_list = Orchestrator.AgentActivityItemReturnGet(inGUIDStr=process_list_guid_str, inTimeoutSecFloat=60.0) if robot_process_wo_exe_str.upper() in process_list: robot_is_started_bool=True else: robot_is_started_bool=False else: if robot_process_wo_exe_str.upper() in Orchestrator.ProcessListGet()['ProcessWOExeUpperList']: robot_is_started_bool=True else: robot_is_started_bool=False robot_status_interval_sec_float = 3.0 # ИНТЕРВАЛ ПРОВЕРКИ АКТИВНОСТИ ПРОЦЕССА РОБОТА def loop_robot_is_started(): global robot_status_interval_sec_float while True: try: robot_is_started() except Exception as e: pass time.sleep(robot_status_interval_sec_float) threading.Thread(target=loop_robot_is_started).start() # ФУНКЦИЯ ЗАПУСКА ФАЙЛА @app.post(path=f"/{robot_key_str}/action/start",tags=[f"{robot_key_str}"]) def robot_start(): cmd_str = robot_start_path_str global robot_is_started_bool if agent_hostname_str: Orchestrator.AgentOSCMD(inHostNameStr=agent_hostname_str, inUserStr=agent_username_str, inCMDStr=cmd_str, inRunAsyncBool=True, inSendOutputToOrchestratorLogsBool=False, inCaptureBool=False) else: Orchestrator.OSCMD(inCMDStr=cmd_str,inRunAsyncBool=True) # ФУНКЦИЯ ОСТАНОВКИ ПРОЦЕССА @app.post(path=f"/{robot_key_str}/action/stop",tags=[f"{robot_key_str}"]) def robot_stop(): cmd_str = f"taskkill /f /FI \"USERNAME eq %username%\" /im {robot_process_wo_exe_str}.exe" global robot_is_started_bool if agent_hostname_str: Orchestrator.AgentOSCMD(inHostNameStr=agent_hostname_str, inUserStr=agent_username_str, inCMDStr=cmd_str, inRunAsyncBool=True, inSendOutputToOrchestratorLogsBool=False, inCaptureBool=False) else: Orchestrator.OSCMD(inCMDStr=cmd_str,inRunAsyncBool=True) # ИНИЦИАЛИЗАЦИЯ ПАНЕЛИ УПРАВЛЕНИЯ РОБОТОМ cp_manager = Orchestrator.Managers.ControlPanel(inControlPanelNameStr=robot_key_str, inRefreshHTMLJinja2TemplatePathStr=os.path.join(cp_path_str, "index.html"), inJinja2TemplateRefreshBool = True) cp_manager.Jinja2DataUpdateDictSet(inJinja2DataUpdateDict={"config": sys.modules[__name__]} ) # HOTFIX Orchestrator.AgentProcessWOExeUpperUserListGet def HOTFIX_01(inHostNameStr, inUserStr, inGSettings = None): """L-,W+: Получить список процессов, которые выполняется на сессии Агента. Все процессы фиксируются без постфикса .exe, а также в верхнем регистре. ПРИМЕР РЕЗУЛЬТАТА, КОТОРЫЙ МОЖНО ПОЛУЧИТЬ ПО ГУИД ЧЕРЕЗ ФУНКЦИЮ AgentActivityItemReturnGet: ["ORCHESTRATOR", "AGENT", "CHROME", "EXPLORER", ...] :param inGSettings: Глобальный словарь настроек Оркестратора (синглтон) :param inHostNameStr: Наименование хоста, на котором запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления :param inUserStr: Наименование пользователя, на графической сессии которого запущен Агент. Наименования подключенных агентов доступно для просмотра в панели управления :return: ГУИД (GUID) строка Активности (ActivityItem). Далее можно ожидать результат этой функции по ГУИД с помощью функции AgentActivityItemReturnGet """ inGSettings = Orchestrator.GSettingsGet(inGSettings=inGSettings) # Set the global settings lActivityItemDict = { "Def":"ProcessWOExeUpperUserListGet", # def alias (look pyOpeRPA.Agent gSettings["ProcessorDict"]["AliasDefDict"]) "ArgList":[], # Args list "ArgDict":{}, # 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) } #Send item in AgentDict for the futher data transmition return Orchestrator.AgentActivityItemAdd(inGSettings=inGSettings, inHostNameStr=inHostNameStr, inUserStr=inUserStr, inActivityItemDict=lActivityItemDict) Orchestrator.AgentProcessWOExeUpperUserListGet = HOTFIX_01