Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class ImageRegion(object):
- """
- -- single: single representation of the menu (for static menus)
- images/App.Menu.png
- -- single, multi-image: segmented (for dynamic menus: changes as resized)
- images/App.Menu-0.png
- images/App.Menu-1.png
- -- set: for menus that can exist in different orientations
- images/App.Menu[0].png
- images/App.Menu[1].png
- -- set, multi-image: different orientations, segmented (changes as resized)
- images/App.Menu[0]-0.png
- images/App.Menu[0]-1.png
- images/App.Menu[1]-0.png
- images/App.Menu[1]-1.png
- """
- # collection constants
- COL_TYPE_SINGLE = 'SINGLE'
- COL_TYPE_SERIES = 'SERIES'
- COL_TYPE_SEQUENCE = 'SEQUNECE'
- COL_TYPE_SERIES_SEQUENCE = 'SERIES_SEQUENCE'
- # name types
- NAME_TYPE_FULL = 'FULL' # Application.FileMenu.SaveDialog,button
- NAME_TYPE_GENERIC = 'GENERIC' # Application.SaveDialog,button
- NAME_TYPE_CLASS_ENTITY = "CLASS_ENTITY" # Button,button
- NAME_TYPE_CLASS = 'CLASS' # Button
- log = None
- name = None
- collectionType = None
- nameType = None
- range = None
- entity = None
- region = None
- state = None
- filename = None
- threadLock = None
- def __init__(self, entity, region=None, state=None):
- self.log = RobotLogger(entity=entity) # get logger singleton
- self.entity = entity # entity images are associated with
- if region:
- self.region = region # set the region to search within
- else:
- self.region = Config.screen # default to entire screen
- self.log.debug("region=%s" % self.region)
- # check button state
- if state == None or state == "":
- self.state = "" #enabled state doesn't need a tag
- else:
- self.state = "[%s]" % state
- """
- NAME_TYPE_FULL = 'FULL' # Application.FileMenu.SaveDialog,button # Application.FileMenu.SaveDialog
- NAME_TYPE_GENERIC = 'GENERIC' # Application.SaveDialog,button # Application.SaveDialog
- NAME_TYPE_CLASS_ENTITY = 'CLASS_ENTITY' # Button,button # Window.SaveDialog
- NAME_TYPE_CLASS = 'CLASS' # Button # Window
- """
- for filename, nameType in ( \
- (entity.getCanonicalName(ancestorEntities=False, topLevel=False) + '/' + entity.getCanonicalName(),self.NAME_TYPE_FULL), \
- (entity.getCanonicalName(ancestorEntities=False, topLevel=False) + '/' + entity.getCanonicalName(ancestorEntities=False), self.NAME_TYPE_GENERIC), \
- (entity.getClassName() + entity.getCanonicalName(rootEntity=False, ancestorEntities=False, parentEntity=False), self.NAME_TYPE_CLASS_ENTITY), \
- (entity.getClassName(), self.NAME_TYPE_CLASS)
- ):
- # single
- try:
- ImageLocator().locate(filename + self.state + Config.imageSuffix)[:-4] # get full path, minus .png extension
- except:
- pass # file doesn't exist
- else:
- self.filename = filename
- self.nameType = nameType
- self.collectionType = self.COL_TYPE_SINGLE
- self.range = [0,]
- self.__logFound()
- return
- # sequence
- try:
- ImageLocator().locate(filename + '-0' + self.state + Config.imageSuffix)[:-4] # get full path, minus .png extension
- except:
- pass # file doesn't exist
- else:
- self.filename = filename
- self.nameType = nameType
- self.collectionType = self.COL_TYPE_SEQUENCE
- self.range = [0,]
- self.__logFound()
- return
- # series
- seq = 0
- while True:
- try:
- ImageLocator().locate(filename + '[' + str(seq) + ']' + self.state + Config.imageSuffix)[:-4] # get full path, minus .png extension
- except:
- break # end of series
- else:
- seq += 1
- if seq > 0:
- self.filename = filename
- self.nameType = nameType
- self.collectionType = self.COL_TYPE_SERIES
- self.range = range(0, seq)
- self.__logFound()
- return
- # sequence + series
- seq = 0
- while True:
- try:
- ImageLocator().locate(filename + '[' + str(seq) + ']-0' + self.state + Config.imageSuffix)[:-4] # get full path, minus .png extension
- except:
- break # end of sequence
- else:
- seq += 1
- if seq > 0:
- self.filename = filename
- self.nameType = nameType
- self.collectionType = self.COL_TYPE_SERIES_SEQUENCE
- self.range = range(0, seq)
- self.__logFound()
- return
- self.log.debug("failed to find image on disk [\"%s%s\"] nameType=%s" % (filename, self.state, nameType))
- raise ImageMissing("cannot find image on disk [\"%s%s\"]" % (filename, self.state)) # if we don't have single image or sequence, file cannot be found
- def __logFound(self):
- pngs = []
- # sequence and series
- for series in self.range:
- pngs.append( ','.join( self.log.image(self.getImageNames(), tag='series_' + str(series) )) )
- self.log.debug("[\"%s\"](%s) colType=%s nameType=%s" % (self.filename, ','.join(pngs), self.collectionType, self.nameType))
- def getImageNames(self, series=0, state=None):
- """ Return the image names for a certain sequence
- @keyword type: Collection type
- @keyword series: If COL_SERIES or COL_SERIES_SEQUENCE, series #
- """
- files = []
- sequence = 0
- while True:
- try:
- # form suffix based on type, series/sequence #
- if self.collectionType == self.COL_TYPE_SINGLE:
- suffix = ''
- elif self.collectionType == self.COL_TYPE_SERIES:
- suffix = '[' + str(series) + ']'
- elif self.collectionType == self.COL_TYPE_SEQUENCE:
- suffix = '-' + str(sequence)
- elif self.collectionType == self.COL_TYPE_SERIES_SEQUENCE:
- suffix = '[' + str(series) + ']-' + str(sequence)
- files.append( ImageLocator().locate(self.filename + suffix + self.state + Config.imageSuffix) )
- except java.io.FileNotFoundException, e:
- break # end of sequence
- else:
- # If single image, or series only 1 file to return
- if (self.collectionType == self.COL_TYPE_SINGLE) or (self.collectionType == self.COL_TYPE_SERIES):
- return files
- else:
- sequence += 1
- assert len(files) > 0 # we should have returned at least one file
- return files
- def find(self, timeout=5):
- self.log.debug(" colType=%s" % (self.collectionType))
- #startTime = time.time() (time.time() - startTime)
- attempt = 0
- while attempt < timeout:
- attempt += 1
- try:
- result = self.performFind()
- self.log.debug("-- success! [attempt=%i]" % attempt)
- return result
- except ImageSearchExhausted, e:
- self.log.debug("-- failure! [attempt=%i]" % attempt)
- raise FindExhausted()
- def performFind(self):
- # poorman's lock? Major problems were encountered by sleeping the main thread
- # This will sleep the main thread when a handler is active
- if (Thread.currentThread() != ImageRegion.threadLock) and ImageRegion.threadLock:
- self.log.debug("threadlock in effect, sleeping %s" % Thread.currentThread())
- while ImageRegion.threadLock:
- sleep(1)
- self.log.debug("threadlock cleared, waking %s" % Thread.currentThread())
- # sequence and series
- for series in self.range:
- regions = []
- lastRegion = self.region
- nextRegion = Region(self.region)
- # try to match all images in the sequence
- try:
- for (sequence, filename) in enumerate(self.getImageNames(series=series,state=self.state)):
- transforms = Transforms(filename, entity=self.entity)
- # Apply prev search attribs
- nextRegion = transforms.apply(nextRegion, Transforms.CONTEXT_PREVIOUS)
- # Apply search attribs
- pattern = transforms.apply(Pattern(filename), Transforms.CONTEXT_CURRENT)
- # find the image on the screen
- lastRegion = nextRegion.wait( pattern ) # If we don't set to zero wait time (dialog handler threads wait indefinitely)
- self.log.debug("validated [%s](%s) [%s](%s) in region [%s](%s) nameType=%s colType=%s ser=%s seq=%s" % (filename, self.log.image(filename), lastRegion, self.log.region(region=lastRegion), nextRegion, self.log.region(region=nextRegion), self.nameType, self.collectionType, series, sequence))
- regions.append( lastRegion )
- # Transform next region with the spacial region
- # spacialRegion is only used if there are spacial modifiers
- nextRegion = transforms.apply(Region(nextRegion), Transforms.CONTEXT_NEXT, override=lastRegion)
- except FindFailed, e:
- self.log.debug("failed to find on screen [\"images\"](%s) in [%s](%s) nameType=%s colType=%s ser=%s seq=%s" % (','.join(self.log.image(self.getImageNames(series=series,state=self.state))), nextRegion, self.log.region(nextRegion), self.nameType, self.collectionType, series, sequence))
- else:
- # if single region just return it
- if len(regions) == 1:
- return regions[0]
- # more than one region, get min/max region
- minX, minY = 9999, 9999
- maxX, maxY = -9999, -9999
- for region in regions:
- if region.getX() < minX: minX = region.getX()
- if region.getY() < minY: minY = region.getY()
- if (region.getX() + region.getW()) > maxX: maxX = region.getX() + region.getW()
- if (region.getY() + region.getH()) > maxY: maxY = region.getY() + region.getH()
- # return final region
- region = Region(minX, minY, maxX-minX, maxY-minY)
- return region
- raise ImageSearchExhausted()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement