import time
from win32com.client import Dispatch
import pythoncom
import types

class IE:
	def __init__(self):
		self.ie = Dispatch("InternetExplorer.Application")
		self.ie.Visible = False
		
	def safely(self, method, args=None):
		new_method = 'self.ie.' + method
		
		if args is None:
			new_args = ()
		elif not isinstance(args, types.TupleType): # we assume there's 1 of it, ala a string/number/etc
			new_args = (args,)
		else:
			new_args = args
			
		# call
		retval = self.safely2(new_method, new_args, 1)
		
		# check if we just navigated somewhere or performed some sort of action
		# if so, wait a second or so for the page to move on, or the next call may
		# accidentaly still perform on the current page
		if method.startswith('Navigate') or method.endswith('click()'): time.sleep(2)
		
		# done
		return retval


	def safely2(self, method, args, attempts):
		try:
			# evaluate the expression, this will raise the exception if the object isn't 'ready' yet
			obj = eval(method)
			
			# if we called a method, call it, if we got a value (from eval) simply return it
			if callable(obj): 	return obj(*args)
			else:				return obj

		except:# pythoncom.com_error, x:
			if attempts > 30: raise					# don't try too many times
			time.sleep(5)							# wait a little
			return self.safely2(method, args, attempts+1)

