diff --git a/Robot/GUI.py b/Robot/GUI.py index 24c440a7..719f6152 100644 --- a/Robot/GUI.py +++ b/Robot/GUI.py @@ -13,6 +13,7 @@ import win32clipboard import time import traceback import ProcessCommunicator +import JSONNormalize from threading import Timer #################################### @@ -198,6 +199,7 @@ def PWASpecification_Get_UIO(inControlSpecificationArray): lBackend=mDefaultPywinautoBackend if "backend" in inControlSpecificationArray[0]: lBackend=inControlSpecificationArray[0]["backend"] + inControlSpecificationArray[0].pop("backend") #Подготовка входного массива inControlSpecificationArray=UIOSelector_SearchNormalize_UIOSelector(inControlSpecificationArray) #Выполнить идентификацию объектов, если передан массив @@ -555,7 +557,7 @@ def UIOXY_SearchChild_ListDict(inRootElement,inX,inY,inHierarchyList=[]): #Get list of child UIO's by Parent UIOSelector #inControlSpecificationArray- UIOSelector #old name - ElementGetChildElementList -def UIOSelector_GetChildList_UIOList(inControlSpecificationArray=[]): +def UIOSelector_GetChildList_UIOList(inControlSpecificationArray=[],inBackend=mDefaultPywinautoBackend): #Подготовка входного массива inControlSpecificationArray=UIOSelector_SearchNormalize_UIOSelector(inControlSpecificationArray) #Выполнить идентификацию объектов, если передан массив @@ -578,7 +580,7 @@ def UIOSelector_GetChildList_UIOList(inControlSpecificationArray=[]): #Инкремент счетчика lIterator=lIterator+1 else: - lResultList=BackendStr_GetTopLevelList_UIOInfo() + lResultList=BackendStr_GetTopLevelList_UIOInfo(inBackend) return lResultList #################################################################################################### @@ -721,7 +723,7 @@ def UIOEI_Convert_UIOInfo(inElementInfo): #old name - GetRootElementList def BackendStr_GetTopLevelList_UIOInfo(inBackend): #Получить список объектов - lResultList=pywinauto.findwindows.find_elements(top_level_only=True,backend=mPywinautoActiveBackend) + lResultList=pywinauto.findwindows.find_elements(top_level_only=True,backend=mDefaultPywinautoBackend) lResultList2=[] for lI in lResultList: lTempObjectInfo=lI @@ -825,20 +827,24 @@ if len(sys.argv) > 1: mFlagIsDebug=True #Выполнить чтение буфера, если не отладка библиотеки if not mFlagIsDebug: - #{'functionName':'', 'argsArray':[]} while True: + lProcessResponse={"ErrorFlag":False} try: + #Ожидаем синхронно поступление объекта lJSONInput = ProcessCommunicator.ProcessParentReadWaitObject() - lJSONInputString=str(lJSONInput) - #{'outputObject':''} + lProcessResponse["ActivitySpecificationDict"]=lJSONInput #Выполнить вызов функции - lResult=locals()[lJSONInput['ActivityName']](*lJSONInput['ArgumentList']) - lJSONInput['Result']=JSONNormalizeDictList(lResult) - ProcessCommunicator.ProcessParentWriteObject(lJSONInput) + lProcessResponse["Result"]=JSONNormalize.JSONNormalizeDictList(locals()[lJSONInput['ActivityName']](*lJSONInput['ArgumentList'],**lJSONInput['ArgumentDict'])) except Exception as e: - #Вывод ошибки в родительский поток - ProcessCommunicator.ProcessParentWriteObject({'Error':str(e) + traceback.format_exc(), 'ArgObject':str(lJSONInputString)}) - #ctypes.windll.user32.MessageBoxW(0, str(e), "Your title", 1) + #Установить флаг ошибки + lProcessResponse["ErrorFlag"]=True + #Зафиксировать traceback + lProcessResponse["ErrorTraceback"]=traceback.format_exc() + #Зафиксировать Error message + lProcessResponse["ErrorMessage"]=str(e) + #Отправить ответ в родительский процесс + ProcessCommunicator.ProcessParentWriteObject(lProcessResponse) + else: print('Debug mode is turned on!') diff --git a/Robot/JSONNormalize.py b/Robot/JSONNormalize.py index ad6bf55f..651c1a4d 100644 --- a/Robot/JSONNormalize.py +++ b/Robot/JSONNormalize.py @@ -28,7 +28,7 @@ def JSONNormalizeDict(inDictionary): lFlagRemoveAttribute=True #Рекурсивный вызов, если объект является словарем if type(lItemValue) is dict: - lResult[lItemKey]=JSONNormalizeDictionary(lItemValue) + lResult[lItemKey]=JSONNormalizeDict(lItemValue) #Рекурсивный вызов, если объект является списком if type(lItemValue) is list: lResult[lItemKey]=JSONNormalizeList(lItemValue) @@ -51,7 +51,7 @@ def JSONNormalizeList(inList): lResult.append(lItemValue) #Если является словарем - вызвать функцию нормализации словаря if type(lItemValue) is dict: - lResult.append(JSONNormalizeDictionary(lItemValue)) + lResult.append(JSONNormalizeDict(lItemValue)) #Если является массиваом - вызвать функцию нормализации массива if type(lItemValue) is list: lResult.append(JSONNormalizeList(lItemValue)) @@ -61,7 +61,7 @@ def JSONNormalizeList(inList): def JSONNormalizeDictList(inDictList): lResult={} if type(inDictList) is dict: - lResult=JSONNormalizeDictionary(inDictList) + lResult=JSONNormalizeDict(inDictList) if type(inDictList) is list: lResult=JSONNormalizeList(inDictList) return lResult; diff --git a/Robot/Robot.py b/Robot/Robot.py index 425009f3..86a1f3ca 100644 --- a/Robot/Robot.py +++ b/Robot/Robot.py @@ -51,7 +51,7 @@ import traceback #Section: Module initialization #################### #Start childprocess - GUI Module 32 bit -mProcessGUI_x32 = subprocess.Popen(['..\\Resources\\WPy32-3720\\python-3.7.2\\python.exe','GUI.py'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) +mProcessGUI_x32 = subprocess.Popen(['..\\Resources\\WPy32-3720\\python-3.7.2\\python.exe','..\\Robot\\GUI.py'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) #Start childprocess - GUI Module 64 bit - uncomment after WPy64 installation #mProcessGUI_x64 = subprocess.Popen(['..\\Resources\\WPy64-3720\\python-3.7.2\\python.exe','GUI.py'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) @@ -60,8 +60,13 @@ mProcessGUI_x32 = subprocess.Popen(['..\\Resources\\WPy32-3720\\python-3.7.2\\py #Section: Activity #################### def ActivityRun(inActivitySpecificationDict): + #Выполнить отправку в модуль GUI, если ModuleName == "GUI" if inActivitySpecificationDict["ModuleName"] == "GUI": + if "ArgumentList" not in inActivitySpecificationDict: + inActivitySpecificationDict["ArgumentList"]=[] + if "ArgumentDict" not in inActivitySpecificationDict: + inActivitySpecificationDict["ArgumentDict"]={} #TODO: Доделать определение разрядности (32 и 64) #Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами ProcessCommunicator.ProcessChildSendObject(mProcessGUI_x32,inActivitySpecificationDict) @@ -70,14 +75,14 @@ def ActivityRun(inActivitySpecificationDict): #Вернуть результат #Остальные модули подключать и выполнять здесь else: - #Подготовить результирующую структуру - lResponseObject={"ActivitySpecificationDict":inActivitySpecificationDict,"ErrorFlag":False} lArgumentList=[] if "ArgumentList" in inActivitySpecificationDict: lArgumentList=inActivitySpecificationDict["ArgumentList"] lArgumentDict={} if "ArgumentDict" in inActivitySpecificationDict: lArgumentDict=inActivitySpecificationDict["ArgumentDict"] + #Подготовить результирующую структуру + lResponseObject={"ActivitySpecificationDict":inActivitySpecificationDict,"ErrorFlag":False} try: #Подключить модуль для вызова lModule=importlib.import_module(inActivitySpecificationDict["ModuleName"]) diff --git a/Robot/__init__.py b/Robot/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/Studio/JSONNormalize.py b/Studio/JSONNormalize.py new file mode 100644 index 00000000..651c1a4d --- /dev/null +++ b/Studio/JSONNormalize.py @@ -0,0 +1,69 @@ +import json + +#################################### +#Info: Internal JSONNormalize module of the Robot app (OpenRPA - Robot) +#################################### +# JSONNormalize Module - Prepare dict or list for JSON (delete object from the structure) + +############################### +####Нормализация под JSON (в JSON нельзя передавать классы - только null, числа, строки, словари и массивы) +############################### +#Нормализация словаря под JSON +def JSONNormalizeDict(inDictionary): + #Сделать копию объекта + lResult=inDictionary.copy() + #Перебор всех элементов + for lItemKey,lItemValue in inDictionary.items(): + #Флаг удаления атрибута + lFlagRemoveAttribute=False + #Если строка или число или массив или объект или None - оставить + if ( + type(lItemValue) is dict or + type(lItemValue) is int or + type(lItemValue) is str or + type(lItemValue) is list or + lItemValue is None): + True==True + else: + lFlagRemoveAttribute=True + #Рекурсивный вызов, если объект является словарем + if type(lItemValue) is dict: + lResult[lItemKey]=JSONNormalizeDict(lItemValue) + #Рекурсивный вызов, если объект является списком + if type(lItemValue) is list: + lResult[lItemKey]=JSONNormalizeList(lItemValue) + ############################# + #Конструкция по удалению ключа из словаря + if lFlagRemoveAttribute: + lResult.pop(lItemKey) + #Вернуть результат + return lResult +#Нормализация массива под JSON +def JSONNormalizeList(inList): + lResult=[] + #Циклический обход + for lItemValue in inList: + #Если строка или число или массив или объект или None - оставить + if ( + type(lItemValue) is int or + type(lItemValue) is str or + lItemValue is None): + lResult.append(lItemValue) + #Если является словарем - вызвать функцию нормализации словаря + if type(lItemValue) is dict: + lResult.append(JSONNormalizeDict(lItemValue)) + #Если является массиваом - вызвать функцию нормализации массива + if type(lItemValue) is list: + lResult.append(JSONNormalizeList(lItemValue)) + #Вернуть результат + return lResult +#Определить объект - dict or list - и нормализовать его для JSON +def JSONNormalizeDictList(inDictList): + lResult={} + if type(inDictList) is dict: + lResult=JSONNormalizeDict(inDictList) + if type(inDictList) is list: + lResult=JSONNormalizeList(inDictList) + return lResult; + + diff --git a/Studio/ProcessCommunicator.py b/Studio/ProcessCommunicator.py new file mode 100644 index 00000000..9f1dfdd6 --- /dev/null +++ b/Studio/ProcessCommunicator.py @@ -0,0 +1,141 @@ +import json +import subprocess +import zlib +import sys +import os +import JSONNormalize +############################################ +####Межпроцессное взаимодействие +############################################ +#ProcessParentReadWaitString +def ProcessParentReadWaitString(): + #Выполнить чтение строки + #ctypes.windll.user32.MessageBoxW(0, "Hello", "Your title", 1) + lResult = sys.stdin.buffer.readline() + #Вернуть потенциальные \n + lResult = lResult.replace(b'{{n}}',b'\n') + lResult = zlib.decompress(lResult[0:-1]) + lResult = lResult.decode("utf-8") + #Вернуть результат + return lResult + +#ParentProcessWriteString +def ProcessParentWriteString(lString): + lByteString = zlib.compress(lString.encode("utf-8")) + #Выполнить отправку строки в родительский процесс + #Вернуть потенциальные \n + lByteString = lByteString.replace(b'\n',b'{{{n}}}') + #Вернуть \r + lByteString = lByteString.replace(b'\r',b'{{{r}}}') + #Вернуть \0 + lByteString = lByteString.replace(b'\0',b'{{{0}}}') + #Вернуть \a + lByteString = lByteString.replace(b'\a',b'{{{a}}}') + #Вернуть \b + lByteString = lByteString.replace(b'\b',b'{{{b}}}') + #Вернуть \t + lByteString = lByteString.replace(b'\t',b'{{{t}}}') + #Вернуть \v + lByteString = lByteString.replace(b'\v',b'{{{v}}}') + #Вернуть \f + lByteString = lByteString.replace(b'\f',b'{{{f}}}') + ############################ + #print(b"Result: "+lByteString) + #lByteString= b'x\x9c\xdd\x95]O\xc20\x14\x86\xffJ\xb3[5\xa1Cqz\x07\xc4\xe8\x8d\x1fQ\x13.\x0cYJw\xb6U\xbav\xe9\xce"\x84\xf0\xdfm\'"\xb8\xa0L%Q\xb3\x9b\xf6=\xdfO\x9a\xb3\x99\x17\x97\x8a\xa3\xd0\xea\x8ae\xe0\x9d\x12\xaf[\xa2\xce\x98S\xee\x80\x19\x9e^\xea\xb2\x803\t\x19(\xbc\x10`\x9c6\xf5\xf6\x89\xc7LRt\x8daS\x1b\xf5\xf00\xf3\xd4"\xc1u\x0e\xea\xf6\xa6K\x0e\xc8\xb9\xd6\x89\x04\xd2O\x8d\xb6&\x1bb\x04OC\x84\t~\xe2\x97\x1b\xcd\xa1(B\x11YG\xdaj\xfb\xc1\x9b\xb8\xa2\xa4LE\xd2\xd5\xa4\xf6\xdenY\x85Kf\xc3^;yI\x18\x0eD\x94\x00\x0e\x84{{n}}\xa9K\xce\xb5B\xa3e\x88\xd3\xbc\xf2Z\xd5\xaa\x82\xaa\x94\xd25\x0b\x1c\x99J\xaa\x023OB\xec\xbavEP\xe7\x8b\x93\x11I\xeaTz\xe2\xbb\xebH\xa3eW5\xe8\xb7\xe6\xce^*\x14\xb6\x83e\xda\xf9phe]b^\xe2\xf5\xe8\xd1Vp\xf0\xfe.\xbb\x1b\xa6`\x87\xfc8\x1a\x9bSE0q\xa2\x15\xeer\xe0"\x16\xbcz\x9f\xfdT\xc8h\x9d\xdf\xc7\xd4\xbe\xcdj1\xd9:\xa9\x1f\xe1B7\x81\xa1\xef\xc0\xd0:\x98\xc3-\xc0\xd4X\xfc\xda\xf1i\xbb\xe9\xfc\xdb<\x8c\xff2\x7f\'\xa8\x8d\xdf\xdab\xfc\x9e\xd6\xe3\x8c\x99qQ\xe3\xb0f\xd9\x19\x90{\xade\x8f\x99/3\xa1AC(\xfe\x16P\x06F \x90\xb3\t\x07Iba\x17\x83P\xa4\xbf\xb7G\x9e\x04\xa6vE\x13\xb6\xfc\x13\xd6\xa85\x0b\xdd\x19\xd6^i\x11\xa8FT;G\xfe\x06\xac\xc1q\xb0N\x956\xd84\xae\xe4p\xbe\xfa=\x03\x01\xce\x95\x9a' + #lByteString = b"x\x9c\xb5\x91\xcfO\xc3 \x14\xc7\xff\x95\xa6\xd7uI\xf9Q\x8a\xde\xd4\x93\x07\xbdx\xf00\x97\x05)[I(\x90\x8ef3\xcb\xfew\x81M\xbb\xd9M]\x8c!y\xd0\xf7}\xbc\xef\xe3\xd3\xc9&\xd5\xac\x11\xe9u\x92j\xb1J@2N\x1e\x8d\x13\x96U\xa3Q\x9a%i+y=sb\xed\xceV\xd8\xd6p\xb1\\\xced\xe5K{{n}}\x80`\x9f\xeb\x135\xd3\x95{{n}}.\x08RR\xe4>\xc3\x15\xf3\x97>\xbc\x8f:r\xa3]k\xd4\xcc\xbd\xd9(>K]\x99\xd5\xa1\x12\xbd\x00\xc6\xb0\xcc\xcb0\xa4\xe0\x8e\xe9E4\xd8\xa4J\xcc\xc3\xb44\x07^r\xc6\xfa3\x04(\xbeeQ\x07\x05P\x1a\xa4W\xe3\x9ci\xfc\xf7\x15(\xb6A\xee\xb4\x93\x8d\xd85\x9f`?\xf6n\xd8i0v\xadw\xd5\x95X\x87n>\xf1d\x05\x97s\xc9\x99\x93F\xdf\xd5R\xc5K=\xcc\x1bk\xd5^\x1d`\xfc\xa2]\x06PwJ\r\xf0\x9d\xa2\xf6 tw\xcb\xda\x01\xb6}\x83\xd3\xcc\x00\xec\x99\x15\xf4\x88Y\x99\x1f2\x83\xb4\xfc\x8e\x99\xdf\xb3d\x0c\x01.1E\x04\x93l\xff\x8e\xcf\x7f6\xa4Z\xfc\x82\xeaK\x97c BD\xf3\x101\x89g\xba\x8b\x03\xd0?\x97\xff#\xfb{'\x9a\x8b\xe0\x03H\xc89\xfa\x08\x15\x7f\xa2\x0f >\x80_\x0e\xe0\x93\xb3\xf0\xc3\xc4\xd3m\\\xef\xf8\x958\xa0" + #lt=open("logSendByteStringWithoutN.log","wb") + #lt.write(lByteString) + #lt.close() + ############################ + sys.stdout.buffer.write(lByteString+bytes("\n","utf-8")) + sys.stdout.flush(); + return +#ProcessParentWriteObject +def ProcessParentWriteObject(inObject): + #Выполнить нормализацию объекта перед форматированием в JSON + JSONNormalize.JSONNormalizeDictList(inObject) + #Выполнить отправку сконвертированного объекта в JSON + ProcessParentWriteString(json.dumps(inObject)) + return +#ProcessParentReadWaitObject +def ProcessParentReadWaitObject(): + #Выполнить получение и разбор объекта + lResult=json.loads(ProcessParentReadWaitString()); + return lResult; + +#ProcessChildSendString +def ProcessChildSendString(lProcess,lString): + lByteString = zlib.compress(lString.encode("utf-8")) + #Вернуть потенциальные \n + lByteString = lByteString.replace(b'\n',b'{{n}}') + #Отправить сообщение в дочерний процесс + lProcess.stdin.write(lByteString+bytes('\n',"utf-8")) + #print(str(lByteString+bytes('\n',"utf-8"))) + lProcess.stdin.flush() + #Вернуть результат + return + +#ProcessChildReadWaitString +def ProcessChildReadWaitString(lProcess): + #Ожидаем ответ от процесса + lResult = lProcess.stdout.readline() + #Обработка спец символов + #print(b'NewLine: '+lResult) + #Вернуть потенциальные \n + lResult = lResult.replace(b'{{{n}}}',b'\n') + #Вернуть \r + lResult = lResult.replace(b'{{{r}}}',b'\r') + #Вернуть \0 + lResult = lResult.replace(b'{{{0}}}',b'\0') + #Вернуть \a + lResult = lResult.replace(b'{{{a}}}',b'\a') + #Вернуть \b + lResult = lResult.replace(b'{{{b}}}',b'\b') + #Вернуть \t + lResult = lResult.replace(b'{{{t}}}',b'\t') + #Вернуть \v + lResult = lResult.replace(b'{{{v}}}',b'\v') + #Вернуть \f + lResult = lResult.replace(b'{{{f}}}',b'\f') + #print("check") + #print(str(lResult)) + lResult = zlib.decompress(lResult[0:-1]) + lResult = lResult.decode("utf-8") + #Вернуть результат + return lResult + +#ProcessChildSendObject +def ProcessChildSendObject(inProcess,inObject): + #Выполнить отправку сконвертированного объекта в JSON + ProcessChildSendString(inProcess,json.dumps(inObject)) + return +#ProcessChildReadWaitObject +def ProcessChildReadWaitObject(inProcess): + #Выполнить получение и разбор объекта + lResult=json.loads(ProcessChildReadWaitString(inProcess)); + return lResult; + +#ProcessChildSendReadWaitString +def ProcessChildSendReadWaitString(lProcess,lString): + ProcessChildSendString(lProcess,lString) + #Вернуть результат + return ProcessChildReadWaitString(lProcess) +#ProcessChildSendReadWaitObject +def ProcessChildSendReadWaitObject(inProcess,inObject): + ProcessChildSendObject(inProcess,inObject) + #Вернуть результат + return ProcessChildReadWaitString(inProcess) +#ProcessChildSendReadWaitQueue +#QueueObject - [Object,Object,...] +def ProcessChildSendReadWaitQueueObject(inProcess,inQueueObject): + lOutputObject=[] + #Циклическая отправка запросов в дочерний объект + for lItem in inQueueObject: + #Отправить запрос в дочерний процесс, который отвечает за работу с Windows окнами + ProcessChildSendObject(inProcess,lItem) + #Получить ответ от дочернего процесса + lResponseObject=ProcessChildReadWaitObject(inProcess) + #Добавить в выходной массив + lOutputObject.append(lResponseObject) + #Сформировать ответ + return lOutputObject diff --git a/Studio/PythonDebug_32.cmd b/Studio/PythonDebug_32.cmd new file mode 100644 index 00000000..eca1167e --- /dev/null +++ b/Studio/PythonDebug_32.cmd @@ -0,0 +1,3 @@ +cd %~dp0 +.\..\Resources\WPy32-3720\python-3.7.2\python.exe +pause >nul \ No newline at end of file diff --git a/Studio/Studio.py b/Studio/Studio.py new file mode 100644 index 00000000..00ae7cac --- /dev/null +++ b/Studio/Studio.py @@ -0,0 +1,162 @@ +from http.server import BaseHTTPRequestHandler, HTTPServer +import pdb +import pywinauto +import json +import subprocess +import zlib +import os +import ProcessCommunicator +import sys +sys.path.append('../Robot') +import Robot + +# 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',"Web\\Index.xhtml") + #Мост между файлом и http запросом (новый формат) + if self.path == '/3rdParty/Semantic-UI-CSS-master/semantic.min.css': + self.SendResponseContentTypeFile('text/css',"..\\Resources\\Web\\Semantic-UI-CSS-master\\semantic.min.css") + #Мост между файлом и http запросом (новый формат) + if self.path == '/3rdParty/Semantic-UI-CSS-master/semantic.min.js': + self.SendResponseContentTypeFile('application/javascript',"..\\Resources\\Web\\Semantic-UI-CSS-master\\semantic.min.js") + #Мост между файлом и http запросом (новый формат) + if self.path == '/3rdParty/jQuery/jquery-3.1.1.min.js': + self.SendResponseContentTypeFile('application/javascript',"..\\Resources\\Web\\jQuery\\jquery-3.1.1.min.js") + #Мост между файлом и http запросом (новый формат) + if self.path == '/3rdParty/Google/LatoItalic.css': + self.SendResponseContentTypeFile('font/css',"..\\Resources\\Web\\Google\\LatoItalic.css") + #Мост между файлом и http запросом (новый формат) + if self.path == '/3rdParty/Semantic-UI-CSS-master/themes/default/assets/fonts/icons.woff2': + self.SendResponseContentTypeFile('font/woff2',"..\\Resources\\Web\\Semantic-UI-CSS-master\\themes\\default\\assets\\fonts\\icons.woff2") + #Мост между файлом и http запросом (новый формат) + if self.path == '/favicon.ico': + self.SendResponseContentTypeFile('image/x-icon',"Web\\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=ProcessCommunicator.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 окнами + ProcessCommunicator.ProcessChildSendObject(p,lRequestObject) + + #Получить ответ от дочернего процесса + lResponseObject=ProcessCommunicator.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 + #Отправить команду роботу + lResponseObject=Robot.ActivityRun(lRequestObject) + 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 окнами + ProcessCommunicator.ProcessChildSendObject(p,lItem) + #Получить ответ от дочернего процесса + lResponseObject=ProcessCommunicator.ProcessChildReadWaitObject(p) + #Добавить в выходной массив + lOutputObject.append(lResponseObject) + #Сформировать текстовый ответ + message = json.dumps(lOutputObject) + # Write content as utf-8 data + self.wfile.write(bytes(message, "utf8")) + return + +def run(): + 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() + +#Start childprocess 32 bit +p = subprocess.Popen(['..\\Resources\\WPy32-3720\\python-3.7.2\\python.exe','winGUI.py'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) + +#print(ChildProcessReadWaitString(p)) +run() diff --git a/Studio/StudioRun_32.cmd b/Studio/StudioRun_32.cmd new file mode 100644 index 00000000..37e21ec9 --- /dev/null +++ b/Studio/StudioRun_32.cmd @@ -0,0 +1,3 @@ +cd %~dp0 +.\..\Resources\WPy32-3720\python-3.7.2\python.exe Studio.py +pause >nul \ No newline at end of file diff --git a/Studio/ValueVerify.py b/Studio/ValueVerify.py new file mode 100644 index 00000000..ee28f066 --- /dev/null +++ b/Studio/ValueVerify.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 diff --git a/Studio/Web/Index.xhtml b/Studio/Web/Index.xhtml new file mode 100644 index 00000000..5e980453 --- /dev/null +++ b/Studio/Web/Index.xhtml @@ -0,0 +1,875 @@ + + + + + OpenRPA + + + + + + + + +
+
+
+

Studio

+ +
+
+
+ +
+
+
+

OpenRPA

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

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

+
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+
Edit GUI selector
+ + + +
Validate Result
+
+
+
+
Select action
+ + +
Set arguments
+
+ +
+

+ + +
Result
+
+
+
+
+
+
+
+
+
+
Additional actions
+
+ + +
+
+
Code list
+
+ + + +
+ + +
+
+ + + + + + + + diff --git a/Studio/Web/favicon.ico b/Studio/Web/favicon.ico new file mode 100644 index 00000000..27dd4696 Binary files /dev/null and b/Studio/Web/favicon.ico differ