From 9f77336c4cd577f07d8a6157de5d8d1dc4643553 Mon Sep 17 00:00:00 2001 From: Ivan Maslov Date: Wed, 17 Apr 2019 21:13:53 +0300 Subject: [PATCH] #DaemonServerPrototype #NeedPILToGetScreenshot #DaemonMultithreading #GeneralLibVerify --- Index.xhtml | 34 +-- .../RobotDaemonServerWeb/Index.xhtml | 226 ++++++++++++++++++ .../robotDaemonServer.cpython-37.pyc | Bin 0 -> 3784 bytes Orchestrator/RobotDaemon/robotDaemon.py | 7 +- Orchestrator/RobotDaemon/robotDaemonServer.py | 167 +++++++++++++ general.py | 21 ++ 6 files changed, 427 insertions(+), 28 deletions(-) create mode 100644 Orchestrator/RobotDaemon/RobotDaemonServerWeb/Index.xhtml create mode 100644 Orchestrator/RobotDaemon/__pycache__/robotDaemonServer.cpython-37.pyc create mode 100644 Orchestrator/RobotDaemon/robotDaemonServer.py create mode 100644 general.py diff --git a/Index.xhtml b/Index.xhtml index 972832a4..46a84a24 100644 --- a/Index.xhtml +++ b/Index.xhtml @@ -152,11 +152,14 @@ var lSubItemActionOnRightClick=' oncontextmenu="mGlobal.ElementHighlightNew(\''+lElementId+'\');" ' var lIconSelectOnClick=' onclick="mGlobal.TreeObjectInfoLoad(\''+lElementId+'\');" ' var lIconTestOnClick=' onclick="mGlobal.Test(\''+lElementId+'\');" ' + var lIconUpOnClick=' onclick="mGlobal.Actions.fAutomationSearchMouseElementHierarchyRun(\''+lElementId+'\');" ' + lHTMLTree+='\
\ \ \ \ + \
\
'+lResponseJSON.outputObject[i].title+'
\
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+'
\ @@ -517,34 +520,11 @@ success: function(lData,l2,l3) { - var lHTMLTree='
' var lResponseJSON=JSON.parse(lData) - for (i=0;i\ - \ - \ - \ -
\ -
\ - '+lResponseJSON.outputObject[i].title+'\ - 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+'
\ -
\ -
' - //Добавить информацию об элементе в словарь JS - mGlobal.GUIElement[lElementId]={}; - mGlobal.GUIElement[lElementId]['GUISelectorLocal']=lResponseJSON.outputObject[i] - mGlobal.GUIElement[lElementId]['GUISelectorFull']=[lResponseJSON.outputObject[i]] - } - lHTMLTree+='
' - $(".rpa-object-tree").html(lHTMLTree); + ///Очистить дерево + mGlobal.ElementTree.fClear(); + ///Прогрузить новое дерево + mGlobal.ElementTree.fRender(lResponseJSON.outputObject); }, dataType: "text" }); diff --git a/Orchestrator/RobotDaemon/RobotDaemonServerWeb/Index.xhtml b/Orchestrator/RobotDaemon/RobotDaemonServerWeb/Index.xhtml new file mode 100644 index 00000000..1d4fcc98 --- /dev/null +++ b/Orchestrator/RobotDaemon/RobotDaemonServerWeb/Index.xhtml @@ -0,0 +1,226 @@ + + + + + OpenRPA + + + + + + + + +
+
+
+

OpenRPA

+
+
+

Daemon GUI

+
+
+
by UnicodeLabs
+
+ +
+
+
+ +
+
+

This example shows how to use lazy loaded images, a sticky menu, and a simple text container

+
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+ + + +
+
+ + + + + + + + diff --git a/Orchestrator/RobotDaemon/__pycache__/robotDaemonServer.cpython-37.pyc b/Orchestrator/RobotDaemon/__pycache__/robotDaemonServer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bda2d2148bc0a18e34228a925680cea2efb16c58 GIT binary patch literal 3784 zcmb_f+in}j8QvogOG=_-TS@E$aZ}_uvpihvie*Y{*$+V(0MVFk@w=@4g^PlG52Xk|t zf#-Vo_x8?*hVf4toIMUYpQ6Y^RLo#zWb{qn>|4HN(%6b@-`1_;JGym!SGNVfpxdHf z)NRQx>9*{b(b|#MulNq%cz&W1b3ruWy=o& z$sg_PY(L@8hg_;hLChj9GLNtp7caQjteaV3XJ7Dub!pYvW1;gYihLIpH++*BzQs&t zy)tkDn>lE)6L2eJi%*i>L_G|6KZ$dyU0O~LwKmEcioA|W8Dn!~oSLRFLff&J0TSkB z-4-Oftkmg*ai}_-%!z|O#~B>Sqn;?@<=+fZM)TFy+RxjoyRsdK?tb`!w`DgO@RsO4 zecav}@c7C0YI_T>a9$CpM6@sLt}SMF+87*(0;pC|ByGVkJu|&|VNHIb#@WWYCQZUa z$C@7PBMcPueS(8A>)2H0$W+#eb!-8(2_0Eu`_v#Sz=563bV;f}s4(8UEwv&VjYi!{ z%lAI{N#kSu?uCDN-!RfeF^uEaCpnor5MitYG0)ypq}QoBJ2RS|)5JTyL~tk@QZCV= z`J81ZU`%i+eRp4}0n^gWE3)v+2JZ!Qq_%gnWIGT|$xLs&DICn)th=N=(i*hqbvpfo z4I}DTJDumlAj;opVGAOAfgPz;5EtR1s-S39l)zIXT_DqEYMFNceZ6I}0xZ;JMe+wh z+U=6O=pijrSwoQzQH_i-RHtnc*2%1qc?x$0YLUW}J+h!e>)0L{2hP|X+2g`#Zo&4r zctNFK{sXkq>RJ*j9;+2~G~k&fcI%}KT8LQ(q8=o%|)CTC26v z52WIvDJO8FAI6QYlxa!Rr{0enjW+&g6xx?lXum<><8R0GK&H#VU=W4fK!r)%JP2L{ zvMa)YN`Le}>;UBMoNwUZw?i(Dng_VE#L>$A#y$M#q?lEoA)ZfdUpDpqbAszhvKR5@ zV_XLtD!`_5q4nUYO%mFj8LIjG_RRc8=L9d8YE$j=K9^0#d%-YL%|J@7WRuv)X4r-A zH(n;a-Y2Q2Ip_V~%<#UPbUP>Ao{(g_ z7_rHa2;dH{_J(nn>|_(SLskyNo?I0oILe%%>ix7{$(#W~mv|4H#0{#Jsd@`l<{S`t zmks*^nJq+T!D|xV-l2InX`Z`#gitlT;4o2VJo&t=2(?H^Vm2TaSkhVlZ0Gx+AU{Hd z*k@M1zPLIv+8)~U&ef4ICp-;;bnQ-q;9rqKOoQMbkt!GmNDdf+#))}MBf4d9A0c@t zAZ;ijKd*kjHlNLAQ0WR9ykNEJsmDbuu8Z$rN@gSZ^NVLGgT2R9<_gLf#4RF2=~Gr{a-y8ex5BOVOZ12~!X-29;a!VK(J zb7110*u1ap#p)4Kf2L|;{91~EW&BFw^}9vr<4<6wxOtCi%*;qE{r zT?DGkQ6b`_lSbigW+gH!!={h~;yXZpCFz`4^SEq7S?L#f>itXlQqdn>HKcPFe~{e5 Fe*kE)`h)-g literal 0 HcmV?d00001 diff --git a/Orchestrator/RobotDaemon/robotDaemon.py b/Orchestrator/RobotDaemon/robotDaemon.py index 48cbf03c..9e92f4a2 100644 --- a/Orchestrator/RobotDaemon/robotDaemon.py +++ b/Orchestrator/RobotDaemon/robotDaemon.py @@ -6,6 +6,11 @@ import codecs import os import signal import pdb +import robotDaemonServer + +#Инициализация сервера +lThreadServer = robotDaemonServer.RobotDaemonServer("ServerThread") +lThreadServer.start() #Чтение конфигурации lDaemonConfigurationFile = codecs.open("robotDaemonConfiguration.json", "r","utf_8_sig") @@ -61,7 +66,7 @@ while True: #Запись в массив отработанных активностей lDaemonActivityLogDict[(lItem["activityType"],lActivityDateTime,lItem["processName"])]={"ActivityStartDateTime":lCurrentDateTime} #Сформировать команду на завершение - lActivityCloseCommand='taskkill /im '+lItem["processName"]' + lActivityCloseCommand='taskkill /im '+lItem["processName"] #TODO Сделать безопасную обработку,если параметра нет в конфигурации if lItem['flagCloseForce']: lActivityCloseCommand+=" /F" diff --git a/Orchestrator/RobotDaemon/robotDaemonServer.py b/Orchestrator/RobotDaemon/robotDaemonServer.py new file mode 100644 index 00000000..1f2cbaf7 --- /dev/null +++ b/Orchestrator/RobotDaemon/robotDaemonServer.py @@ -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)) diff --git a/general.py b/general.py new file mode 100644 index 00000000..ee28f066 --- /dev/null +++ b/general.py @@ -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