draft 1.2.7 (need test)

# Create Managers.ControlPanel class - manage control panels
# Orchestrator.WeCPUpdate updated for the new Managers.ControlPanel
# BackwardCompatibility is released
# Need test for the New usage of Managers.ControlPanel
# Need to create DataProcess
# Need to check verification if data is equal - do not send the response (check for None in HTML and JSON)
dev-linux
Ivan Maslov 3 years ago
parent cd3e3211ff
commit 34396b13dd

@ -488,4 +488,22 @@ def Update(inGSettings):
if "AgentLimitLogSizeBytesInt" not in inGSettings["ServerDict"]: if "AgentLimitLogSizeBytesInt" not in inGSettings["ServerDict"]:
inGSettings["ServerDict"]["AgentLimitLogSizeBytesInt"] = 300 inGSettings["ServerDict"]["AgentLimitLogSizeBytesInt"] = 300
if lL: lL.warning( if lL: lL.warning(
f"Backward compatibility (v1.2.3 to v1.2.4): Add new key ServerDict > AgentLimitLogSizeBytesInt") # Log about compatibility f"Backward compatibility (v1.2.3 to v1.2.4): Add new key ServerDict > AgentLimitLogSizeBytesInt") # Log about compatibility
# Remove ControlPanelDict and CPDict > go to ServerDict > ControlPanelDict
if "ControlPanelDict" in inGSettings:
del inGSettings["ControlPanelDict"]
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Remove old key: ControlPanelDict") # Log about compatibility
if "CPDict" in inGSettings:
for lCPKeyStr in inGSettings["CPDict"]:
lCPItemDict = inGSettings["CPDict"][lCPKeyStr]
__Orchestrator__.WebCPUpdate(inCPKeyStr=lCPKeyStr,inHTMLRenderDef=lCPItemDict["HTMLRenderDef"],
inJSONGeneratorDef=lCPItemDict["JSONGeneratorDef"],
inJSInitGeneratorDef=lCPItemDict["JSInitGeneratorDef"])
del inGSettings["CPDict"]
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Remove old key: CPDict") # Log about compatibility
if "ControlPanelDict" not in inGSettings["ServerDict"]:
inGSettings["ServerDict"]["ControlPanelDict"]={}
if lL: lL.warning(
f"Backward compatibility (v1.2.4 to v1.2.7): Create new key: ServerDict > ControlPanelDict") # Log about compatibility

@ -0,0 +1,202 @@
from ... import Orchestrator
import jinja2
import os
from inspect import signature # For detect count of def args
from ..Web import Basic
class ControlPanel():
"""
Manage your control panel on the orchestrator
"""
mControlPanelNameStr = None
mJinja2TemplatePathStr = None
mJinja2Loader = None
mJinja2Env = None
mJinja2Template = None
mBackwardCompatibilityHTMLDef = None
mBackwardCompatibilityJSDef = None
mBackwardCompatibilityJSONDef = None
def __init__(self, inControlPanelNameStr, inJinja2TemplatePathStr = None):
"""
Constructor of the control panel manager
:param inControlPanelNameStr:
:param inJinja2TemplatePathStr:
"""
# Connect self witch pyOpenRPA via ControlPanelNameStr
if inControlPanelNameStr in Orchestrator.GSettingsGet()["ServerDict"]["ControlPanelDict"]:
raise Exception(f"Another control panel with name {inControlPanelNameStr} is already exists. Please resolve the error and restart")
Orchestrator.GSettingsGet()["ServerDict"]["ControlPanelDict"][inControlPanelNameStr] = self
self.Jinja2TemplatePathSet(inJinja2TemplatePathStr = inJinja2TemplatePathStr)
self.mControlPanelNameStr = inControlPanelNameStr # Set the name of the control panel
def Jinja2TemplatePathSet(self, inJinja2TemplatePathStr):
"""
Create Jinja2 env and load the template html
:param inJinja2TemplatePathStr:
:return:
"""
if inJinja2TemplatePathStr is not None:
lSystemLoaderPathStr = "/".join(inJinja2TemplatePathStr.split("\\")[0:-1])
lTemplateFileNameStr = inJinja2TemplatePathStr.split("\\")[-1]
self.mJinja2Loader = jinja2.FileSystemLoader(lSystemLoaderPathStr)
self.mJinja2Env = jinja2.Environment(loader=self.mJinja2Loader, trim_blocks=True)
self.mJinja2Template = self.mJinja2Env.get_template(lTemplateFileNameStr)
def Jinja2StrGenerate(self, inDataDict):
"""
Generate the HTML str from the Jinja2. Pass the context inDataDict
:param inDataDict:
:return:
"""
lHTMLStr = self.mJinja2Template.render(**inDataDict) # Render the template into str
return lHTMLStr
def DataDictGenerate(self, inRequest):
"""
:return:
"""
lData = {}
return lData
def OnRefreshHTMLStr(self, inRequest):
"""
Event to generate HTML code of the control panel when refresh time is over.
Support backward compatibility for previous versions.
:param inRequest:
:return:
"""
lHTMLStr = None
lL = Orchestrator.OrchestratorLoggerGet()
if self.mBackwardCompatibilityHTMLDef is None:
if self.mJinja2Template is not None:
lDataDict = self.OnRefreshHTMLDataDict(inRequest = inRequest)
# Jinja code
lHTMLStr = self.Jinja2StrGenerate(inDataDict=lDataDict)
else:
lHTMLStr = self.BackwardAdapterHTMLDef(inRequest=inRequest)
# return the str
return lHTMLStr
def OnRefreshHTMLDataDict(self, inRequest):
"""
Event to prepare data context for the futher Jinja2 HTML generation. You can override this def if you want some thing more data
:return: dict
"""
return self.DataDictGenerate(inRequest=inRequest)
def OnRefreshJSONDict(self, inRequest):
"""
Event to transmit some data from server side to the client side in JSON format. Call when page refresh is initialized
:return: Dict type
"""
lResultDict = None
if self.mBackwardCompatibilityJSONDef is None:
pass
else:
lResultDict = self.BackwardAdapterJSONDef(inRequest=inRequest)
return lResultDict
def OnInitJSStr(self, inRequest):
"""
Event when orchestrator web page is init on the client side - you can transmit some java script code is str type to execute it once.
:return: ""
"""
lJSStr = ""
if self.mBackwardCompatibilityJSDef is None:
pass
else:
lJSStr = self.BackwardAdapterJSDef(inRequest=inRequest)
return lJSStr
def BackwardAdapterHTMLDef(self,inRequest):
lGS = Orchestrator.GSettingsGet()
lL = Orchestrator.OrchestratorLoggerGet()
# HTMLRenderDef
lItemHTMLRenderDef = self.mBackwardCompatibilityHTMLDef
lResultStr = ""
if lItemHTMLRenderDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings)
lHTMLResult = None
lDEFSignature = signature(lItemHTMLRenderDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lHTMLResult = lItemHTMLRenderDef(lGS)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lHTMLResult = lItemHTMLRenderDef(inRequest, lGS)
elif lDEFARGLen == 0: # def ()
lHTMLResult = lItemHTMLRenderDef()
# RunFunction
# Backward compatibility up to 1.2.0 - call HTML generator if result has no "HTMLStr"
if type(lHTMLResult) is str:
lResultStr = lHTMLResult
elif "HTMLStr" in lHTMLResult or "JSONDict" in lHTMLResult:
lResultStr = lHTMLResult["HTMLStr"]
else:
# Call backward compatibility HTML generator
lResultStr = Basic.HTMLControlPanelBC(inCPDict=lHTMLResult)
except Exception as e:
if lL: lL.exception(f"Error in control panel HTMLRenderDef. CP Key {self.mControlPanelNameStr}. Exception are below")
return lResultStr
def BackwardAdapterJSONDef(self,inRequest):
lGS = Orchestrator.GSettingsGet()
lL = Orchestrator.OrchestratorLoggerGet()
# HTMLRenderDef
lItemJSONGeneratorDef = self.mBackwardCompatibilityJSONDef
lResultDict = {}
if lItemJSONGeneratorDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings)
lJSONResult = None
lDEFSignature = signature(lItemJSONGeneratorDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lJSONResult = lItemJSONGeneratorDef(lGS)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lJSONResult = lItemJSONGeneratorDef(inRequest, lGS)
elif lDEFARGLen == 0: # def ()
lJSONResult = lItemJSONGeneratorDef()
# RunFunction
# Backward compatibility up to 1.2.0 - call HTML generator if result has no "HTMLStr"
lType = type(lJSONResult)
if lType is str or lJSONResult is None or lType is int or lType is list or lType is dict or lType is bool or lType is float:
lResultDict = lJSONResult
else:
if lL: lL.warning(f"JSONGenerator return bad type: {str(type(lJSONResult))}, CP Key {self.mControlPanelNameStr}")
except Exception as e:
if lL: lL.exception(
f"Error in control panel JSONGeneratorDef. CP Key {self.mControlPanelNameStr}. Exception are below")
return lResultDict
def BackwardAdapterJSDef(self,inRequest):
lGS = Orchestrator.GSettingsGet()
lL = Orchestrator.OrchestratorLoggerGet()
# HTMLRenderDef
lJSInitGeneratorDef = self.mBackwardCompatibilityJSDef
lResultStr = ""
if lJSInitGeneratorDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings)
lJSResult = ""
lDEFSignature = signature(lJSInitGeneratorDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lJSResult = lJSInitGeneratorDef(lGS)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lJSResult = lJSInitGeneratorDef(inRequest, lGS)
elif lDEFARGLen == 0: # def ()
lJSResult = lJSInitGeneratorDef()
if type(lJSResult) is str:
lResultStr = lJSResult # Add delimiter to some cases
else:
if lL: lL.warning(f"JSInitGenerator return bad type: {str(type(lJSResult))}, CP Key {self.mControlPanelNameStr}")
except Exception as e:
if lL: lL.exception(
f"Error in control panel JSInitGeneratorDef. CP Key {self.mControlPanelNameStr}. Exception are below")
return lResultStr

@ -0,0 +1 @@
from .ControlPanel import ControlPanel

@ -24,31 +24,14 @@ def HiddenJSInitGenerate(inRequest, inGSettings):
lUACCPTemplateKeyList=["pyOpenRPADict","CPKeyDict"] lUACCPTemplateKeyList=["pyOpenRPADict","CPKeyDict"]
lL = inGSettings["Logger"] # Alias for logger lL = inGSettings["Logger"] # Alias for logger
lJSInitResultStr = "" lJSInitResultStr = ""
lRenderFunctionsRobotDict = inGSettings["CPDict"] lRenderFunctionsRobotDict = inGSettings["ServerDict"]["ControlPanelDict"]
for lItemKeyStr in lRenderFunctionsRobotDict: for lItemKeyStr in lRenderFunctionsRobotDict:
lItemDict = lRenderFunctionsRobotDict[lItemKeyStr] lItemDict = lRenderFunctionsRobotDict[lItemKeyStr]
lJSInitGeneratorDef = lItemDict.get("JSInitGeneratorDef",None)
lUACBool = dUAC(inRoleKeyList=lUACCPTemplateKeyList+[lItemKeyStr]) # Check if render function is applicable User Access Rights (UAC) lUACBool = dUAC(inRoleKeyList=lUACCPTemplateKeyList+[lItemKeyStr]) # Check if render function is applicable User Access Rights (UAC)
if lItemKeyStr=="VersionCheck": lUACBool=True # For backward compatibility for the old fron version which not reload page when new orch version is comming if lItemKeyStr=="VersionCheck": lUACBool=True # For backward compatibility for the old fron version which not reload page when new orch version is comming
if lUACBool: # Run function if UAC is TRUE if lUACBool: # Run function if UAC is TRUE
# JSONGeneratorDef # JSONGeneratorDef
if lJSInitGeneratorDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings) lJSInitResultStr = lJSInitResultStr + ";" + lItemDict.OnInitJSStr(inRequest=inRequest)
lJSResult = None
lDEFSignature = signature(lJSInitGeneratorDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lJSResult = lJSInitGeneratorDef(inGSettings)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lJSResult = lJSInitGeneratorDef(inRequest, inGSettings)
elif lDEFARGLen == 0: # def ()
lJSResult = lJSInitGeneratorDef()
if type(lJSResult) is str:
lJSInitResultStr += "; "+lJSResult # Add delimiter to some cases
else:
if lL: lL.warning(f"JSInitGenerator return bad type: {str(type(lJSResult))}, CP Key {lItemKeyStr}")
except Exception as e:
if lL: lL.exception(f"Error in control panel JSInitGeneratorDef. CP Key {lItemKeyStr}. Exception are below")
return lJSInitResultStr return lJSInitResultStr
# Generate CP HTML + JSON # Generate CP HTML + JSON
@ -59,59 +42,17 @@ def HiddenCPDictGenerate(inRequest, inGSettings):
lL = inGSettings["Logger"] # Alias for logger lL = inGSettings["Logger"] # Alias for logger
# Create result JSON # Create result JSON
lCPDict = {} lCPDict = {}
lRenderFunctionsRobotDict = inGSettings["CPDict"] lRenderFunctionsRobotDict = inGSettings["ServerDict"]["ControlPanelDict"]
for lItemKeyStr in lRenderFunctionsRobotDict: for lItemKeyStr in lRenderFunctionsRobotDict:
lItemDict = lRenderFunctionsRobotDict[lItemKeyStr] lItemDict = lRenderFunctionsRobotDict[lItemKeyStr]
lItemHTMLRenderDef = lItemDict.get("HTMLRenderDef",None)
lItemJSONGeneratorDef = lItemDict.get("JSONGeneratorDef",None)
lUACBool = dUAC(inRoleKeyList=lUACCPTemplateKeyList+[lItemKeyStr]) # Check if render function is applicable User Access Rights (UAC) lUACBool = dUAC(inRoleKeyList=lUACCPTemplateKeyList+[lItemKeyStr]) # Check if render function is applicable User Access Rights (UAC)
if lItemKeyStr=="VersionCheck": lUACBool=True # For backward compatibility for the old fron version which not reload page when new orch version is comming if lItemKeyStr=="VersionCheck": lUACBool=True # For backward compatibility for the old fron version which not reload page when new orch version is comming
if lUACBool: # Run function if UAC is TRUE if lUACBool: # Run function if UAC is TRUE
lCPItemDict = {"HTMLStr": None, "JSONDict":None} lCPItemDict = {"HTMLStr": None, "JSONDict":None}
# HTMLRenderDef # HTML Render
if lItemHTMLRenderDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings) lCPItemDict["HTMLStr"] = lItemDict.OnRefreshHTMLStr(inRequest=inRequest)
lHTMLResult = None
lDEFSignature = signature(lItemHTMLRenderDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lHTMLResult = lItemHTMLRenderDef(inGSettings)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lHTMLResult = lItemHTMLRenderDef(inRequest, inGSettings)
elif lDEFARGLen == 0: # def ()
lHTMLResult = lItemHTMLRenderDef()
# RunFunction
# Backward compatibility up to 1.2.0 - call HTML generator if result has no "HTMLStr"
if type(lHTMLResult) is str:
lCPItemDict["HTMLStr"] = lHTMLResult
elif "HTMLStr" in lHTMLResult or "JSONDict" in lHTMLResult:
lCPItemDict = lHTMLResult # new version
else:
# Call backward compatibility HTML generator
lCPItemDict["HTMLStr"] = Basic.HTMLControlPanelBC(inCPDict=lHTMLResult)
except Exception as e:
if lL: lL.exception(f"Error in control panel HTMLRenderDef. CP Key {lItemKeyStr}. Exception are below")
# JSONGeneratorDef # JSONGeneratorDef
if lItemJSONGeneratorDef is not None: # Call def (inRequest, inGSettings) or def (inGSettings) lCPItemDict["JSONDict"] = lItemDict.OnRefreshJSONDict(inRequest=inRequest)
lJSONResult = None
lDEFSignature = signature(lItemJSONGeneratorDef) # Get signature of the def
lDEFARGLen = len(lDEFSignature.parameters.keys()) # get count of the def args
try:
if lDEFARGLen == 1: # def (inGSettings)
lJSONResult = lItemJSONGeneratorDef(inGSettings)
elif lDEFARGLen == 2: # def (inRequest, inGSettings)
lJSONResult = lItemJSONGeneratorDef(inRequest, inGSettings)
elif lDEFARGLen == 0: # def ()
lJSONResult = lItemJSONGeneratorDef()
# RunFunction
# Backward compatibility up to 1.2.0 - call HTML generator if result has no "HTMLStr"
lType = type(lJSONResult)
if lType is str or lJSONResult is None or lType is int or lType is list or lType is dict or lType is bool or lType is float:
lCPItemDict["JSONDict"] = lJSONResult
else:
if lL: lL.warning(f"JSONGenerator return bad type: {str(type(lJSONResult))}, CP Key {lItemKeyStr}")
except Exception as e:
if lL: lL.exception(f"Error in control panel JSONGeneratorDef. CP Key {lItemKeyStr}. Exception are below")
# Insert CPItemDict in result CPDict # Insert CPItemDict in result CPDict
lCPDict[lItemKeyStr]=lCPItemDict lCPDict[lItemKeyStr]=lCPItemDict
return lCPDict return lCPDict
@ -207,6 +148,8 @@ def pyOpenRPA_ServerData(inRequest,inGSettings):
def pyOpenRPA_ServerJSInit(inRequest,inGSettings): def pyOpenRPA_ServerJSInit(inRequest,inGSettings):
lResultStr = HiddenJSInitGenerate(inRequest=inRequest, inGSettings=inGSettings) lResultStr = HiddenJSInitGenerate(inRequest=inRequest, inGSettings=inGSettings)
inResponseDict = inRequest.OpenRPAResponseDict inResponseDict = inRequest.OpenRPAResponseDict
if lResultStr is None:
lResultStr = ""
# Write content as utf-8 data # Write content as utf-8 data
inResponseDict["Body"] = bytes(lResultStr, "utf8") inResponseDict["Body"] = bytes(lResultStr, "utf8")

@ -39,6 +39,9 @@ def __Create__():
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
}, },
"ServerDict": { "ServerDict": {
"ControlPanelDict": {
# "CPKey": <Managers.ControlPanel instance>
},
"AgentLimitLogSizeBytesInt": 300, # Don't show body if json body of transmition is more than "AgentLimitLogSizeBytesInt": 300, # Don't show body if json body of transmition is more than
"ServerThread": None, # Server thread is there "ServerThread": None, # Server thread is there
"AgentActivityLifetimeSecFloat": 1200.0, # Time in seconds to life for activity for the agent "AgentActivityLifetimeSecFloat": 1200.0, # Time in seconds to life for activity for the agent
@ -162,6 +165,7 @@ def __Create__():
"ThreadIdInt": None, # Technical field - will be setup when processor init "ThreadIdInt": None, # Technical field - will be setup when processor init
"WarningExecutionMoreThanSecFloat": 60.0 # Push warning if execution more than n seconds "WarningExecutionMoreThanSecFloat": 60.0 # Push warning if execution more than n seconds
}, },
# TODO REMOVE DEPRECATED KEYS IN v.2.0.0
"ControlPanelDict": { # Old structure > CPDict "ControlPanelDict": { # Old structure > CPDict
"RefreshSeconds": 5, # deprecated parameter "RefreshSeconds": 5, # deprecated parameter
"RobotList": [ "RobotList": [
@ -171,6 +175,7 @@ def __Create__():
#} #}
] ]
}, },
# TODO REMOVE DEPRECATED KEYS IN v.2.0.0
"CPDict": { "CPDict": {
# "CPKey": {"HTMLRenderDef":None, "JSONGeneratorDef":None, "JSInitGeneratorDef":None} # "CPKey": {"HTMLRenderDef":None, "JSONGeneratorDef":None, "JSInitGeneratorDef":None}
}, },

@ -8,6 +8,7 @@ from . import Timer
from . import Processor from . import Processor
from . import BackwardCompatibility # Backward compatibility from v1.1.13 from . import BackwardCompatibility # Backward compatibility from v1.1.13
from . import Core from . import Core
from . import Managers
from subprocess import CREATE_NEW_CONSOLE from subprocess import CREATE_NEW_CONSOLE
from .Utils import LoggerHandlerDumpLogList from .Utils import LoggerHandlerDumpLogList
@ -799,19 +800,13 @@ def WebCPUpdate(inCPKeyStr, inHTMLRenderDef=None, inJSONGeneratorDef=None, inJSI
:param inJSONGeneratorDef: :param inJSONGeneratorDef:
:param inJSInitGeneratorDef: :param inJSInitGeneratorDef:
""" """
inGSettings = GSettingsGet(inGSettings=inGSettings) # Set the global settings lCPManager = Managers.ControlPanel(inControlPanelNameStr=inCPKeyStr, inJinja2TemplatePathStr=None)
# Create Struct if the re is current key
if inCPKeyStr not in inGSettings["CPDict"]:
inGSettings["CPDict"][inCPKeyStr] = {"HTMLRenderDef": None,"JSONGeneratorDef": None, "JSInitGeneratorDef": None}
# CASE HTMLRender # CASE HTMLRender
if inHTMLRenderDef is not None: if inHTMLRenderDef is not None: lCPManager.mBackwardCompatibilityHTMLDef = inHTMLRenderDef
inGSettings["CPDict"][inCPKeyStr]["HTMLRenderDef"]=inHTMLRenderDef
# CASE JSONGenerator # CASE JSONGenerator
if inJSONGeneratorDef is not None: if inJSONGeneratorDef is not None: lCPManager.mBackwardCompatibilityJSONDef = inJSONGeneratorDef
inGSettings["CPDict"][inCPKeyStr]["JSONGeneratorDef"] = inJSONGeneratorDef
# CASE JSInitGeneratorDef # CASE JSInitGeneratorDef
if inJSInitGeneratorDef is not None: if inJSInitGeneratorDef is not None: lCPManager.mBackwardCompatibilityJSDef = inJSInitGeneratorDef
inGSettings["CPDict"][inCPKeyStr]["JSInitGeneratorDef"] = inJSInitGeneratorDef
def WebAuditMessageCreate(inRequest, inOperationCodeStr="-", inMessageStr="-"): def WebAuditMessageCreate(inRequest, inOperationCodeStr="-", inMessageStr="-"):

Loading…
Cancel
Save