|
|
import psutil
|
|
|
import datetime
|
|
|
import logging
|
|
|
import os
|
|
|
import json
|
|
|
lProcessName = "OpenRPA_RobotRDPActive.exe"
|
|
|
lStartFilePath = os.path.join(os.getcwd(), "..\\Utils\\RobotRDPActive\\pyOpenRPA.Tools.RobotRDPActive_x64.cmd")
|
|
|
def RenderRobotRDPActive(inGlobalConfiguration):
|
|
|
#Subheader Variants
|
|
|
lSubheaderRunTrueText="State: <span style=\"color:green\">Turned on</span>"
|
|
|
lSubheaderRunFalseText="State: <span style=\"color:red\">Turned off</span>"
|
|
|
#Run button
|
|
|
#Такое большое количество слэшей связано с тем, что этот текст отправляется сначала в браузер, рендерится там, а потом отправляется на процессор оркестратора
|
|
|
lRobotRDPActivePath = f"start cmd /K {lStartFilePath}"
|
|
|
lOnClickRunButton=f"mGlobal.Controller.CMDRunText('{lRobotRDPActivePath}');"
|
|
|
#Safe turn off
|
|
|
lOnClickSafeTurnOff = "mGlobal.Processor.ServerValueSet(['Storage','RobotRDPActive','OrchestratorToRobotResetStorage','SafeTurnOff'],true);"
|
|
|
#Force close button
|
|
|
lOnClickForceCloseButton=f"mGlobal.Controller.CMDRunText('taskkill /F /im {lProcessName}');"
|
|
|
#Result template
|
|
|
lResultDict={
|
|
|
"HeaderLeftText":"Keep active RDP sessions",
|
|
|
"HeaderRightText":"Tech",
|
|
|
"DataStorageKey":"RobotRDPActive", #Use key for set current dict in mGlobal.DataStorage["DataStorageKey"] on client side
|
|
|
"SubheaderText":lSubheaderRunFalseText,
|
|
|
"BodyKeyValueList":[
|
|
|
{"Key":"Session list","Value":""}
|
|
|
],
|
|
|
"FooterText":"Last update: 9:38:00 09.10.2019",
|
|
|
"FooterButtonX2List":[
|
|
|
{"Text":"Turn on", "Color":"green", "Link":"", "OnClick": lOnClickRunButton.replace("\\","\\\\")},
|
|
|
{"Text":"Safe turn off", "Color":"orange", "Link":"", "OnClick": lOnClickSafeTurnOff.replace("\\","\\\\")}
|
|
|
],
|
|
|
"FooterButtonX1List":[
|
|
|
{"Text":"Kill", "Color":"red", "Link":"", "OnClick": lOnClickForceCloseButton.replace("\\","\\\\")}
|
|
|
]#,
|
|
|
#"GlobalStorage": inGlobalConfiguration.get("Storage",{})
|
|
|
}
|
|
|
#Read RDPList
|
|
|
lRDPList = inGlobalConfiguration.get("Storage",{}).get("RobotRDPActive",{}).get("RobotToOrchestratorStorage",{}).get("RDPList",[])
|
|
|
lFullScreenSessionIndex = inGlobalConfiguration.get("Storage",{}).get("RobotRDPActive",{}).get("RobotToOrchestratorStorage",{}).get("FullScreenSessionIndex",None)
|
|
|
lRDPListIndex = 0
|
|
|
for lItem in lRDPList:
|
|
|
#Lable that session has fullscreen
|
|
|
lLabelSessionFullScreen = ""
|
|
|
lLabelIsIgnored = ""
|
|
|
#Link set full screen
|
|
|
##############################
|
|
|
lOnClickSetFullScreen = f"mGlobal.Processor.ServerValueSet(['Storage','RobotRDPActive','OrchestratorToRobotStorage','FullScreenSessionIndex'],{lRDPListIndex});"
|
|
|
lSetFullScreenA = f'<a onclick="{lOnClickSetFullScreen}" style=\"color:blue\">Set fullscreen</a>'
|
|
|
if lRDPListIndex == lFullScreenSessionIndex:
|
|
|
lLabelSessionFullScreen = '<span style=\"color:blue\">[Fullscreen]</span>'
|
|
|
lOnClickSetFullScreen = f"mGlobal.Processor.ServerValueSet(['Storage','RobotRDPActive','OrchestratorToRobotStorage','FullScreenSessionIndex'],null);"
|
|
|
lSetFullScreenA = f'<a onclick="{lOnClickSetFullScreen}" style=\"color:blue\">Set minimized</a>'
|
|
|
#################################
|
|
|
lIgnoreIndexListOnClick = "$.ajax({type: 'POST', url: 'RobotRDPActive/IgnoreIndexListAppend', data: '"+str(lRDPListIndex)+"', success: function(lData,l2,l3){}, dataType: 'text'});"
|
|
|
lIgnoreIndexListLink = f'<a onclick="{lIgnoreIndexListOnClick}" style=\"color:red\">Ignore</a>'
|
|
|
#Check if in ignore
|
|
|
if lRDPListIndex in inGlobalConfiguration.get("Storage",{}).get("RobotRDPActive",{}).get("OrchestratorToRobotStorage",{}).get("IgnoreIndexList",[]):
|
|
|
lLabelIsIgnored = '<span style=\"color:red\">[Ignored]</span>'
|
|
|
lIgnoreIndexListOnClick = "$.ajax({type: 'POST', url: 'RobotRDPActive/IgnoreIndexListRemove', data: '"+str(lRDPListIndex)+"', success: function(lData,l2,l3){}, dataType: 'text'});"
|
|
|
lIgnoreIndexListLink = f'<a onclick="{lIgnoreIndexListOnClick}" style=\"color:red\">Unignore</a>'
|
|
|
################################
|
|
|
#Session state
|
|
|
lItemSessionState='<span style=\"color:red\">Disconnected</span>'
|
|
|
if lItem.get("FlagSessionIsActive",False):
|
|
|
lItemSessionState='<span style=\"color:green\">Connected</span>'
|
|
|
lResultDict["BodyKeyValueList"].append({"Key":f"[{str(lRDPListIndex)}]{lLabelSessionFullScreen}{lLabelIsIgnored}{lItem.get('Host','localhost')}:{lItem.get('Port','--')}","Value":f"{lItem.get('Login','--')}, {lItem.get('SessionHex','--')}, State {lItemSessionState}, {lSetFullScreenA}, {lIgnoreIndexListLink}"})
|
|
|
lRDPListIndex = lRDPListIndex + 1
|
|
|
#Check if process running
|
|
|
if CheckIfProcessRunning("OpenRPA_RobotRDPActive"):
|
|
|
lResultDict["SubheaderText"]=lSubheaderRunTrueText
|
|
|
#Process not running
|
|
|
lResultDict["FooterText"]=f'Last update: {datetime.datetime.now().strftime("%H:%M:%S %d.%m.%Y")}'
|
|
|
return lResultDict
|
|
|
#Add to ignore list
|
|
|
def IgnoreIndexListAppend(inRequest,inConfiguration):
|
|
|
lIgnoreList = inConfiguration["Storage"]["RobotRDPActive"]["OrchestratorToRobotStorage"]["IgnoreIndexList"]
|
|
|
lIgnoreIndex={}
|
|
|
if inRequest.headers.get('Content-Length') is not None:
|
|
|
lInputByteArrayLength = int(inRequest.headers.get('Content-Length'))
|
|
|
lInputByteArray=inRequest.rfile.read(lInputByteArrayLength)
|
|
|
#Превращение массива байт в объект
|
|
|
lIgnoreIndex=int(lInputByteArray.decode('utf8'))
|
|
|
#check if index not in list
|
|
|
if lIgnoreIndex not in lIgnoreList:
|
|
|
#append to list
|
|
|
lIgnoreList.append(lIgnoreIndex)
|
|
|
#remove from Ignore list
|
|
|
def IgnoreIndexListRemove(inRequest,inConfiguration):
|
|
|
lIgnoreList = inConfiguration["Storage"]["RobotRDPActive"]["OrchestratorToRobotStorage"]["IgnoreIndexList"]
|
|
|
lIgnoreIndex={}
|
|
|
if inRequest.headers.get('Content-Length') is not None:
|
|
|
lInputByteArrayLength = int(inRequest.headers.get('Content-Length'))
|
|
|
lInputByteArray=inRequest.rfile.read(lInputByteArrayLength)
|
|
|
#Превращение массива байт в объект
|
|
|
lIgnoreIndex=int(lInputByteArray.decode('utf8'))
|
|
|
#check if index not in list
|
|
|
if lIgnoreIndex in lIgnoreList:
|
|
|
#append to list
|
|
|
lIgnoreList.remove(lIgnoreIndex) #Remove delete the element lIgnoreIndex
|
|
|
def CheckIfProcessRunning(processName):
|
|
|
'''
|
|
|
Check if there is any running process that contains the given name processName.
|
|
|
'''
|
|
|
#Iterate over the all the running process
|
|
|
for proc in psutil.process_iter():
|
|
|
try:
|
|
|
# Check if process name contains the given name string.
|
|
|
if processName.lower() in proc.name().lower():
|
|
|
return True
|
|
|
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
|
pass
|
|
|
return False;
|
|
|
|
|
|
#Orchestrator settings
|
|
|
def SettingsUpdate(inDict):
|
|
|
#Add RobotRDPActive in control panel
|
|
|
inDict["ControlPanelDict"]["RobotList"].append({"RenderFunction": RenderRobotRDPActive})
|
|
|
#Default structure
|
|
|
inDict["Storage"]["RobotRDPActive"]={
|
|
|
"OrchestratorToRobotResetStorage":{"SafeTurnOff":False},
|
|
|
"OrchestratorToRobotStorage":{
|
|
|
"FullScreenSessionIndex":None,
|
|
|
"IgnoreIndexList": []
|
|
|
}
|
|
|
}
|
|
|
#Add methods
|
|
|
inDict["Server"]["URLList"].append(
|
|
|
{
|
|
|
"Method":"POST",
|
|
|
"URL": "/RobotRDPActive/IgnoreIndexListAppend", #URL of the request
|
|
|
"MatchType": "Equal", #"BeginWith|Contains|Equal|EqualCase",
|
|
|
"ResponseDefRequestGlobal": IgnoreIndexListAppend #Function with str result
|
|
|
}
|
|
|
)
|
|
|
inDict["Server"]["URLList"].append(
|
|
|
{
|
|
|
"Method":"POST",
|
|
|
"URL": "/RobotRDPActive/IgnoreIndexListRemove", #URL of the request
|
|
|
"MatchType": "Equal", #"BeginWith|Contains|Equal|EqualCase",
|
|
|
"ResponseDefRequestGlobal": IgnoreIndexListRemove #Function with str result
|
|
|
}
|
|
|
)
|
|
|
return inDict |