Merge branch 'master' of git://git.assembla.com/fpdb-eric

This commit is contained in:
Eratosthenes 2009-10-31 17:03:51 -04:00
commit 1e051e47ec
6 changed files with 182 additions and 148 deletions

View File

@ -41,7 +41,8 @@ class GuiPlayerStats (threading.Thread):
self.main_window = mainwin self.main_window = mainwin
self.sql = querylist self.sql = querylist
self.liststore = None self.liststore = [] # gtk.ListStore[] stores the contents of the grids
self.listcols = [] # gtk.TreeViewColumn[][] stores the columns in the grids
self.MYSQL_INNODB = 2 self.MYSQL_INNODB = 2
self.PGSQL = 3 self.PGSQL = 3
@ -162,6 +163,8 @@ class GuiPlayerStats (threading.Thread):
def refreshStats(self, widget, data): def refreshStats(self, widget, data):
try: self.stats_vbox.destroy() try: self.stats_vbox.destroy()
except AttributeError: pass except AttributeError: pass
self.liststore = []
self.listcols = []
#self.stats_vbox = gtk.VBox(False, 0) #self.stats_vbox = gtk.VBox(False, 0)
self.stats_vbox = gtk.VPaned() self.stats_vbox = gtk.VPaned()
self.stats_vbox.show() self.stats_vbox.show()
@ -217,8 +220,10 @@ class GuiPlayerStats (threading.Thread):
# 3rd parameter passes extra flags, currently includes: # 3rd parameter passes extra flags, currently includes:
# holecards - whether to display card breakdown (True/False) # holecards - whether to display card breakdown (True/False)
# numhands - min number hands required when displaying all players # numhands - min number hands required when displaying all players
flags = [False, self.filters.getNumHands()] # gridnum - index for grid data structures
self.addTable(swin, 'playerDetailedStats', flags, playerids, sitenos, limits, type, seats, groups, dates) flags = [False, self.filters.getNumHands(), 0]
self.addGrid(swin, 'playerDetailedStats', flags, playerids
,sitenos, limits, type, seats, groups, dates)
# Separator # Separator
vbox2 = gtk.VBox(False, 0) vbox2 = gtk.VBox(False, 0)
@ -236,7 +241,9 @@ class GuiPlayerStats (threading.Thread):
# Detailed table # Detailed table
flags[0] = True flags[0] = True
self.addTable(swin, 'playerDetailedStats', flags, playerids, sitenos, limits, type, seats, groups, dates) flags[2] = 1
self.addGrid(swin, 'playerDetailedStats', flags, playerids
,sitenos, limits, type, seats, groups, dates)
self.db.rollback() self.db.rollback()
print "Stats page displayed in %4.2f seconds" % (time() - starttime) print "Stats page displayed in %4.2f seconds" % (time() - starttime)
@ -257,11 +264,12 @@ class GuiPlayerStats (threading.Thread):
return return
def sortnums(self, model, iter1, iter2, n): def sortnums(self, model, iter1, iter2, nums):
try: try:
ret = 0 ret = 0
a = self.liststore.get_value(iter1, n) (n, grid) = nums
b = self.liststore.get_value(iter2, n) a = self.liststore[grid].get_value(iter1, n)
b = self.liststore[grid].get_value(iter2, n)
if 'f' in self.cols_to_show[n][4]: if 'f' in self.cols_to_show[n][4]:
try: a = float(a) try: a = float(a)
except: a = 0.0 except: a = 0.0
@ -281,7 +289,7 @@ class GuiPlayerStats (threading.Thread):
ret = 0 ret = 0
else: else:
ret = 1 ret = 1
#print "n =", n, "iter1[n] =", self.liststore.get_value(iter1,n), "iter2[n] =", self.liststore.get_value(iter2,n), "ret =", ret #print "n =", n, "iter1[n] =", self.liststore[grid].get_value(iter1,n), "iter2[n] =", self.liststore[grid].get_value(iter2,n), "ret =", ret
except: except:
err = traceback.extract_tb(sys.exc_info()[2]) err = traceback.extract_tb(sys.exc_info()[2])
print "***sortnums error: " + str(sys.exc_info()[1]) print "***sortnums error: " + str(sys.exc_info()[1])
@ -289,18 +297,19 @@ class GuiPlayerStats (threading.Thread):
return(ret) return(ret)
def sortcols(self, col, n): def sortcols(self, col, nums):
try: try:
#This doesn't actually work yet - clicking heading in top section sorts bottom section :-( #This doesn't actually work yet - clicking heading in top section sorts bottom section :-(
if col.get_sort_order() == gtk.SORT_ASCENDING: (n, grid) = nums
if not col.get_sort_indicator() or col.get_sort_order() == gtk.SORT_ASCENDING:
col.set_sort_order(gtk.SORT_DESCENDING) col.set_sort_order(gtk.SORT_DESCENDING)
else: else:
col.set_sort_order(gtk.SORT_ASCENDING) col.set_sort_order(gtk.SORT_ASCENDING)
self.liststore.set_sort_column_id(n, col.get_sort_order()) self.liststore[grid].set_sort_column_id(n, col.get_sort_order())
self.liststore.set_sort_func(n, self.sortnums, n) self.liststore[grid].set_sort_func(n, self.sortnums, (n,grid))
for i in xrange(len(self.listcols)): for i in xrange(len(self.listcols[grid])):
self.listcols[i].set_sort_indicator(False) self.listcols[grid][i].set_sort_indicator(False)
self.listcols[n].set_sort_indicator(True) self.listcols[grid][n].set_sort_indicator(True)
# use this listcols[col].set_sort_indicator(True) # use this listcols[col].set_sort_indicator(True)
# to turn indicator off for other cols # to turn indicator off for other cols
except: except:
@ -308,12 +317,12 @@ class GuiPlayerStats (threading.Thread):
print "***sortcols error: " + str(sys.exc_info()[1]) print "***sortcols error: " + str(sys.exc_info()[1])
print "\n".join( [e[0]+':'+str(e[1])+" "+e[2] for e in err] ) print "\n".join( [e[0]+':'+str(e[1])+" "+e[2] for e in err] )
def addTable(self, vbox, query, flags, playerids, sitenos, limits, type, seats, groups, dates): def addGrid(self, vbox, query, flags, playerids, sitenos, limits, type, seats, groups, dates):
counter = 0 counter = 0
row = 0 row = 0
sqlrow = 0 sqlrow = 0
if not flags: holecards = False if not flags: holecards,grid = False,0
else: holecards = flags[0] else: holecards,grid = flags[0],flags[2]
tmp = self.sql.query[query] tmp = self.sql.query[query]
tmp = self.refineQuery(tmp, flags, playerids, sitenos, limits, type, seats, groups, dates) tmp = self.refineQuery(tmp, flags, playerids, sitenos, limits, type, seats, groups, dates)
@ -325,8 +334,9 @@ class GuiPlayerStats (threading.Thread):
self.cols_to_show = [x for x in self.columns if x[colshow]] self.cols_to_show = [x for x in self.columns if x[colshow]]
hgametypeid_idx = colnames.index('hgametypeid') hgametypeid_idx = colnames.index('hgametypeid')
self.liststore = gtk.ListStore(*([str] * len(self.cols_to_show))) assert len(self.liststore) == grid, "len(self.liststore)="+str(len(self.liststore))+" grid-1="+str(grid)
view = gtk.TreeView(model=self.liststore) self.liststore.append( gtk.ListStore(*([str] * len(self.cols_to_show))) )
view = gtk.TreeView(model=self.liststore[grid])
view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH) view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
#vbox.pack_start(view, expand=False, padding=3) #vbox.pack_start(view, expand=False, padding=3)
vbox.add(view) vbox.add(view)
@ -335,7 +345,8 @@ class GuiPlayerStats (threading.Thread):
textcell50.set_property('xalign', 0.5) textcell50.set_property('xalign', 0.5)
numcell = gtk.CellRendererText() numcell = gtk.CellRendererText()
numcell.set_property('xalign', 1.0) numcell.set_property('xalign', 1.0)
self.listcols = [] assert len(self.listcols) == grid
self.listcols.append( [] )
# Create header row eg column: ("game", True, "Game", 0.0, "%s") # Create header row eg column: ("game", True, "Game", 0.0, "%s")
for col, column in enumerate(self.cols_to_show): for col, column in enumerate(self.cols_to_show):
@ -343,31 +354,33 @@ class GuiPlayerStats (threading.Thread):
s = [x for x in self.columns if x[colalias] == 'hand'][0][colheading] s = [x for x in self.columns if x[colalias] == 'hand'][0][colheading]
else: else:
s = column[colheading] s = column[colheading]
self.listcols.append(gtk.TreeViewColumn(s)) self.listcols[grid].append(gtk.TreeViewColumn(s))
view.append_column(self.listcols[col]) view.append_column(self.listcols[grid][col])
if column[colformat] == '%s': if column[colformat] == '%s':
if column[colxalign] == 0.0: if column[colxalign] == 0.0:
self.listcols[col].pack_start(textcell, expand=True) self.listcols[grid][col].pack_start(textcell, expand=True)
self.listcols[col].add_attribute(textcell, 'text', col) self.listcols[grid][col].add_attribute(textcell, 'text', col)
cellrend = textcell
else: else:
self.listcols[col].pack_start(textcell50, expand=True) self.listcols[grid][col].pack_start(textcell50, expand=True)
self.listcols[col].add_attribute(textcell50, 'text', col) self.listcols[grid][col].add_attribute(textcell50, 'text', col)
self.listcols[col].set_expand(True) cellrend = textcell50
self.listcols[grid][col].set_expand(True)
else: else:
self.listcols[col].pack_start(numcell, expand=True) self.listcols[grid][col].pack_start(numcell, expand=True)
self.listcols[col].add_attribute(numcell, 'text', col) self.listcols[grid][col].add_attribute(numcell, 'text', col)
self.listcols[col].set_expand(True) self.listcols[grid][col].set_expand(True)
#self.listcols[col].set_alignment(column[colxalign]) # no effect? cellrend = numcell
if holecards: #self.listcols[grid][col].set_alignment(column[colxalign]) # no effect?
self.listcols[col].set_clickable(True) self.listcols[grid][col].set_clickable(True)
self.listcols[col].connect("clicked", self.sortcols, col) self.listcols[grid][col].connect("clicked", self.sortcols, (col,grid))
if col == 0: if col == 0:
self.listcols[col].set_sort_order(gtk.SORT_DESCENDING) self.listcols[grid][col].set_sort_order(gtk.SORT_DESCENDING)
self.listcols[col].set_sort_indicator(True) self.listcols[grid][col].set_sort_indicator(True)
if column[coltype] == 'cash': if column[coltype] == 'cash':
self.listcols[col].set_cell_data_func(numcell, self.ledger_style_render_func) self.listcols[grid][col].set_cell_data_func(numcell, self.ledger_style_render_func)
else: else:
self.listcols[col].set_cell_data_func(numcell, self.reset_style_render_func) self.listcols[grid][col].set_cell_data_func(cellrend, self.reset_style_render_func)
rows = len(result) # +1 for title row rows = len(result) # +1 for title row
@ -408,12 +421,12 @@ class GuiPlayerStats (threading.Thread):
treerow.append(column[colformat] % value) treerow.append(column[colformat] % value)
else: else:
treerow.append(' ') treerow.append(' ')
iter = self.liststore.append(treerow) iter = self.liststore[grid].append(treerow)
sqlrow += 1 sqlrow += 1
row += 1 row += 1
vbox.show_all() vbox.show_all()
#end def addTable(self, query, vars, playerids, sitenos, limits, type, seats, groups, dates): #end def addGrid(self, query, vars, playerids, sitenos, limits, type, seats, groups, dates):
def refineQuery(self, query, flags, playerids, sitenos, limits, type, seats, groups, dates): def refineQuery(self, query, flags, playerids, sitenos, limits, type, seats, groups, dates):
having = '' having = ''

View File

@ -24,18 +24,22 @@ import os
import traceback import traceback
from time import time, strftime, localtime from time import time, strftime, localtime
try: try:
calluse = not 'matplotlib' in sys.modules
import matplotlib import matplotlib
matplotlib.use('GTK') if calluse:
matplotlib.use('GTK')
from matplotlib.figure import Figure from matplotlib.figure import Figure
from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas
from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar
from matplotlib.finance import candlestick2 from matplotlib.finance import candlestick2
from numpy import diff, nonzero, sum, cumsum, max, mina from numpy import diff, nonzero, sum, cumsum, max, min
# from matplotlib.dates import DateFormatter, WeekdayLocator, HourLocator, \ # from matplotlib.dates import DateFormatter, WeekdayLocator, HourLocator, \
# DayLocator, MONDAY, timezone # DayLocator, MONDAY, timezone
except: except:
err = traceback.extract_tb(sys.exc_info()[2])[-1]
print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
print """Failed to load numpy in Session Viewer""" print """Failed to load numpy in Session Viewer"""
print """This is of no consequence as the module currently doesn't do anything.""" print """This is of no consequence as the module currently doesn't do anything."""

View File

@ -189,99 +189,95 @@ class HUD_main(object):
# be passed to HUDs for use in the gui thread. HUD objects should not # 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 # need their own access to the database, but should open their own
# if it is required. # if it is required.
try: self.db_connection = Database.Database(self.config)
self.db_connection = Database.Database(self.config) tourny_finder = re.compile('(\d+) (\d+)')
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])
while 1: # wait for a new hand number on stdin # get hero's screen names and player ids
new_hand_id = sys.stdin.readline() self.hero, self.hero_ids = {}, {}
new_hand_id = string.rstrip(new_hand_id) for site in self.config.get_supported_sites():
if new_hand_id == "": # blank line means quit result = self.db_connection.get_site_id(site)
self.destroy() if result:
break # this thread is not always killed immediately with gtk.main_quit() 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 # get basic info about the new hand from the db
# if there is a db error, complain, skip hand, and proceed # if there is a db error, complain, skip hand, and proceed
try: try:
(table_name, max, poker_game, type, site_id) = self.db_connection.get_table_name(new_hand_id) (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) cards = self.db_connection.get_cards(new_hand_id)
comm_cards = self.db_connection.get_common_cards(new_hand_id) comm_cards = self.db_connection.get_common_cards(new_hand_id)
if comm_cards != {}: # stud! if comm_cards != {}: # stud!
cards['common'] = comm_cards['common'] cards['common'] = comm_cards['common']
except Exception, err: except Exception, err:
err = traceback.extract_tb(sys.exc_info()[2])[-1] 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]) 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 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))) 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 continue
if type == "tour": # hand is from a tournament else:
mat_obj = tourny_finder.search(table_name) temp_key = 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
# Update an existing HUD # Update an existing HUD
if temp_key in self.hud_dict: if temp_key in self.hud_dict:
try: try:
# get stats using hud's specific params # get stats using hud's specific params
self.db_connection.init_hud_stat_vars( self.hud_dict[temp_key].hud_params['hud_days'] 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']) , 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]) 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: except:
err = traceback.extract_tb(sys.exc_info()[2])[-1] 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]) 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 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))) sys.stderr.write("Database get_stats error %s in hand %d. Skipping.\n" % (err, int(new_hand_id)))
continue continue
self.hud_dict[temp_key].stat_dict = stat_dict self.hud_dict[temp_key].stat_dict = stat_dict
self.hud_dict[temp_key].cards = cards 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] [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) self.update_HUD(new_hand_id, temp_key, self.config)
# Or create a new HUD # 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: else:
try: tablewindow = Tables.discover_table_by_name(self.config, table_name)
# get stats using default params if tablewindow == None:
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:
# If no client window is found on the screen, complain and continue # If no client window is found on the screen, complain and continue
if type == "tour": if type == "tour":
table_name = "%s %s" % (tour_number, tab_number) table_name = "%s %s" % (tour_number, tab_number)
sys.stderr.write("table name "+table_name+" not found, skipping.\n") sys.stderr.write("table name "+table_name+" not found, skipping.\n")
else: else:
self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, type, stat_dict, cards) self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, type, stat_dict, cards)
self.db_connection.connection.rollback() 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 __name__== "__main__": if __name__== "__main__":

View File

@ -238,7 +238,8 @@ def discover_nt_by_name(c, tablename):
try: try:
# maybe it's better to make global titles[hwnd] decoding? # 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 # 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: except:
continue continue
if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window 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 '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? 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) temp = decode_windows(c, titles[hwnd], hwnd)
#print "attach to window", temp print "attach to window", temp
return decode_windows(c, titles[hwnd], hwnd) return temp
return None return None
def discover_nt_tournament(c, tour_number, tab_number): def discover_nt_tournament(c, tour_number, tab_number):
@ -257,9 +258,12 @@ def discover_nt_tournament(c, tour_number, tab_number):
titles ={} titles ={}
win32gui.EnumWindows(win_enum_handler, titles) win32gui.EnumWindows(win_enum_handler, titles)
for hwnd in titles: for hwnd in titles:
if 'Chat:' in titles[hwnd]: continue # Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows # 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 'Chat:' in titles[hwnd]: continue
if 'HUD:' in titles[hwnd]: continue # FPDB HUD window # 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]): if re.search(search_string, titles[hwnd]):
return decode_windows(c, titles[hwnd], 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): def get_nt_exe(hwnd):
"""Finds the name of the executable that the given window handle belongs to.""" """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 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" # enable "debug process"
privilege_id = win32security.LookupPrivilegeValue (None, win32security.SE_DEBUG_NAME) privilege_id = win32security.LookupPrivilegeValue(None,
old_privs = win32security.AdjustTokenPrivileges (hToken, 0, [(privilege_id, win32security.SE_PRIVILEGE_ENABLED)]) win32security.SE_DEBUG_NAME)
old_privs = win32security.AdjustTokenPrivileges(hToken, 0,
[(privilege_id,
win32security.SE_PRIVILEGE_ENABLED)])
# Open the process, and query it's filename # Open the process, and query it's filename
processid = win32process.GetWindowThreadProcessId(hwnd) processid = win32process.GetWindowThreadProcessId(hwnd)
pshandle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, False, processid[1]) pshandle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION |
exename = win32process.GetModuleFileNameEx(pshandle, 0) win32con.PROCESS_VM_READ, False,
processid[1])
# clean up try:
win32api.CloseHandle(pshandle) exename = win32process.GetModuleFileNameEx(pshandle, 0)
win32api.CloseHandle(hToken) 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 return exename
def decode_windows(c, title, hwnd): def decode_windows(c, title, hwnd):
@ -305,6 +321,8 @@ def decode_windows(c, title, hwnd):
info['width'] = int( width ) - 2*b_width info['width'] = int( width ) - 2*b_width
info['height'] = int( height ) - b_width - tb_height info['height'] = int( height ) - b_width - tb_height
info['exe'] = get_nt_exe(hwnd) 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']) title_bits = re.split(' - ', info['title'])
info['name'] = title_bits[0] info['name'] = title_bits[0]

View File

@ -516,6 +516,8 @@ class fpdb:
print "Quitting normally" print "Quitting normally"
#check if current settings differ from profile, if so offer to save or abort #check if current settings differ from profile, if so offer to save or abort
self.db.disconnect() self.db.disconnect()
# hide icon as it doesn't go away immediately in Windows - is this ok in Linux Eric?
self.statusIcon.set_visible(False)
gtk.main_quit() gtk.main_quit()
def release_global_lock(self): def release_global_lock(self):

View File

@ -77,10 +77,11 @@ class fpdb_db:
import MySQLdb import MySQLdb
if use_pool: if use_pool:
MySQLdb = pool.manage(MySQLdb, pool_size=5) MySQLdb = pool.manage(MySQLdb, pool_size=5)
try: # try:
self.db = MySQLdb.connect(host = host, user = user, passwd = password, db = database, use_unicode=True) self.db = MySQLdb.connect(host=host, user=user, passwd=password, db=database, use_unicode=True)
except: #TODO: Add port option
raise FpdbMySQLFailedError("MySQL connection failed") # except:
# raise FpdbMySQLFailedError("MySQL connection failed")
elif backend==fpdb_db.PGSQL: elif backend==fpdb_db.PGSQL:
import psycopg2 import psycopg2
import psycopg2.extensions import psycopg2.extensions