@ -2,72 +2,122 @@ from pyOpenRPA.Tools import CrossOS
import os
import sys
import time
import json
import threading
from pyOpenRPA import Orchestrator
from datetime import date
from pyOpenRPA . Orchestrator . Server import app
import threading
from fastapi import Depends , Body
from fastapi . responses import PlainTextResponse
from fastapi . responses import FileResponse
time . sleep ( 1.5 ) # Определить очередность в панели управления
from fastapi . staticfiles import StaticFiles
# путь к папке, в которой расположена панель управления (используется для формирования других путей)
cp_path_str = CrossOS . PathJoinList ( CrossOS . PathSplitList ( __file__ ) [ : - 1 ] )
#AGENT SETTINGS
agent_hostname_str = " "
agent_username_str = " "
time . sleep ( 1.5 ) # Определить очередность в панели управления
cp_path_str = CrossOS . PathJoinList ( CrossOS . PathSplitList ( __file__ ) [ : - 1 ] ) # ПАПКА ПАНЕЛИ УПРАВЛЕНИЯ (АВТОИДЕНТИФИКАЦИЯ ПО ТЕКУЩЕМУ ФАЙЛУ)
# # # # # # # # # # # # # # БЛОК # # # # # ПАРАМЕТРОВ # # # # # НАЧАЛО # # # # # # # # # # #
# ПАРАМЕТРЫ АГЕНТА
agent_hostname_str = " OPENRPA-00001 " # ЕСЛИ Н Е УКАЗЫВАТЬ - О Р К Е С Т Р А Т О Р БУДЕТ ЗАПУСКАТЬ ПРОЦЕСС Н А СВОЕЙ У З
agent_username_str = " IMASL "
# ПАРАМЕТРЫ РОБОТА
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 " ) # ПУТЬ К ИНСТРУКЦИИ Н А ДИСКЕ
# # # # # # # # # # # # # # БЛОК # # # # # ПАРАМЕТРОВ # # # # # КОНЕЦ # # # # # # # # # # #
# ROBOT SETTINGS
robot_logs_path_str = f " { cp_path_str } "
# ПОДКЛЮЧЕНИЕ ПАПКИ С ПАНЕЛЬЮ УПРАВЛЕНИЯ. ДОСТУПНА БУДЕТ ПО 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 ) )
gSettings = Orchestrator . GSettingsGet ( )
# ПОДКЛЮЧЕНИЕ ПАПКИ С ЛОГАМИ
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_key_str = " SIMPLE_01 "
# ПРОВЕРКА ПРОЦЕССА (ЗАПУЩЕН ИЛИ ОСТАНОВЛЕН) ВНИМАНИЕ! АСИНХРОННАЯ ПРОВЕРКА, ЧТОБЫ Н Е ЗАВИСАЛ ПОТОК ОБРАБОТКИ (С Е Т Е В О Е ВЗАИМОДЕЙСТВИЕ)
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
# Подключить папку
#app.mount(f"/{robot_key_str}/calendar", StaticFiles(directory=os.path.join(os.path.abspath(cpPathStr), "calendar")), name=f"{robot_key_str}_calendar")
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 ( )
# пути для ...
htmlPath = os . path . join ( cp_path_str , " index.html " )
scriptPath = os . path . join ( cp_path_str , f " scripts.js " )
# ФУНКЦИЯ ЗАПУСКА ФАЙЛА
@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 )
# вывод папки логов
def check_folder ( folder ) :
files = os . listdir ( folder )
return files [ : : - 1 ]
app . mount ( f " / { robot_key_str } /logs " , StaticFiles ( directory = robot_logs_path_str ) , name = f " { robot_key_str } -logs " )
# ФУНКЦИЯ ОСТАНОВКИ ПРОЦЕССА
@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 )
@app.get ( path = f " / { robot_key_str } /scripts.js " , tags = [ f " { robot_key_str } " ] )
def get_file2 ( ) :
return FileResponse ( os . path . abspath ( scriptPath ) )
# ИНИЦИАЛИЗАЦИЯ ПАНЕЛИ УПРАВЛЕНИЯ РОБОТОМ
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__ ] } )
# сторонние файлы
infoPath = os . path . join ( cp_path_str , " how_to.docx " )
@app.get ( path = f " / { robot_key_str } /how_to.docx " , tags = [ f " { robot_key_str } " ] )
def get_file ( ) :
return FileResponse ( os . path . abspath ( infoPath ) )
# проверка процесса
def process_is_started( ) :
return Orchestrator . ProcessIsStarted ( inProcessNameWOExeStr = robot_key_str )
# HOTFIX Orchestrator.AgentProcessWOExeUpperUserListGet
def HOTFIX_01 ( inHostNameStr , inUserStr , inGSettings = None ) :
""" L-,W+: Получить список процессов, которые выполняется на сессии Агента. В с е процессы фиксируются без постфикса .exe, а также в верхнем регистре.
# функции для запуска процессов
buildPathStr = CrossOS . PathJoinList ( CrossOS . PathSplitList ( __file__ ) [ : - 3 ] + [ " builds " ] )
startHandPathStr = os . path . join ( buildPathStr , " startHand.cmd " )
def startHand ( ) :
Orchestrator . AgentOSCMD ( inHostNameStr = agent_hostname_str , inUserStr = agent_username_str , inCMDStr = startHandPathStr , inRunAsyncBool = True , inSendOutputToOrchestratorLogsBool = False , inCaptureBool = False )
@app.get ( path = f " / { robot_key_str } /startHand " , tags = [ f " { robot_key_str } " ] )
def start_app ( ) :
startHand ( )
ПРИМЕР РЕЗУЛЬТАТА , КОТОРЫЙ МОЖНО ПОЛУЧИТЬ ПО ГУИД ЧЕРЕЗ ФУНКЦИЮ AgentActivityItemReturnGet : [ " ORCHESTRATOR " , " AGENT " , " CHROME " , " EXPLORER " , . . . ]
# инициализация панели
lCPManager = Orchestrator . Managers . ControlPanel ( inControlPanelNameStr = robot_key_str ,
inRefreshHTMLJinja2TemplatePathStr = htmlPath , inJinja2TemplateRefreshBool = True )
contextDict = { " config " : sys . modules [ __name__ ] }
lCPManager . Jinja2DataUpdateDictSet ( inJinja2DataUpdateDict = contextDict )
: 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