#####Внимание#####UIOSelectorsSecs_WaitAppear_List_Функция ожидания появления элементов (тк элементы могут быть недоступны, неизвестно в каком фреймворке каждый из них может появиться)

#TODO
#StudioTryCatchПриОтправкеНекорректнойПоследовательности символов
dev-linux
Ivan Maslov 5 years ago
parent 190023fa93
commit 499ce682f8

@ -18,12 +18,15 @@ from threading import Timer
import datetime import datetime
import logging import logging
import re import re
import copy
#Создать файл логирования #Создать файл логирования
# add filemode="w" to overwrite # add filemode="w" to overwrite
if not os.path.exists("Reports"): if not os.path.exists("Reports"):
os.makedirs("Reports") os.makedirs("Reports")
logging.basicConfig(filename="Reports\ReportRobotGUIRun_"+datetime.datetime.now().strftime("%Y_%m_%d__%H_%M_%S")+".log", level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s") logging.basicConfig(filename="Reports\ReportRobotGUIRun_"+datetime.datetime.now().strftime("%Y_%m_%d__%H_%M_%S")+".log", level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
#####Внимание#######
#TODO В перспективе нужно реализовать алгоритм определения разрядности не в Robot.py, а в GUI.py, тк начинают появляться функции, на входе в которые еще неизвестна разрядность элемента + селектор может охватить сразу два элемента из 2-х разных разрядностей - обрабатываться это должно непосредственно при выполнении
#################################### ####################################
#Info: GUI module of the Robot app (OpenRPA - Robot) #Info: GUI module of the Robot app (OpenRPA - Robot)
@ -108,9 +111,10 @@ def UIOSelector_Get_UIOList (inSpecificationList,inElement=None,inFlagRaiseExcep
if inElement is None: if inElement is None:
#сформировать спецификацию на получение элемента #сформировать спецификацию на получение элемента
lRootElementSpecification=[inSpecificationList[0]] lRootElementSpecification=[inSpecificationList[0]]
lRootElement=PWASpecification_Get_UIO(lRootElementSpecification) lRootElementList=PWASpecification_Get_UIO(lRootElementSpecification)
if lRootElement is not None: for lRootItem in lRootElementList:
lChildrenList.append(lRootElement.wrapper_object()) if lRootItem is not None:
lChildrenList.append(lRootItem.wrapper_object())
#Елемент на вход поступил - выполнить его анализ #Елемент на вход поступил - выполнить его анализ
else: else:
#Получить список элементов #Получить список элементов
@ -136,7 +140,6 @@ def UIOSelector_Get_UIOList (inSpecificationList,inElement=None,inFlagRaiseExcep
if 'depth_start' in inSpecificationList[0]: if 'depth_start' in inSpecificationList[0]:
if inSpecificationList[0]["depth_start"]>1: if inSpecificationList[0]["depth_start"]>1:
lFlagGoCheck=False lFlagGoCheck=False
#pdb.set_trace()
#Циклический обход по детям, на предмет соответствия всем условиям #Циклический обход по детям, на предмет соответствия всем условиям
for lChildrenItem in lElementChildrenList: for lChildrenItem in lElementChildrenList:
#Обработка глубины depth (рекурсивный вызов для всех детей с занижением индекса глубины) #Обработка глубины depth (рекурсивный вызов для всех детей с занижением индекса глубины)
@ -149,7 +152,6 @@ def UIOSelector_Get_UIOList (inSpecificationList,inElement=None,inFlagRaiseExcep
lChildrenItemNewSpecificationList[0]["depth_end"]=lChildrenItemNewSpecificationList[0]["depth_end"]-1 lChildrenItemNewSpecificationList[0]["depth_end"]=lChildrenItemNewSpecificationList[0]["depth_end"]-1
if 'depth_start' in lChildrenItemNewSpecificationList[0]: if 'depth_start' in lChildrenItemNewSpecificationList[0]:
lChildrenItemNewSpecificationList[0]["depth_start"]=lChildrenItemNewSpecificationList[0]["depth_start"]-1 lChildrenItemNewSpecificationList[0]["depth_start"]=lChildrenItemNewSpecificationList[0]["depth_start"]-1
#pdb.set_trace()
#Циклический вызов для всех детей со скорректированной спецификацией #Циклический вызов для всех детей со скорректированной спецификацией
lResultList.extend(UIOSelector_Get_UIOList(lChildrenItemNewSpecificationList,lChildrenItem,inFlagRaiseException)) lResultList.extend(UIOSelector_Get_UIOList(lChildrenItemNewSpecificationList,lChildrenItem,inFlagRaiseException))
#Фильтрация #Фильтрация
@ -246,6 +248,8 @@ def UIOSelector_Exist_Bool (inSpecificationList):
#inFlagWaitAllInMoment - доп. условие - ожидать появление всех UIOSelector одновременно #inFlagWaitAllInMoment - доп. условие - ожидать появление всех UIOSelector одновременно
#return: [0,1,2] - index of UIOSpecification, which is appear #return: [0,1,2] - index of UIOSpecification, which is appear
#old name - - #old name - -
#####Внимание#####
##Функция ожидания появления элементов (тк элементы могут быть недоступны, неизвестно в каком фреймворке каждый из них может появиться)
def UIOSelectorsSecs_WaitAppear_List (inSpecificationListList,inWaitSecs,inFlagWaitAllInMoment=False): def UIOSelectorsSecs_WaitAppear_List (inSpecificationListList,inWaitSecs,inFlagWaitAllInMoment=False):
lResultFlag=False lResultFlag=False
lSecsSleep = 1 #Настроечный параметр lSecsSleep = 1 #Настроечный параметр
@ -294,7 +298,6 @@ def UIOSelectorSecs_WaitAppear_Bool (inSpecificationList,inWaitSecs):
#return None (if Process not found), int 32, or int 64 #return None (if Process not found), int 32, or int 64
def UIOSelector_Get_BitnessInt (inSpecificationList): def UIOSelector_Get_BitnessInt (inSpecificationList):
lResult=None lResult=None
#pdb.set_trace()
#Получить объект Application (Для проверки разрядности) #Получить объект Application (Для проверки разрядности)
lRootElement=PWASpecification_Get_PWAApplication(inSpecificationList) lRootElement=PWASpecification_Get_PWAApplication(inSpecificationList)
if lRootElement is not None: if lRootElement is not None:
@ -315,43 +318,54 @@ def Get_OSBitnessInt ():
################################################################################################## ##################################################################################################
#inControlSpecificationArray - List of dict, dict in pywinauto.find_windows notation #inControlSpecificationArray - List of dict, dict in pywinauto.find_windows notation
#Backend selection - attribute "backend" ("win32" || "uia") in 1-st list element #Backend selection - attribute "backend" ("win32" || "uia") in 1-st list element
#return UIO object #return list of UIO object
#old name - GetControl #old name - GetControl
def PWASpecification_Get_UIO(inControlSpecificationArray): def PWASpecification_Get_UIO(inControlSpecificationArray):
#Определение backend #Определение backend
lBackend=mDefaultPywinautoBackend lBackend=mDefaultPywinautoBackend
#pdb.set_trace()
if "backend" in inControlSpecificationArray[0]: if "backend" in inControlSpecificationArray[0]:
lBackend=inControlSpecificationArray[0]["backend"] lBackend=inControlSpecificationArray[0]["backend"]
inControlSpecificationArray[0].pop("backend") inControlSpecificationArray[0].pop("backend")
#Подготовка входного массива #Подготовка входного массива
inControlSpecificationOriginArray=inControlSpecificationArray inControlSpecificationOriginArray=copy.deepcopy(inControlSpecificationArray)
inControlSpecificationArray=UIOSelector_SearchProcessNormalize_UIOSelector(inControlSpecificationArray) inControlSpecificationArray=UIOSelector_SearchProcessNormalize_UIOSelector(inControlSpecificationArray)
#Выполнить идентификацию объектов, если передан массив #Выполнить идентификацию объектов, если передан массив
lResultList=[]; lResultList=[];
lTempObject=None lTempObject=None
if len(inControlSpecificationArray) > 0: if len(inControlSpecificationArray) > 0:
#Выполнить подключение к объекту #Сформировать выборку элементов, которые подходят под первый уровень спецификации
lRPAApplication = pywinauto.Application(backend=lBackend) lSpecificationLvL1List = pywinauto.findwindows.find_elements(**inControlSpecificationArray[0])
#Проверка разрядности for lItem in lSpecificationLvL1List:
try: #Сделать независимую копию и установить информацию о process_id и handle
lRPAApplication.connect(**inControlSpecificationArray[0]) lItemControlSpecificationArray=copy.deepcopy(inControlSpecificationArray)
except Exception as e: lItemControlSpecificationArray[0]["process_id"]=lItem.process_id
UIOSelector_TryRestore_Dict(inControlSpecificationArray) lItemControlSpecificationArray[0]["handle"]=lItem.handle
lItemControlSpecificationOriginArray=copy.deepcopy(inControlSpecificationOriginArray)
lItemControlSpecificationOriginArray[0]["process_id"]=lItem.process_id
lItemControlSpecificationOriginArray[0]["handle"]=lItem.handle
#Выполнить подключение к объекту
lRPAApplication = pywinauto.Application(backend=lBackend)
#Проверка разрядности
try: try:
lRPAApplication.connect(**inControlSpecificationArray[0]) lRPAApplication.connect(**lItemControlSpecificationArray[0])
except Exception as e: except Exception as e:
lRPAApplication = None UIOSelector_TryRestore_Dict(lItemControlSpecificationArray)
if lRPAApplication is not None: try:
#lTempObject=lRPAApplication.window(**inControlSpecificationArray[0]) lRPAApplication.connect(**lItemControlSpecificationArray[0])
#Скорректировано из-за недопонимания структуры except Exception as e:
lTempObject=lRPAApplication lRPAApplication = None
#Нормализация массива для целей выборки объекта (удаление конфликтующих ключей) if lRPAApplication is not None:
inControlSpecificationArray=UIOSelector_SearchUIONormalize_UIOSelector(inControlSpecificationOriginArray) #lTempObject=lRPAApplication.window(**lItemControlSpecificationArray[0])
#Циклическое прохождение к недрам объекта #Скорректировано из-за недопонимания структуры
for lWindowSpecification in inControlSpecificationArray[0:]: lTempObject=lRPAApplication
lTempObject=lTempObject.window(**lWindowSpecification) #Нормализация массива для целей выборки объекта (удаление конфликтующих ключей)
return lTempObject lItemControlSpecificationArray=UIOSelector_SearchUIONormalize_UIOSelector(lItemControlSpecificationOriginArray)
#Циклическое прохождение к недрам объекта
for lWindowSpecification in lItemControlSpecificationArray[0:]:
lTempObject=lTempObject.window(**lWindowSpecification)
#Добавить объект в результирующий массив
lResultList.append(lTempObject)
return lResultList
################################################################################################## ##################################################################################################
#inControlSpecificationArray - List of dict, dict in pywinauto.find_windows notation #inControlSpecificationArray - List of dict, dict in pywinauto.find_windows notation
#Backend selection - attribute "backend" ("win32" || "uia") in 1-st list element #Backend selection - attribute "backend" ("win32" || "uia") in 1-st list element
@ -360,7 +374,6 @@ def PWASpecification_Get_UIO(inControlSpecificationArray):
def PWASpecification_Get_PWAApplication(inControlSpecificationArray): def PWASpecification_Get_PWAApplication(inControlSpecificationArray):
#Определение backend #Определение backend
lBackend=mDefaultPywinautoBackend lBackend=mDefaultPywinautoBackend
#pdb.set_trace()
if "backend" in inControlSpecificationArray[0]: if "backend" in inControlSpecificationArray[0]:
lBackend=inControlSpecificationArray[0]["backend"] lBackend=inControlSpecificationArray[0]["backend"]
inControlSpecificationArray[0].pop("backend") inControlSpecificationArray[0].pop("backend")
@ -441,7 +454,6 @@ def UIOSelector_SearchChildByMouse_UIOTree(inElementSpecification):
#Detect backend of the elements #Detect backend of the elements
lFlagIsBackendWin32 = True lFlagIsBackendWin32 = True
#Если объект имеется (не None), то выполнить построение иерархии #Если объект имеется (не None), то выполнить построение иерархии
#pdb.set_trace()
if lElement is not None: if lElement is not None:
if lElement.backend.name == 'uia': if lElement.backend.name == 'uia':
lFlagIsBackendWin32 = False lFlagIsBackendWin32 = False
@ -1016,7 +1028,6 @@ def UIO_Highlight(lWrapperObject,colour='green',thickness=2,fill=win32defines.BS
#Установить фокус на объект, чтобы было видно выделение #Установить фокус на объект, чтобы было видно выделение
lWrapperObject.set_focus() lWrapperObject.set_focus()
time.sleep(0.5) time.sleep(0.5)
#pdb.set_trace()
# don't draw if dialog is not visible # don't draw if dialog is not visible
#if not lWrapperObject.is_visible(): #if not lWrapperObject.is_visible():
# return # return
@ -1095,7 +1106,7 @@ if not mFlagIsDebug:
lJSONInput = ProcessCommunicator.ProcessParentReadWaitObject() lJSONInput = ProcessCommunicator.ProcessParentReadWaitObject()
lProcessResponse["ActivitySpecificationDict"]=lJSONInput lProcessResponse["ActivitySpecificationDict"]=lJSONInput
#Выполнить вызов функции #Выполнить вызов функции
lProcessResponse["Result"]=JSONNormalize.JSONNormalizeDictListStrInt(locals()[lJSONInput['ActivityName']](*lJSONInput['ArgumentList'],**lJSONInput['ArgumentDict'])) lProcessResponse["Result"]=JSONNormalize.JSONNormalizeDictListStrIntBool(locals()[lJSONInput['ActivityName']](*lJSONInput['ArgumentList'],**lJSONInput['ArgumentDict']))
except Exception as e: except Exception as e:
#Установить флаг ошибки #Установить флаг ошибки
lProcessResponse["ErrorFlag"]=True lProcessResponse["ErrorFlag"]=True

@ -22,6 +22,7 @@ def JSONNormalizeDict(inDictionary):
type(lItemValue) is int or type(lItemValue) is int or
type(lItemValue) is str or type(lItemValue) is str or
type(lItemValue) is list or type(lItemValue) is list or
type(lItemValue) is bool or
lItemValue is None): lItemValue is None):
True==True True==True
else: else:
@ -47,6 +48,7 @@ def JSONNormalizeList(inList):
if ( if (
type(lItemValue) is int or type(lItemValue) is int or
type(lItemValue) is str or type(lItemValue) is str or
type(lItemValue) is bool or
lItemValue is None): lItemValue is None):
lResult.append(lItemValue) lResult.append(lItemValue)
#Если является словарем - вызвать функцию нормализации словаря #Если является словарем - вызвать функцию нормализации словаря
@ -65,15 +67,17 @@ def JSONNormalizeDictList(inDictList):
if type(inDictList) is list: if type(inDictList) is list:
lResult=JSONNormalizeList(inDictList) lResult=JSONNormalizeList(inDictList)
return lResult; return lResult;
def JSONNormalizeDictListStrInt(inDictListStrInt): def JSONNormalizeDictListStrIntBool(inDictListStrIntBool):
lResult=None lResult=None
if type(inDictListStrInt) is dict: if type(inDictListStrIntBool) is dict:
lResult=JSONNormalizeDict(inDictListStrInt) lResult=JSONNormalizeDict(inDictListStrIntBool)
if type(inDictListStrInt) is list: if type(inDictListStrIntBool) is list:
lResult=JSONNormalizeList(inDictListStrInt) lResult=JSONNormalizeList(inDictListStrIntBool)
if type(inDictListStrInt) is str: if type(inDictListStrIntBool) is str:
lResult=inDictListStrInt lResult=inDictListStrIntBool
if type(inDictListStrInt) is int: if type(inDictListStrIntBool) is int:
lResult=inDictListStrInt lResult=inDictListStrIntBool
if type(inDictListStrIntBool) is bool:
lResult=inDictListStrIntBool
return lResult; return lResult;

@ -88,7 +88,10 @@ def ActivityRun(inActivitySpecificationDict):
if mProcessGUI_x64 is None: if mProcessGUI_x64 is None:
lFlagRun64=False lFlagRun64=False
else: else:
if inActivitySpecificationDict["ActivityName"].startswith("UIOSelector") or inActivitySpecificationDict["ActivityName"].startswith("PWASpecification"): if inActivitySpecificationDict["ActivityName"]=="UIOSelectorsSecs_WaitAppear_List":
#Функция ожидания появления элементов (тк элементы могут быть недоступны, неизвестно в каком фреймворке каждый из них может появиться)
lFlagRun64=True
elif inActivitySpecificationDict["ActivityName"].startswith("UIOSelector") or inActivitySpecificationDict["ActivityName"].startswith("PWASpecification"):
if len(inActivitySpecificationDict["ArgumentList"])>0: if len(inActivitySpecificationDict["ArgumentList"])>0:
if len(inActivitySpecificationDict["ArgumentList"][0])>0: if len(inActivitySpecificationDict["ArgumentList"][0])>0:
#Определение разрядности (32 и 64) для тех функций, где это необходимо #Определение разрядности (32 и 64) для тех функций, где это необходимо

@ -22,6 +22,7 @@ def JSONNormalizeDict(inDictionary):
type(lItemValue) is int or type(lItemValue) is int or
type(lItemValue) is str or type(lItemValue) is str or
type(lItemValue) is list or type(lItemValue) is list or
type(lItemValue) is bool or
lItemValue is None): lItemValue is None):
True==True True==True
else: else:
@ -47,6 +48,7 @@ def JSONNormalizeList(inList):
if ( if (
type(lItemValue) is int or type(lItemValue) is int or
type(lItemValue) is str or type(lItemValue) is str or
type(lItemValue) is bool or
lItemValue is None): lItemValue is None):
lResult.append(lItemValue) lResult.append(lItemValue)
#Если является словарем - вызвать функцию нормализации словаря #Если является словарем - вызвать функцию нормализации словаря

@ -7,6 +7,7 @@ import zlib
import os import os
import ProcessCommunicator import ProcessCommunicator
import sys import sys
import traceback
sys.path.append('../Robot') sys.path.append('../Robot')
import Robot import Robot
@ -110,25 +111,39 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
# Write content as utf-8 data # Write content as utf-8 data
self.wfile.write(bytes(message, "utf8")) self.wfile.write(bytes(message, "utf8"))
if self.path == '/GUIAction': if self.path == '/GUIAction':
#ReadRequest #Обернуть в try, чтобы вернуть ответ, что сообщение не может быть обработано
lInputByteArrayLength = int(self.headers.get('Content-Length')) # pdb.set_trace()
lInputByteArray=self.rfile.read(lInputByteArrayLength)
#Превращение массива байт в объект
lInputObject=json.loads(lInputByteArray.decode('utf8'))
# Send response status code # Send response status code
self.send_response(200) self.send_response(200)
# Send headers # Send headers
self.send_header('Content-type','application/json') self.send_header('Content-type','application/json')
self.end_headers() self.end_headers()
# Send message back to client try:
#{'functionName':'', 'argsArray':[]} #ReadRequest
#pdb.set_trace() lInputByteArrayLength = int(self.headers.get('Content-Length'))
lRequestObject=lInputObject lInputByteArray=self.rfile.read(lInputByteArrayLength)
#Отправить команду роботу #Превращение массива байт в объект
lResponseObject=Robot.ActivityRun(lRequestObject) lInputObject=json.loads(lInputByteArray.decode('utf8'))
message = json.dumps(lResponseObject) # Send message back to client
# Write content as utf-8 data #{'functionName':'', 'argsArray':[]}
self.wfile.write(bytes(message, "utf8")) #pdb.set_trace()
lRequestObject=lInputObject
#Отправить команду роботу
lResponseObject=Robot.ActivityRun(lRequestObject)
message = json.dumps(lResponseObject)
except Exception as e:
#Установить флаг ошибки
lProcessResponse={"Result":None}
lProcessResponse["ErrorFlag"]=True
#Зафиксировать traceback
lProcessResponse["ErrorTraceback"]=traceback.format_exc()
#Зафиксировать Error message
lProcessResponse["ErrorMessage"]=str(e)
#lProcessResponse["ErrorArgs"]=str(e.args)
message = json.dumps(lProcessResponse)
finally:
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
if self.path == '/GUIActionList': if self.path == '/GUIActionList':
#ReadRequest #ReadRequest
lInputByteArrayLength = int(self.headers.get('Content-Length')) lInputByteArrayLength = int(self.headers.get('Content-Length'))

Loading…
Cancel
Save