#DaemonServerPrototype #NeedPILToGetScreenshot #DaemonMultithreading #GeneralLibVerify

dev-linux
Ivan Maslov 6 years ago
parent 52416cdf47
commit 9f77336c4c

@ -152,11 +152,14 @@
var lSubItemActionOnRightClick=' oncontextmenu="mGlobal.ElementHighlightNew(\''+lElementId+'\');" ' var lSubItemActionOnRightClick=' oncontextmenu="mGlobal.ElementHighlightNew(\''+lElementId+'\');" '
var lIconSelectOnClick=' onclick="mGlobal.TreeObjectInfoLoad(\''+lElementId+'\');" ' var lIconSelectOnClick=' onclick="mGlobal.TreeObjectInfoLoad(\''+lElementId+'\');" '
var lIconTestOnClick=' onclick="mGlobal.Test(\''+lElementId+'\');" ' var lIconTestOnClick=' onclick="mGlobal.Test(\''+lElementId+'\');" '
var lIconUpOnClick=' onclick="mGlobal.Actions.fAutomationSearchMouseElementHierarchyRun(\''+lElementId+'\');" '
lHTMLTree+='\ lHTMLTree+='\
<div class="item handle_'+lSubItemHandleId+'" handle_id="'+lSubItemHandleId+'" id="'+lElementId+'">\ <div class="item handle_'+lSubItemHandleId+'" handle_id="'+lSubItemHandleId+'" id="'+lElementId+'">\
<i class="folder icon"></i>\ <i class="folder icon"></i>\
<i class="angle double right icon" '+lIconSelectOnClick+'></i>\ <i class="angle double right icon" '+lIconSelectOnClick+'></i>\
<i class="angle double right icon" '+lIconTestOnClick+'></i>\ <i class="angle double right icon" '+lIconTestOnClick+'></i>\
<i class="angle double up icon" '+lIconUpOnClick+'></i>\
<div class="content">\ <div class="content">\
<div class="header" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>'+lResponseJSON.outputObject[i].title+'</div>\ <div class="header" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>'+lResponseJSON.outputObject[i].title+'</div>\
<div class="description" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>process_id:'+lResponseJSON.outputObject[i].process_id+'; handle:'+lSubItemHandleId+'; class_name: '+lResponseJSON.outputObject[i].class_name+'; RECT:L'+lResponseJSON.outputObject[i].rectangle.left+' T'+lResponseJSON.outputObject[i].rectangle.top+' R'+lResponseJSON.outputObject[i].rectangle.right+' B'+lResponseJSON.outputObject[i].rectangle.bottom+'</div>\ <div class="description" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>process_id:'+lResponseJSON.outputObject[i].process_id+'; handle:'+lSubItemHandleId+'; class_name: '+lResponseJSON.outputObject[i].class_name+'; RECT:L'+lResponseJSON.outputObject[i].rectangle.left+' T'+lResponseJSON.outputObject[i].rectangle.top+' R'+lResponseJSON.outputObject[i].rectangle.right+' B'+lResponseJSON.outputObject[i].rectangle.bottom+'</div>\
@ -517,34 +520,11 @@
success: success:
function(lData,l2,l3) function(lData,l2,l3)
{ {
var lHTMLTree='<div class="ui list" style="height:350px;overflow:scroll;">'
var lResponseJSON=JSON.parse(lData) var lResponseJSON=JSON.parse(lData)
for (i=0;i<lResponseJSON.outputObject.length;i++) { ///Очистить дерево
var lElementId = mGlobal.GenerateUniqueID() mGlobal.ElementTree.fClear();
var lSubItemHandleId=lResponseJSON.outputObject[i].handle; ///Прогрузить новое дерево
var lSubItemActionOnClick=' onclick="mGlobal.TreeLoadSubTree(\''+lElementId+'\');" ' mGlobal.ElementTree.fRender(lResponseJSON.outputObject);
var lSubItemActionOnRightClick=' oncontextmenu="mGlobal.ElementHighlightNew(\''+lElementId+'\');" '
var lIconSelectOnClick=' onclick="mGlobal.TreeObjectInfoLoad(\''+lElementId+'\');" '
var lIconUpOnClick=' onclick="mGlobal.Actions.fAutomationSearchMouseElementHierarchyRun(\''+lElementId+'\');" '
lHTMLTree+='\
<div class="item" id="'+lElementId+'">\
<i class="folder icon"></i>\
<i class="angle double right icon" '+lIconSelectOnClick+'></i>\
<i class="angle double up icon" '+lIconUpOnClick+'></i>\
<div class="content">\
<div class="description" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>\
<b>'+lResponseJSON.outputObject[i].title+'</b>\
process_id:'+lResponseJSON.outputObject[i].process_id+'; handle:'+lSubItemHandleId+'; class_name: '+lResponseJSON.outputObject[i].class_name+'; RECT:L'+lResponseJSON.outputObject[i].rectangle.left+' T'+lResponseJSON.outputObject[i].rectangle.top+' R'+lResponseJSON.outputObject[i].rectangle.right+' B'+lResponseJSON.outputObject[i].rectangle.bottom+'</div>\
</div>\
</div>'
//Добавить информацию об элементе в словарь JS
mGlobal.GUIElement[lElementId]={};
mGlobal.GUIElement[lElementId]['GUISelectorLocal']=lResponseJSON.outputObject[i]
mGlobal.GUIElement[lElementId]['GUISelectorFull']=[lResponseJSON.outputObject[i]]
}
lHTMLTree+='</div>'
$(".rpa-object-tree").html(lHTMLTree);
}, },
dataType: "text" dataType: "text"
}); });

@ -0,0 +1,226 @@
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="utf-8">
<title>OpenRPA</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>
var mGlobal={}
$(document)
.ready(function() {
// 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'
});
})
;
</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;
}
</style>
</head>
<body>
<div class="ui internally celled grid">
<div class="row black">
<div class="two wide column">
<h1 class="ui header inverted">OpenRPA</h1>
</div>
<div class="twelve wide column">
<h1 class="ui header inverted">Daemon GUI</h1>
</div>
<div class="two wide column">
<h5>by UnicodeLabs</h5>
</div>
</div>
<div class="row">
<div class="six wide column rpa-object-tree" >
</div>
<div class="six wide column rpa-hierarchy" >
<p>This example shows how to use lazy loaded images, a sticky menu, and a simple text container</p>
</div>
<div class="four wide column rpa-property-list" >
</div>
</div>
<div class="row black">
<div class="two wide column">
<button class="ui button grey labeled icon mini" onclick="mGlobal.GUIRefreshTree()">
<i class="up refresh icon"></i>
Refresh tree
</button>
</div>
<div class="two wide column">
<button class="ui button grey labeled icon mini">
<i class="up arrow icon"></i>
From
</button>
</div>
<div class="two wide column">
<button class="ui button grey labeled icon mini">
<i class="down arrow icon"></i>
To
</button>
</div>
<div class="ten wide column">
</div>
</div>
<div class="row">
</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">OpenRPA repository</a>
<a href="https://gitlab.com/UnicodeLabs" class="item" target="_blank">UnicodeLabs</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">OpenRPA</h4>
<p>Open source Robotic Process Automation software by the Unicode Labs (Created by Ivan Maslov). Under the MIT license.</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 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>

@ -6,6 +6,11 @@ import codecs
import os import os
import signal import signal
import pdb import pdb
import robotDaemonServer
#Инициализация сервера
lThreadServer = robotDaemonServer.RobotDaemonServer("ServerThread")
lThreadServer.start()
#Чтение конфигурации #Чтение конфигурации
lDaemonConfigurationFile = codecs.open("robotDaemonConfiguration.json", "r","utf_8_sig") lDaemonConfigurationFile = codecs.open("robotDaemonConfiguration.json", "r","utf_8_sig")
@ -61,7 +66,7 @@ while True:
#Запись в массив отработанных активностей #Запись в массив отработанных активностей
lDaemonActivityLogDict[(lItem["activityType"],lActivityDateTime,lItem["processName"])]={"ActivityStartDateTime":lCurrentDateTime} lDaemonActivityLogDict[(lItem["activityType"],lActivityDateTime,lItem["processName"])]={"ActivityStartDateTime":lCurrentDateTime}
#Сформировать команду на завершение #Сформировать команду на завершение
lActivityCloseCommand='taskkill /im '+lItem["processName"]' lActivityCloseCommand='taskkill /im '+lItem["processName"]
#TODO Сделать безопасную обработку,если параметра нет в конфигурации #TODO Сделать безопасную обработку,если параметра нет в конфигурации
if lItem['flagCloseForce']: if lItem['flagCloseForce']:
lActivityCloseCommand+=" /F" lActivityCloseCommand+=" /F"

@ -0,0 +1,167 @@
from http.server import BaseHTTPRequestHandler, HTTPServer
import pdb
import pywinauto
import json
import subprocess
import time
import zlib
import os
from threading import Thread
class RobotDaemonServer(Thread):
def __init__(self,name):
Thread.__init__(self)
self.name = name
def run(self):
print('starting server...')
# Server settings
# Choose port 8080, for port 80, which is normally used for a http server, you need root access
server_address = ('127.0.0.1', 8081)
httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
print('running server...')
httpd.serve_forever()
# HTTPRequestHandler class
class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
#ResponseContentTypeFile
def SendResponseContentTypeFile(self,inContentType,inFilePath):
# Send response status code
self.send_response(200)
# Send headers
self.send_header('Content-type',inContentType)
self.end_headers()
lFileObject = open(inFilePath, "rb")
# Write content as utf-8 data
self.wfile.write(lFileObject.read())
#Закрыть файловый объект
lFileObject.close()
# GET
def do_GET(self):
#Мост между файлом и http запросом (новый формат)
if self.path == "/":
self.SendResponseContentTypeFile('text/html',"RobotDaemonServerWeb\\Index.xhtml")
#Мост между файлом и http запросом (новый формат)
if self.path == '/3rdParty/Semantic-UI-CSS-master/semantic.min.css':
self.SendResponseContentTypeFile('text/css',"..\\..\\3rdParty\\Semantic-UI-CSS-master\\semantic.min.css")
#Мост между файлом и http запросом (новый формат)
if self.path == '/3rdParty/Semantic-UI-CSS-master/semantic.min.js':
self.SendResponseContentTypeFile('application/javascript',"..\\..\\3rdParty\\Semantic-UI-CSS-master\\semantic.min.js")
#Мост между файлом и http запросом (новый формат)
if self.path == '/3rdParty/jQuery/jquery-3.1.1.min.js':
self.SendResponseContentTypeFile('application/javascript',"..\\..\\3rdParty\\jQuery\\jquery-3.1.1.min.js")
#Мост между файлом и http запросом (новый формат)
if self.path == '/3rdParty/Google/LatoItalic.css':
self.SendResponseContentTypeFile('font/css',"..\\..\\3rdParty\\Google\\LatoItalic.css")
#Мост между файлом и http запросом (новый формат)
if self.path == '/3rdParty/Semantic-UI-CSS-master/themes/default/assets/fonts/icons.woff2':
self.SendResponseContentTypeFile('font/woff2',"..\\..\\3rdParty\\Semantic-UI-CSS-master\\themes\\default\\assets\\fonts\\icons.woff2")
#Мост между файлом и http запросом (новый формат)
if self.path == '/favicon.ico':
self.SendResponseContentTypeFile('image/x-icon',"..\\..\\favicon.ico")
#Action ObjectInspector GetObjectList
if self.path == '/ObjectDetector/JSONGetWindowList':
#ReadRequest
#lInputByteArray=self.rfile.read()
#print(str(len(os.stat(self.rfile).st_size)))
# Send response status code
self.send_response(200)
# Send headers
self.send_header('Content-type','application/json')
self.end_headers()
# Send message back to client
#{'functionName':'', 'argsArray':[]}
lRequestObject={'functionName':'ElementGetChildElementList','argsArray':[]}
#Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
#ProcessChildSendObject(p,lRequestObject)
#Получить ответ от дочернего процесса
#lResponseObject=ProcessChildReadWaitObject(p)
message = json.dumps(lResponseObject)
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
# POST
def do_POST(self):
#Action ObjectInspector GetObjectList
if self.path == '/ObjectDetector/JSONGetWindowListArgs':
#ReadRequest
lInputByteArrayLength = int(self.headers.get('Content-Length'))
lInputByteArray=self.rfile.read(lInputByteArrayLength)
#Превращение массива байт в объект
print(lInputByteArray.decode('utf8'))
lInputObject=json.loads(lInputByteArray.decode('utf8'))
# Send response status code
self.send_response(200)
# Send headers
self.send_header('Content-type','application/json')
self.end_headers()
# Send message back to client
#{'functionName':'', 'argsArray':[]}
lRequestObject={'functionName':'ElementGetChildElementList','argsArray':lInputObject}
#Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
#ProcessChildSendObject(p,lRequestObject)
#Получить ответ от дочернего процесса
#lResponseObject=ProcessChildReadWaitObject(p)
print(str(lResponseObject))
message = json.dumps(lResponseObject)
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
if self.path == '/GUIAction':
#ReadRequest
lInputByteArrayLength = int(self.headers.get('Content-Length'))
lInputByteArray=self.rfile.read(lInputByteArrayLength)
#Превращение массива байт в объект
lInputObject=json.loads(lInputByteArray.decode('utf8'))
# Send response status code
self.send_response(200)
# Send headers
self.send_header('Content-type','application/json')
self.end_headers()
# Send message back to client
#{'functionName':'', 'argsArray':[]}
#pdb.set_trace()
lRequestObject=lInputObject
#Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
#ProcessChildSendObject(p,lRequestObject)
#Получить ответ от дочернего процесса
#lResponseObject=ProcessChildReadWaitObject(p)
message = json.dumps(lResponseObject)
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
if self.path == '/GUIActionList':
#ReadRequest
lInputByteArrayLength = int(self.headers.get('Content-Length'))
lInputByteArray=self.rfile.read(lInputByteArrayLength)
#Превращение массива байт в объект
lInputObject=json.loads(lInputByteArray.decode('utf8'))
# Send response status code
self.send_response(200)
# Send headers
self.send_header('Content-type','application/json')
self.end_headers()
# Send message back to client
#{'functionName':'', 'argsArray':[]}
lRequestObject=lInputObject
lOutputObject=[]
#pdb.set_trace()
#Циклическая отправка запросов в дочерний объект
for lItem in lRequestObject:
#Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами
#ProcessChildSendObject(p,lItem)
#Получить ответ от дочернего процесса
#lResponseObject=ProcessChildReadWaitObject(p)
#Добавить в выходной массив
lOutputObject.append(lResponseObject)
#Сформировать текстовый ответ
message = json.dumps(lOutputObject)
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
return
#print(ChildProcessReadWaitString(p))

@ -0,0 +1,21 @@
#valueVerify
#inTypeClass int, str, dict, list, NoneType
def valueVerify(inValue,inTypeClass,inNotValidValue):
lResult = inNotValidValue
if inValue is not None:
if type(inValue) == inTypeClass:
lResult = inValue
#Вернуть результат
return lResult
#valueVerifyDict
def valueVerifyDict(inDict,inKey,inTypeClass,inNotValidValue):
lResult = inNotValidValue
if inKey in inDict:
lResult = valueVerify(inDict[inKey],inTypeClass,inNotValidValue)
return lResult
#valueVerifyList
def valueVerifyList(inList,inIndex,inTypeClass,inNotValidValue):
lResult = inNotValidValue
if inIndex in inList:
lResult = valueVerify(inList[inIndex],inTypeClass,inNotValidValue)
return lResult
Loading…
Cancel
Save