loops/agent/crawl/watsup/AppControls.py
tschmid 41e98f0bef initial check in
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2069 fd906abe-77d9-0310-91a1-e0d9ade77398
2007-09-25 06:31:14 +00:00

152 lines
5.4 KiB
Python

""" Class and functions to find the windowText and className for a given executable
"""
# Author : Tim Couper - tim@2wave.net
# Date : 22 July 2004
# Version : 1.1
# Copyright : Copyright TAC Software Ltd, under Python-style licence.
# Provided as-is, with no warranty.
# Notes : Requires Python 2.3, win32all, ctypes & watsup package
import os.path
from watsup.winGuiAuto import findTopWindows,findControls,dumpWindow,\
dumpTopWindows
from watsup.utils import dumpHwnd,tupleHwnd
from watsup.launcher import AppThread,terminateApp
from watsup.OrderedDict import OrderedDict
from time import time,sleep
from types import ListType
THREAD_TIMEOUT_SECS=2.0
INDENT=2
#wstruct is of the form [hwnd,wclass,wtext] or
# [hwnd,wclass,wtext,[winstruct]
##def printwstruct(wstruct):
## print 'printFormat had trouble with:\n%s' % str(wstruct[3])
## import pprint
## print '------'
## pprint.pprint(wstruct)
## print '------'
def printFormat(wstruct,indent=0):
def printwstruct(wstruct):
print 'printFormat had trouble with:\n%s' % str(wstruct[3])
import pprint
print '------'
pprint.pprint(wstruct)
print '------'
"""wstruct is either a wintuple, or a recursive list of wintuples
"""
# type 1
if type(wstruct[1]) is not ListType:
print '%s%s: %s' % (' '*indent,wstruct[2],wstruct[1])
if len(wstruct)>3 and wstruct[3]<>None:
try:
for item in wstruct[3]:
printFormat(item,indent+INDENT)
except:
print_wstruct(wstruct)
# type 2:
else:
for item in wstruct[1]:
printFormat(item,indent+INDENT)
class AppControls(object):
def __init__(self,program,wantedText=None,wantedClass=None,selectionFunction=None,verbose=False):
self.wantedText=wantedText
self.wantedClass=wantedClass
self.selectionFunction=selectionFunction
self.verbose=verbose
topHwnds,unwantedHwnds,self.appThread=findAppTopWindows(program,verbose=verbose) #should only be one, but you never know
self.topHwnds=[]
self.unwantedHwnds=unwantedHwnds
def run(self):
while self.appThread.isAlive():
results=findNewTopWindows(self.unwantedHwnds,self.verbose)
if results:
self.process(results) # update the list of topWindows and unwanted TopWindows
def process(self,results):
for hwnd in results:
ctHwnds=findControls(hwnd)
if ctHwnds:
# we only add hwnd if there are controlHwnds
# as there may be a form which exists
# as an hwnd, but has not controls materialised yet
self.unwantedHwnds.append(hwnd)
self.write(hwnd)
for ctHwnd in ctHwnds:
self.unwantedHwnds.append(ctHwnd)
def write(self,hwnd):
h=tupleHwnd(hwnd)
t=[h[0],h[1],h[2],dumpWindow(hwnd)]
printFormat(t)
def findNewTopWindows(unwantedHwnds=[],verbose=False):
# returns a list of all top windows' hwnds we haven't
# found yet
htuples=dumpTopWindows()
if verbose:
print '..%d windows found (%d windows in unwanted)' % (len(htuples),len(unwantedHwnds))
results=[]
for htuple in htuples:
hwnd=htuple[0]
if hwnd not in unwantedHwnds:
if verbose:
print '..adding %s' % dumpHwnd(hwnd)
results.append(hwnd)
return results
def findAppTopWindows(program,verbose=False):
"""returns the hwnds for the program, along with the hwnds for the
stuff that are to be ignored
"""
# first we run findTopWindows before launching the program; store the hwnds found
# (note that it doesn't matter if an instance of the program IS running
# as we'll start another one whose hwnds will be new)
# run findTopWindows, and remove from the list any which are stored
unwantedHwnds=findNewTopWindows() # list of topWindow hwnds that exist
if verbose:
print '..%d original window(s)' % len(unwantedHwnds)
# run the program
appThread=AppThread(program,verbose)
appThread.start()
# give the thread a chance to get going:
results=[]
t=time()
while not results and ((time()-t)<THREAD_TIMEOUT_SECS):
sleep(0.2) # means that the thread hasn't launched; give it a chance
results=findNewTopWindows(unwantedHwnds,verbose)
if not results:
# stop the program
terminateApp()
raise Exception, 'Failed to find any new windows!'
if verbose:
print '..%d additional (new) non-trivial window(s)' % len(results)
if verbose:
for hwnd in results:
print '..%s: %s' % tupleHwnd(hwnd)[:2]
return results,unwantedHwnds,appThread
if __name__=='__main__':
pass