import subprocess import json import datetime import time import codecs import os import signal import pdb import orchestratorServer import orchestratorTimer import logging #Создать файл логирования # 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": #"ActivityLog":[{""}] #"ActivityLogSchedule" #Чтение конфигурации lDaemonConfigurationFile = codecs.open("orchestratorConfiguration.json", "r","utf_8_sig") lDaemonConfigurationJSONString = lDaemonConfigurationFile.read() #Закрыть файловый объект lDaemonConfigurationFile.close() #Преобразование в JSON lDaemonConfigurationObject=json.loads(lDaemonConfigurationJSONString) #Инициализация настроечных параметров lDaemonLoopSeconds=lDaemonConfigurationObject["loopSeconds"] lDaemonActivityLogDict={} #Словарь отработанных активностей, ключ - кортеж (, , , ) lDaemonStartDateTime=datetime.datetime.now() #Инициализация globalDict lGlobalDict["JSONConfigurationDict"]=lDaemonConfigurationObject lGlobalDict["ActivityLogSchedule"]=lDaemonActivityLogDict lGlobalDict["ActivityLogScheduleList"]=[] orchestratorServer.mActivityLogDict = lDaemonActivityLogDict #Инициализация сервера lThreadServer = orchestratorServer.RobotDaemonServer("ServerThread",lGlobalDict) lThreadServer.start() #Вечный цикл while True: lCurrentDateTime=datetime.datetime.now() #Циклический обход правил lFlagSearchActivityType=True for lItem in lDaemonConfigurationObject["activityList"]: #Проверка дней недели, в рамках которых можно запускать активность 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=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)