parent
cfbdefd161
commit
b3d04a6393
@ -0,0 +1 @@
|
||||
<div>11231231</div>
|
@ -0,0 +1 @@
|
||||
alert(123)
|
@ -0,0 +1,422 @@
|
||||
import inspect
|
||||
from pyOpenRPA.Tools import CrossOS
|
||||
import urllib.parse # decode URL in string
|
||||
import os #for path operations
|
||||
from . import __Orchestrator__
|
||||
import mimetypes
|
||||
mimetypes.add_type("font/woff2",".woff2")
|
||||
mimetypes.add_type("text/javascript",".js")
|
||||
|
||||
# объявление import
|
||||
from fastapi import FastAPI, Form, Request, HTTPException, Depends, Header, Response, Body
|
||||
|
||||
gCacheDict = {}
|
||||
|
||||
|
||||
# Tool to merge complex dictionaries
|
||||
def __ComplexDictMerge2to1__(in1Dict, in2Dict):
|
||||
lPathList=None
|
||||
if lPathList is None: lPathList = []
|
||||
for lKeyStr in in2Dict:
|
||||
if lKeyStr in in1Dict:
|
||||
if isinstance(in1Dict[lKeyStr], dict) and isinstance(in2Dict[lKeyStr], dict):
|
||||
__ComplexDictMerge2to1__(in1Dict[lKeyStr], in2Dict[lKeyStr])
|
||||
elif in1Dict[lKeyStr] == in2Dict[lKeyStr]:
|
||||
pass # same leaf value
|
||||
else:
|
||||
raise Exception('Conflict at %s' % '.'.join(lPathList + [str(lKeyStr)]))
|
||||
else:
|
||||
in1Dict[lKeyStr] = in2Dict[lKeyStr]
|
||||
return in1Dict
|
||||
|
||||
# Tool to merge complex dictionaries - no exceptions, just overwrite dict 2 in dict 1
|
||||
def __ComplexDictMerge2to1Overwrite__(in1Dict, in2Dict):
|
||||
"""
|
||||
Merge in2Dict in in1Dict. In conflict override and get value from dict 2
|
||||
|
||||
:param in1Dict: Source dict. Save the link (structure)
|
||||
:param in2Dict: New data dict
|
||||
:return: Merged dict 1
|
||||
"""
|
||||
lPathList=None
|
||||
if lPathList is None: lPathList = []
|
||||
for lKeyStr in in2Dict:
|
||||
if lKeyStr in in1Dict:
|
||||
if isinstance(in1Dict[lKeyStr], dict) and isinstance(in2Dict[lKeyStr], dict):
|
||||
__ComplexDictMerge2to1Overwrite__(in1Dict[lKeyStr], in2Dict[lKeyStr])
|
||||
else:
|
||||
in1Dict[lKeyStr] = in2Dict[lKeyStr]
|
||||
else:
|
||||
in1Dict[lKeyStr] = in2Dict[lKeyStr]
|
||||
return in1Dict
|
||||
|
||||
|
||||
def AuthenticateBlock(inRequest):
|
||||
raise HTTPException(status_code=401, detail="here is the details", headers={'Content-type':'text/html', 'WWW-Authenticate':'Basic'})
|
||||
|
||||
#Check access before execute the action
|
||||
#return bool True - go execute, False - dont execute
|
||||
def UserAccessCheckBefore(inMethod, inRequest):
|
||||
# Help def - Get access flag from dict
|
||||
#pdb.set_trace()
|
||||
def HelpGetFlag(inAccessRuleItem, inRequest, inGlobalDict, inAuthenticateDict):
|
||||
if "FlagAccess" in inAccessRuleItem:
|
||||
return inAccessRuleItem["FlagAccess"]
|
||||
elif "FlagAccessDefRequestGlobalAuthenticate" in inAccessRuleItem:
|
||||
return inAccessRuleItem["FlagAccessDefRequestGlobalAuthenticate"](inRequest, inGlobalDict,
|
||||
inAuthenticateDict)
|
||||
##########################################
|
||||
inMethod=inMethod.upper()
|
||||
#Prepare result false
|
||||
lResult = False
|
||||
lAuthToken = inRequest.OpenRPA["AuthToken"]
|
||||
#go next if user is identified
|
||||
lUserDict = None
|
||||
#print(f"lAuthToken: {lAuthToken}")
|
||||
if lAuthToken:
|
||||
lUserDict = __Orchestrator__.GSettingsGet()["ServerDict"]["AccessUsers"]["AuthTokensDict"][lAuthToken]
|
||||
#print(f"lUserDict: {lUserDict}")
|
||||
#pdb.set_trace()
|
||||
########################################
|
||||
########################################
|
||||
#Check general before rule (without User domain)
|
||||
#Check rules
|
||||
inRuleMatchURLList = __Orchestrator__.GSettingsGet().get("ServerDict", {}).get("AccessUsers", {}).get("RuleMethodMatchURLBeforeList", [])
|
||||
for lAccessRuleItem in inRuleMatchURLList:
|
||||
#Go next execution if flag is false
|
||||
if not lResult:
|
||||
#Check if Method is identical
|
||||
if lAccessRuleItem["Method"].upper() == inMethod:
|
||||
#check Match type variant: BeginWith
|
||||
if lAccessRuleItem["MatchType"].upper() == "BEGINWITH":
|
||||
lURLPath = inRequest.path
|
||||
lURLPath = lURLPath.upper()
|
||||
if lURLPath.startswith(lAccessRuleItem["URL"].upper()):
|
||||
lResult = HelpGetFlag(lAccessRuleItem, inRequest, __Orchestrator__.GSettingsGet(), lUserDict)
|
||||
# check Match type variant: Contains
|
||||
elif lAccessRuleItem["MatchType"].upper() == "CONTAINS":
|
||||
lURLPath = inRequest.path
|
||||
lURLPath = lURLPath.upper()
|
||||
if lURLPath.contains(lAccessRuleItem["URL"].upper()):
|
||||
lResult = HelpGetFlag(lAccessRuleItem, inRequest, __Orchestrator__.GSettingsGet(), lUserDict)
|
||||
# check Match type variant: Equal
|
||||
elif lAccessRuleItem["MatchType"].upper() == "EQUAL":
|
||||
if lAccessRuleItem["URL"].upper() == inRequest.path.upper():
|
||||
lResult = HelpGetFlag(lAccessRuleItem, inRequest, __Orchestrator__.GSettingsGet(), lUserDict)
|
||||
# check Match type variant: EqualCase
|
||||
elif lAccessRuleItem["MatchType"].upper() == "EQUALCASE":
|
||||
if lAccessRuleItem["URL"] == inRequest.path:
|
||||
lResult = HelpGetFlag(lAccessRuleItem, inRequest, __Orchestrator__.GSettingsGet(), lUserDict)
|
||||
#########################################
|
||||
#########################################
|
||||
#Do check if lResult is false
|
||||
if not lResult:
|
||||
#Check access by User Domain
|
||||
#Check rules to find first appicable
|
||||
#Check rules
|
||||
lMethodMatchURLList = __Orchestrator__.GSettingsGet().get("ServerDict", {}).get("AccessUsers", {}).get("RuleDomainUserDict", {}).get((lUserDict["Domain"].upper(), lUserDict["User"].upper()), {}).get("MethodMatchURLBeforeList", [])
|
||||
if len(lMethodMatchURLList) > 0:
|
||||
for lAccessRuleItem in lMethodMatchURLList:
|
||||
#Go next execution if flag is false
|
||||
if not lResult:
|
||||
#Check if Method is identical
|
||||
if lAccessRuleItem["Method"].upper() == inMethod:
|
||||
#check Match type variant: BeginWith
|
||||
if lAccessRuleItem["MatchType"].upper() == "BEGINWITH":
|
||||
lURLPath = inRequest.path
|
||||
lURLPath = lURLPath.upper()
|
||||
if lURLPath.startswith(lAccessRuleItem["URL"].upper()):
|
||||
lResult = HelpGetFlag(lAccessRuleItem, inRequest, __Orchestrator__.GSettingsGet(), lUserDict)
|
||||
#check Match type variant: Contains
|
||||
elif lAccessRuleItem["MatchType"].upper() == "CONTAINS":
|
||||
lURLPath = inRequest.path
|
||||
lURLPath = lURLPath.upper()
|
||||
if lURLPath.contains(lAccessRuleItem["URL"].upper()):
|
||||
lResult = HelpGetFlag(lAccessRuleItem, inRequest, __Orchestrator__.GSettingsGet(), lUserDict)
|
||||
# check Match type variant: Equal
|
||||
elif lAccessRuleItem["MatchType"].upper() == "EQUAL":
|
||||
if lAccessRuleItem["URL"].upper() == inRequest.path.upper():
|
||||
lResult = HelpGetFlag(lAccessRuleItem, inRequest, __Orchestrator__.GSettingsGet(), lUserDict)
|
||||
# check Match type variant: EqualCase
|
||||
elif lAccessRuleItem["MatchType"].upper() == "EQUALCASE":
|
||||
if lAccessRuleItem["URL"] == inRequest.path:
|
||||
lResult = HelpGetFlag(lAccessRuleItem, inRequest, __Orchestrator__.GSettingsGet(), lUserDict)
|
||||
else:
|
||||
return True
|
||||
#####################################
|
||||
#####################################
|
||||
#Return lResult
|
||||
return lResult
|
||||
|
||||
class HTTPRequestOld():
|
||||
mRequest:Request = None
|
||||
mResponse:Response = None
|
||||
OpenRPA: dict = {}
|
||||
headers={}
|
||||
|
||||
def __init__(self,inRequest,inResponse,inAuthDict):
|
||||
self.mRequest = inRequest
|
||||
self.mResponse = inResponse
|
||||
if inAuthDict is None:
|
||||
self.OpenRPA = {}
|
||||
self.OpenRPA["IsSuperToken"] = False
|
||||
self.OpenRPA["AuthToken"] = None
|
||||
self.OpenRPA["Domain"] = None
|
||||
self.OpenRPA["User"] = None
|
||||
else: self.OpenRPA = inAuthDict
|
||||
self.headers=inRequest.headers
|
||||
|
||||
# Def to check User Role access grants
|
||||
def UACClientCheck(self, inRoleKeyList): # Alias
|
||||
return self.UserRoleAccessAsk(inRoleKeyList=inRoleKeyList)
|
||||
def UserRoleAccessAsk(self, inRoleKeyList):
|
||||
lResult = True # Init flag
|
||||
lRoleHierarchyDict = self.UserRoleHierarchyGet() # get the Hierarchy
|
||||
# Try to get value from key list
|
||||
lKeyValue = lRoleHierarchyDict # Init the base
|
||||
for lItem in inRoleKeyList:
|
||||
if type(lKeyValue) is dict:
|
||||
if lItem in lKeyValue: # Has key
|
||||
lKeyValue = lKeyValue[lItem] # Get the value and go to the next loop iteration
|
||||
else: # Else branch - true or false
|
||||
if len(lKeyValue)>0: # False - if Dict has some elements
|
||||
lResult = False # Set the False Flag
|
||||
else:
|
||||
lResult = True # Set the True flag
|
||||
break # Stop the loop
|
||||
else: # Has element with no detalization - return True
|
||||
lResult = True # Set the flag
|
||||
break # Close the loop
|
||||
return lResult # Return the result
|
||||
|
||||
# Def to get hierarchy of the current user roles
|
||||
# if return {} - all is available
|
||||
def UserRoleHierarchyGet(self):
|
||||
lDomainUpperStr = self.OpenRPA["Domain"].upper()
|
||||
lUserUpperStr = self.OpenRPA["User"].upper()
|
||||
return __Orchestrator__.GSettingsGet().get("ServerDict", {}).get("AccessUsers", {}).get("RuleDomainUserDict", {}).get((lDomainUpperStr, lUserUpperStr), {}).get("RoleHierarchyAllowedDict", {})
|
||||
|
||||
#Tech def
|
||||
#return {"headers":[],"body":"","statuscode":111}
|
||||
def URLItemCheckDo(self, inURLItem, inMethod, inOnlyFlagUACBool = False):
|
||||
###############################
|
||||
#Tech sub def - do item
|
||||
################################
|
||||
def URLItemDo(inURLItem,inRequest,inGlobalDict):
|
||||
global gCacheDict
|
||||
inResponseDict = inRequest.OpenRPAResponseDict
|
||||
inResponseDict["Headers"]["Content-type"]= None
|
||||
#Set status code 200
|
||||
inResponseDict["StatusCode"] = 200
|
||||
#Content-type
|
||||
if "ResponseContentType" in inURLItem:
|
||||
inResponseDict["Headers"]["Content-type"] = inURLItem["ResponseContentType"]
|
||||
#If file path is set
|
||||
if "ResponseFilePath" in inURLItem:
|
||||
# Check cache
|
||||
if inURLItem.get("UseCacheBool",False) == True:
|
||||
if inURLItem["ResponseFilePath"] in gCacheDict:
|
||||
# Write content as utf-8 data
|
||||
inResponseDict["Body"] = gCacheDict[inURLItem["ResponseFilePath"]]
|
||||
else:
|
||||
if os.path.exists(inURLItem["ResponseFilePath"]) and os.path.isfile(inURLItem["ResponseFilePath"]):
|
||||
lFileObject = open(CrossOS.PathStr(inURLItem["ResponseFilePath"]), "rb")
|
||||
# Write content as utf-8 data
|
||||
gCacheDict[inURLItem["ResponseFilePath"]] = lFileObject.read()
|
||||
inResponseDict["Body"] = gCacheDict[inURLItem["ResponseFilePath"]]
|
||||
# Закрыть файловый объект
|
||||
lFileObject.close()
|
||||
else: inResponseDict["Headers"]["Content-type"]= "application/x-empty"; inResponseDict["StatusCode"] = 204 # NOCONTENT
|
||||
else:
|
||||
if os.path.exists(inURLItem["ResponseFilePath"]) and os.path.isfile(inURLItem["ResponseFilePath"]):
|
||||
lFileObject = open(CrossOS.PathStr(inURLItem["ResponseFilePath"]), "rb")
|
||||
# Write content as utf-8 data
|
||||
inResponseDict["Body"] = lFileObject.read()
|
||||
# Закрыть файловый объект
|
||||
lFileObject.close()
|
||||
else: inResponseDict["Headers"]["Content-type"]= "application/x-empty"; inResponseDict["StatusCode"] = 204 # NOCONTENT
|
||||
# detect MIME type if none
|
||||
if inResponseDict["Headers"]["Content-type"] is None:
|
||||
inResponseDict["Headers"]["Content-type"]= mimetypes.guess_type(inURLItem["ResponseFilePath"])[0]
|
||||
#If function is set
|
||||
if "ResponseDefRequestGlobal" in inURLItem:
|
||||
lDef = inURLItem["ResponseDefRequestGlobal"]
|
||||
lDefSignature = inspect.signature(lDef)
|
||||
if len(lDefSignature.parameters) == 2:
|
||||
inURLItem["ResponseDefRequestGlobal"](inRequest, inGlobalDict)
|
||||
elif len(lDefSignature.parameters) == 1:
|
||||
inURLItem["ResponseDefRequestGlobal"](inRequest)
|
||||
else:
|
||||
inURLItem["ResponseDefRequestGlobal"]()
|
||||
if "ResponseFolderPath" in inURLItem:
|
||||
#lRequestPath = inRequest.path
|
||||
lRequestPath = urllib.parse.unquote(inRequest.path)
|
||||
if inURLItem["URL"][-1]!="/": inURLItem["URL"]+= "/" # Fix for settings
|
||||
lFilePathSecondPart = lRequestPath.replace(inURLItem["URL"],"")
|
||||
lFilePathSecondPart = lFilePathSecondPart.split("?")[0]
|
||||
lFilePath = CrossOS.PathStr(os.path.join(inURLItem["ResponseFolderPath"],lFilePathSecondPart))
|
||||
#print(f"File full path {lFilePath}")
|
||||
#Check if file exist
|
||||
if os.path.exists(lFilePath) and os.path.isfile(lFilePath):
|
||||
# Check cache
|
||||
if inURLItem.get("UseCacheBool",False) == True:
|
||||
if lFilePath in gCacheDict:
|
||||
# Write content as utf-8 data
|
||||
inResponseDict["Body"] = gCacheDict[lFilePath]
|
||||
else:
|
||||
lFileObject = open(lFilePath, "rb")
|
||||
# Write content as utf-8 data
|
||||
gCacheDict[lFilePath] = lFileObject.read()
|
||||
inResponseDict["Body"] = gCacheDict[lFilePath]
|
||||
# Закрыть файловый объект
|
||||
lFileObject.close()
|
||||
else:
|
||||
lFileObject = open(lFilePath, "rb")
|
||||
# Write content as utf-8 data
|
||||
inResponseDict["Body"] = lFileObject.read()
|
||||
# Закрыть файловый объект
|
||||
lFileObject.close()
|
||||
# detect MIME type if none
|
||||
if inResponseDict["Headers"]["Content-type"] is None:
|
||||
inResponseDict["Headers"]["Content-type"]= mimetypes.guess_type(lFilePath)[0]
|
||||
else:
|
||||
inResponseDict["Headers"]["Content-type"]= "application/x-empty"; inResponseDict["StatusCode"] = 204 # NOCONTENT
|
||||
# If No content-type
|
||||
if inResponseDict["Headers"]["Content-type"] is None:
|
||||
inResponseDict["Headers"]["Content-type"]= "application/octet-stream"
|
||||
##############################################
|
||||
# UAC Check
|
||||
if inOnlyFlagUACBool == True and inURLItem.get("UACBool",None) in [None, True]:
|
||||
return False
|
||||
if inURLItem["Method"].upper() == inMethod.upper():
|
||||
# check Match type variant: BeginWith
|
||||
if inURLItem["MatchType"].upper() == "BEGINWITH":
|
||||
lURLPath = urllib.parse.unquote(self.path)
|
||||
lURLPath = lURLPath.upper()
|
||||
if lURLPath.startswith(inURLItem["URL"].upper()):
|
||||
URLItemDo(inURLItem, self, __Orchestrator__.GSettingsGet())
|
||||
return True
|
||||
# check Match type variant: Contains
|
||||
elif inURLItem["MatchType"].upper() == "CONTAINS":
|
||||
lURLPath = urllib.parse.unquote(self.path)
|
||||
lURLPath = lURLPath.upper()
|
||||
if lURLPath.contains(inURLItem["URL"].upper()):
|
||||
URLItemDo(inURLItem, self, __Orchestrator__.GSettingsGet())
|
||||
return True
|
||||
# check Match type variant: Equal
|
||||
elif inURLItem["MatchType"].upper() == "EQUAL":
|
||||
if inURLItem["URL"].upper() == urllib.parse.unquote(self.path).upper():
|
||||
URLItemDo(inURLItem, self, __Orchestrator__.GSettingsGet())
|
||||
return True
|
||||
# check Match type variant: EqualNoParam
|
||||
elif inURLItem["MatchType"].upper() == "EQUALNOPARAM":
|
||||
if inURLItem["URL"].upper() == urllib.parse.unquote(self.path).upper().split("?")[0]:
|
||||
URLItemDo(inURLItem, self, __Orchestrator__.GSettingsGet())
|
||||
return True
|
||||
# check Match type variant: EqualCase
|
||||
elif inURLItem["MatchType"].upper() == "EQUALCASE":
|
||||
if inURLItem["URL"] == urllib.parse.unquote(self.path):
|
||||
URLItemDo(inURLItem, self, __Orchestrator__.GSettingsGet())
|
||||
return True
|
||||
return False
|
||||
#ResponseContentTypeFile
|
||||
def SendResponseContentTypeFile(self, inContentType, inFilePath):
|
||||
inResponseDict = self.OpenRPAResponseDict
|
||||
self.mResponse.status_code = 200
|
||||
# Send headers
|
||||
self.mResponse.headers["Content-type"]=inContentType
|
||||
#Check if var exist
|
||||
if hasattr(self, "OpenRPASetCookie"):
|
||||
self.mResponse.set_cookie(key='AuthToken',value=self.OpenRPA['AuthToken'])
|
||||
lFileObject = open(inFilePath, "rb")
|
||||
# Write content as utf-8 data
|
||||
lFileBytes = lFileObject.read()
|
||||
#Закрыть файловый объект
|
||||
lFileObject.close()
|
||||
return lFileBytes
|
||||
# ResponseContentTypeFile
|
||||
def ResponseDictSend(self):
|
||||
inResponseDict = self.OpenRPAResponseDict
|
||||
self.mResponse.status_code = inResponseDict["StatusCode"]
|
||||
# Send headers
|
||||
for lItemKey, lItemValue in inResponseDict["Headers"].items():
|
||||
self.mResponse.headers[lItemKey]=lItemValue
|
||||
# Send headers: Set-Cookie
|
||||
for lItemKey, lItemValue in inResponseDict["SetCookies"].items():
|
||||
self.mResponse.set_cookie(key=lItemKey,value=lItemValue)
|
||||
self.send_header("Set-Cookie", f"{lItemKey}={lItemValue}")
|
||||
return inResponseDict["Body"]
|
||||
|
||||
def do_GET(self, inBodyStr):
|
||||
try:
|
||||
try:
|
||||
self.OpenRPA["DefUserRoleAccessAsk"]=self.UserRoleAccessAsk # Alias for def
|
||||
self.OpenRPA["DefUserRoleHierarchyGet"]=self.UserRoleHierarchyGet # Alias for def
|
||||
except Exception as e:
|
||||
pass
|
||||
# Prepare result dict
|
||||
lResponseDict = {"Headers": {}, "SetCookies": {}, "Body": b"", "StatusCode": None, "BodyIsText":True}
|
||||
self.OpenRPAResponseDict = lResponseDict
|
||||
#Check the user access (if flag, UAC)
|
||||
####################################
|
||||
lFlagUserAccess = True
|
||||
#If need user authentication
|
||||
if __Orchestrator__.GSettingsGet().get("ServerDict", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False):
|
||||
if self.OpenRPA["AuthToken"] != None:
|
||||
lFlagUserAccess = UserAccessCheckBefore("GET", self)
|
||||
######################################
|
||||
if lFlagUserAccess:
|
||||
if CrossOS.IS_WINDOWS_BOOL: lOrchestratorFolder = "\\".join(__file__.split("\\")[:-1])
|
||||
if CrossOS.IS_LINUX_BOOL: lOrchestratorFolder = "/".join(__file__.split("/")[:-1])
|
||||
############################
|
||||
#New server engine (url from global dict (URLList))
|
||||
############################
|
||||
for lURLItem in __Orchestrator__.GSettingsGet()["ServerDict"]["URLList"]:
|
||||
#Check if all condition are applied
|
||||
lFlagURLIsApplied=False
|
||||
lFlagURLIsApplied=self.URLItemCheckDo(lURLItem, "GET")
|
||||
if lFlagURLIsApplied:
|
||||
return self.ResponseDictSend()
|
||||
else:
|
||||
raise HTTPException(status_code=403, detail="here is the details", headers={})
|
||||
except Exception as e:
|
||||
lL = __Orchestrator__.OrchestratorLoggerGet()
|
||||
if lL: lL.exception(f"Сервер (do_GET): Неопознанная ошибка сети - см. текст ошибки. Сервер продолжает работу")
|
||||
# POST
|
||||
def do_POST(self, inBodyStr):
|
||||
try:
|
||||
lL = __Orchestrator__.OrchestratorLoggerGet()
|
||||
try:
|
||||
self.OpenRPA["DefUserRoleAccessAsk"]=self.UserRoleAccessAsk # Alias for def
|
||||
self.OpenRPA["DefUserRoleHierarchyGet"]=self.UserRoleHierarchyGet # Alias for def
|
||||
except Exception as e:
|
||||
pass
|
||||
# Prepare result dict
|
||||
#pdb.set_trace()
|
||||
lResponseDict = {"Headers": {}, "SetCookies": {}, "Body": b"", "StatusCode": None, "BodyIsText":True}
|
||||
self.OpenRPAResponseDict = lResponseDict
|
||||
#Check the user access (if flag)
|
||||
####################################
|
||||
lFlagUserAccess = True
|
||||
#If need user authentication
|
||||
if __Orchestrator__.GSettingsGet().get("ServerDict", {}).get("AccessUsers", {}).get("FlagCredentialsAsk", False):
|
||||
if self.OpenRPA["AuthToken"] != None:
|
||||
lFlagUserAccess = UserAccessCheckBefore("POST", self)
|
||||
######################################
|
||||
if lFlagUserAccess:
|
||||
lOrchestratorFolder = "\\".join(__file__.split("\\")[:-1])
|
||||
############################
|
||||
#New server engine (url from global dict (URLList))
|
||||
############################
|
||||
for lURLItem in __Orchestrator__.GSettingsGet()["ServerDict"]["URLList"]:
|
||||
#Check if all condition are applied
|
||||
lFlagURLIsApplied=False
|
||||
lFlagURLIsApplied=self.URLItemCheckDo(lURLItem, "POST")
|
||||
if lFlagURLIsApplied:
|
||||
return self.ResponseDictSend()
|
||||
else:
|
||||
raise HTTPException(status_code=403, detail="here is the details", headers={})
|
||||
except Exception as e:
|
||||
lL = __Orchestrator__.OrchestratorLoggerGet()
|
||||
if lL: lL.exception(f"Сервер, обратная совместимость (do_POST): Неопознанная ошибка сети - см. текст ошибки. Сервер продолжает работу")
|
||||
|
@ -1,992 +0,0 @@
|
||||
var mGlobal={}
|
||||
mGlobal.pyOpenRPA = {}
|
||||
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.cookie = "SessionGUIDStr=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||
console.log("Cookie is deleted")
|
||||
// fix main menu to page on passing
|
||||
$('.main.menu').visibility({
|
||||
type: 'fixed'
|
||||
});
|
||||
$('.overlay').visibility({
|
||||
type: 'fixed',
|
||||
offset: 80
|
||||
});
|
||||
|
||||
// lazy load images
|
||||
$('.image').visibility({
|
||||
type: 'image',
|
||||
transition: 'vertical flip in',
|
||||
duration: 500
|
||||
});
|
||||
|
||||
// show dropdown on hover
|
||||
$('.main.menu .ui.dropdown').dropdown({
|
||||
on: 'hover'
|
||||
});
|
||||
function clone(obj) {
|
||||
var copy;
|
||||
|
||||
// Handle the 3 simple types, and null or undefined
|
||||
if (null == obj || "object" != typeof obj) return obj;
|
||||
|
||||
// Handle Date
|
||||
if (obj instanceof Date) {
|
||||
copy = new Date();
|
||||
copy.setTime(obj.getTime());
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Handle Array
|
||||
if (obj instanceof Array) {
|
||||
copy = [];
|
||||
for (var i = 0, len = obj.length; i < len; i++) {
|
||||
copy[i] = clone(obj[i]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Handle Object
|
||||
if (obj instanceof Object) {
|
||||
copy = {};
|
||||
for (var attr in obj) {
|
||||
if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
throw new Error("Unable to copy obj! Its type isn't supported.");
|
||||
}
|
||||
//For data storage key
|
||||
mGlobal["DataStorage"] = {}
|
||||
// Clear the session cookie
|
||||
|
||||
String.prototype.replaceAll = function(search, replace){
|
||||
return this.split(search).join(replace);
|
||||
}
|
||||
mGlobal.GeneralGenerateHTMLCodeHandlebars=function(inInnerTemplateSelector,inData) {
|
||||
lHTMLTemplate=$(inInnerTemplateSelector)[0].innerHTML
|
||||
//console.log(lHTMLTemplate)
|
||||
//Компиляция
|
||||
var template = Handlebars.compile(lHTMLTemplate);
|
||||
//Вставка данных
|
||||
var lHTMLResult = template(inData);
|
||||
return lHTMLResult
|
||||
}
|
||||
mGlobal.GeneralGenerateHTMLCode=function(inTemplateHTMLSelector,inItemDictionary,inKeywordPrefix="::",inKeywordPostfix="::") {
|
||||
///Получить заготовку
|
||||
lTemplateHTMLCode=$(inTemplateHTMLSelector)[0].outerHTML
|
||||
///Определить ключь экранирования специальных ключевых слов
|
||||
///Выполнить циклические замены, если там есть пожходящие ключи
|
||||
lResultHTMLCode=lTemplateHTMLCode
|
||||
for(var lKey in inItemDictionary) {
|
||||
lHTMLKey=inKeywordPrefix+lKey+inKeywordPostfix;
|
||||
lResultHTMLCode=lResultHTMLCode.replaceAll(lHTMLKey,inItemDictionary[lKey])
|
||||
}
|
||||
///Вернуть результат
|
||||
return lResultHTMLCode
|
||||
}
|
||||
//////////////////////////
|
||||
/////Info JS module
|
||||
//////////////////////////
|
||||
mGlobal.Info={};
|
||||
|
||||
mGlobal.Info.TableActivityLogScheduleListRefresh=function() {
|
||||
|
||||
}
|
||||
//////////////////////////
|
||||
/////Controller JS module
|
||||
//////////////////////////
|
||||
mGlobal.Controller={};
|
||||
|
||||
mGlobal.Controller.CMDRunText=function(inCMDText) {
|
||||
///Подготовить конфигурацию
|
||||
lData = [
|
||||
{"Type":"CMDStart", "Command": inCMDText}
|
||||
]
|
||||
///Обнулить таблицу
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3){},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
mGlobal.Controller.CMDRun=function() {
|
||||
///Обнулить таблицу
|
||||
lCMDCode=$(".openrpa-controller-cmd-run-input")[0].value
|
||||
///Подготовить конфигурацию
|
||||
lData = [
|
||||
{
|
||||
"Def":"OSCMD", // def link or def alias (look gSettings["Processor"]["AliasDefDict"])
|
||||
"ArgList":[], // Args list
|
||||
"ArgDict":{"inCMDStr":lCMDCode,"inRunAsyncBool":false}, // Args dictionary
|
||||
"ArgGSettings": null, // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
|
||||
"ArgLogger": "inLogger" // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
|
||||
}
|
||||
]
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '/pyOpenRPA/ActivityListExecute',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///Отправить запрос на формирование таблицы
|
||||
//lHTMLCode=console.log("CMDRun result: "+lResponseJSON[0].result)
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
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('"', "\\\"");
|
||||
///Подготовить конфигурацию
|
||||
lData = [
|
||||
{"Type":"CMDStart", "Command": lCMDCode }
|
||||
]
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///Отправить запрос на формирование таблицы
|
||||
//lHTMLCode=console.log("CMDRun result: "+lResponseJSON[0].result)
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
///Restart PC
|
||||
mGlobal.Controller.PCRestart = function () {
|
||||
mGlobal.Controller.OrchestratorSessionSave()
|
||||
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
|
||||
mGlobal.Controller.OrchestratorRestart=function() {
|
||||
///Подготовить конфигурацию
|
||||
lData = [
|
||||
{"Type":"OrchestratorRestart"}
|
||||
]
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
},
|
||||
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
|
||||
//////////////////////////
|
||||
mGlobal.Monitor={};
|
||||
mGlobal.Monitor.ScreenshotModal={};
|
||||
mGlobal.Monitor.GenerateUniqueID=function(inPrefix="tempUID=") {
|
||||
return inPrefix+Math.round(Math.random()*1000)+"-"+Math.round(Math.random()*10000)+"-"+Math.round(Math.random()*1000)
|
||||
}
|
||||
//inHostURI: http://localhost:8081
|
||||
mGlobal.Monitor.ScreenshotModal.Show=function(inHostURI=" ") {
|
||||
$('.ui.modal.daemon-screenshot').modal({'onHide':function (inElement) {mGlobal.Monitor.ScreenshotModal.Close();} }).modal('show');
|
||||
|
||||
//Функция обновления картинки
|
||||
lScreenshotUpdate=function() {
|
||||
lScreenshotSrc=inHostURI+"/GetScreenshot?"+mGlobal.Monitor.GenerateUniqueID()
|
||||
$(".daemon-screenshot img").attr('src', lScreenshotSrc);
|
||||
}
|
||||
|
||||
mGlobal.Monitor.ScreenshotModal.timerId=setInterval(lScreenshotUpdate,1500)
|
||||
}
|
||||
mGlobal.Monitor.ScreenshotModal.Close=function() {
|
||||
clearInterval(mGlobal.Monitor.ScreenshotModal.timerId);
|
||||
}
|
||||
///Monitor
|
||||
mGlobal.Monitor.DaemonList={}
|
||||
mGlobal.Monitor.DaemonList.fRefreshTable=function() {
|
||||
///Загрузка данных
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: 'Monitor/JSONDaemonListGet',
|
||||
data: '',
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///Сформировать HTML код новой таблицы
|
||||
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-monitor-table-general",lResponseJSON)
|
||||
///Очистить дерево
|
||||
//mGlobal.ElementTree.fClear();
|
||||
///Прогрузить новую таблицу
|
||||
$(".openrpa-monitor").html(lHTMLCode)
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
////////////////////////////////
|
||||
///////Control panel
|
||||
///////////////////////////////
|
||||
///Refresh control panel
|
||||
function sleep(ms) {
|
||||
ms += new Date().getTime();
|
||||
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.RobotRDPActive = {}
|
||||
mGlobal.Monitor.fControlPanelRefresh_TechnicalRender = function()
|
||||
{
|
||||
lResponseJSON = mGlobal.Monitor.mDatasetLast
|
||||
|
||||
if (lResponseJSON!= null) {
|
||||
/// New version of control panels
|
||||
for (var lKeyStr in lResponseJSON){
|
||||
if (lKeyStr != "RenderRobotList") { /// Check if not "RenderRobotList"
|
||||
lCPDict = lResponseJSON[lKeyStr]
|
||||
/// Render HTML
|
||||
if ("HTMLStr" in lCPDict) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// v1.2.0 Backward compatibility - support old control panels
|
||||
if ("RenderRobotList" in lResponseJSON) {
|
||||
///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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
||||
lItem["OnClick"] = lOnClickEscaped;
|
||||
}
|
||||
}
|
||||
);
|
||||
/// FooterButtonX1List
|
||||
lItem["FooterButtonX1List"].forEach(
|
||||
function(lItem2){
|
||||
if ('OnClick' in lItem) {
|
||||
lOnClickEscaped = lItem["OnClick"];
|
||||
lOnClickEscaped = lOnClickEscaped.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
||||
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)
|
||||
////////////////////////////////////////////////////
|
||||
/// !RDP List ! Сформировать 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();
|
||||
////////////////////////////////////////////////////
|
||||
/// !UserAgent List ! Сформировать HTML код новой таблицы - список RDP
|
||||
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".pyOpenRPA-Agent-ListTemplate",lResponseJSON)
|
||||
//Присвоить ответ в mGlobal.RobotRDPActive.mResponseList
|
||||
mGlobal.RobotRDPActive.mResponseList = lResponseJSON
|
||||
///Прогрузить новую таблицу
|
||||
$(".pyOpenRPA-Agent-List").html(lHTMLCode)
|
||||
///Очистить дерево
|
||||
//mGlobal.ElementTree.fClear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///v 1.2.0 pyOpenRPA
|
||||
/// Execute ActivityItem
|
||||
mGlobal.pyOpenRPA.ActivityItemExecute=function(inActivityItem) {
|
||||
///EXAMPLE
|
||||
// {
|
||||
// "Def":"OSCMD", // def link or def alias (look gSettings["Processor"]["AliasDefDict"])
|
||||
// "ArgList":[], // Args list
|
||||
// "ArgDict":{"inCMDStr":lCMDCode,"inRunAsyncBool":false}, // Args dictionary
|
||||
// "ArgGSettings": null, // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
|
||||
// "ArgLogger": "inLogger" // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
|
||||
// }
|
||||
///Подготовить конфигурацию
|
||||
lData = [inActivityItem]
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '/pyOpenRPA/ActivityListExecute',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
console.log(lResponseJSON)
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
/// Execute ActivityList
|
||||
mGlobal.pyOpenRPA.ActivityListExecute=function(inActivityList) {
|
||||
///EXAMPLE
|
||||
// [{
|
||||
// "Def":"OSCMD", // def link or def alias (look gSettings["Processor"]["AliasDefDict"])
|
||||
// "ArgList":[], // Args list
|
||||
// "ArgDict":{"inCMDStr":lCMDCode,"inRunAsyncBool":false}, // Args dictionary
|
||||
// "ArgGSettings": null, // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
|
||||
// "ArgLogger": "inLogger" // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
|
||||
// }]
|
||||
///Подготовить конфигурацию
|
||||
lData = inActivityList
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '/pyOpenRPA/ActivityListExecute',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
console.log(lResponseJSON)
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
/// Add ActivityList in processor queue
|
||||
mGlobal.pyOpenRPA.ProcessorQueueAdd=function(inActivityList) {
|
||||
///EXAMPLE
|
||||
// [{
|
||||
// "Def":"OSCMD", // def link or def alias (look gSettings["Processor"]["AliasDefDict"])
|
||||
// "ArgList":[], // Args list
|
||||
// "ArgDict":{"inCMDStr":lCMDCode,"inRunAsyncBool":false}, // Args dictionary
|
||||
// "ArgGSettings": null, // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
|
||||
// "ArgLogger": "inLogger" // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
|
||||
// }]
|
||||
///Подготовить конфигурацию
|
||||
lData = inActivityList
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '/pyOpenRPA/ProcessorQueueAdd',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
console.log(lResponseJSON)
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
|
||||
/// v1.2.0 pyOpenRPA ServerJSInit
|
||||
mGlobal.pyOpenRPA.ServerJSInitDef=function() {
|
||||
try {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
headers: {},
|
||||
url: 'pyOpenRPA/ServerJSInit',
|
||||
data: mGlobal.pyOpenRPA.ServerDataHashStr,
|
||||
async: false,
|
||||
success: function(lJSText) {
|
||||
try {
|
||||
eval(lJSText)
|
||||
}
|
||||
catch(error) {
|
||||
console.log(error)
|
||||
}
|
||||
},
|
||||
dataType: "text",
|
||||
error: function(jqXHR, textStatus, errorThrown ) {
|
||||
console.log(textStatus)
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
/// v1.2.0 pyOpenRPA ServerData
|
||||
mGlobal.pyOpenRPA.ServerDataDict = null
|
||||
mGlobal.pyOpenRPA.ServerDataHashStr = ""
|
||||
mGlobal.pyOpenRPA.ServerDataRefreshDef_TechnicalRender = function()
|
||||
{
|
||||
lResponseJSON = mGlobal.pyOpenRPA.ServerDataDict
|
||||
if (lResponseJSON!= null) {
|
||||
/// New version of control panels
|
||||
lHTMLCode = '<div class="ui cards">'
|
||||
for (var lKeyStr in lResponseJSON["CPDict"]){
|
||||
lCPDict = lResponseJSON["CPDict"][lKeyStr]
|
||||
/// Render HTML
|
||||
if ("HTMLStr" in lCPDict) {
|
||||
lHTMLCode+=lCPDict["HTMLStr"]
|
||||
}
|
||||
}
|
||||
lHTMLCode += '</div>'
|
||||
///Прогрузить новую таблицу
|
||||
$(".openrpa-control-panel").html(lHTMLCode)
|
||||
////////////////////////////////////////////////////
|
||||
/// !RDP List ! Сформировать HTML код новой таблицы - список RDP
|
||||
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-hidden-robotrdpactive-control-panel",lResponseJSON["RDPDict"])
|
||||
//Присвоить ответ в mGlobal.RobotRDPActive.mResponseList
|
||||
mGlobal.RobotRDPActive.mResponseList = lResponseJSON["RDPDict"]
|
||||
///Прогрузить новую таблицу
|
||||
$(".openrpa-robotrdpactive-control-panel").html(lHTMLCode)
|
||||
///Очистить дерево
|
||||
//mGlobal.ElementTree.fClear();
|
||||
////////////////////////////////////////////////////
|
||||
/// !UserAgent List ! Сформировать HTML код новой таблицы - список RDP
|
||||
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".pyOpenRPA-Agent-ListTemplate",lResponseJSON["AgentDict"])
|
||||
///Прогрузить новую таблицу
|
||||
$(".pyOpenRPA-Agent-List").html(lHTMLCode)
|
||||
///Очистить дерево
|
||||
//mGlobal.ElementTree.fClear();
|
||||
}
|
||||
}
|
||||
mGlobal.pyOpenRPA.ServerDataRefreshDef=function() {
|
||||
try {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
headers: {},
|
||||
url: 'pyOpenRPA/ServerData',
|
||||
data: mGlobal.pyOpenRPA.ServerDataHashStr,
|
||||
success: function(lData,l2,l3) {
|
||||
try {
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
mGlobal.VersionStr = lResponseJSON["ServerDataDict"]["UserDict"]["VersionStr"]
|
||||
mGlobal.pyOpenRPA.ServerDataDict = lResponseJSON["ServerDataDict"]
|
||||
mGlobal.pyOpenRPA.ServerDataHashStr = lResponseJSON["HashStr"]
|
||||
mGlobal.pyOpenRPA.ServerDataRefreshDef_TechnicalRender()
|
||||
mGlobal.UserRoleUpdate();
|
||||
setTimeout(mGlobal.pyOpenRPA.ServerDataRefreshDef,600) // If LOGS are update every ms - set some limit in ms on the client side
|
||||
//mGlobal.pyOpenRPA.ServerDataRefreshDef() // Go to the next call
|
||||
}
|
||||
catch(error) {
|
||||
console.log(error)
|
||||
setTimeout(mGlobal.pyOpenRPA.ServerDataRefreshDef,3000)
|
||||
}
|
||||
//mGlobal.pyOpenRPA.ServerDataRefreshDef() // recursive
|
||||
},
|
||||
dataType: "text",
|
||||
error: function(jqXHR, textStatus, errorThrown ) {
|
||||
setTimeout(mGlobal.pyOpenRPA.ServerDataRefreshDef,3000)
|
||||
//sleep(3000)
|
||||
//mGlobal.pyOpenRPA.ServerDataRefreshDef() // recursive
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(error) {
|
||||
setTimeout(mGlobal.pyOpenRPA.ServerDataRefreshDef,3000)
|
||||
//sleep(3000)
|
||||
//mGlobal.pyOpenRPA.ServerDataRefreshDef() // recursive
|
||||
}
|
||||
}
|
||||
/////////////////////////////////////////////////////////////
|
||||
/// v1.2.0 pyOpenRPA ServerLogs
|
||||
mGlobal.pyOpenRPA.ServerLogList = null
|
||||
mGlobal.pyOpenRPA.ServerLogListHashStr = ""
|
||||
mGlobal.pyOpenRPA.ServerLogListDoRenderBool = true
|
||||
///Turn OFF rendering
|
||||
mGlobal.pyOpenRPA.ServerLogListDoRenderFalse = function() {
|
||||
///Set unfreeze button
|
||||
$("a.mGlobal-pyOpenRPA-ServerLogListDoRender").html("Unfreeze textarea")
|
||||
$("a.mGlobal-pyOpenRPA-ServerLogListDoRender").attr("onclick","mGlobal.pyOpenRPA.ServerLogListDoRenderTrue()")
|
||||
$("textarea.mGlobal-pyOpenRPA-ServerLogList").css("background-color","#b9e2e8")
|
||||
mGlobal.pyOpenRPA.ServerLogListDoRenderBool = false
|
||||
}
|
||||
///Turn ON rendering
|
||||
mGlobal.pyOpenRPA.ServerLogListDoRenderTrue = function() {
|
||||
mGlobal.pyOpenRPA.ServerLogListDoRenderBool = true
|
||||
///Render last data
|
||||
mGlobal.pyOpenRPA.ServerLogListRefreshDef_TechnicalRender()
|
||||
///Set unfreeze button
|
||||
$("a.mGlobal-pyOpenRPA-ServerLogListDoRender").html("Freeze textarea")
|
||||
$("a.mGlobal-pyOpenRPA-ServerLogListDoRender").attr("onclick","mGlobal.pyOpenRPA.ServerLogListDoRenderFalse()")
|
||||
$("textarea.mGlobal-pyOpenRPA-ServerLogList").css("background-color","")
|
||||
|
||||
}
|
||||
mGlobal.pyOpenRPA.ServerLogListScrollBottomDef = function() {
|
||||
var lTA = $("textarea.mGlobal-pyOpenRPA-ServerLogList")[0];
|
||||
lTA.scrollTop = lTA.scrollHeight;
|
||||
}
|
||||
mGlobal.pyOpenRPA.ServerLogListRefreshDef_TechnicalRender = function()
|
||||
{
|
||||
lResponseJSON = mGlobal.pyOpenRPA.ServerLogList
|
||||
if (lResponseJSON!= null && mGlobal.pyOpenRPA.ServerLogListDoRenderBool==true) {
|
||||
lText = lResponseJSON.join("\n") /// Code for the processing the text
|
||||
$("textarea.mGlobal-pyOpenRPA-ServerLogList")[0].value= lText ///Прогрузить новую таблицу
|
||||
mGlobal.pyOpenRPA.ServerLogListScrollBottomDef() //Scroll to the bottom
|
||||
}
|
||||
}
|
||||
mGlobal.pyOpenRPA.ServerLogListRefreshDef=function() {
|
||||
try {
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
headers: {},
|
||||
url: 'pyOpenRPA/ServerLog',
|
||||
data: mGlobal.pyOpenRPA.ServerLogListHashStr,
|
||||
success: function(lData,l2,l3) {
|
||||
try {
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
mGlobal.pyOpenRPA.ServerLogList = lResponseJSON["ServerLogList"]
|
||||
mGlobal.pyOpenRPA.ServerLogListHashStr = lResponseJSON["HashStr"]
|
||||
mGlobal.pyOpenRPA.ServerLogListRefreshDef_TechnicalRender()
|
||||
}
|
||||
catch(error) {
|
||||
}
|
||||
setTimeout(mGlobal.pyOpenRPA.ServerLogListRefreshDef,600) // If LOGS are update every ms - set some limit in ms on the client side
|
||||
//mGlobal.pyOpenRPA.ServerLogListRefreshDef() // recursive
|
||||
},
|
||||
dataType: "text",
|
||||
error: function(jqXHR, textStatus, errorThrown ) {
|
||||
setTimeout(mGlobal.pyOpenRPA.ServerLogListRefreshDef,3000)
|
||||
//sleep(3000)
|
||||
//mGlobal.pyOpenRPA.ServerLogListRefreshDef() // recursive
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(error) {
|
||||
setTimeout(mGlobal.pyOpenRPA.ServerLogListRefreshDef,3000)
|
||||
//sleep(3000)
|
||||
//mGlobal.pyOpenRPA.ServerLogListRefreshDef() // recursive
|
||||
}
|
||||
}
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
mGlobal.Monitor.mDatasetLast = null
|
||||
|
||||
///////////////////////////////
|
||||
///Processor functions
|
||||
///////////////////////////////
|
||||
mGlobal.Processor = {}
|
||||
mGlobal.Processor.ServerValueAppend = function(inKeyList,inValue) {
|
||||
lData = [
|
||||
{
|
||||
"Type":"GlobalDictKeyListValueAppend",
|
||||
"KeyList": inKeyList,
|
||||
"Value": inValue
|
||||
}
|
||||
]
|
||||
///Обнулить таблицу
|
||||
$('.ui.modal.basic .content').html("");
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///TODO Show error if exist error
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
mGlobal.Processor.ServerValueSet = function(inKeyList,inValue) {
|
||||
lData = [
|
||||
{
|
||||
"Type":"GlobalDictKeyListValueSet",
|
||||
"KeyList": inKeyList,
|
||||
"Value": inValue
|
||||
}
|
||||
]
|
||||
///Обнулить таблицу
|
||||
$('.ui.modal.basic .content').html("");
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///TODO Show error if exist error
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
mGlobal.Processor.ServerValueOperatorPlus = function(inKeyList,inValue) {
|
||||
lData = [
|
||||
{
|
||||
"Type":"GlobalDictKeyListValueOperator+",
|
||||
"KeyList": inKeyList,
|
||||
"Value": inValue
|
||||
}
|
||||
]
|
||||
///Обнулить таблицу
|
||||
$('.ui.modal.basic .content').html("");
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///TODO Show error if exist error
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
mGlobal.Processor.Send = function(inData) {
|
||||
lData = inData
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: 'Utils/Processor',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
///TODO Show error if exist error
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
mGlobal.Server= {}
|
||||
mGlobal.Server.JSONGet=function(inMethod, inURL, inDataJSON, inCallback)
|
||||
{
|
||||
$.ajax({
|
||||
type: inMethod,
|
||||
url: inURL,
|
||||
data: JSON.stringify(inDataJSON),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
inCallback(lResponseJSON)
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
|
||||
/////////////////
|
||||
///Modal
|
||||
///////////////////
|
||||
mGlobal.Modal={}
|
||||
/////////////////////////////////////////////////////
|
||||
mGlobal.Modal.TableFilter={}
|
||||
mGlobal.Modal.TableFilter.Show=function(inJSON) {
|
||||
//{
|
||||
// "Title":"",
|
||||
// "Headers":["Header1","Header2"],
|
||||
// "Rows": [["Cell1","Cell2"],["Cell2-1","Cell2-2"]],
|
||||
// "FilterOnKeyUp": "<JS Code>" //Fill here in function
|
||||
//}
|
||||
//Set js handler to Search field
|
||||
inJSON["FilterOnKeyUp"]="mGlobal.Modal.TableFilter.FilterUpdate(this.value);"
|
||||
///Set value
|
||||
mGlobal.Modal.TableFilter.mDataJSON = inJSON
|
||||
//Render HTML
|
||||
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-handlebar-template-table-filter",inJSON);
|
||||
///Установить HTML код
|
||||
$('.ui.modal.basic .content').html(lHTMLCode);
|
||||
$('.ui.modal.basic').modal('show');
|
||||
//DO widest modal for table with scroll x
|
||||
$("div.ui.basic.modal.transition.visible.active.scrolling")[0].style["width"]="1300px"
|
||||
$("div.ui.basic.modal.transition.visible.active.scrolling")[0].style["overflow"]="scroll"
|
||||
}
|
||||
//Service function
|
||||
mGlobal.Modal.TableFilter.FilterUpdate=function(inFilterValue) {
|
||||
//Get JSON, apply filter, clone data
|
||||
lDataJSON = clone(mGlobal.Modal.TableFilter.mDataJSON)
|
||||
delete lDataJSON["Rows"]
|
||||
lDataJSON["Rows"]=[]
|
||||
//Filter code [any occurence in the row is ok for push! ]
|
||||
mGlobal.Modal.TableFilter.mDataJSON["Rows"].forEach(
|
||||
function(inElement) {
|
||||
lFlagElementAppend = false
|
||||
inElement.forEach(
|
||||
function(inElement2) {
|
||||
if (String(inElement2).includes(inFilterValue)) {
|
||||
lFlagElementAppend = true
|
||||
}
|
||||
}
|
||||
)
|
||||
if (lFlagElementAppend) {
|
||||
lDataJSON["Rows"].push(inElement)
|
||||
}
|
||||
}
|
||||
)
|
||||
//Clear Filter Title property (fixed in html)
|
||||
delete lDataJSON["FilterOnKeyUp"]
|
||||
delete lDataJSON["Title"]
|
||||
//Search the table element [replace only table html]
|
||||
lElement = $('.ui.modals.active .content table.table')[0]
|
||||
lElementParentElement = lElement.parentNode
|
||||
lElement.parentNode.removeChild(lElement);
|
||||
//Render HTML
|
||||
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-handlebar-template-table-filter",lDataJSON);
|
||||
///Установить HTML код
|
||||
lElementParentElement.insertAdjacentHTML("beforeend",lHTMLCode);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////
|
||||
mGlobal.Modal.ListFilter={}
|
||||
mGlobal.Modal.ListFilter.Show=function(inJSON) {
|
||||
//{
|
||||
// "Title":"",
|
||||
// "List":[{"Header":"","Description":""}],
|
||||
// "FilterOnKeyUp": "<JS Code>" //Fill here in function
|
||||
//}
|
||||
//Set js handler to Search field
|
||||
inJSON["FilterOnKeyUp"]="mGlobal.Modal.ListFilter.FilterUpdate(this.value);"
|
||||
///Set value
|
||||
mGlobal.Modal.ListFilter.mDataJSON = inJSON
|
||||
//Render HTML
|
||||
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-handlebar-template-list-filter",inJSON);
|
||||
///Установить HTML код
|
||||
$('.ui.modal.basic .content').html(lHTMLCode);
|
||||
$('.ui.modal.basic').modal('show');
|
||||
}
|
||||
//Service function
|
||||
mGlobal.Modal.ListFilter.FilterUpdate=function(inFilterValue) {
|
||||
//Get JSON, apply filter, clone data
|
||||
lDataJSON = clone(mGlobal.Modal.ListFilter.mDataJSON)
|
||||
delete lDataJSON["List"]
|
||||
lDataJSON["List"]=[]
|
||||
//Filter code [any occurence in the row is ok for push! ]
|
||||
mGlobal.Modal.ListFilter.mDataJSON["List"].forEach(
|
||||
function(inElement) {
|
||||
lFlagElementAppend = false
|
||||
if (String(inElement["Header"]).includes(inFilterValue)) {
|
||||
lFlagElementAppend = true
|
||||
}
|
||||
if (String(inElement["Description"]).includes(inFilterValue)) {
|
||||
lFlagElementAppend = true
|
||||
}
|
||||
if (lFlagElementAppend) {
|
||||
lDataJSON["List"].push(inElement)
|
||||
}
|
||||
}
|
||||
)
|
||||
//Clear Filter Title property (fixed in html)
|
||||
delete lDataJSON["FilterOnKeyUp"]
|
||||
delete lDataJSON["Title"]
|
||||
//Search the table element [replace only table html]
|
||||
lElement = $('.ui.modals.active .content div.ui.inverted.segment')[0]
|
||||
lElementParentElement = lElement.parentNode
|
||||
lElement.parentNode.removeChild(lElement);
|
||||
//Render HTML
|
||||
lHTMLCode=mGlobal.GeneralGenerateHTMLCodeHandlebars(".openrpa-handlebar-template-list-filter",lDataJSON);
|
||||
///Установить HTML код
|
||||
lElementParentElement.insertAdjacentHTML("beforeend",lHTMLCode);
|
||||
}
|
||||
mGlobal.UserRoleHierarchyDict = null // Put here the user role hierarchy
|
||||
// UAC Ask
|
||||
mGlobal.UserRoleAsk=function(inList) {
|
||||
var lResult = true; // Init flag
|
||||
var lRoleHierarchyDict = mGlobal.pyOpenRPA.ServerDataDict.UserDict.UACClientDict; // get the Hierarchy
|
||||
// Try to get value from key list
|
||||
var lKeyValue = lRoleHierarchyDict; // Init the base
|
||||
var lListLength = inList.length;
|
||||
for (var i = 0; i<lListLength; i++) {
|
||||
var lItem = inList[i]; // get the item
|
||||
if (typeof lKeyValue == "object") {
|
||||
if (lItem in lKeyValue) { // Has key
|
||||
lKeyValue = lKeyValue[lItem]; // Get the value and go to the next loop iteration
|
||||
} else { // Else branch - true or false
|
||||
if (Object.keys(lKeyValue).length > 0) { // false - if Dict has some elements
|
||||
lResult = false; // Set the False Flag
|
||||
} else {
|
||||
lResult = true; // Set the true flag
|
||||
}
|
||||
break; // Stop the loop
|
||||
}
|
||||
} else { // Has element with no detalization - return true
|
||||
lResult = true; // Set the flag
|
||||
break; // Close the loop
|
||||
}
|
||||
}
|
||||
return lResult; // Return the result
|
||||
}
|
||||
// Check user roles and update the Orchestrator UI
|
||||
mGlobal.UserRoleUpdate=function() {
|
||||
var lUACAsk = mGlobal.UserRoleAsk // Alias
|
||||
//CPKeyDict
|
||||
if (lUACAsk(["pyOpenRPADict","CPKeyDict"])) { $(".UACClient-pyOpenRPADict-CPKeyDict").show(); }
|
||||
|
||||
//RDPKeyDict
|
||||
if (lUACAsk(["pyOpenRPADict","RDPKeyDict"])) { $(".UACClient-pyOpenRPADict-RDPKeyDict").show(); }
|
||||
|
||||
//AgentKeyDict
|
||||
if (lUACAsk(["pyOpenRPADict","AgentKeyDict"])) { $(".UACClient-pyOpenRPADict-AgentKeyDict").show(); }
|
||||
|
||||
// AdminDict
|
||||
if (lUACAsk(["pyOpenRPADict","AdminDict","LogViewerBool"])) { $(".UACClient-pyOpenRPADict-AdminDict-LogViewerBool").show(); }
|
||||
if (lUACAsk(["pyOpenRPADict","AdminDict","CMDInputBool"])) { $(".UACClient-pyOpenRPADict-AdminDict-CMDInputBool").show(); }
|
||||
if (lUACAsk(["pyOpenRPADict","AdminDict","ScreenshotViewerBool"])) { $(".UACClient-pyOpenRPADict-AdminDict-ScreenshotViewerBool").show(); }
|
||||
if (lUACAsk(["pyOpenRPADict","AdminDict","RestartOrchestratorBool"])) { $(".UACClient-pyOpenRPADict-AdminDict-RestartOrchestratorBool").show(); }
|
||||
if (lUACAsk(["pyOpenRPADict","AdminDict","RestartOrchestratorGITPullBool"])) { $(".UACClient-pyOpenRPADict-AdminDict-RestartOrchestratorGITPullBool").show(); }
|
||||
if (lUACAsk(["pyOpenRPADict","AdminDict","RestartPCBool"])) { $(".UACClient-pyOpenRPADict-AdminDict-RestartPCBool").show(); }
|
||||
if (lUACAsk(["pyOpenRPADict","AdminDict","Debugging"])) { $(".UACClient-pyOpenRPADict-AdminDict-Debugging").show(); }
|
||||
|
||||
}
|
||||
|
||||
/// v1.2.0 pyOpenRPA Init defs
|
||||
mGlobal.pyOpenRPA.ServerDataRefreshDef(); // Init the refresh data def from server side
|
||||
mGlobal.pyOpenRPA.ServerLogListRefreshDef(); // Init the refresh data def from the log window
|
||||
mGlobal.pyOpenRPA.ServerLogListDoRenderTrue(); // Init button to freeze/unfreeze textare with logs
|
||||
mGlobal.pyOpenRPA.ServerJSInitDef(); // Recieve JS from server (if exist) and then call anothe url ServerData
|
||||
//$('.ui.dropdown').dropdown();
|
||||
|
||||
////////////////////////////////////////////
|
||||
// 1.2.7 Debugging
|
||||
/// Execute ActivityItem
|
||||
|
||||
// Debugging onchange def autofill init
|
||||
var lDropdownOnChange = function(inEvent){
|
||||
//lValueStr = inEvent.target.value
|
||||
lValueStr = inEvent
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: '/pyOpenRPA/Debugging/HelperDefAutofill/'+lValueStr,
|
||||
data: null,
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
console.log("HelperDefAutofill:")
|
||||
console.log(lResponseJSON)
|
||||
//ArgDict merge
|
||||
var lArgDictTargetDict = lResponseJSON["ArgDict"]
|
||||
var lArgDictStr = $(".mGlobal-pyOpenRPA-Debugging-ArgDict")[0].value
|
||||
if (lArgDictStr !="" && lArgDictStr !=null) {
|
||||
lArgDictLastDict = JSON.parse(lArgDictStr)
|
||||
lArgDictTargetDict = mGlobal.pyOpenRPA.DebuggingAutofillMerge(lArgDictTargetDict, lArgDictLastDict)
|
||||
}
|
||||
|
||||
$(".mGlobal-pyOpenRPA-Debugging-ArgList")[0].value = JSON.stringify(lResponseJSON["ArgList"])
|
||||
$(".mGlobal-pyOpenRPA-Debugging-ArgDict")[0].value = JSON.stringify(lArgDictTargetDict)
|
||||
$(".mGlobal-pyOpenRPA-Debugging-ArgGSettingsStr")[0].value = JSON.stringify(lResponseJSON["ArgGSettingsStr"])
|
||||
$(".mGlobal-pyOpenRPA-Debugging-ArgLoggerStr")[0].value = JSON.stringify(lResponseJSON["ArgLoggerStr"])
|
||||
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
//$('.ui.dropdown.mGlobal-pyOpenRPA-Debugging-Def-Dropdown')[0].onchange=lDropdownOnChange
|
||||
|
||||
|
||||
|
||||
mGlobal.pyOpenRPA.DebuggingExecute=function() {
|
||||
///EXAMPLE
|
||||
// {
|
||||
// "Def":"OSCMD", // def link or def alias (look gSettings["Processor"]["AliasDefDict"])
|
||||
// "ArgList":[], // Args list
|
||||
// "ArgDict":{"inCMDStr":lCMDCode,"inRunAsyncBool":false}, // Args dictionary
|
||||
// "ArgGSettings": null, // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
|
||||
// "ArgLogger": "inLogger" // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
|
||||
// }
|
||||
///Подготовить конфигурацию
|
||||
lArgListStr = $(".mGlobal-pyOpenRPA-Debugging-ArgList")[0].value
|
||||
lArgDictStr = $(".mGlobal-pyOpenRPA-Debugging-ArgDict")[0].value
|
||||
lArgGSettingsStr = $(".mGlobal-pyOpenRPA-Debugging-ArgGSettingsStr")[0].value
|
||||
lArgLoggerStr = $(".mGlobal-pyOpenRPA-Debugging-ArgLoggerStr")[0].value
|
||||
lActivityItem = {
|
||||
"Def":$(".mGlobal-pyOpenRPA-Debugging-Def")[0].value, // def link or def alias (look gSettings["Processor"]["AliasDefDict"])
|
||||
"ArgList":(lArgListStr == "" ? [] : JSON.parse(lArgListStr)), // Args list
|
||||
"ArgDict":(lArgDictStr == "" ? {} : JSON.parse(lArgDictStr)), // Args dictionary
|
||||
"ArgGSettingsStr": (lArgGSettingsStr == "" ? null : lArgGSettingsStr), // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
|
||||
"ArgLoggerStr": (lArgLoggerStr == "" ? null : lArgLoggerStr) // Name of GSettings attribute: str (ArgDict) or index (for ArgList)
|
||||
}
|
||||
lData = [lActivityItem]
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '/pyOpenRPA/ActivityListExecute',
|
||||
data: JSON.stringify(lData),
|
||||
success:
|
||||
function(lData,l2,l3)
|
||||
{
|
||||
var lResponseJSON=JSON.parse(lData)
|
||||
console.log(lResponseJSON)
|
||||
$(".mGlobal-pyOpenRPA-Debugging-Output")[0].value = JSON.stringify(lResponseJSON[0])
|
||||
},
|
||||
dataType: "text"
|
||||
});
|
||||
}
|
||||
mGlobal.pyOpenRPA.DebuggingAutofillMerge=function(inTargetDict, inLastDict) {
|
||||
// Merge 2 dict (get values from Last dict if key exists in new dict
|
||||
for (const [lKeyStr, lValue] of Object.entries(inTargetDict)) {
|
||||
//Check if key exists in LastDict
|
||||
if (lKeyStr in inLastDict) {
|
||||
inTargetDict[lKeyStr] = inLastDict[lKeyStr]
|
||||
}
|
||||
}
|
||||
return inTargetDict
|
||||
}
|
||||
// 1.2.7 Debugging toolbox init
|
||||
$('.ui.dropdown.mGlobal-pyOpenRPA-Debugging-Def-Dropdown')
|
||||
.dropdown({
|
||||
apiSettings: {
|
||||
// this url parses query server side and returns filtered results
|
||||
url: '/pyOpenRPA/Debugging/HelperDefList/{query}'
|
||||
},
|
||||
onChange: lDropdownOnChange
|
||||
})
|
||||
;
|
||||
});
|
@ -1,499 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" >
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>pyOpenRPA Orchestrator</title>
|
||||
<link rel="stylesheet" type="text/css" href="3rdParty/Semantic-UI-CSS-master/semantic.min.css">
|
||||
<script
|
||||
src="3rdParty/jQuery/jquery-3.1.1.min.js"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="3rdParty/Semantic-UI-CSS-master/semantic.min.js"></script>
|
||||
<script src="3rdParty/Handlebars/handlebars-v4.1.2.js"></script>
|
||||
<script src = "Index.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
.main.container {
|
||||
margin-top: 2em;
|
||||
}
|
||||
.overlay {
|
||||
float: left;
|
||||
margin: 0em 3em 1em 0em;
|
||||
}
|
||||
.overlay .menu {
|
||||
position: relative;
|
||||
left: 0;
|
||||
transition: left 0.5s ease;
|
||||
}
|
||||
.main.menu.fixed {
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #DDD;
|
||||
box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.overlay.fixed .menu {
|
||||
left: 800px;
|
||||
}
|
||||
.text.container .left.floated.image {
|
||||
margin: 2em 2em 2em -4em;
|
||||
}
|
||||
.text.container .right.floated.image {
|
||||
margin: 2em -4em 2em 2em;
|
||||
}
|
||||
.ui.footer.segment {
|
||||
margin: 5em 0em 0em;
|
||||
padding: 5em 0em;
|
||||
}
|
||||
.ui.search.dropdown>input.search {
|
||||
width:100%;
|
||||
font-family:monospace;
|
||||
font-weight: bold;
|
||||
}
|
||||
.ui.search.dropdown>.text {
|
||||
width:100%;
|
||||
font-family:monospace;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="ui internally celled grid">
|
||||
<div class="row black">
|
||||
<div class="sixteen wide column" style="display: flex;">
|
||||
<img src="pyOpenRPA_logo.png" width="70px;" height="70px"></img>
|
||||
|
||||
<h1 class="ui header inverted" style="cursor: pointer" onclick="window.open('https://gitlab.com/UnicodeLabs/OpenRPA','_blank');">pyOpenRPA</h1>
|
||||
<h5 style="cursor: pointer" onclick="window.open('https://www.facebook.com/RU.IT4Business','_blank');">by Ivan Maslov</h5>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h1 class="ui header inverted">ORCHESTRATOR WEB GUI</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="sixteen wide column openrpa-control-panel-general UACClient-pyOpenRPADict-CPKeyDict" style="display:none;" >
|
||||
<h4 class="ui horizontal divider header">
|
||||
<i class="clipboard list icon"></i>
|
||||
Dashboard (Robot control panel)
|
||||
</h4>
|
||||
<div class="openrpa-control-panel"></div>
|
||||
<script class="openrpa-hidden-control-panel" style="display:none" type="text/x-handlebars-template">
|
||||
<div class="ui cards">
|
||||
{{#RenderRobotList}}
|
||||
<div class="card">
|
||||
<div class="content">
|
||||
<div class="right floated mini ui ">
|
||||
{{{HeaderRightText}}}
|
||||
</div>
|
||||
<div class="header">
|
||||
{{{HeaderLeftText}}}
|
||||
|
||||
</div>
|
||||
<div class="meta">
|
||||
{{{SubheaderText}}}
|
||||
</div>
|
||||
<div class="description">
|
||||
<ul style="padding-inline-start:16px;margin:0px">
|
||||
{{#BodyKeyValueList}}
|
||||
<li>{{{Key}}}: {{{Value}}}</li>
|
||||
{{/BodyKeyValueList}}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="extra content">
|
||||
{{{FooterText}}}
|
||||
</div>
|
||||
<div class="extra content">
|
||||
<div class="ui two buttons">
|
||||
{{#FooterButtonX2List}}
|
||||
<div class="ui basic {{Color}} button" onclick="{{OnClick}}">{{{Text}}}</div>
|
||||
{{/FooterButtonX2List}}
|
||||
</div>
|
||||
<div class="ui horizontal divider">Add. controls</div>
|
||||
<div class="ui one buttons">
|
||||
{{#FooterButtonX1List}}
|
||||
<div class="ui basic {{Color}} button" onclick="{{OnClick}}">{{{Text}}}</div>
|
||||
{{/FooterButtonX1List}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/RenderRobotList}}
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<script class="openrpa-hidden-monitor-table-general" style="display:none" type="text/x-handlebars-template">
|
||||
<table class="ui celled table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Machine name</th>
|
||||
<th>Machihe host</th>
|
||||
<th>Status</th>
|
||||
<th>Actions,length: {{childs.length}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#ListenURLList}}
|
||||
<tr><td>{{Description}}</td><td>{{URL}}</td><td class="negative">None</td></tr>
|
||||
{{/ListenURLList}}
|
||||
</tbody>
|
||||
</table>
|
||||
</script>
|
||||
|
||||
<script class="openrpa-handlebar-template-table-filter" style="display:none" type="text/x-handlebars-template">
|
||||
{{#if Title}}
|
||||
<h1>{{{Title}}}</h1>
|
||||
{{/if}}
|
||||
{{#if FilterOnKeyUp}}
|
||||
<div class="ui icon input search" style="width:500px;">
|
||||
<input type="text" onkeyup="{{#if FilterOnKeyUp}}{{{FilterOnKeyUp}}}{{/if}}" placeholder="Search...">
|
||||
<i class="inverted circular search link icon"></i>
|
||||
</div>
|
||||
{{/if}}
|
||||
<table class="ui celled table selectable inverted">
|
||||
<thead>
|
||||
<tr>
|
||||
{{#Columns}}
|
||||
<th>{{{this}}}</th>
|
||||
{{/Columns}}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#Rows}}
|
||||
<tr>
|
||||
{{#this}}
|
||||
<td>
|
||||
{{{this}}}
|
||||
</td>
|
||||
{{/this}}
|
||||
</tr>
|
||||
{{/Rows}}
|
||||
</tbody>
|
||||
</table>
|
||||
</script>
|
||||
<script class="openrpa-handlebar-template-list-filter" style="display:none" type="text/x-handlebars-template">
|
||||
{{#if Title}}
|
||||
<h1>{{{Title}}}</h1>
|
||||
{{/if}}
|
||||
{{#if FilterOnKeyUp}}
|
||||
<div class="ui icon input search" style="width:500px;">
|
||||
<input type="text" onkeyup="{{#if FilterOnKeyUp}}{{{FilterOnKeyUp}}}{{/if}}" placeholder="Search...">
|
||||
<i class="inverted circular search link icon"></i>
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="ui inverted segment">
|
||||
<div class="ui inverted relaxed divided list">
|
||||
{{#List}}
|
||||
<div class="item">
|
||||
<i class="map marker icon"></i>
|
||||
<div class="content">
|
||||
<a class="header">{{{Header}}}</a>
|
||||
<div class="description">{{{Description}}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/List}}
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<div class="eight wide column openrpa-robotrdpactive-control-panel-general UACClient-pyOpenRPADict-RDPKeyDict" style="display:none;">
|
||||
<h2 class="ui header openrpa-rdpactive-title">
|
||||
<i class="desktop icon"></i>
|
||||
<div class="content">
|
||||
RDP active list
|
||||
</div>
|
||||
</h2>
|
||||
<div class="openrpa-robotrdpactive-control-panel"></div>
|
||||
<script class="openrpa-hidden-robotrdpactive-control-panel" style="display:none" type="text/x-handlebars-template">
|
||||
<div class="ui inverted segment" style="background: #368279">
|
||||
<div class="ui inverted relaxed divided list">
|
||||
{{#HandlebarsList}}
|
||||
<div class="item">
|
||||
<div class="right floated content">
|
||||
<div class="ui button" onclick="mGlobal.Processor.ServerValueAppend(['RobotRDPActive','ActivityList'],{'DefNameStr': 'RDPSessionReconnect', 'ArgList': [], 'ArgDict': {'inRDPSessionKeyStr': '{{{SessionKeyStr}}}'} })" >Reconnect</div>
|
||||
</div>
|
||||
<div class="right floated content">
|
||||
{{#if IsIgnoredBool}}
|
||||
<div class="ui button red" onclick="mGlobal.Processor.ServerValueSet(['RobotRDPActive','RDPList','{{{SessionKeyStr}}}','SessionIsIgnoredBool'],false);">Ignore</div>
|
||||
{{else}}
|
||||
<div class="ui button" onclick="mGlobal.Processor.ServerValueSet(['RobotRDPActive','RDPList','{{{SessionKeyStr}}}','SessionIsIgnoredBool'],true);">Ignore</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="right floated content">
|
||||
{{#if IsFullScreenBool}}
|
||||
<div class="ui button green" onclick="mGlobal.Processor.ServerValueSet(['RobotRDPActive','FullScreenRDPSessionKeyStr'],null);">Full screen</div>
|
||||
{{else}}
|
||||
<div class="ui button" onclick="mGlobal.Processor.ServerValueSet(['RobotRDPActive','FullScreenRDPSessionKeyStr'],'{{{SessionKeyStr}}}');">Full screen</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="header">Session key: {{{SessionKeyStr}}}</div>
|
||||
{{{SessionHexStr}}}
|
||||
</div>
|
||||
</div>
|
||||
{{/HandlebarsList}}
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
<div class="eight wide column UACClient-pyOpenRPADict-AgentKeyDict" style="display:none">
|
||||
<h2 class="ui header " style="">
|
||||
<i class="bug icon"></i>
|
||||
<div class="content">
|
||||
Agent active list
|
||||
</div>
|
||||
</h2>
|
||||
<div class="pyOpenRPA-Agent-List"></div>
|
||||
<script class="pyOpenRPA-Agent-ListTemplate" style="display:none" type="text/x-handlebars-template">
|
||||
<div class="ui inverted segment" style="background: #368279">
|
||||
<div class="ui inverted relaxed divided list">
|
||||
{{#HandlebarsList}}
|
||||
<div class="item">
|
||||
<div class="right floated content">
|
||||
{{#if IsListenBool}}
|
||||
<i class="circle icon green"></i>
|
||||
Online
|
||||
{{else}}
|
||||
<i class="circle icon red"></i>
|
||||
Offline
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="header">Hostname: {{{HostnameUpperStr}}}, User: {{{UserUpperStr}}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/HandlebarsList}}
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row openrpa-monitor">
|
||||
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="sixteen wide column" style="">
|
||||
<h2 class="ui header">
|
||||
<i class="settings icon"></i>
|
||||
<div class="content">
|
||||
Administration
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="sixteen wide column" style="">
|
||||
<h4 class="ui horizontal divider header" >
|
||||
<i class="clipboard list icon"></i>
|
||||
Logs
|
||||
</h4>
|
||||
|
||||
<textarea class="mGlobal-pyOpenRPA-ServerLogList UACClient-pyOpenRPADict-AdminDict-LogViewerBool" readonly="readonly" style="width:100%; display:none; resize: none; font-family:monospace; font-weight: bold;" id="textarea_id" rows="20">
|
||||
|
||||
</textarea>
|
||||
<a class="mGlobal-pyOpenRPA-ServerLogListDoRender" onclick="" style="cursor: pointer;">Freeze textarea</a>
|
||||
<div class="ui fluid action input UACClient-pyOpenRPADict-AdminDict-CMDInputBool" style="display:none;">
|
||||
<input class="openrpa-controller-cmd-run-input" type="text" placeholder="CMD Code...">
|
||||
<div class="ui button" onclick="mGlobal.Controller.CMDRun();">Run!</div>
|
||||
<div class="ui button" onclick="mGlobal.Controller.CMDRunGUILogout();">GUI Logout</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row UACClient-pyOpenRPADict-AdminDict-Debugging" style= "display:none;">
|
||||
<div class="twelve wide column">
|
||||
<h4 class="ui horizontal divider header" >
|
||||
<i class="bug icon"></i>
|
||||
Debugging - Send
|
||||
</h4>
|
||||
<div class="ui labeled input">
|
||||
<div class="ui label">Def</div>
|
||||
</div>
|
||||
<div class="ui fluid search selection dropdown mGlobal-pyOpenRPA-Debugging-Def-Dropdown" style="margin-bottom:10px;">
|
||||
<input class="mGlobal-pyOpenRPA-Debugging-Def" type="hidden" name="country" style="width:100%; font-family:monospace; font-weight: bold;">
|
||||
<i class="dropdown icon"></i>
|
||||
<div class="default text">Def</div>
|
||||
<div class="menu">
|
||||
<div class="item" data-value="eh">pyOpenRPA... sys.. os.. </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui fluid labeled input" style="margin-bottom:10px;">
|
||||
<div class="ui label">
|
||||
ArgList
|
||||
</div>
|
||||
<input type="text" placeholder="[1,2,3]" class="mGlobal-pyOpenRPA-Debugging-ArgList" style="width:100%; font-family:monospace; font-weight: bold;">
|
||||
</div>
|
||||
<div class="ui fluid labeled input" style="margin-bottom:10px;">
|
||||
<div class="ui label">
|
||||
ArgDict
|
||||
</div>
|
||||
<input type="text" placeholder="{"Key1":"Value1"}" class="mGlobal-pyOpenRPA-Debugging-ArgDict" style="width:100%; font-family:monospace; font-weight: bold;">
|
||||
</div>
|
||||
<div class="ui fluid labeled input" style="margin-bottom:10px;">
|
||||
<div class="ui label">
|
||||
ArgGSettingsStr
|
||||
</div>
|
||||
<input type="text" placeholder="inGSettings" class="mGlobal-pyOpenRPA-Debugging-ArgGSettingsStr" style="width:100%; font-family:monospace; font-weight: bold;">
|
||||
</div>
|
||||
<div class="ui fluid labeled input" style="margin-bottom:10px;">
|
||||
<div class="ui label">
|
||||
ArgLoggerStr
|
||||
</div>
|
||||
<input type="text" placeholder="inLogger" class="mGlobal-pyOpenRPA-Debugging-ArgLoggerStr" style="width:100%; font-family:monospace; font-weight: bold;">
|
||||
</div>
|
||||
<div class="ui fluid button" onclick="mGlobal.pyOpenRPA.DebuggingExecute();">Execute</div>
|
||||
</div>
|
||||
<div class="four wide column">
|
||||
<h4 class="ui horizontal divider header" >
|
||||
<i class="bug icon"></i>
|
||||
Debugging - Output
|
||||
</h4>
|
||||
<p><textarea class="mGlobal-pyOpenRPA-Debugging-Output" readonly="readonly" style="width:100%; font-family:monospace; font-weight: bold;" rows="16" cols="60"></textarea></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 class="ui horizontal divider header">
|
||||
<i class="clipboard list icon"></i>
|
||||
Controls
|
||||
</h4>
|
||||
<div class="four ui buttons">
|
||||
<div class="ui animated button openrpa-control-lookmachinescreenshot green UACClient-pyOpenRPADict-AdminDict-ScreenshotViewerBool" onclick="mGlobal.Monitor.ScreenshotModal.Show();" style="display: none; margin-top: 5px;">
|
||||
<div class="visible content">Show live screenshots</div>
|
||||
<div class="hidden content">
|
||||
<i class="right arrow icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui animated button openrpa-control-restartorchestrator orange UACClient-pyOpenRPADict-AdminDict-RestartOrchestratorBool" onclick="mGlobal.Controller.OrchestratorRestart();" style="display: none; margin-top: 5px;">
|
||||
<div class="visible content">Restart orchestrator</div>
|
||||
<div class="hidden content">
|
||||
<i class="right arrow icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui animated button openrpa-control-gitrestartorchestrator teal UACClient-pyOpenRPADict-AdminDict-RestartOrchestratorGITPullBool" onclick="mGlobal.Controller.OrchestratorGITPullRestart();" style="display: none; margin-top: 5px;">
|
||||
<div class="visible content">Git pull, restart orchestrator</div>
|
||||
<div class="hidden content">
|
||||
<i class="right arrow icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui animated button openrpa-control-restartpc red UACClient-pyOpenRPADict-AdminDict-RestartPCBool" onclick="mGlobal.Controller.PCRestart();" style="display: none; margin-top: 5px;">
|
||||
<div class="visible content">Restart PC</div>
|
||||
<div class="hidden content">
|
||||
<i class="right arrow icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row black">
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui inverted vertical footer segment">
|
||||
<div class="ui center aligned container">
|
||||
<div class="ui stackable inverted divided grid">
|
||||
<div class="three wide column">
|
||||
<h4 class="ui inverted header">Pywinauto</h4>
|
||||
<div class="ui inverted link list">
|
||||
<a href="https://pywinauto.readthedocs.io/en/latest/code/pywinauto.findwindows.html" class="item" target="_blank">Specification manual</a>
|
||||
<a href="https://pywinauto.readthedocs.io/en/latest/code/code.html#main-user-modules" class="item" target="_blank">Classes manual</a>
|
||||
<a href="https://pywinauto.readthedocs.io/en/latest/code/code.html#main-user-modules" class="item" target="_blank">How to use manual</a>
|
||||
<a href="https://pywinauto.readthedocs.io/en/latest/code/pywinauto.base_wrapper.html" class="item" target="_blank">Base wrapper manual</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="three wide column">
|
||||
<h4 class="ui inverted header">Semantic UI</h4>
|
||||
<div class="ui inverted link list">
|
||||
<a href="https://semantic-ui.com/usage/theming.html" class="item" target="_blank">Color manual</a>
|
||||
<a href="https://semantic-ui.com/elements/input.html" class="item" target="_blank">Input manual</a>
|
||||
<a href="https://semantic-ui.com/elements/icon.html" class="item" target="_blank">Icon list</a>
|
||||
<a href="https://semantic-ui.com/elements/button.html" class="item" target="_blank">Button manual</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="three wide column">
|
||||
<h4 class="ui inverted header">GitLab</h4>
|
||||
<div class="ui inverted link list">
|
||||
<a href="https://gitlab.com/UnicodeLabs/OpenRPA" class="item" target="_blank">pyOpenRPA repository</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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="seven wide column">
|
||||
<h4 class="ui inverted header">pyOpenRPA</h4>
|
||||
<p>Open source Robotic Process Automation software by the pyOpenRPA LLC (Created by Ivan Maslov in Russia). Licensed under LICENSE.PDF or https://pyopenrpa.ru/license/oferta.pdf #IT4Business</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui inverted section divider"></div>
|
||||
<div class="ui horizontal inverted small divided link list">
|
||||
<a class="item" href="#">Site Map</a>
|
||||
<a class="item" href="#">Contact Us</a>
|
||||
<a class="item" href="#">Terms and Conditions</a>
|
||||
<a class="item" href="#">Privacy Policy</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui basic modal">
|
||||
<div class="ui icon header">
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>Here is the message text!</p>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<div class="ui red basic cancel inverted button">
|
||||
<i class="remove icon"></i>
|
||||
No
|
||||
</div>
|
||||
<div class="ui green ok inverted button">
|
||||
<i class="checkmark icon"></i>
|
||||
Yes
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui daemon-screenshot modal">
|
||||
<div class="ui icon header">
|
||||
</div>
|
||||
<div class="content">
|
||||
<img src="GetScreenshot" class="ui fluid image">
|
||||
</div>
|
||||
<div class="actions">
|
||||
<div class="ui green ok inverted button" onclick="mGlobal.Monitor.ScreenshotModal.Close()">
|
||||
<i class="checkmark icon"></i>
|
||||
Close
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ui modal openrpa-code-list-gui-import-modal">
|
||||
<i class="close icon"></i>
|
||||
<div class="header">
|
||||
Code list import
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="description">
|
||||
<div class="ui header">Insert your JSON specification here.</div>
|
||||
<p><textarea style="width:100%" rows="6" cols="60"></textarea></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<div class="ui black deny button">
|
||||
Cancel
|
||||
</div>
|
||||
<div class="ui positive right labeled icon button" onclick="mGlobal.CodeList.fActionSpecificationImportFromJSON();">
|
||||
Parse
|
||||
<i class="checkmark icon"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 110 KiB |
Loading…
Reference in new issue