#OrchestratorDraftCommit (BigRefactoring, ProcessingConsolidation)

Signed-off-by: Ivan Maslov <Ivan.Maslov@UnicodeLabs.ru>
dev-linux
Ivan Maslov 5 years ago
parent 22d089213f
commit d145cec21d

@ -48,6 +48,7 @@ def RenderRobotR01(inGlobalConfiguration):
#Process not running
lResultDict["FooterText"]=f'Дата изменения: {datetime.datetime.now().strftime("%H:%M:%S %d.%m.%Y")}'
return lResultDict
def CheckIfProcessRunning(processName):
'''
Check if there is any running process that contains the given name processName.
@ -76,78 +77,45 @@ mDict = {
]
},
"Scheduler":{
"ActivityTimeCheckLoopSeconds_":"Количество секунд, между циклами проверки действий",
"ActivityTimeCheckLoopSeconds":5,
"ActivityTimeCheckLoopSeconds":5, #Количество секунд, между циклами проверки действий
"ActivityTimeList":[
{
"description":"Запуск Python консоли",
"__processCode":"Код процесса в openRPA daemon. Данные код может использоваться в дальнейшем для того, чтобы завершить именно тот процесс, который пораждался этой программой",
"processCode":"PythonDebug",
"__activityType":"processStart/processStop",
"activityType":"processStart",
"__time":"__Время запуска активности",
"time":"22:57",
"__timeZone":"Часовой пояс, в рамках которого указано время. По-умолчанию часовой пояс МСК (GMT+4). Формат UTC offset in the form ±HHMM[SS[.ffffff]] ",
"timeZone":"+0400",
"__processPath":"Полный путь/наименование процесса. Запуск производится через subprocess. Идентификатор процесса в дальнейшем сохраняется и его можно будет закрыть с помощью параметра processCode",
"____processPath":"C:\\Abs\\Archive\\scopeSrcUL\\OpenRPA\\OpenRPA_32.cmd",
"processPath":"C:\\Abs\\Archive\\scopeSrcUL\\OpenRPA\\Orchestrator\\RobotDaemon\\runProcessOpenRPARobotDaemon_x32.cmd",
"__processArgs":"Аргументы, передаваемые при запуске процесса",
"processArgs":"",
"__weekdayNumList":"Список номеров дней недели, по которым выполнять инициализаци активности. Отсчет ведется от 0 до 6",
"weekdayNumList":[1,2,3]
},
{
"description":"Запуск Python консоли",
"__activityType":"processStart/processStop",
"activityType":"processStart",
"__time":"__Время запуска активности",
"time":"23:24",
"__timeZone":"Часовой пояс, в рамках которого указано время. По-умолчанию часовой пояс МСК (GMT+4). Формат UTC offset in the form ±HHMM[SS[.ffffff]] ",
"timeZone":"+0400",
"__processPath":"Полный путь/наименование процесса. Запуск производится через subprocess. Идентификатор процесса в дальнейшем сохраняется и его можно будет закрыть с помощью параметра processCode",
"processPath":"notepad",
"processArgs":""
"TimeHH:MM":"19:25", #Time [HH:MM] to trigger activity
"WeekdayList":[1,2,3], #List of the weekday index when activity is applicable, Default [1,2,3,4,5,6,7]
"Activity":{
"Type":"ProcessStart", #Activity type
"Path":"Notepad", #Executable file path
"ArgList": [] #List of the arguments
}
},
{
"description":"Остановка Python консоли",
"activityType":"processStop",
"time":"19:20",
"timeZone":"4",
"processName":"OpenRPARobotDaemon.exe",
"_flagCloseForce":"Признак, что процесс нужно принудительно закрыть (если флага нет, то на процесс просто посылается команда terminate)",
"flagCloseForce":True,
"_flagCloseOnlyCurrentUser":"Признак, что процесс нужно закрыть только у текущего пользователя",
"flagCloseOnlyCurrentUser":True
"TimeHH:MM":"19:20", #Time [HH:MM] to trigger activity
"WeekdayList":[1,2,3], #List of the weekday index when activity is applicable, Default [1,2,3,4,5,6,7]
"Activity":{
"Type":"ProcessStop", #Activity type
"Name":"OpenRPARobotDaemon.exe", #Process name
"FlagForce":True, #Force process close
"User": "%username%" #Empty, user or %username%
}
},
{
"activityType":"loopActivity",
"loopSeconds":6,
"loopTimeStart":"21:45",
"loopTimeEnd":"21:46",
"pythonPackageName":"CheckActivity",
"pythonFunctionName":"test_activity",
"pythonFunctionArgList":["TestArg1","TestArg2"],
"processPath":"notepad",
"processArgs":""
"TimeHH:MMStart":"19:20", #Time [HH:MM] to trigger activity
"TimeHH:MMStop":"19:20",
"ActivityIntervalSeconds":5,
"WeekdayList":[1,2,3], #List of the weekday index when activity is applicable, Default [1,2,3,4,5,6,7]
"Activity":{
"Type": "PythonStart", #Activity type
"ModuleName": "CheckActivity", #Python function module name
"FunctionName": "test_activity", #Python function name
"ArgList": ["TestArg1","TestArg2"] #Input python function args
}
}
]
],
"LogList":[]
},
"Processor":{
"LogList_":"Fill list when orchestrator is running",
"TransactionList_":"List of processor activity, whick was executed",
"TransactionList__":[
{
"DateTimeStart":"2009-09-01T00:00:00.000Z",
"DateTimeEnd":"2009-09-01T00:00:00.000Z",
"ActivityList":[]
}
],
"TransactionList":[],
"TransactionTrace_<ActivityTypeName>":"<bool> if Trace for command is selected for False, the tracing will be off for such activity type",
"TransactionTrace_ActivityCMDRun":True,
"LogType_CMDStart":True, #LogType_<Type>: <bool> if Trace for command is selected for False, the tracing will be off for such activity type. Default True
"LogList":[] #List of processor activity, which was executed. Fill list when orchestrator is running
},
"ControlPanelDict":{
"RefreshSeconds": 5,

@ -72,11 +72,15 @@
//////////////////////////
mGlobal.Controller={};
mGlobal.Controller.CMDRunText=function(inCMDText) {
///Подготовить конфигурацию
lData = [
{"Type":"CMDStart", "Command": inCMDText}
]
///Обнулить таблицу
$.ajax({
type: "POST",
url: 'ProcessingRun',
data: '{"actionList":[{"type":"ActivityCMDRun", "code":"'+inCMDText+'"}]}',
url: 'Utils/Processor',
data: JSON.stringify(lData),
success:
function(lData,l2,l3){},
dataType: "text"
@ -85,10 +89,14 @@
mGlobal.Controller.CMDRun=function() {
///Обнулить таблицу
lCMDCode=$(".openrpa-controller-cmd-run-input")[0].value
///Подготовить конфигурацию
lData = [
{"Type":"CMDStart", "Command": lCMDCode }
]
$.ajax({
type: "POST",
url: 'ProcessingRun',
data: '{"actionList":[{"type":"ActivityCMDRun", "code":"'+lCMDCode+'"}]}',
url: 'Utils/Processor',
data: JSON.stringify(lData),
success:
function(lData,l2,l3)
{
@ -102,19 +110,23 @@
mGlobal.Controller.CMDRunGUILogout=function() {
///Обнулить таблицу
lCMDCode="for /f \"skip=1 tokens=2\" %s in ('query user %USERNAME%') do (tscon \\dest:console)"
lCMDCode = lCMDCode.replace(/\\n/g, "\\n")
.replace(/\\'/g, "\\'")
.replace(/\\"/g, '\\"')
.replace(/\\&/g, "\\&")
.replace(/\\r/g, "\\r")
.replace(/\\t/g, "\\t")
.replace(/\\b/g, "\\b")
.replace(/\\f/g, "\\f")
.replace('"', "\\\"");
//lCMDCode = lCMDCode.replace(/\\n/g, "\\n")
// .replace(/\\'/g, "\\'")
// .replace(/\\"/g, '\\"')
// .replace(/\\&/g, "\\&")
// .replace(/\\r/g, "\\r")
// .replace(/\\t/g, "\\t")
// .replace(/\\b/g, "\\b")
// .replace(/\\f/g, "\\f")
// .replace('"', "\\\"");
///Подготовить конфигурацию
lData = [
{"Type":"CMDStart", "Command": lCMDCode }
]
$.ajax({
type: "POST",
url: 'ProcessingRun',
data: '{"actionList":[{"type":"ActivityCMDRun", "code":"'+lCMDCode+'"}]}',
url: 'Utils/Processor',
data: JSON.stringify(lData),
success:
function(lData,l2,l3)
{
@ -129,10 +141,14 @@
///Перезагрузить Orchestrator
mGlobal.Controller.OrchestratorRestart=function() {
///Подготовить конфигурацию
lData = [
{"Type":"OrchestratorRestart"}
]
$.ajax({
type: "POST",
url: 'ProcessingRun',
data: '{"actionList":[{"type":"ActivityRestartOrchestrator"}]}',
url: 'Utils/Processor',
data: JSON.stringify(lData),
success:
function(lData,l2,l3)
{
@ -233,11 +249,21 @@
mGlobal.Test=function() {
///Обнулить таблицу
lData = [
{
"Type":"GlobalDictKeyListValueSet",
"key_list":["Storage","Robot_R01"],
"value":{
"RunDateTimeString":"Test1",
"StepCurrentName":"Test2",
"StepCurrentDuration":"Test3"
}
}
]
$.ajax({
type: "POST",
url: 'ProcessingRun',
data: '{"actionList":[{"type":"AdministrationGlobalDictSetKeyListValue","key_list":["Storage","Robot_R01"],"value":{"RunDateTimeString":"Test1","StepCurrentName":"Test2","StepCurrentDuration":"Test3"}}]}',
url: 'Utils/Processor',
data: JSON.stringify(lData),
success:
function(lData,l2,l3)
{
@ -253,10 +279,16 @@
mGlobal.Scheduler = {}
mGlobal.Scheduler.ActivityTimeListShow = function() {
lData = [
{
"Type":"GlobalDictKeyListValueGet",
"KeyList":["Scheduler","ActivityTimeList"]
}
]
$.ajax({
type: "POST",
url: 'ProcessingRun',
data: '{"actionList":[{"type":"PlanLogListGet"}]}',
url: 'Utils/Processor',
data: JSON.stringify(lData),
success:
function(lData,l2,l3)
{
@ -278,12 +310,18 @@
mGlobal.Processor = {}
mGlobal.Processor.LogListShow = function() {
lData = [
{
"Type":"GlobalDictKeyListValueGet",
"KeyList":["Processor","LogList"]
}
]
///Обнулить таблицу
$('.ui.modal.basic .content').html("");
$.ajax({
type: "POST",
url: 'ProcessingRun',
data: '{"actionList":[{"type":"ActivityLogScheduleListGet"}]}',
url: 'Utils/Processor',
data: JSON.stringify(lData),
success:
function(lData,l2,l3)
{

@ -8,6 +8,7 @@ import signal
import pdb
import orchestratorServer
import orchestratorTimer
import orchestratorProcessor
import logging
from Settings import Settings
@ -24,6 +25,10 @@ lGlobalDict={}
lDaemonConfigurationObject=Settings.mDict
#Единый глобальный словарь (За основу взять из Settings.py)
global mGlobalDict
mGlobalDict = Settings.Dict
#Инициализация настроечных параметров
lDaemonLoopSeconds=lDaemonConfigurationObject["Scheduler"]["ActivityTimeCheckLoopSeconds"]
lDaemonActivityLogDict={} #Словарь отработанных активностей, ключ - кортеж (<activityType>, <datetime>, <processPath || processName>, <processArgs>)
@ -44,82 +49,53 @@ while True:
lCurrentDateTime=datetime.datetime.now()
#Циклический обход правил
lFlagSearchActivityType=True
for lItem in lDaemonConfigurationObject["Scheduler"]["ActivityTimeList"]:
for lIndex, lItem in enumerate(lDaemonConfigurationObject["Scheduler"]["ActivityTimeList"]):
#Проверка дней недели, в рамках которых можно запускать активность
lItemWeekdayList=lItem.get("weekdayNumList",[0,1,2,3,4,5,6])
lItemWeekdayList=lItem.get("WeekdayList",[0,1,2,3,4,5,6])
if lCurrentDateTime.weekday() in lItemWeekdayList:
if lFlagSearchActivityType:
#Определить вид активности
if lItem["activityType"]=="processStart":
#Лог
lItemCopy = copy.deepcopy(lItem)
lItemCopy["DateTimeUTCStringStart"]=datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%dT%H:%M:%S.%f")
mGlobalDict["Scheduler"]["LogList"].append(lItemCopy)
#######################################################################
#Branch 1 - if has TimeHH:MM
#######################################################################
if "TimeHH:MM" in lItem:
#Вид активности - запуск процесса
#Сформировать временной штамп, относительно которого надо будет проверять время
#часовой пояс пока не учитываем
lActivityDateTime=datetime.datetime.strptime(lItem["time"],"%H:%M")
lActivityDateTime=datetime.datetime.strptime(lItem["TimeHH:MM"],"%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):
(lIndex,lActivityDateTime) 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)})
lDaemonActivityLogDict[(lIndex,lActivityDateTime)]={"ActivityStartDateTime":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":
orchestratorProcessor.ActivityListOrDict(lItem["Activity"])
#######################################################################
#Banch 2 - if TimeHH:MMStart, TimeHH:MMStop, ActivityIntervalSeconds
#######################################################################
if "TimeHH:MMStart" in lItem and "TimeHH:MMStop" in lItem and "ActivityIntervalSeconds" in lItem:
#Сформировать временной штамп, относительно которого надо будет проверять время
#часовой пояс пока не учитываем
lActivityDateTime=datetime.datetime.strptime(lItem["loopTimeStart"],"%H:%M")
lActivityDateTime=datetime.datetime.strptime(lItem["TimeHH:MMStart"],"%H:%M")
lActivityDateTime=lActivityDateTime.replace(year=lCurrentDateTime.year,month=lCurrentDateTime.month,day=lCurrentDateTime.day)
lActivityTimeEndDateTime=datetime.datetime.strptime(lItem["loopTimeEnd"],"%H:%M")
lActivityTimeEndDateTime=datetime.datetime.strptime(lItem["TimeHH:MMStop"],"%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 ")
(lIndex,lActivityDateTime) not in lDaemonActivityLogDict):
#Запись в массив отработанных активностей
lDaemonActivityLogDict[(lItem["activityType"],lActivityDateTime,lItem["processPath"])]={"ActivityStartDateTime":lCurrentDateTime}
#Лог
lGlobalDict["ActivityLogScheduleList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processPath"], "activityStartDateTime":str(lCurrentDateTime)})
lDaemonActivityLogDict[(lIndex,lActivityDateTime)]={"ActivityStartDateTime":lCurrentDateTime}
#Запуск циклической процедуры
orchestratorTimer.activityLoopStart(lItem["loopSeconds"],lItem["processPath"],lItem["processArgs"],lActivityTimeEndDateTime,lItem["pythonPackageName"],lItem["pythonFunctionName"],lItem["pythonFunctionArgList"])
orchestratorTimer.activityLoopStart(lItem["ActivityIntervalSeconds"],lActivityTimeEndDateTime, lItem["Activity"])
#Уснуть до следующего прогона
time.sleep(lDaemonLoopSeconds)

@ -6,143 +6,184 @@ import os
import sys
import subprocess
import copy
import win32ts
#Глобальная переменная - все глобальные значения программы
global mGlobalDict
#Включить WTS (WIN32TS)
mWTSServer = lWTSServer = win32ts.WTSOpenServer("localhost")
#{
# actionList:
import importlib
#Input arg
# [
# {
# type: <RemoteMachineProcessingRun>,
# "Type": <RemoteMachineProcessingRun>,
# host: <localhost>,
# port: <port>,
# bodyObject: <object dict, int, str, list>
# },
# {
# type: <ActivityLogScheduleListGet>
# "Type": "CMDStart",
# "Command": ""
# },
# {
# type: <ActivityCMDRun>,
# code: <str>
# "Type": "OrchestratorRestart"
# },
# {
# type: <ActivityRestartOrchestrator>
# "Type": "GlobalDictKeyListValueSet",
# "KeyList": ["key1","key2",...],
# "Value": <List, Dict, String, int>
# },
# {
# type: <ActivitySessionCheckSetActive>
# "Type": "GlobalDictKeyListValueGet",
# "KeyList": ["key1","key2",...]
# },
# {
# type: <AdministrationGlobalDictSetKeyListValue>
# key_list: ["key1","key2",...]
# value: <List, Dict, String, int>
# "Type":"ProcessStart",
# "Path":"",
# "ArgList":[]
#
# },
# {
# type: <AdministrationGlobalDictGetKeyListValue>
# key_list: ["key1","key2",...]
# "Type":"ProcessStop",
# "Name":"",
# "FlagForce":True,
# "User":"" #Empty, user or %username%
# },
# {
# "Type":"PythonStart",
# "ModuleName":"",
# "FunctionName":"",
# "ArgList":[],
# "ArgDict":{}
# }
# ]
#
#}
def ProcessingRun(inConfigurationDict):
#print(mGlobalDict)
lDateTimeString=datetime.datetime.strftime(datetime.datetime.now(),"%Y.%m.%d %H:%M:%S::%f")
lResult={"dateTime":lDateTimeString, "state":"connected", "actionListResult":[]}
lTransactionItem={}
#Transaction start
lTransactionItem["DateTimeStart"] = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")
lTransactionItem["ActivityList"]=[]
for lItem in inConfigurationDict["actionList"]:
#Добавить входные значения
lResult["actionListResult"].append({"inArgs":lItem})
#Обработка запроса на отправку команды на удаленную машину
if lItem["type"]=="RemoteMachineProcessingRun":
lHTTPConnection = http.client.HTTPConnection(lItem["host"], lItem["port"], timeout=5)
try:
lHTTPConnection.request("POST","/ProcessingRun",json.dumps(lItem["bodyObject"]))
except Exception as e:
#Объединение словарей
lResult["actionListResult"][-1] = {**lResult["actionListResult"][-1], **{"state":"disconnected","errorMessage":str(e)}}
#lResult["actionListResult"][-1].join({"state":"disconnected","errorMessage":str(e)})
##################################
#Output result
# <input arg> with attributes:
# "DateTimeUTCStringStart"
# "DateTimeUTCStringStop"
# "Result"
def Activity(inActivity):
#Глобальная переменная - глобальный словарь унаследованный от Settings.py
global mGlobalDict
#Fill DateTimeUTCStringStart
inActivity["DateTimeUTCStringStart"] = datetime.datetime.strftime(datetime.datetime.now(),"%Y-%m-%dT%H:%M:%S.%f")
#Alias (compatibility)
lItem = inActivity
###########################################################
#Обработка запроса на отправку команды на удаленную машину
###########################################################
if lItem["Type"]=="RemoteMachineProcessingRun":
lHTTPConnection = http.client.HTTPConnection(lItem["host"], lItem["port"], timeout=5)
try:
lHTTPConnection.request("POST","/ProcessingRun",json.dumps(lItem["bodyObject"]))
except Exception as e:
#Объединение словарей
lItem["Result"] = {"State":"disconnected","ExceptionString":str(e)}
else:
lHTTPResponse=lHTTPConnection.getresponse()
lHTTPResponseByteArray=lHTTPResponse.read()
lItem["Result"] = json.loads(lHTTPResponseByteArray.decode('utf8'))
###########################################################
#Обработка команды CMDStart
###########################################################
if lItem["Type"]=="CMDStart":
lCMDCode="cmd /c "+lItem["code"]
subprocess.Popen(lCMDCode)
lResultCMDRun=1#os.system(lCMDCode)
lItem["Result"] = str(lResultCMDRun)
###########################################################
#Обработка команды OrchestratorRestart
###########################################################
if lItem["Type"]=="OrchestratorRestart":
os.execl(sys.executable,os.path.abspath(__file__),*sys.argv)
lItem["Result"] = True
sys.exit(0)
###########################################################
#Обработка команды GlobalDictKeyListValueSet
###########################################################
if lItem["Type"]=="GlobalDictKeyListValueSet":
for lItem2 in lItem["KeyList"][:-1]:
#Check if key - value exists
if lItem2 in mGlobalDict:
pass
else:
lHTTPResponse=lHTTPConnection.getresponse()
lHTTPResponseByteArray=lHTTPResponse.read()
lResult["actionListResult"][-1] = {**lResult["actionListResult"][-1], **json.loads(lHTTPResponseByteArray.decode('utf8'))}
#Обработка команды ActivityLogScheduleListGet
if lItem["type"]=="ActivityLogScheduleListGet":
#pdb.set_trace()
lResult["actionListResult"][-1] = {**lResult["actionListResult"][-1], **{"result":mGlobalDict["ActivityLogScheduleList"]}}
#Обработка команды PlanLogListGet
if lItem["type"]=="PlanLogListGet":
#pdb.set_trace()
lResult["actionListResult"][-1] = {**lResult["actionListResult"][-1], **{"result":mGlobalDict["JSONConfigurationDict"]["Scheduler"]["ActivityTimeList"]}}
#Обработка команды ActivityCMDRun
if lItem["type"]=="ActivityCMDRun":
lCMDCode="cmd /c "+lItem["code"]
subprocess.Popen(lCMDCode)
lResultCMDRun=1#os.system(lCMDCode)
lResult["actionListResult"][-1] = {**lResult["actionListResult"][-1], **{"result":str(lResultCMDRun)}}
#Обработка команды ActivityRestartOrchestrator
if lItem["type"]=="ActivityRestartOrchestrator":
os.execl(sys.executable,os.path.abspath(__file__),*sys.argv)
sys.exit(0)
#Обработка команды ActivitySessionCheckSetActive
if lItem["type"]=="ActivitySessionCheckSetActive":
lResult["actionListResult"][-1] = {**lResult["actionListResult"][-1], **{"result":{"IsActivated":False}}}
lPID = os.getpid()
#pdb.set_trace()
lSessionId = win32ts.ProcessIdToSessionId(lPID)
lSessionList = win32ts.WTSEnumerateSessions(lWTSServer)
#При попытке закрыть сервер возникает ошибка
#win32ts.WTSCloseServer(lWTSServer)
#Наложить фильтр
lSessionFiltered = [d for d in lSessionList if d["SessionId"]==lSessionId]
#Выполнить переход в активное состояние , если State != 0
if lSessionFiltered[0]["State"] != 0:
lCMDCodeTSCON = "tscon " + str(lSeessionId) + " /dest:console"
lCMDCode="cmd /c "+lCMDCodeTSCON
subprocess.Popen(lCMDCode)
lResult["actionListResult"][-1] = {**lResult["actionListResult"][-1], **{"result":{"IsActivated":True}}}
#Выключить соединение
#Обработка команды AdministrationGlobalDictSetKeyListValue
if lItem["type"]=="AdministrationGlobalDictSetKeyListValue":
lGlobalDict=mGlobalDict["JSONConfigurationDict"]
for lItem2 in lItem["key_list"][:-1]:
#Check if key - value exists
if lItem2 in lGlobalDict:
pass
else:
lGlobalDict[lItem2]={}
lGlobalDict=lGlobalDict[lItem2]
#Set value
#pdb.set_trace()
lGlobalDict[lItem["key_list"][-1]]=lItem["value"]
#Обработка команды AdministrationGlobalDictGetKeyListValue
if lItem["type"]=="AdministrationGlobalDictGetKeyListValue":
lGlobalDict=mGlobalDict["JSONConfigurationDict"]
for lItem2 in lItem["key_list"][:-1]:
#Check if key - value exists
if lItem2 in lGlobalDict:
pass
else:
lGlobalDict[lItem2]={}
lGlobalDict=lGlobalDict[lItem2]
#Set value
#pdb.set_trace()
lResult["actionListResult"][-1]["key_list"]=lItem["key_list"]
lResult["actionListResult"][-1]["value"]=lGlobalDict.get(lItem["key_list"][-1],None)
##################
#Trace activity
##################
if mGlobalDict["Processor"].get(f"TransactionTrace_{lItem['type']}",True):
#Add activity in TransactionList if it is applicable
lTransactionItem["ActivityList"].append(copy.deepcopy(lItem))
#Transaction end
lTransactionItem["DateTimeEnd"] = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")
#Перенос результатов в TransactionList
mGlobalDict["Processor"]["TransactionList"].append(lTransactionItem)
mGlobalDict[lItem2]={}
mGlobalDict=mGlobalDict[lItem2]
#Set value
mGlobalDict[lItem["KeyList"][-1]]=lItem["value"]
###########################################################
#Обработка команды GlobalDictKeyListValueGet
###########################################################
if lItem["type"]=="GlobalDictKeyListValueGet":
for lItem2 in lItem["KeyList"][:-1]:
#Check if key - value exists
if lItem2 in mGlobalDict:
pass
else:
mGlobalDict[lItem2]={}
mGlobalDict=mGlobalDict[lItem2]
#Return value
lItem["Result"]==mGlobalDict.get(lItem["KeyList"][-1],None)
#Определить вид активности
lActivityDateTime=inActivity["DateTimeUTCStringStart"]
#####################################
#ProcessStart
#####################################
if lItem["Type"]=="ProcessStart":
#Вид активности - запуск процесса
#Запись в массив отработанных активностей
lDaemonActivityLogDict[(lItem["activityType"],lActivityDateTime,lItem["processPath"])]={"ActivityStartDateTime":lCurrentDateTime}
#Лог
mGlobalDict["Processor"]["LogList"].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)
#################################
#ProcessStop
#################################
if lItem["Type"]=="ProcessStop":
#Вид активности - остановка процесса
#часовой пояс пока не учитываем
#Запись в массив отработанных активностей
lDaemonActivityLogDict[(lItem["Type"],lActivityDateTime,lItem["Name"])]={"ActivityStartDateTime":lCurrentDateTime}
#Сформировать команду на завершение
lActivityCloseCommand='taskkill /im '+lItem["processName"]
#TODO Сделать безопасную обработку,если параметра нет в конфигурации
if lItem.get('FlagForce',False):
lActivityCloseCommand+=" /F"
#Завершить процессы только текущего пользоваиеля
if lItem.get('User',"")!="":
lActivityCloseCommand+=f' /fi "username eq {lItem["User"]}"'
#Лог
mGlobalDict["Processor"]["LogList"].append({"activityType":lItem["activityType"], "activityDateTime":str(lActivityDateTime), "processPath":lItem["processName"], "activityStartDateTime":str(lCurrentDateTime)})
#Завершить процесс
os.system(lActivityCloseCommand)
#################################
#PythonStart
#################################
if lItem["Type"]=="PythonStart":
try:
#Подключить модуль для вызова
lModule=importlib.import_module(lItem["ModuleName"])
#Найти функцию
lFunction=getattr(lModule,lItem["FunctionName"])
lItem["Result"]=lFunction(*lItem.get("ArgList",[]),**lItem.get("ArgDict",{}))
except Exception as e:
logging.exception("Loop activity error: module/function not founded")
#Set datetime stop
lItem["DateTimeUTCStringStop"] = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")
##################
#Trace activity
##################
if mGlobalDict["Processor"].get(f"LogType_{lItem['Type']}",True):
#Add activity in TransactionList if it is applicable
mGlobalDict["Processor"]["LogList"].append(copy.deepcopy(lItem))
#Вернуть результат
return lResult
return lItem
def ActivityListOrDict(inActivityListOrDict):
#Check arg type (list or dict)
if type(inActivityListOrDict)==list:
#List activity
for lItem in inActivityListOrDict:
lResult.append(Activity(lItem))
return lResult
if type(inActivityListOrDict)==dict:
#Dict activity
return Activity(inActivityListOrDict)

@ -162,7 +162,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# POST
def do_POST(self):
#Централизованная функция получения запросов/отправки
if self.path == '/ProcessingRun':
if self.path == '/Utils/Processor':
#ReadRequest
lInputObject={}
if self.headers.get('Content-Length') is not None:
@ -176,7 +176,7 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
self.send_header('Content-type','application/json')
self.end_headers()
# Send message back to client
message = json.dumps(orchestratorProcessor.ProcessingRun(lInputObject))
message = json.dumps(orchestratorProcessor.ActivityListOrDict(lInputObject))
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
return

@ -3,6 +3,7 @@ import datetime
import subprocess
import importlib
import logging
import orchestratorProcessor
class RepeatedTimer(object):
def __init__(self, interval, function, *args, **kwargs):
self._timer = None
@ -31,31 +32,11 @@ class RepeatedTimer(object):
############################################################
####Техническая функция обработки таймера - потока
############################################################
def activityLoopExecution(inProcessPath,inProcessArgList,inLoopTimeEndDateTime,inPythonPackageName,inPythonFunctionName,inPythonFunctionArgList=[]):
def activityLoopExecution(inLoopTimeEndDateTime, inActivity):
lResultGoLoop=True
lCurrentDateTime=datetime.datetime.now()
print (datetime.datetime.now().isoformat()+":: Loop activity check")
logging.info("Loop activity check")
#Запустить процесс, если установлен inProcessPath
if inProcessPath is not None:
if inProcessPath != "":
lItemArgs=[inProcessPath]
lItemArgs.extend(inProcessArgList)
subprocess.Popen(lItemArgs,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#Импорт Python пакета и запуск функции из него
if inPythonPackageName is not None:
if inPythonPackageName != "":
try:
#Подключить модуль для вызова
lModule=importlib.import_module(inPythonPackageName)
#Найти функцию
lFunction=getattr(lModule,inPythonFunctionName)
lFunction(*inPythonFunctionArgList)
except Exception as e:
print (datetime.datetime.now().isoformat()+":: Loop activity error: module/function not founded")
logging.info("Loop activity error: module/function not founded")
#Запустить актитвость через процессор (orchestratorProcessor)
orchestratorProcessor.ActivityListOrDict(inActivity)
#Выключить таймер, если время наступило
if lCurrentDateTime>=inLoopTimeEndDateTime:
lResultGoLoop=False
@ -64,6 +45,6 @@ def activityLoopExecution(inProcessPath,inProcessArgList,inLoopTimeEndDateTime,i
############################################################
####Функция запуска таймера - потока
############################################################
def activityLoopStart(inActivityLoopSeconds,inProcessPath,inProcessArgList,inLoopTimeEndDateTime,inPythonPackageName,inPythonFunctionName,inPythonFunctionArgList=[]):
lTimer = RepeatedTimer(inActivityLoopSeconds, activityLoopExecution, inProcessPath,inProcessArgList,inLoopTimeEndDateTime,inPythonPackageName,inPythonFunctionName,inPythonFunctionArgList) # it auto-starts, no need of rt.start()
def activityLoopStart(inActivityLoopSeconds, inLoopTimeEndDateTime, inActivity):
lTimer = RepeatedTimer(inActivityLoopSeconds, activityLoopExecution, inLoopTimeEndDateTime, inActivity) # it auto-starts, no need of rt.start()
lTimer.start()

@ -0,0 +1,5 @@
for /f "skip=1 tokens=3" %%s in ('query user %USERNAME%') do (
%windir%\System32\tscon.exe %%s /dest:console
)
timeout 10
QRes.exe /x 1680 /y 1050
Loading…
Cancel
Save