# Test + Add web button + add model in front + Backward compatibility from v1.1.13 + try..except when load CP

dev-linux
Ivan Maslov 4 years ago
parent 5333209528
commit e2c1d3e575

@ -79,12 +79,12 @@ def Settings():
lOrchestratorFolder = "\\".join(pyOpenRPA.Orchestrator.__file__.split("\\")[:-1]) lOrchestratorFolder = "\\".join(pyOpenRPA.Orchestrator.__file__.split("\\")[:-1])
mDict = { mDict = {
"Autocleaner": { # Some gurbage is collecting in g settings. So you can configure autocleaner to periodically clear gSettings "Autocleaner": { # Some gurbage is collecting in g settings. So you can configure autocleaner to periodically clear gSettings
"IntervalSecFloat": 10, # Sec float to periodically clear gsettings "IntervalSecFloat": 600.0, # Sec float to periodically clear gsettings
}, },
"Client":{ # Settings about client web orchestrator "Client":{ # Settings about client web orchestrator
"Session":{ # Settings about web session. Session algorythms works only for special requests (URL in ServerSettings) "Session":{ # Settings about web session. Session algorythms works only for special requests (URL in ServerSettings)
"LifetimeSecFloat": 10.0, # Client Session lifetime in seconds. after this time server will forget about this client session "LifetimeSecFloat": 600.0, # Client Session lifetime in seconds. after this time server will forget about this client session
"LifetimeRequestSecFloat": 15.0, # 1 client request lifetime in server in seconds "LifetimeRequestSecFloat": 120.0, # 1 client request lifetime in server in seconds
"ControlPanelRefreshIntervalSecFloat": 1.5, # Interval to refresh control panels for session, "ControlPanelRefreshIntervalSecFloat": 1.5, # Interval to refresh control panels for session,
"TechnicalSessionGUIDCache": { # TEchnical cache. Fills when web browser is requesting "TechnicalSessionGUIDCache": { # TEchnical cache. Fills when web browser is requesting
#"SessionGUIDStr":{ # Session with some GUID str. On client session guid stored in cookie "SessionGUIDStr" #"SessionGUIDStr":{ # Session with some GUID str. On client session guid stored in cookie "SessionGUIDStr"
@ -103,6 +103,8 @@ def Settings():
} }
}, },
"Server": { "Server": {
"WorkingDirectoryPathStr": None , # Will be filled automatically
"RequestTimeoutSecFloat": 300, # Time to handle request in seconds
"ListenPort_": "Порт, по которому можно подключиться к демону", "ListenPort_": "Порт, по которому можно подключиться к демону",
"ListenPort": 80, "ListenPort": 80,
"ListenURLList": [ "ListenURLList": [
@ -363,12 +365,15 @@ def Settings():
lFileList = [f for f in os.listdir(lSettingsPath) if os.path.isfile(os.path.join(lSettingsPath, f)) and f.split(".")[-1] == "py" and os.path.join(lSettingsPath, f) != __file__] lFileList = [f for f in os.listdir(lSettingsPath) if os.path.isfile(os.path.join(lSettingsPath, f)) and f.split(".")[-1] == "py" and os.path.join(lSettingsPath, f) != __file__]
import importlib.util import importlib.util
for lModuleFilePathItem in lFileList + gControlPanelPyFilePathList: # UPD 2020 04 27 Add gControlPanelPyFilePathList to import py files from Robots for lModuleFilePathItem in lFileList + gControlPanelPyFilePathList: # UPD 2020 04 27 Add gControlPanelPyFilePathList to import py files from Robots
lModuleName = lModuleFilePathItem[0:-3] try: # Try to init - go next if error and log in logger
lFileFullPath = os.path.join(lSettingsPath, lModuleFilePathItem) lModuleName = lModuleFilePathItem[0:-3]
lTechSpecification = importlib.util.spec_from_file_location(lModuleName, lFileFullPath) lFileFullPath = os.path.join(lSettingsPath, lModuleFilePathItem)
lTechModuleFromSpec = importlib.util.module_from_spec(lTechSpecification) lTechSpecification = importlib.util.spec_from_file_location(lModuleName, lFileFullPath)
lTechSpecificationModuleLoader = lTechSpecification.loader.exec_module(lTechModuleFromSpec) lTechModuleFromSpec = importlib.util.module_from_spec(lTechSpecification)
if lSubmoduleFunctionName in dir(lTechModuleFromSpec): lTechSpecificationModuleLoader = lTechSpecification.loader.exec_module(lTechModuleFromSpec)
#Run SettingUpdate function in submodule if lSubmoduleFunctionName in dir(lTechModuleFromSpec):
getattr(lTechModuleFromSpec, lSubmoduleFunctionName)(mDict) #Run SettingUpdate function in submodule
getattr(lTechModuleFromSpec, lSubmoduleFunctionName)(mDict)
except Exception as e:
if mRobotLogger: mRobotLogger.exception(f"Error when init .py file in orchestrator '{lModuleFilePathItem}'. Exception is below:")
return mDict return mDict

@ -0,0 +1,41 @@
# Def to check inGSettings and update structure to the backward compatibility
# !!! ATTENTION: Backward compatibility has been started from v1.1.13 !!!
# So you can use config of the orchestrator 1.1.13 in new Orchestrator versions and all will be ok :) (hope it's true)
def Update(inGSettings):
lL = inGSettings["Logger"] # Alias for logger
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# v1.1.13 to v1.1.14
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
if "Autocleaner" not in inGSettings: # Add "Autocleaner" structure
inGSettings["Autocleaner"] = { # Some gurbage is collecting in g settings. So you can configure autocleaner to periodically clear gSettings
"IntervalSecFloat": 600.0, # Sec float to periodically clear gsettings
}
if lL: lL.warning(f"Backward compatibility (v1.1.13 to v1.1.14): Add default 'Autocleaner' structure") # Log about compatibility
if "Client" not in inGSettings: # Add "Client" structure
inGSettings["Client"] = { # Settings about client web orchestrator
"Session":{ # Settings about web session. Session algorythms works only for special requests (URL in ServerSettings)
"LifetimeSecFloat": 600.0, # Client Session lifetime in seconds. after this time server will forget about this client session
"LifetimeRequestSecFloat": 120.0, # 1 client request lifetime in server in seconds
"ControlPanelRefreshIntervalSecFloat": 1.5, # Interval to refresh control panels for session,
"TechnicalSessionGUIDCache": { # TEchnical cache. Fills when web browser is requesting
#"SessionGUIDStr":{ # Session with some GUID str. On client session guid stored in cookie "SessionGUIDStr"
# "InitDatetime": None, # Datetime when session GUID was created
# "DatasetLast": {
# "ControlPanel": {
# "Data": None, # Struct to check with new iterations. None if starts
# "ReturnBool": False # flag to return, close request and return data as json
# }
# },
# "ClientRequestHandler": None, # Last client request handler
# "UserADStr": None, # User, who connect. None if user is not exists
# "DomainADStr": None, # Domain of the user who connect. None if user is not exists
#}
}
}
}
if lL: lL.warning(
f"Backward compatibility (v1.1.13 to v1.1.14): Add default 'Client' structure") # Log about compatibility
if "RequestTimeoutSecFloat" not in inGSettings["Server"]: # Add Server > "RequestTimeoutSecFloat" property
inGSettings["Server"]["RequestTimeoutSecFloat"] = 300 # Time to handle request in seconds
if lL: lL.warning(
f"Backward compatibility (v1.1.13 to v1.1.14): Add default 'Server' > 'RequestTimeoutSecFloat' property") # Log about compatibility

@ -10,6 +10,7 @@ import pdb
from . import Server from . import Server
from . import Timer from . import Timer
from . import Processor from . import Processor
from . import BackwardCompatibility # Backward compatibility from v1.1.13
#from .Settings import Settings #from .Settings import Settings
import importlib import importlib
@ -79,6 +80,10 @@ if os.path.exists("_SessionLast_RDPList.json"):
lDaemonLoopSeconds=gSettingsDict["Scheduler"]["ActivityTimeCheckLoopSeconds"] lDaemonLoopSeconds=gSettingsDict["Scheduler"]["ActivityTimeCheckLoopSeconds"]
lDaemonActivityLogDict={} #Словарь отработанных активностей, ключ - кортеж (<activityType>, <datetime>, <processPath || processName>, <processArgs>) lDaemonActivityLogDict={} #Словарь отработанных активностей, ключ - кортеж (<activityType>, <datetime>, <processPath || processName>, <processArgs>)
lDaemonLastDateTime=datetime.datetime.now() lDaemonLastDateTime=datetime.datetime.now()
gSettingsDict["Server"]["WorkingDirectoryPathStr"] = os.getcwd() # Set working directory in g settings
# Turn on backward compatibility
BackwardCompatibility.Update(inGSettings= gSettingsDict)
#Инициализация сервера #Инициализация сервера
lThreadServer = Server.RobotDaemonServer("ServerThread", gSettingsDict) lThreadServer = Server.RobotDaemonServer("ServerThread", gSettingsDict)

@ -23,6 +23,9 @@ import psutil
# "Type": "OrchestratorRestart" # "Type": "OrchestratorRestart"
# }, # },
# { # {
# "Type": "OrchestratorSessionSave"
# },
# {
# "Type": "GlobalDictKeyListValueSet", # "Type": "GlobalDictKeyListValueSet",
# "KeyList": ["key1","key2",...], # "KeyList": ["key1","key2",...],
# "Value": <List, Dict, String, int> # "Value": <List, Dict, String, int>
@ -117,12 +120,23 @@ def Activity(inActivity):
lFile = open("_SessionLast_RDPList.json", "w", encoding="utf-8") lFile = open("_SessionLast_RDPList.json", "w", encoding="utf-8")
lFile.write(json.dumps(gSettingsDict["RobotRDPActive"]["RDPList"])) # dump json to file lFile.write(json.dumps(gSettingsDict["RobotRDPActive"]["RDPList"])) # dump json to file
lFile.close() # Close the file lFile.close() # Close the file
if lL: lL.info(f"Orchestrator has dump the RDP list before the restart. The RDP List is {gSettingsDict['RobotRDPActive']['RDPList']}") if lL: lL.info(f"Orchestrator has dump the RDP list before the restart. The RDP List is {gSettingsDict['RobotRDPActive']['RDPList']}. Do restart")
# Restart session # Restart session
os.execl(sys.executable, os.path.abspath(__file__), *sys.argv) os.execl(sys.executable, os.path.abspath(__file__), *sys.argv)
lItem["Result"] = True lItem["Result"] = True
sys.exit(0) sys.exit(0)
########################################################### ###########################################################
# Обработка команды OrchestratorSessionSave
###########################################################
if lItem["Type"] == "OrchestratorSessionSave":
# Dump RDP List in file json
lFile = open("_SessionLast_RDPList.json", "w", encoding="utf-8")
lFile.write(json.dumps(gSettingsDict["RobotRDPActive"]["RDPList"])) # dump json to file
lFile.close() # Close the file
if lL: lL.info(
f"Orchestrator has dump the RDP list before the restart. The RDP List is {gSettingsDict['RobotRDPActive']['RDPList']}")
lItem["Result"] = True
###########################################################
#Обработка команды GlobalDictKeyListValueSet #Обработка команды GlobalDictKeyListValueSet
########################################################### ###########################################################
if lItem["Type"]=="GlobalDictKeyListValueSet": if lItem["Type"]=="GlobalDictKeyListValueSet":

@ -467,7 +467,7 @@ class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
daemon_threads = True daemon_threads = True
"""Handle requests in a separate thread.""" """Handle requests in a separate thread."""
def finish_request(self, request, client_address): def finish_request(self, request, client_address):
request.settimeout(30) request.settimeout(gSettingsDict["Server"]["RequestTimeoutSecFloat"])
# "super" can not be used because BaseServer is not created from object # "super" can not be used because BaseServer is not created from object
HTTPServer.finish_request(self, request, client_address) HTTPServer.finish_request(self, request, client_address)
#inGlobalDict #inGlobalDict

@ -50,8 +50,8 @@ def Monitor_ControlPanelDictGet_SessionCheckInit(inRequest,inGlobalDict):
lItemValue["DatasetLast"]["ControlPanel"]["ReturnBool"] = True # Set flag to return the data lItemValue["DatasetLast"]["ControlPanel"]["ReturnBool"] = True # Set flag to return the data
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Technicaldef - Create new session struct # Technicaldef - Create new session struct
def TechnicalSessionNew(): def TechnicalSessionNew(inSessionGUIDStr):
lCookieSessionGUIDStr = str(uuid.uuid4()) # Generate the new GUID lCookieSessionGUIDStr = inSessionGUIDStr # Generate the new GUID
lSessionNew = { # Session with some GUID str. On client session guid stored in cookie "SessionGUIDStr" lSessionNew = { # Session with some GUID str. On client session guid stored in cookie "SessionGUIDStr"
"InitDatetime": datetime.datetime.now(), # Datetime when session GUID was created "InitDatetime": datetime.datetime.now(), # Datetime when session GUID was created
"DatasetLast": { "DatasetLast": {
@ -71,13 +71,15 @@ def Monitor_ControlPanelDictGet_SessionCheckInit(inRequest,inGlobalDict):
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
lCreateNewSessionBool = False # Flag to create new session structure lCreateNewSessionBool = False # Flag to create new session structure
# step 1 - get cookie SessionGUIDStr # step 1 - get cookie SessionGUIDStr
lCookies = cookies.SimpleCookie(inRequest.headers.get("Cookie", "")) lSessionGUIDStr = inRequest.headers.get("SessionGUIDStr", None)
if "SessionGUIDStr" in lCookies: if lSessionGUIDStr is not None: # Check if GUID session is ok
lCookieSessionGUIDStr = lCookies.get("SessionGUIDStr", None).value # Get the cookie lCookieSessionGUIDStr = lSessionGUIDStr # Get the existing GUID
if lCookieSessionGUIDStr not in inGlobalDict["Client"]["Session"]["TechnicalSessionGUIDCache"]: if lSessionGUIDStr not in inGlobalDict["Client"]["Session"]["TechnicalSessionGUIDCache"]:
lCookieSessionGUIDStr= TechnicalSessionNew() # Create new session lCookieSessionGUIDStr= TechnicalSessionNew(inSessionGUIDStr = lSessionGUIDStr) # Create new session
else: # Update the datetime of the request session
inGlobalDict["Client"]["Session"]["TechnicalSessionGUIDCache"][lCookieSessionGUIDStr]["InitDatetime"]=datetime.datetime.now()
else: else:
lCookieSessionGUIDStr = TechnicalSessionNew() # Create new session lCookieSessionGUIDStr = TechnicalSessionNew(inSessionGUIDStr = lSessionGUIDStr) # Create new session
# Init the RobotRDPActive in another thread # Init the RobotRDPActive in another thread
#lThreadCheckCPInterval = threading.Thread(target=TechnicalIntervalCheck) #lThreadCheckCPInterval = threading.Thread(target=TechnicalIntervalCheck)
#lThreadCheckCPInterval.daemon = True # Run the thread in daemon mode. #lThreadCheckCPInterval.daemon = True # Run the thread in daemon mode.
@ -103,7 +105,7 @@ def Monitor_ControlPanelDictGet_SessionCheckInit(inRequest,inGlobalDict):
lItemValue["DatasetLast"]["ControlPanel"]["ReturnBool"] = False # Set flag that data was returned lItemValue["DatasetLast"]["ControlPanel"]["ReturnBool"] = False # Set flag that data was returned
lDoWhileBool = False # Stop the iterations lDoWhileBool = False # Stop the iterations
else: else:
lCookieSessionGUIDStr = TechnicalSessionNew() # Create new session lCookieSessionGUIDStr = TechnicalSessionNew(inSessionGUIDStr = lCookieSessionGUIDStr) # Create new session
if lDoWhileBool: # Sleep if we wait hte next iteration if lDoWhileBool: # Sleep if we wait hte next iteration
time.sleep(lControlPanelRefreshIntervalSecFloat) # Sleep to the next iteration time.sleep(lControlPanelRefreshIntervalSecFloat) # Sleep to the next iteration

@ -1,5 +1,12 @@
var mGlobal={} var mGlobal={}
window.onload=function() {
//document.cookie = "SessionGUIDStr=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
//Render existing data
//mGlobal.Monitor.fControlPanelRefresh_TechnicalRender()
}
$(document).ready(function() { $(document).ready(function() {
document.cookie = "SessionGUIDStr=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
console.log("Cookie is deleted")
// fix main menu to page on passing // fix main menu to page on passing
$('.main.menu').visibility({ $('.main.menu').visibility({
type: 'fixed' type: 'fixed'
@ -55,7 +62,7 @@ $(document).ready(function() {
//For data storage key //For data storage key
mGlobal["DataStorage"] = {} mGlobal["DataStorage"] = {}
// Clear the session cookie // Clear the session cookie
document.cookie = "SessionGUIDStr=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
String.prototype.replaceAll = function(search, replace){ String.prototype.replaceAll = function(search, replace){
return this.split(search).join(replace); return this.split(search).join(replace);
} }
@ -93,6 +100,7 @@ $(document).ready(function() {
/////Controller JS module /////Controller JS module
////////////////////////// //////////////////////////
mGlobal.Controller={}; mGlobal.Controller={};
mGlobal.Controller.CMDRunText=function(inCMDText) { mGlobal.Controller.CMDRunText=function(inCMDText) {
///Подготовить конфигурацию ///Подготовить конфигурацию
lData = [ lData = [
@ -159,6 +167,28 @@ $(document).ready(function() {
dataType: "text" dataType: "text"
}); });
} }
///Restart PC
mGlobal.Controller.PCRestart = function () {
mGlobal.Controller.CMDRunText("shutdown -r")
}
///Orchestrator save session
mGlobal.Controller.OrchestratorSessionSave=function() {
///Подготовить конфигурацию
lData = [
{"Type":"OrchestratorSessionSave"}
]
$.ajax({
type: "POST",
url: 'Utils/Processor',
data: JSON.stringify(lData),
success:
function(lData,l2,l3)
{
var lResponseJSON=JSON.parse(lData)
},
dataType: "text"
});
}
///Перезагрузить Orchestrator ///Перезагрузить Orchestrator
mGlobal.Controller.OrchestratorRestart=function() { mGlobal.Controller.OrchestratorRestart=function() {
///Подготовить конфигурацию ///Подготовить конфигурацию
@ -177,6 +207,10 @@ $(document).ready(function() {
dataType: "text" dataType: "text"
}); });
} }
mGlobal.Controller.OrchestratorGITPullRestart = function() {
mGlobal.Controller.OrchestratorSessionSave() //Save current RDP list session
mGlobal.Controller.CMDRunText("timeout 3 & taskkill /f /im OpenRPA_Orchestrator.exe & timeout 2 & cd "+mGlobal.WorkingDirectoryPathStr+" & git reset --hard & git pull & pyOpenRPA.Orchestrator_x64_administrator_startup.cmd");
}
////////////////////////// //////////////////////////
/////Monitor JS module /////Monitor JS module
////////////////////////// //////////////////////////
@ -230,83 +264,102 @@ $(document).ready(function() {
ms += new Date().getTime(); ms += new Date().getTime();
while (new Date() < ms){} while (new Date() < ms){}
} }
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
mGlobal.SessionGUIDStr = uuidv4() // Generate uuid4 of the session
//console.log(uuidv4());
mGlobal.Monitor.fControlPanelRefresh_TechnicalRender = function()
{
lResponseJSON = mGlobal.Monitor.mDatasetLast
if (lResponseJSON!= null) {
///Escape onclick
/// RenderRobotList
lResponseJSON["RenderRobotList"].forEach(
function(lItem){
if ('FooterButtonX2List' in lItem) {
/// FooterButtonX2List
lItem["FooterButtonX2List"].forEach(
function(lItem2){
if ('OnClick' in lItem) {
lOnClickEscaped = lItem["OnClick"];
lOnClickEscaped = lOnClickEscaped.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
lItem["OnClick"] = lOnClickEscaped;
}
}
);
/// FooterButtonX1List
lItem["FooterButtonX1List"].forEach(
function(lItem2){
if ('OnClick' in lItem) {
lOnClickEscaped = lItem["OnClick"];
lOnClickEscaped = lOnClickEscaped.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
lItem["OnClick"] = lOnClickEscaped;
}
}
);
}
}
);
//////////////////////////////////////////////////////////
///Сформировать HTML код новой таблицы - контрольная панель
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-control-panel",lResponseJSON)
//Присвоить ответ в mGlobal.Monitor.mResponseList
mGlobal.Monitor.mResponseList = lResponseJSON
///Set result in mGlobal.DataStorage
lResponseJSON["RenderRobotList"].forEach(
function(lItem){
if ('DataStorageKey' in lItem) {
mGlobal["DataStorage"][lItem['DataStorageKey']]=lItem
}
}
)
///Прогрузить новую таблицу
$(".openrpa-control-panel").html(lHTMLCode)
////////////////////////////////////////////////////
///Сформировать HTML код новой таблицы - список RDP
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-robotrdpactive-control-panel",lResponseJSON)
//Присвоить ответ в mGlobal.RobotRDPActive.mResponseList
mGlobal.RobotRDPActive.mResponseList = lResponseJSON
///Прогрузить новую таблицу
$(".openrpa-robotrdpactive-control-panel").html(lHTMLCode)
///Очистить дерево
//mGlobal.ElementTree.fClear();
}
}
mGlobal.Monitor.mDatasetLast = null
mGlobal.Monitor.fControlPanelRefresh=function() { mGlobal.Monitor.fControlPanelRefresh=function() {
try { try {
//var XHR = new XMLHttpRequest();
//XHR.setRequestHeader("Cookies",document.cookie)
///Загрузка данных ///Загрузка данных
//console.log("Request is sent")
//console.log(document.cookie)
$.ajax({ $.ajax({
type: "GET", type: "GET",
url: 'Monitor/ControlPanelDictGet', headers: {"SessionGUIDStr":mGlobal.SessionGUIDStr},
data: '', url: 'Monitor/ControlPanelDictGet',
xhrFields: { data: '',
withCredentials: true //cache: false,
}, //xhr: XHR,
success: function(lData,l2,l3) success: function(lData,l2,l3) {
{
try { try {
var lResponseJSON=JSON.parse(lData) var lResponseJSON=JSON.parse(lData)
///Escape onclick mGlobal.Monitor.mDatasetLast = lResponseJSON
/// RenderRobotList mGlobal.Monitor.fControlPanelRefresh_TechnicalRender()
lResponseJSON["RenderRobotList"].forEach(
function(lItem){
if ('FooterButtonX2List' in lItem) {
/// FooterButtonX2List
lItem["FooterButtonX2List"].forEach(
function(lItem2){
if ('OnClick' in lItem) {
lOnClickEscaped = lItem["OnClick"];
lOnClickEscaped = lOnClickEscaped.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
lItem["OnClick"] = lOnClickEscaped;
}
}
);
/// FooterButtonX1List
lItem["FooterButtonX1List"].forEach(
function(lItem2){
if ('OnClick' in lItem) {
lOnClickEscaped = lItem["OnClick"];
lOnClickEscaped = lOnClickEscaped.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
lItem["OnClick"] = lOnClickEscaped;
}
}
);
}
}
);
//////////////////////////////////////////////////////////
///Сформировать HTML код новой таблицы - контрольная панель
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-control-panel",lResponseJSON)
//Присвоить ответ в mGlobal.Monitor.mResponseList
mGlobal.Monitor.mResponseList = lResponseJSON
///Set result in mGlobal.DataStorage
lResponseJSON["RenderRobotList"].forEach(
function(lItem){
if ('DataStorageKey' in lItem) {
mGlobal["DataStorage"][lItem['DataStorageKey']]=lItem
}
}
)
///Прогрузить новую таблицу
$(".openrpa-control-panel").html(lHTMLCode)
////////////////////////////////////////////////////
///Сформировать HTML код новой таблицы - список RDP
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-robotrdpactive-control-panel",lResponseJSON)
//Присвоить ответ в mGlobal.RobotRDPActive.mResponseList
mGlobal.RobotRDPActive.mResponseList = lResponseJSON
///Прогрузить новую таблицу
$(".openrpa-robotrdpactive-control-panel").html(lHTMLCode)
///Очистить дерево
//mGlobal.ElementTree.fClear();
} }
catch(error) { catch(error) {
} }
mGlobal.Monitor.fControlPanelRefresh() // recursive mGlobal.Monitor.fControlPanelRefresh() // recursive
}, },
dataType: "text", dataType: "text",
error: function(jqXHR, textStatus, errorThrown ) { error: function(jqXHR, textStatus, errorThrown ) {
sleep(3000) sleep(3000)
mGlobal.Monitor.fControlPanelRefresh() // recursive mGlobal.Monitor.fControlPanelRefresh() // recursive
} }
}); });
} }
catch(error) { catch(error) {
@ -615,4 +668,28 @@ $(document).ready(function() {
}); });
} }
mGlobal.UserRoleUpdate() // Cal the update User Roles function mGlobal.UserRoleUpdate() // Cal the update User Roles function
// Orchestrator model
mGlobal.WorkingDirectoryPathStr = null
mGlobal.OrchestratorModelUpdate=function() {
lData = [
{
"Type": "GlobalDictKeyListValueGet",
"KeyList": ["Server","WorkingDirectoryPathStr"]
}
]
$.ajax({
type: "POST",
url: 'Utils/Processor',
data: JSON.stringify(lData),
success:
function(lData,l2,l3)
{
var lUACAsk = mGlobal.UserRoleAsk // Alias
var lResponseList=JSON.parse(lData)
mGlobal.WorkingDirectoryPathStr = lResponseList[0]["Result"]
},
dataType: "text"
});
}
mGlobal.OrchestratorModelUpdate() // Cal the update orchestrator model
}); });

@ -2,7 +2,7 @@
<html lang="en" > <html lang="en" >
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>OpenRPA</title> <title>pyOpenRPA Orchestrator</title>
<link rel="stylesheet" type="text/css" href="3rdParty/Semantic-UI-CSS-master/semantic.min.css"> <link rel="stylesheet" type="text/css" href="3rdParty/Semantic-UI-CSS-master/semantic.min.css">
<script <script
src="3rdParty/jQuery/jquery-3.1.1.min.js" src="3rdParty/jQuery/jquery-3.1.1.min.js"
@ -135,14 +135,14 @@
<i class="right arrow icon"></i> <i class="right arrow icon"></i>
</div> </div>
</div> </div>
<div class="ui animated button openrpa-control-restartorchestrator" onclick="mGlobal.Controller.OrchestratorRestart();" style="display: none; margin-top: 5px;"> <div class="ui animated button openrpa-control-restartorchestrator" onclick="mGlobal.Controller.OrchestratorGITPullRestart();" style="display: none; margin-top: 5px;">
<div class="visible content">Git pull + restart Orchestrator (next release)</div> <div class="visible content">Git pull + restart Orchestrator</div>
<div class="hidden content"> <div class="hidden content">
<i class="right arrow icon"></i> <i class="right arrow icon"></i>
</div> </div>
</div> </div>
<div class="ui animated button openrpa-control-restartorchestrator red" onclick="mGlobal.Controller.OrchestratorRestart();" style="display: none; margin-top: 5px;"> <div class="ui animated button openrpa-control-restartorchestrator red" onclick="mGlobal.Controller.PCRestart();" style="display: none; margin-top: 5px;">
<div class="visible content">Restart PC (next release)</div> <div class="visible content">Restart PC</div>
<div class="hidden content"> <div class="hidden content">
<i class="right arrow icon"></i> <i class="right arrow icon"></i>
</div> </div>
@ -299,14 +299,14 @@
<div class="three wide column"> <div class="three wide column">
<h4 class="ui inverted header">GitLab</h4> <h4 class="ui inverted header">GitLab</h4>
<div class="ui inverted link list"> <div class="ui inverted link list">
<a href="https://gitlab.com/UnicodeLabs/OpenRPA" class="item" target="_blank">OpenRPA repository</a> <a href="https://gitlab.com/UnicodeLabs/OpenRPA" class="item" target="_blank">pyOpenRPA repository</a>
<a href="https://gitlab.com/UnicodeLabs" class="item" target="_blank">UnicodeLabs</a> <a href="https://www.facebook.com/RU.IT4Business" class="item" target="_blank">Ivan Maslov</a>
<a href="#" class="item">Link -</a> <a href="#" class="item">Link -</a>
<a href="#" class="item">Link -</a> <a href="#" class="item">Link -</a>
</div> </div>
</div> </div>
<div class="seven wide column"> <div class="seven wide column">
<h4 class="ui inverted header">OpenRPA</h4> <h4 class="ui inverted header">pyOpenRPA</h4>
<p>Open source Robotic Process Automation software by the Unicode Labs (Created by Ivan Maslov). Under the MIT license.</p> <p>Open source Robotic Process Automation software by the Unicode Labs (Created by Ivan Maslov). Under the MIT license.</p>
</div> </div>
</div> </div>

Loading…
Cancel
Save