You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ORPA-pyOpenRPA/Orchestrator/orchestratorMain.py

126 lines
8.8 KiB

import subprocess
import json
import datetime
import time
import codecs
import os
import signal
import pdb
import orchestratorServer
import orchestratorTimer
import logging
from Settings import Settings
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
os.makedirs("Reports")
logging.basicConfig(filename="Reports\ReportRun_"+datetime.datetime.now().strftime("%Y_%m_%d__%H_%M_%S")+".log", level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
lGlobalDict={}
#"JSONConfigurationDict":<JSON>
#"ActivityLog":[{""}]
#"ActivityLogSchedule"
lDaemonConfigurationObject=Settings.mDict
#Инициализация настроечных параметров
lDaemonLoopSeconds=lDaemonConfigurationObject["Scheduler"]["ActivityTimeCheckLoopSeconds"]
lDaemonActivityLogDict={} #Словарь отработанных активностей, ключ - кортеж (<activityType>, <datetime>, <processPath || processName>, <processArgs>)
lDaemonStartDateTime=datetime.datetime.now()
#Инициализация globalDict
lGlobalDict["JSONConfigurationDict"]=lDaemonConfigurationObject
lGlobalDict["ActivityLogSchedule"]=lDaemonActivityLogDict
6 years ago
lGlobalDict["ActivityLogScheduleList"]=[]
orchestratorServer.mActivityLogDict = lDaemonActivityLogDict
#Инициализация сервера
lThreadServer = orchestratorServer.RobotDaemonServer("ServerThread",lGlobalDict)
lThreadServer.start()
#Вечный цикл
while True:
lCurrentDateTime=datetime.datetime.now()
#Циклический обход правил
lFlagSearchActivityType=True
for lItem in lDaemonConfigurationObject["Scheduler"]["ActivityTimeList"]:
#Проверка дней недели, в рамках которых можно запускать активность
lItemWeekdayList=lItem.get("weekdayNumList",[0,1,2,3,4,5,6])
if lCurrentDateTime.weekday() in lItemWeekdayList:
if lFlagSearchActivityType:
#Определить вид активности
if lItem["activityType"]=="processStart":
#Вид активности - запуск процесса
#Сформировать временной штамп, относительно которого надо будет проверять время
#часовой пояс пока не учитываем
lActivityDateTime=datetime.datetime.strptime(lItem["time"],"%H:%M")
lActivityDateTime=lActivityDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day)
#Убедиться в том, что время наступило
if (
lActivityDateTime>=lDaemonStartDateTime and
lCurrentDateTime>=lActivityDateTime and
(lItem["activityType"],lActivityDateTime,lItem["processPath"]) not in lDaemonActivityLogDict):
#Выполнить операцию
print(datetime.datetime.now().isoformat()+":: ProcessStart:"+lItem["processPath"])
logging.info("ProcessStart:"+lItem["processPath"])
#Запись в массив отработанных активностей
lDaemonActivityLogDict[(lItem["activityType"],lActivityDateTime,lItem["processPath"])]={"ActivityStartDateTime":lCurrentDateTime}
#Лог
lGlobalDict["ActivityLogScheduleList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processPath"], "activityStartDateTime":str(lCurrentDateTime)})
#Запустить процесс
lItemArgs=[lItem["processPath"]]
lItemArgs.extend(lItem["processArgs"])
subprocess.Popen(lItemArgs,shell=True)
#Определить вид активности
if lItem["activityType"]=="processStop":
#Вид активности - остановка процесса
#Сформировать временной штамп, относительно которого надо будет проверять время
#часовой пояс пока не учитываем
lActivityDateTime=datetime.datetime.strptime(lItem["time"],"%H:%M")
lActivityDateTime=lActivityDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day)
#Убедиться в том, что время наступило
if (
lActivityDateTime>=lDaemonStartDateTime and
lCurrentDateTime>=lActivityDateTime and
(lItem["activityType"],lActivityDateTime,lItem["processName"]) not in lDaemonActivityLogDict):
#Запись в массив отработанных активностей
lDaemonActivityLogDict[(lItem["activityType"],lActivityDateTime,lItem["processName"])]={"ActivityStartDateTime":lCurrentDateTime}
#Сформировать команду на завершение
lActivityCloseCommand='taskkill /im '+lItem["processName"]
#TODO Сделать безопасную обработку,если параметра нет в конфигурации
if lItem.get('flagCloseForce',False):
lActivityCloseCommand+=" /F"
#Завершить процессы только текущего пользоваиеля
if lItem.get('flagCloseOnlyCurrentUser',False):
lActivityCloseCommand+=' /fi "username eq %username%"'
#Лог
lGlobalDict["ActivityLogScheduleList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processName"], "activityStartDateTime":str(lCurrentDateTime)})
#Завершить процесс
os.system(lActivityCloseCommand)
print(datetime.datetime.now().isoformat()+":: ProcessStop "+lItem["processName"])
logging.info("ProcessStop "+lItem["processName"])
#Вид активности - запуск отдельного потока с циклическим вызовом
if lItem["activityType"]=="loopActivity":
#Сформировать временной штамп, относительно которого надо будет проверять время
#часовой пояс пока не учитываем
lActivityDateTime=datetime.datetime.strptime(lItem["loopTimeStart"],"%H:%M")
lActivityDateTime=lActivityDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day)
lActivityTimeEndDateTime=datetime.datetime.strptime(lItem["loopTimeEnd"],"%H:%M")
lActivityTimeEndDateTime=lActivityTimeEndDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day)
#Убедиться в том, что время наступило
if (
lCurrentDateTime<lActivityTimeEndDateTime and
lCurrentDateTime>=lActivityDateTime and
(lItem["activityType"],lActivityDateTime,lItem["processPath"]) not in lDaemonActivityLogDict):
logging.info("ActivityLoop Start ")
#Запись в массив отработанных активностей
lDaemonActivityLogDict[(lItem["activityType"],lActivityDateTime,lItem["processPath"])]={"ActivityStartDateTime":lCurrentDateTime}
#Лог
lGlobalDict["ActivityLogScheduleList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processPath"], "activityStartDateTime":str(lCurrentDateTime)})
#Запуск циклической процедуры
orchestratorTimer.activityLoopStart(lItem["loopSeconds"],lItem["processPath"],lItem["processArgs"],lActivityTimeEndDateTime,lItem["pythonPackageName"],lItem["pythonFunctionName"],lItem["pythonFunctionArgList"])
#Уснуть до следующего прогона
time.sleep(lDaemonLoopSeconds)