@ -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 ( * * lItem ControlSpecificationArray[ 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 . JSONNormalizeDictListStrInt Bool ( locals ( ) [ lJSONInput [ ' ActivityName ' ] ] ( * lJSONInput [ ' ArgumentList ' ] , * * lJSONInput [ ' ArgumentDict ' ] ) )
except Exception as e :
except Exception as e :
#Установить флаг ошибки
#Установить флаг ошибки
lProcessResponse [ " ErrorFlag " ] = True
lProcessResponse [ " ErrorFlag " ] = True