From 02e8154710d109be3126c6958570350113f174bf Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 28 Oct 2009 19:53:31 -0400 Subject: [PATCH] remove error trap on read_stdin() - please fix bugs instead of relying on error trap some reformatting in Tables.py, as well as some new debug prints to deal with some potential issues. Add code to deal with potential problems in Win x64, that are biting me at random. Not finished, but the problems stopped happening so can't continue. --- pyfpdb/HUD_main.py | 162 ++++++++++++++++++++++----------------------- pyfpdb/Tables.py | 52 ++++++++++----- 2 files changed, 114 insertions(+), 100 deletions(-) diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py index a0f152b7..8ccc194e 100755 --- a/pyfpdb/HUD_main.py +++ b/pyfpdb/HUD_main.py @@ -189,99 +189,95 @@ class HUD_main(object): # be passed to HUDs for use in the gui thread. HUD objects should not # need their own access to the database, but should open their own # if it is required. - try: - self.db_connection = Database.Database(self.config) - tourny_finder = re.compile('(\d+) (\d+)') - -# get hero's screen names and player ids - self.hero, self.hero_ids = {}, {} - for site in self.config.get_supported_sites(): - result = self.db_connection.get_site_id(site) - if result: - site_id = result[0][0] - self.hero[site_id] = self.config.supported_sites[site].screen_name - self.hero_ids[site_id] = self.db_connection.get_player_id(self.config, site, self.hero[site_id]) + self.db_connection = Database.Database(self.config) + tourny_finder = re.compile('(\d+) (\d+)') - while 1: # wait for a new hand number on stdin - new_hand_id = sys.stdin.readline() - new_hand_id = string.rstrip(new_hand_id) - if new_hand_id == "": # blank line means quit - self.destroy() - break # this thread is not always killed immediately with gtk.main_quit() +# get hero's screen names and player ids + self.hero, self.hero_ids = {}, {} + for site in self.config.get_supported_sites(): + result = self.db_connection.get_site_id(site) + if result: + site_id = result[0][0] + self.hero[site_id] = self.config.supported_sites[site].screen_name + self.hero_ids[site_id] = self.db_connection.get_player_id(self.config, site, self.hero[site_id]) + + while 1: # wait for a new hand number on stdin + new_hand_id = sys.stdin.readline() + new_hand_id = string.rstrip(new_hand_id) + if new_hand_id == "": # blank line means quit + self.destroy() + break # this thread is not always killed immediately with gtk.main_quit() # get basic info about the new hand from the db # if there is a db error, complain, skip hand, and proceed - try: - (table_name, max, poker_game, type, site_id) = self.db_connection.get_table_name(new_hand_id) + try: + (table_name, max, poker_game, type, site_id) = self.db_connection.get_table_name(new_hand_id) - cards = self.db_connection.get_cards(new_hand_id) - comm_cards = self.db_connection.get_common_cards(new_hand_id) - if comm_cards != {}: # stud! - cards['common'] = comm_cards['common'] - except Exception, err: - err = traceback.extract_tb(sys.exc_info()[2])[-1] - print "db error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) - if new_hand_id: # new_hand_id is none if we had an error prior to the store - sys.stderr.write("Database error %s in hand %d. Skipping.\n" % (err, int(new_hand_id))) + cards = self.db_connection.get_cards(new_hand_id) + comm_cards = self.db_connection.get_common_cards(new_hand_id) + if comm_cards != {}: # stud! + cards['common'] = comm_cards['common'] + except Exception, err: + err = traceback.extract_tb(sys.exc_info()[2])[-1] + print "db error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) + if new_hand_id: # new_hand_id is none if we had an error prior to the store + sys.stderr.write("Database error %s in hand %d. Skipping.\n" % (err, int(new_hand_id))) + continue + + if type == "tour": # hand is from a tournament + mat_obj = tourny_finder.search(table_name) + if mat_obj: + (tour_number, tab_number) = mat_obj.group(1, 2) + temp_key = tour_number + else: # tourney, but can't get number and table + print "could not find tournament: skipping " + #sys.stderr.write("Could not find tournament %d in hand %d. Skipping.\n" % (int(tour_number), int(new_hand_id))) continue - - if type == "tour": # hand is from a tournament - mat_obj = tourny_finder.search(table_name) - if mat_obj: - (tour_number, tab_number) = mat_obj.group(1, 2) - temp_key = tour_number - else: # tourney, but can't get number and table - print "could not find tournament: skipping " - #sys.stderr.write("Could not find tournament %d in hand %d. Skipping.\n" % (int(tour_number), int(new_hand_id))) - continue - - else: - temp_key = table_name + + else: + temp_key = table_name # Update an existing HUD - if temp_key in self.hud_dict: - try: - # get stats using hud's specific params - self.db_connection.init_hud_stat_vars( self.hud_dict[temp_key].hud_params['hud_days'] - , self.hud_dict[temp_key].hud_params['h_hud_days']) - stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_dict[temp_key].hud_params, self.hero_ids[site_id]) - except: - err = traceback.extract_tb(sys.exc_info()[2])[-1] - print "db get_stats error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) - if new_hand_id: # new_hand_id is none if we had an error prior to the store - sys.stderr.write("Database get_stats error %s in hand %d. Skipping.\n" % (err, int(new_hand_id))) - continue - self.hud_dict[temp_key].stat_dict = stat_dict - self.hud_dict[temp_key].cards = cards - [aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[temp_key].aux_windows] - self.update_HUD(new_hand_id, temp_key, self.config) - + if temp_key in self.hud_dict: + try: + # get stats using hud's specific params + self.db_connection.init_hud_stat_vars( self.hud_dict[temp_key].hud_params['hud_days'] + , self.hud_dict[temp_key].hud_params['h_hud_days']) + stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_dict[temp_key].hud_params, self.hero_ids[site_id]) + except: + err = traceback.extract_tb(sys.exc_info()[2])[-1] + print "db get_stats error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) + if new_hand_id: # new_hand_id is none if we had an error prior to the store + sys.stderr.write("Database get_stats error %s in hand %d. Skipping.\n" % (err, int(new_hand_id))) + continue + self.hud_dict[temp_key].stat_dict = stat_dict + self.hud_dict[temp_key].cards = cards + [aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[temp_key].aux_windows] + self.update_HUD(new_hand_id, temp_key, self.config) + # Or create a new HUD + else: + try: + # get stats using default params + self.db_connection.init_hud_stat_vars( self.hud_params['hud_days'], self.hud_params['h_hud_days'] ) + stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_params, self.hero_ids[site_id]) + except: + err = traceback.extract_tb(sys.exc_info()[2])[-1] + print "db get_stats error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) + if new_hand_id: # new_hand_id is none if we had an error prior to the store + sys.stderr.write("Database get_stats error %s in hand %d. Skipping.\n" % (err, int(new_hand_id))) + continue + if type == "tour": + tablewindow = Tables.discover_tournament_table(self.config, tour_number, tab_number) else: - try: - # get stats using default params - self.db_connection.init_hud_stat_vars( self.hud_params['hud_days'], self.hud_params['h_hud_days'] ) - stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_params, self.hero_ids[site_id]) - except: - err = traceback.extract_tb(sys.exc_info()[2])[-1] - print "db get_stats error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) - if new_hand_id: # new_hand_id is none if we had an error prior to the store - sys.stderr.write("Database get_stats error %s in hand %d. Skipping.\n" % (err, int(new_hand_id))) - continue - if type == "tour": - tablewindow = Tables.discover_tournament_table(self.config, tour_number, tab_number) - else: - tablewindow = Tables.discover_table_by_name(self.config, table_name) - if tablewindow == None: + tablewindow = Tables.discover_table_by_name(self.config, table_name) + if tablewindow == None: # If no client window is found on the screen, complain and continue - if type == "tour": - table_name = "%s %s" % (tour_number, tab_number) - sys.stderr.write("table name "+table_name+" not found, skipping.\n") - else: - self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, type, stat_dict, cards) - self.db_connection.connection.rollback() - except: - err = traceback.extract_tb(sys.exc_info()[2])[-1] - print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) + if type == "tour": + table_name = "%s %s" % (tour_number, tab_number) + sys.stderr.write("table name "+table_name+" not found, skipping.\n") + else: + self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, type, stat_dict, cards) + self.db_connection.connection.rollback() if __name__== "__main__": diff --git a/pyfpdb/Tables.py b/pyfpdb/Tables.py index e725d5b8..46addabc 100755 --- a/pyfpdb/Tables.py +++ b/pyfpdb/Tables.py @@ -238,7 +238,8 @@ def discover_nt_by_name(c, tablename): try: # maybe it's better to make global titles[hwnd] decoding? # this can blow up in XP on some windows, eg firefox displaying http://docs.python.org/tutorial/classes.html - if not tablename.lower() in titles[hwnd].decode(LOCALE_ENCODING).lower(): continue + if not tablename.lower() in titles[hwnd].decode(LOCALE_ENCODING).lower(): + continue except: continue if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window @@ -246,8 +247,8 @@ def discover_nt_by_name(c, tablename): if 'Chat:' in titles[hwnd]: continue # Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows if ' - Table ' in titles[hwnd]: continue # Absolute table Chat window.. sigh. TODO: Can we tell what site we're trying to discover for somehow in here, so i can limit this check just to AP searches? temp = decode_windows(c, titles[hwnd], hwnd) - #print "attach to window", temp - return decode_windows(c, titles[hwnd], hwnd) + print "attach to window", temp + return temp return None def discover_nt_tournament(c, tour_number, tab_number): @@ -257,9 +258,12 @@ def discover_nt_tournament(c, tour_number, tab_number): titles ={} win32gui.EnumWindows(win_enum_handler, titles) for hwnd in titles: - if 'Chat:' in titles[hwnd]: continue # Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows - if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window - if 'HUD:' in titles[hwnd]: continue # FPDB HUD window + # Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows + if 'Chat:' in titles[hwnd]: continue + # Everleaf Network HH viewer window + if 'History for table:' in titles[hwnd]: continue + # FPDB HUD window + if 'HUD:' in titles[hwnd]: continue if re.search(search_string, titles[hwnd]): return decode_windows(c, titles[hwnd], hwnd) @@ -268,22 +272,34 @@ def discover_nt_tournament(c, tour_number, tab_number): def get_nt_exe(hwnd): """Finds the name of the executable that the given window handle belongs to.""" - # Request privileges to enable "debug process", so we can later use PROCESS_VM_READ, retardedly required to GetModuleFileNameEx() + # Request privileges to enable "debug process", so we can later use + # PROCESS_VM_READ, retardedly required to GetModuleFileNameEx() priv_flags = win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY - hToken = win32security.OpenProcessToken (win32api.GetCurrentProcess(), priv_flags) + hToken = win32security.OpenProcessToken (win32api.GetCurrentProcess(), + priv_flags) # enable "debug process" - privilege_id = win32security.LookupPrivilegeValue (None, win32security.SE_DEBUG_NAME) - old_privs = win32security.AdjustTokenPrivileges (hToken, 0, [(privilege_id, win32security.SE_PRIVILEGE_ENABLED)]) + privilege_id = win32security.LookupPrivilegeValue(None, + win32security.SE_DEBUG_NAME) + old_privs = win32security.AdjustTokenPrivileges(hToken, 0, + [(privilege_id, + win32security.SE_PRIVILEGE_ENABLED)]) # Open the process, and query it's filename processid = win32process.GetWindowThreadProcessId(hwnd) - pshandle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, False, processid[1]) - exename = win32process.GetModuleFileNameEx(pshandle, 0) - - # clean up - win32api.CloseHandle(pshandle) - win32api.CloseHandle(hToken) - + pshandle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | + win32con.PROCESS_VM_READ, False, + processid[1]) + try: + exename = win32process.GetModuleFileNameEx(pshandle, 0) + except pywintypes.error: + # insert code to call GetProcessImageName if we can find it.. + # returning None from here will hopefully break all following code + exename = None + finally: + # clean up + win32api.CloseHandle(pshandle) + win32api.CloseHandle(hToken) + return exename def decode_windows(c, title, hwnd): @@ -305,6 +321,8 @@ def decode_windows(c, title, hwnd): info['width'] = int( width ) - 2*b_width info['height'] = int( height ) - b_width - tb_height info['exe'] = get_nt_exe(hwnd) + print "get_nt_exe returned ", info['exe'] + # TODO: 'width' here is all sorts of screwed up. title_bits = re.split(' - ', info['title']) info['name'] = title_bits[0]