From 5903988e385cb96bf2dd55a516b2c8e5dc2f793b Mon Sep 17 00:00:00 2001 From: eblade Date: Wed, 12 Nov 2008 06:30:49 -0500 Subject: [PATCH 01/14] merge with ray/carl GuiGraphViewer: configure matplotlib to use GTK properly, add in error handling for graphing across a database with hands the player you've requested wasn't involved in. please see # todo note on that. --- pyfpdb/GuiGraphViewer.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/pyfpdb/GuiGraphViewer.py b/pyfpdb/GuiGraphViewer.py index 49a00d20..3505d1f7 100644 --- a/pyfpdb/GuiGraphViewer.py +++ b/pyfpdb/GuiGraphViewer.py @@ -23,6 +23,8 @@ import os #import pokereval try: + import matplotlib + matplotlib.use('GTK') from matplotlib.figure import Figure from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar @@ -90,18 +92,23 @@ class GuiGraphViewer (threading.Thread): #end of def showClicked def getRingProfitGraph(self, name, site): - self.cursor.execute(self.sql.query['getRingWinningsAllGamesPlayerIdSite'], (name, site)) - winnings = self.db.cursor.fetchall() + self.cursor.execute(self.sql.query['getRingWinningsAllGamesPlayerIdSite'], (name, site)) + winnings = self.db.cursor.fetchall() - profit=range(len(winnings)) - for i in profit: - self.cursor.execute(self.sql.query['getRingProfitFromHandId'], (name, winnings[i][0], site)) - spent = self.db.cursor.fetchone() - profit[i]=(i, winnings[i][1]-spent[0]) + profit=range(len(winnings)) + for i in profit: + self.cursor.execute(self.sql.query['getRingProfitFromHandId'], (name, winnings[i][0], site)) + spent = self.db.cursor.fetchone() + if not spent[0] == None: + profit[i]=(i, winnings[i][1]-spent[0]) + else: + profit[i] = (i, 0) + # todo: this probably adds in flat spots on your graph for hands you were not involved in (ie, observing, sitting out, etc) + # and has that counted in your hand totals. Someone needs to figure out the SQL for totally removing any hand you're not in from the equation entirely - y=map(lambda x:float(x[1]), profit) - line = cumsum(y) - return line/100 + y=map(lambda x:float(x[1]), profit) + line = cumsum(y) + return line/100 #end of def getRingProfitGraph def __init__(self, db, settings, querylist, config, debug=True): From 806744bf34eedf46ab0b80b4f23eca60ff59f88b Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 12 Nov 2008 23:02:51 -0500 Subject: [PATCH 02/14] Mucked window enabled. --- pyfpdb/Hud.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index 39f30eea..42587189 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -194,9 +194,9 @@ class Hud: self.stats[config.supported_games[self.poker_game].stats[stat].row] \ [config.supported_games[self.poker_game].stats[stat].col] = \ config.supported_games[self.poker_game].stats[stat].stat_name -# self.mucked_window = gtk.Window() -# self.m = Mucked.Mucked(self.mucked_window, self.db_connection) -# self.mucked_window.show_all() + self.mucked_window = gtk.Window() + self.m = Mucked.Mucked(self.mucked_window, self.db_connection) + self.mucked_window.show_all() def update(self, hand, config, stat_dict): self.hand = hand # this is the last hand, so it is available later From d90fa208de767a6b945fa4f90d33426cb0750a93 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 13 Nov 2008 17:07:24 -0500 Subject: [PATCH 03/14] Smooth wrinkles in mucked card display. --- pyfpdb/Hud.py | 5 ++--- pyfpdb/Mucked.py | 35 ++++++++++++++++++++--------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index 42587189..c2310c38 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -168,7 +168,6 @@ class Hud: adj = self.adj_seats(hand, config) loc = self.config.get_locations(self.table.site, self.max) - print "adj = ", adj # create the stat windows for i in range(1, self.max + 1): @@ -195,7 +194,7 @@ class Hud: [config.supported_games[self.poker_game].stats[stat].col] = \ config.supported_games[self.poker_game].stats[stat].stat_name self.mucked_window = gtk.Window() - self.m = Mucked.Mucked(self.mucked_window, self.db_connection) + self.m = Mucked.Mucked(self.mucked_window, self.config, self.db_name) self.mucked_window.show_all() def update(self, hand, config, stat_dict): @@ -217,7 +216,7 @@ class Hud: tip = stat_dict[s]['screen_name'] + "\n" + number[5] + "\n" + \ number[3] + ", " + number[4] Stats.do_tip(self.stat_windows[stat_dict[s]['seat']].e_box[r][c], tip) -# self.m.update(hand) + self.m.update(hand) def topify_window(self, window): """Set the specified gtk window to stayontop in MS Windows.""" diff --git a/pyfpdb/Mucked.py b/pyfpdb/Mucked.py index efb99e81..51681d2a 100644 --- a/pyfpdb/Mucked.py +++ b/pyfpdb/Mucked.py @@ -45,26 +45,28 @@ import Mucked import HandHistory class Mucked: - def __init__(self, parent, db_connection): + def __init__(self, parent, config, db_name): - self.parent = parent #this is the parent of the mucked cards widget - self.db_connection = db_connection + self.config = config + self.parent = parent #this is the parent of the mucked cards widget + self.db_name = db_name self.vbox = gtk.VBox() self.parent.add(self.vbox) - self.mucked_list = MuckedList (self.vbox, db_connection) - self.mucked_cards = MuckedCards(self.vbox, db_connection) + self.mucked_list = MuckedList (self.vbox, config, db_name) + self.mucked_cards = MuckedCards(self.vbox, config, db_name) self.mucked_list.mucked_cards = self.mucked_cards def update(self, new_hand_id): self.mucked_list.update(new_hand_id) class MuckedList: - def __init__(self, parent, db_connection): + def __init__(self, parent, config, db_name): - self.parent = parent - self.db_connection = db_connection + self.parent = parent + self.config = config + self.db_name = db_name # set up a scrolled window to hold the listbox self.scrolled_window = gtk.ScrolledWindow() @@ -116,10 +118,11 @@ class MuckedList: self.mucked_cards.update(new_hand_id) class MuckedCards: - def __init__(self, parent, db_connection): + def __init__(self, parent, config, db_name = 'fpdb'): - self.parent = parent #this is the parent of the mucked cards widget - self.db_connection = db_connection + self.parent = parent #this is the parent of the mucked cards widget + self.config = config + self.db_name = db_name self.card_images = self.get_card_images() self.seen_cards = {} @@ -173,7 +176,8 @@ class MuckedCards: return old_cards def update(self, new_hand_id): - cards = self.db_connection.get_cards(new_hand_id) + db_connection = Database.Database(self.config, 'fpdb', '') + cards = db_connection.get_cards(new_hand_id) self.clear() cards = self.translate_cards(cards) for c in cards.keys(): @@ -185,7 +189,7 @@ class MuckedCards: set_from_pixbuf(self.card_images[self.split_cards(cards[c][i[1]])]) tips = [] - action = self.db_connection.get_action_from_hand(new_hand_id) + action = db_connection.get_action_from_hand(new_hand_id) for street in action: temp = '' for act in street: @@ -209,6 +213,7 @@ class MuckedCards: for round in range(1, len(tips)): for r in range(0, self.rows): self.eb[(round_to_col[round], r)].set_tooltip_text(tips[round]) + db_connection.close_connection() def split_cards(self, card): return (card[0], card[1].upper()) @@ -248,12 +253,12 @@ if __name__== "__main__": return(True) config = Configuration.Config() - db_connection = Database.Database(config, 'fpdb', '') +# db_connection = Database.Database(config, 'fpdb', '') main_window = gtk.Window() main_window.set_keep_above(True) main_window.connect("destroy", destroy) - m = Mucked(main_window, db_connection) + m = Mucked(main_window, config, 'fpdb') main_window.show_all() s_id = gobject.io_add_watch(sys.stdin, gobject.IO_IN, process_new_hand) From 05f3f5eee2d4c4dc2a7cafd90c5559a16ee237ac Mon Sep 17 00:00:00 2001 From: eblade Date: Thu, 13 Nov 2008 19:42:35 -0500 Subject: [PATCH 04/14] fix indentation typo --- pyfpdb/GuiGraphViewer.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pyfpdb/GuiGraphViewer.py b/pyfpdb/GuiGraphViewer.py index eacaf676..4f3ac38d 100644 --- a/pyfpdb/GuiGraphViewer.py +++ b/pyfpdb/GuiGraphViewer.py @@ -102,12 +102,12 @@ class GuiGraphViewer (threading.Thread): profit=range(len(winnings)) for i in profit: - self.cursor.execute(self.sql.query['getRingProfitFromHandId'], (name, winnings[i][0], site)) - spent = self.db.cursor.fetchone() - if not spent[0] == None: - profit[i]=(i, winnings[i][1]-spent[0]) - else: - profit[i] = (i, 0) + self.cursor.execute(self.sql.query['getRingProfitFromHandId'], (name, winnings[i][0], site)) + spent = self.db.cursor.fetchone() + if not spent[0] == None: + profit[i]=(i, winnings[i][1]-spent[0]) + else: + profit[i] = (i, 0) # todo: this probably adds in flat spots on your graph for hands you were not involved in (ie, observing, sitting out, etc) # and has that counted in your hand totals. Someone needs to figure out the SQL for totally removing any hand you're not in from the equation entirely From 37cd86920962b0d8fd05b55057050d9dce08863c Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 14 Nov 2008 13:10:17 -0500 Subject: [PATCH 05/14] fix reading of mucked cards for stud games --- pyfpdb/fpdb_simple.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/fpdb_simple.py b/pyfpdb/fpdb_simple.py index a746cf64..4c63657f 100644 --- a/pyfpdb/fpdb_simple.py +++ b/pyfpdb/fpdb_simple.py @@ -734,7 +734,7 @@ def parseCardLine(site, category, street, line, names, cardValues, cardSuits, bo print "line:",line,"cardValues[playerNo]:",cardValues[playerNo] raise FpdbError("read too many/too few holecards in parseCardLine") elif (category=="razz" or category=="studhi" or category=="studhilo"): - if (line.find("shows")==-1): + if (line.find("shows")==-1 and line.find("mucked") == -1): #print "parseCardLine(in stud if), street:", street if line[pos+2]=="]": #-> not (hero and 3rd street) cardValues[playerNo][street+2]=line[pos:pos+1] From 17ad79691737b3bec44805f43e5b9dbba1fd5f22 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 16 Nov 2008 17:53:31 -0500 Subject: [PATCH 06/14] More changes to support mucked/aux windows. --- pyfpdb/Configuration.py | 86 ++++++++++++++++++++++++++++++-------- pyfpdb/HUD_main.py | 5 +++ pyfpdb/Hud.py | 13 ++++-- pyfpdb/Mucked.py | 91 ++++++++++++++++++++++++++++++++++++----- 4 files changed, 163 insertions(+), 32 deletions(-) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index 99582935..dcd64c57 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -58,6 +58,7 @@ class Site: self.hudfgcolor = node.getAttribute("fgcolor") self.converter = node.getAttribute("converter") self.enabled = node.getAttribute("enabled") + self.aux_window = node.getAttribute("aux_window") self.layout = {} for layout_node in node.getElementsByTagName('layout'): @@ -100,6 +101,7 @@ class Game: self.db = node.getAttribute("db") self.rows = int( node.getAttribute("rows") ) self.cols = int( node.getAttribute("cols") ) + self.aux = node.getAttribute("aux") self.stats = {} for stat_node in node.getElementsByTagName('stat'): @@ -120,6 +122,7 @@ class Game: temp = temp + " db = %s\n" % self.db temp = temp + " rows = %d\n" % self.rows temp = temp + " cols = %d\n" % self.cols + temp = temp + " aux = %s\n" % self.aux for stat in self.stats.keys(): temp = temp + "%s" % self.stats[stat] @@ -144,18 +147,20 @@ class Database: temp = temp + ' ' + key + " = " + value + "\n" return temp -class Mucked: +class Aux_window: def __init__(self, node): - self.name = node.getAttribute("mw_name") - self.cards = node.getAttribute("deck") - self.card_wd = node.getAttribute("card_wd") - self.card_ht = node.getAttribute("card_ht") - self.rows = node.getAttribute("rows") - self.cols = node.getAttribute("cols") - self.format = node.getAttribute("stud") + for (name, value) in node.attributes.items(): + setattr(self, name, value) +# self.name = node.getAttribute("mw_name") +# self.cards = node.getAttribute("deck") +# self.card_wd = node.getAttribute("card_wd") +# self.card_ht = node.getAttribute("card_ht") +# self.rows = node.getAttribute("rows") +# self.cols = node.getAttribute("cols") +# self.format = node.getAttribute("stud") def __str__(self): - temp = 'Mucked = ' + self.name + "\n" + temp = 'Aux = ' + self.name + "\n" for key in dir(self): if key.startswith('__'): continue value = getattr(self, key) @@ -238,7 +243,7 @@ class Config: self.supported_sites = {} self.supported_games = {} self.supported_databases = {} - self.mucked_windows = {} + self.aux_windows = {} self.popup_windows = {} # s_sites = doc.getElementsByTagName("supported_sites") @@ -257,9 +262,9 @@ class Config: self.supported_databases[db.db_name] = db # s_dbs = doc.getElementsByTagName("mucked_windows") - for mw_node in doc.getElementsByTagName("mw"): - mw = Mucked(node = mw_node) - self.mucked_windows[mw.name] = mw + for aw_node in doc.getElementsByTagName("aw"): + aw = Aux_window(node = aw_node) + self.aux_windows[aw.name] = aw # s_dbs = doc.getElementsByTagName("popup_windows") for pu_node in doc.getElementsByTagName("pu"): @@ -503,6 +508,7 @@ class Config: parms["HH_path"] = self.supported_sites[site].HH_path parms["site_name"] = self.supported_sites[site].site_name parms["enabled"] = self.supported_sites[site].enabled + parms["aux_window"] = self.supported_sites[site].aux_window return parms def set_site_parameters(self, site_name, converter = None, decoder = None, @@ -537,6 +543,44 @@ class Config: if not enabled == None: self.supported_sites[site].enabled = enabled return + def get_aux_windows(self): + """Gets the list of mucked window formats in the configuration.""" + mw = [] + for w in self.aux_windows.keys(): + mw.append(w) + return mw + + def get_aux_parameters(self, name): + """Gets a dict of mucked window parameters from the named mw.""" + param = {} + if self.aux_windows.has_key(name): + for key in dir(self.aux_windows[name]): + if key.startswith('__'): continue + value = getattr(self.aux_windows[name], key) + if callable(value): continue + param[key] = value + + return param + return None + + def get_game_parameters(self, name): + """Get the configuration parameters for the named game.""" + param = {} + if self.supported_games.has_key(name): + param['game_name'] = self.supported_games[name].game_name + param['db'] = self.supported_games[name].db + param['rows'] = self.supported_games[name].rows + param['cols'] = self.supported_games[name].cols + param['aux'] = self.supported_games[name].aux + return param + + def get_supported_games(self): + """Get the list of supported games.""" + sg = [] + for game in c.supported_games.keys(): + sg.append(c.supported_games[game].game_name) + return sg + if __name__== "__main__": c = Config() @@ -557,15 +601,15 @@ if __name__== "__main__": print c.supported_databases[db] print "----------- END SUPPORTED DATABASES -----------" - print "\n----------- MUCKED WINDOW FORMATS -----------" - for w in c.mucked_windows.keys(): - print c.mucked_windows[w] - print "----------- END MUCKED WINDOW FORMATS -----------" + print "\n----------- AUX WINDOW FORMATS -----------" + for w in c.aux_windows.keys(): + print c.aux_windows[w] + print "----------- END AUX WINDOW FORMATS -----------" print "\n----------- POPUP WINDOW FORMATS -----------" for w in c.popup_windows.keys(): print c.popup_windows[w] - print "----------- END MUCKED WINDOW FORMATS -----------" + print "----------- END POPUP WINDOW FORMATS -----------" print "\n----------- IMPORT -----------" tmp = c.get_import_parameters() @@ -586,6 +630,12 @@ if __name__== "__main__": print "paths = ", c.get_default_paths("PokerStars") print "colors = ", c.get_default_colors("PokerStars") print "locs = ", c.get_locations("PokerStars", 8) + for mw in c.get_aux_windows(): + print c.get_aux_parameters(mw) + for site in c.supported_sites.keys(): print "site = ", site, print c.get_site_parameters(site) + + for game in c.get_supported_games(): + print c.get_game_parameters(game) diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py index 1a7e058e..ffa307d0 100755 --- a/pyfpdb/HUD_main.py +++ b/pyfpdb/HUD_main.py @@ -83,6 +83,8 @@ def update_HUD(new_hand_id, table_name, config, stat_dict): gtk.gdk.threads_enter() try: hud_dict[table_name].update(new_hand_id, config, stat_dict) + for m in hud_dict[table_name].aux_windows: + m.update_gui(new_hand_id) return False finally: gtk.gdk.threads_leave() @@ -121,6 +123,9 @@ def read_stdin(): # This is the thread function # if a hud for this CASH table exists, just update it if hud_dict.has_key(table_name): +# update the data for the aux_windows + for aw in hud_dict[table_name].aux_windows: + aw.update_data(new_hand_id) update_HUD(new_hand_id, table_name, config, stat_dict) # if a hud for this TOURNAMENT table exists, just update it elif hud_dict.has_key(tour_number): diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index c2310c38..d9816ef1 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -59,6 +59,7 @@ class Hud: self.stat_windows = {} self.popup_windows = {} + self.aux_windows = [] self.font = pango.FontDescription("Sans 8") # Set up a main window for this this instance of the HUD @@ -193,9 +194,11 @@ class Hud: self.stats[config.supported_games[self.poker_game].stats[stat].row] \ [config.supported_games[self.poker_game].stats[stat].col] = \ config.supported_games[self.poker_game].stats[stat].stat_name - self.mucked_window = gtk.Window() - self.m = Mucked.Mucked(self.mucked_window, self.config, self.db_name) - self.mucked_window.show_all() + + game_params = config.get_game_parameters(self.poker_game) + if not game_params['aux'] == "": + aux_params = config.get_aux_parameters(game_params['aux']) + self.aux_windows.append(eval("%s.%s(gtk.Window(), config, 'fpdb')" % (aux_params['module'], aux_params['class']))) def update(self, hand, config, stat_dict): self.hand = hand # this is the last hand, so it is available later @@ -216,7 +219,9 @@ class Hud: tip = stat_dict[s]['screen_name'] + "\n" + number[5] + "\n" + \ number[3] + ", " + number[4] Stats.do_tip(self.stat_windows[stat_dict[s]['seat']].e_box[r][c], tip) - self.m.update(hand) +# for m in self.aux_windows: +# m.update_data(hand) +# m.update_gui(hand) def topify_window(self, window): """Set the specified gtk window to stayontop in MS Windows.""" diff --git a/pyfpdb/Mucked.py b/pyfpdb/Mucked.py index 51681d2a..6f1fadd0 100644 --- a/pyfpdb/Mucked.py +++ b/pyfpdb/Mucked.py @@ -41,10 +41,21 @@ import Configuration import Database import Tables import Hud -import Mucked import HandHistory -class Mucked: +class Aux_Window: + def __init__(self, parent, config, db_name): + self.config = config + self.parent = parent #this is the parent of the mucked cards widget + self.db_name = db_name + + self.vbox = gtk.VBox() + self.parent.add(self.vbox) + + def update(self): + pass + +class Stud_mucked(Aux_Window): def __init__(self, parent, config, db_name): self.config = config @@ -54,14 +65,18 @@ class Mucked: self.vbox = gtk.VBox() self.parent.add(self.vbox) - self.mucked_list = MuckedList (self.vbox, config, db_name) - self.mucked_cards = MuckedCards(self.vbox, config, db_name) + self.mucked_list = Stud_list(self.vbox, config, db_name) + self.mucked_cards = Stud_cards(self.vbox, config, db_name) self.mucked_list.mucked_cards = self.mucked_cards + self.parent.show_all() - def update(self, new_hand_id): - self.mucked_list.update(new_hand_id) + def update_data(self, new_hand_id): + self.mucked_list.update_data(new_hand_id) -class MuckedList: + def update_gui(self, new_hand_id): + self.mucked_list.update_gui(new_hand_id) + +class Stud_list: def __init__(self, parent, config, db_name): self.parent = parent @@ -116,8 +131,21 @@ class MuckedList: vadj = self.scrolled_window.get_vadjustment() vadj.set_value(vadj.upper) self.mucked_cards.update(new_hand_id) + + def update_data(self, new_hand_id): + self.info_row = ((new_hand_id, "xxxx", 0), ) + self.mucked_cards.update_data(new_hand_id) -class MuckedCards: + def update_gui(self, new_hand_id): + iter = self.liststore.append(self.info_row[0]) + sel = self.treeview.get_selection() + sel.select_iter(iter) + + vadj = self.scrolled_window.get_vadjustment() + vadj.set_value(vadj.upper) + self.mucked_cards.update_gui(new_hand_id) + +class Stud_cards: def __init__(self, parent, config, db_name = 'fpdb'): self.parent = parent #this is the parent of the mucked cards widget @@ -215,6 +243,47 @@ class MuckedCards: self.eb[(round_to_col[round], r)].set_tooltip_text(tips[round]) db_connection.close_connection() + def update_data(self, new_hand_id): + db_connection = Database.Database(self.config, 'fpdb', '') + cards = db_connection.get_cards(new_hand_id) + self.clear() + self.cards = self.translate_cards(cards) + + self.tips = [] + action = db_connection.get_action_from_hand(new_hand_id) + for street in action: + temp = '' + for act in street: + temp = temp + act[0] + " " + act[1] + "s " + if act[2] > 0: + if act[2]%100 > 0: + temp = temp + "%4.2f\n" % (float(act[2])/100) + else: + temp = temp + "%d\n" % (act[2]/100) + else: + temp = temp + "\n" + self.tips.append(temp) + db_connection.close_connection() + + def update_gui(self, new_hand_id): + for c in self.cards.keys(): + self.grid_contents[(1, self.cards[c]['seat_number'] - 1)].set_text(self.cards[c]['screen_name']) + for i in ((0, 'hole_card_1'), (1, 'hole_card_2'), (2, 'hole_card_3'), (3, 'hole_card_4'), + (4, 'hole_card_5'), (5, 'hole_card_6'), (6, 'hole_card_7')): + if not self.cards[c][i[1]] == "xx": + self.seen_cards[(i[0], self.cards[c]['seat_number'] - 1)]. \ + set_from_pixbuf(self.card_images[self.split_cards(self.cards[c][i[1]])]) +## action in tool tips for 3rd street cards + for c in (0, 1, 2): + for r in range(0, self.rows): + self.eb[(c, r)].set_tooltip_text(self.tips[0]) + +# action in tools tips for later streets + round_to_col = (0, 3, 4, 5, 6) + for round in range(1, len(self.tips)): + for r in range(0, self.rows): + self.eb[(round_to_col[round], r)].set_tooltip_text(self.tips[round]) + def split_cards(self, card): return (card[0], card[1].upper()) @@ -249,7 +318,8 @@ if __name__== "__main__": # just read it and pass it to update new_hand_id = sys.stdin.readline() new_hand_id = new_hand_id.rstrip() # remove trailing whitespace - m.update(new_hand_id) + m.update_data(new_hand_id) + m.update_gui(new_hand_id) return(True) config = Configuration.Config() @@ -258,7 +328,8 @@ if __name__== "__main__": main_window.set_keep_above(True) main_window.connect("destroy", destroy) - m = Mucked(main_window, config, 'fpdb') + aux_to_call = "Stud_mucked" + m = eval("%s(main_window, config, 'fpdb')" % aux_to_call) main_window.show_all() s_id = gobject.io_add_watch(sys.stdin, gobject.IO_IN, process_new_hand) From 2155c125870ec558371e3ff843465c11592dd511 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 22 Nov 2008 17:28:12 -0500 Subject: [PATCH 07/14] Fixed error detecting FTP tables on NT --- pyfpdb/Tables.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyfpdb/Tables.py b/pyfpdb/Tables.py index 2b312f40..9f5360e2 100755 --- a/pyfpdb/Tables.py +++ b/pyfpdb/Tables.py @@ -229,6 +229,7 @@ def discover_nt_by_name(c, tablename): if titles[hwnd].find(tablename) == -1: continue if titles[hwnd].find("History for table:") > -1: continue if titles[hwnd].find("HUD:") > -1: continue + if titles[hwnd].find("Chat:") > -1: continue return decode_windows(c, titles[hwnd], hwnd) return False @@ -428,7 +429,7 @@ def discover_mac_by_name(c, tablename): if __name__=="__main__": c = Configuration.Config() - print discover_table_by_name(c, "Ostara V") + print discover_table_by_name(c, "Howard Lederer") print discover_tournament_table(c, "118942908", "3") tables = discover(c) From f8749fe7fb1baed6ed18e878d1373343221cdc6e Mon Sep 17 00:00:00 2001 From: eblade Date: Tue, 25 Nov 2008 06:47:58 -0500 Subject: [PATCH 08/14] Add "hudcolor" attribute to all definitions, drop font size to Sans 7, since i can't fit my stats in comfortably anymore --- pyfpdb/Configuration.py | 1 + pyfpdb/Hud.py | 11 ++++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index dcd64c57..91d74ff1 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -114,6 +114,7 @@ class Game: stat.popup = stat_node.getAttribute("popup") stat.hudprefix = stat_node.getAttribute("hudprefix") stat.hudsuffix = stat_node.getAttribute("hudsuffix") + stat.hudcolor = stat_node.getAttribute("hudcolor") self.stats[stat.stat_name] = stat diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index d9816ef1..d974ca4c 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -60,7 +60,7 @@ class Hud: self.stat_windows = {} self.popup_windows = {} self.aux_windows = [] - self.font = pango.FontDescription("Sans 8") + self.font = pango.FontDescription("Sans 7") # Set up a main window for this this instance of the HUD self.main_window = gtk.Window() @@ -215,6 +215,11 @@ class Hud: this_stat = config.supported_games[self.poker_game].stats[self.stats[r][c]] number = Stats.do_stat(stat_dict, player = stat_dict[s]['player_id'], stat = self.stats[r][c]) statstring = this_stat.hudprefix + str(number[1]) + this_stat.hudsuffix + + if this_stat.hudcolor != "": + self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor'])) + self.stat_windows[stat_dict[s]['seat']].label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(this_stat.hudcolor)) + self.stat_windows[stat_dict[s]['seat']].label[r][c].set_text(statstring) tip = stat_dict[s]['screen_name'] + "\n" + number[5] + "\n" + \ number[3] + ", " + number[4] @@ -361,7 +366,7 @@ class Stat_Window: self.e_box[r][c].add(self.label[r][c]) self.e_box[r][c].connect("button_press_event", self.button_press_cb) -# font = pango.FontDescription("Sans 8") + font = pango.FontDescription("Sans 7") self.label[r][c].modify_font(font) # if not os.name == 'nt': # seems to be a bug in opacity on windows @@ -564,7 +569,7 @@ if __name__== "__main__": c = Configuration.Config() #tables = Tables.discover(c) - t = Tables.discover_table_by_name(c, "Chelsea") + t = Tables.discover_table_by_name(c, "Motorway") if t is None: print "Table not found." db = Database.Database(c, 'fpdb', 'holdem') From 53a95ccc806e2de3b02d65734b1d4c9b59cae86d Mon Sep 17 00:00:00 2001 From: eblade Date: Tue, 25 Nov 2008 07:03:33 -0500 Subject: [PATCH 09/14] stat windows are hidden by default, and only brought forward when there's a player in a seat that has recorded a hand --- pyfpdb/Hud.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index d974ca4c..c2d601e8 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -221,6 +221,8 @@ class Hud: self.stat_windows[stat_dict[s]['seat']].label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(this_stat.hudcolor)) self.stat_windows[stat_dict[s]['seat']].label[r][c].set_text(statstring) + if statstring != "xxx": + self.stat_windows[stat_dict[s]['seat']].window.show_all() tip = stat_dict[s]['screen_name'] + "\n" + number[5] + "\n" + \ number[3] + ", " + number[4] Stats.do_tip(self.stat_windows[stat_dict[s]['seat']].e_box[r][c], tip) @@ -377,6 +379,7 @@ class Stat_Window: self.window.show_all() # set_keep_above(1) for windows if os.name == 'nt': self.topify_window(self.window) + self.window.hide() def topify_window(self, window): """Set the specified gtk window to stayontop in MS Windows.""" From 2c00422f34adcea7db0778eed73092d7356e97ba Mon Sep 17 00:00:00 2001 From: eblade Date: Tue, 25 Nov 2008 07:33:20 -0500 Subject: [PATCH 10/14] clean up some stat descriptions --- pyfpdb/Stats.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pyfpdb/Stats.py b/pyfpdb/Stats.py index 7bb9a8c5..5ca42fe8 100644 --- a/pyfpdb/Stats.py +++ b/pyfpdb/Stats.py @@ -88,14 +88,14 @@ def vpip(stat_dict, player): 'v=%3.1f' % (100*stat) + '%', 'vpip=%3.1f' % (100*stat) + '%', '(%d/%d)' % (stat_dict[player]['vpip'], stat_dict[player]['n']), - 'vpip' + 'Voluntarily Put In Pot %' ) except: return (stat, '%3.1f' % (0) + '%', - 'w=%3.1f' % (0) + '%', - 'wtsd=%3.1f' % (0) + '%', + 'v=%3.1f' % (0) + '%', + 'vpip=%3.1f' % (0) + '%', '(%d/%d)' % (0, 0), - 'wtsd' + 'Voluntarily Put In Pot %' ) def pfr(stat_dict, player): @@ -108,7 +108,7 @@ def pfr(stat_dict, player): 'p=%3.1f' % (100*stat) + '%', 'pfr=%3.1f' % (100*stat) + '%', '(%d/%d)' % (stat_dict[player]['pfr'], stat_dict[player]['n']), - 'pfr' + 'Pre-Flop Raise %' ) except: return (stat, @@ -116,7 +116,7 @@ def pfr(stat_dict, player): 'p=%3.1f' % (0) + '%', 'pfr=%3.1f' % (0) + '%', '(%d/%d)' % (0, 0), - 'pfr' + 'Pre-Flop Raise %' ) def wtsd(stat_dict, player): @@ -172,7 +172,7 @@ def saw_f(stat_dict, player): 'sf=%3.1f' % (100*stat) + '%', 'saw_f=%3.1f' % (100*stat) + '%', '(%d/%d)' % (stat_dict[player]['saw_f'], stat_dict[player]['n']), - 'saw_f' + 'Flop Seen %' ) except: stat = 0.0 @@ -183,7 +183,7 @@ def saw_f(stat_dict, player): 'sf=%3.1f' % (stat) + '%', 'saw_f=%3.1f' % (stat) + '%', '(%d/%d)' % (num, den), - 'saw_f' + 'Flop Seen %' ) def n(stat_dict, player): @@ -412,7 +412,7 @@ def a_freq_4(stat_dict, player): 'a4=%3.1f' % (0) + '%', 'a_fq_4=%3.1f' % (0) + '%', '(%d/%d)' % (0, 0), - 'Aggression Freq flop/4th' + 'Aggression Freq 7th' ) def cb_1(stat_dict, player): From 49390940e375143dfc53584d4798abe8df3d2115 Mon Sep 17 00:00:00 2001 From: eblade Date: Tue, 25 Nov 2008 08:52:59 -0500 Subject: [PATCH 11/14] add middle-click on stat_window to hide it (since we don't currently have a way to hide it when someone leaves) --- pyfpdb/Hud.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index c2d601e8..4ed1060c 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -288,6 +288,7 @@ class Stat_Window: self.double_click(widget, event, *args) if event.button == 2: # middle button event + self.window.hide() # print "middle button clicked" pass From 6e116f4b02bc711c8d95980dc9591d85cf88ff59 Mon Sep 17 00:00:00 2001 From: eblade Date: Thu, 27 Nov 2008 02:31:52 -0500 Subject: [PATCH 12/14] don't bother doing show_all on each stat_window, then hide, just hide first. (probably shouldn't need to even hide them first, but they seem to sometimes start hidden sometimes not) --- pyfpdb/Hud.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index 4ed1060c..cf9ab622 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -375,9 +375,9 @@ class Stat_Window: # if not os.name == 'nt': # seems to be a bug in opacity on windows self.window.set_opacity(parent.colors['hudopacity']) - self.window.realize + self.window.realize() self.window.move(self.x, self.y) - self.window.show_all() +# self.window.show_all() # set_keep_above(1) for windows if os.name == 'nt': self.topify_window(self.window) self.window.hide() From 274cecdc58fcf4df08a098c1747ef1dc6e9363f1 Mon Sep 17 00:00:00 2001 From: eblade Date: Thu, 27 Nov 2008 05:12:07 -0500 Subject: [PATCH 13/14] stat windows no longer call realize() as that is done automatically by gtk when needed importer dumps bad hands to hand-errors.txt after printing the normal email message parse_logic should ignore lines where small blind is found to be "$0", however, it's still causing errors --- pyfpdb/Hud.py | 2 +- pyfpdb/fpdb_import.py | 11 ++++++++--- pyfpdb/fpdb_parse_logic.py | 2 ++ 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index cf9ab622..92a84723 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -375,7 +375,7 @@ class Stat_Window: # if not os.name == 'nt': # seems to be a bug in opacity on windows self.window.set_opacity(parent.colors['hudopacity']) - self.window.realize() +# self.window.realize() self.window.move(self.x, self.y) # self.window.show_all() # set_keep_above(1) for windows diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index 8f815a3c..854877ba 100755 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -248,14 +248,14 @@ class Importer: duplicates+=1 except (ValueError), fe: errors+=1 - self.printEmailErrorMessage(errors, file, hand[0]) + self.printEmailErrorMessage(errors, file, hand) if (self.settings['failOnError']): self.db.commit() #dont remove this, in case hand processing was cancelled. raise except (fpdb_simple.FpdbError), fe: errors+=1 - self.printEmailErrorMessage(errors, file, hand[0]) + self.printEmailErrorMessage(errors, file, hand) #fe.printStackTrace() #todo: get stacktrace self.db.rollback() @@ -302,7 +302,12 @@ class Importer: print "Filename:", filename print "Here is the first line so you can identify it. Please mention that the error was a ValueError:" print self.hand[0] - + print "Hand logged to hand-errors.txt" + logfile = open('hand-errors.txt', 'a') + for s in self.hand: + logfile.write(str(s) + "\n") + logfile.write("\n") + logfile.close() if __name__ == "__main__": print "CLI for fpdb_import is now available as CliFpdb.py" diff --git a/pyfpdb/fpdb_parse_logic.py b/pyfpdb/fpdb_parse_logic.py index ec9a53f6..370a0fc0 100644 --- a/pyfpdb/fpdb_parse_logic.py +++ b/pyfpdb/fpdb_parse_logic.py @@ -42,6 +42,8 @@ def mainParser(db, cursor, site, category, hand): smallBlindLine=0 for i in range(len(hand)): if hand[i].find("posts small blind")!=-1 or hand[i].find("posts the small blind")!=-1: + if hand[i][-2:] == "$0": + continue smallBlindLine=i #print "found small blind line:",smallBlindLine break From 1de34462e3729a2e8c6254cd252457e7f6fc28d1 Mon Sep 17 00:00:00 2001 From: eblade Date: Thu, 27 Nov 2008 08:35:17 -0500 Subject: [PATCH 14/14] remove spurious window realize from popup_window as well printEmailErrorMessage also writes a traceback to the stderr, so we can more easily figure out -what part- it failed in parsePositions will ignore a small blind if it appears to be coming from the same place as the big (does this mess with dead blinds? who knows) --- pyfpdb/Hud.py | 2 +- pyfpdb/fpdb_import.py | 2 ++ pyfpdb/fpdb_simple.py | 11 +++++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index 92a84723..2960db30 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -440,7 +440,7 @@ class Popup_window: self.lab.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudbgcolor'])) self.lab.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudfgcolor'])) - self.window.realize +# self.window.realize() # figure out the row, col address of the click that activated the popup row = 0 diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index 854877ba..0ff8179c 100755 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -31,6 +31,7 @@ try: except: pass +import traceback import math import os import datetime @@ -298,6 +299,7 @@ class Importer: def printEmailErrorMessage(self, errors, filename, line): + traceback.print_exc(file=sys.stderr) print "Error No.",errors,", please send the hand causing this to steffen@sycamoretest.info so I can fix it." print "Filename:", filename print "Here is the first line so you can identify it. Please mention that the error was a ValueError:" diff --git a/pyfpdb/fpdb_simple.py b/pyfpdb/fpdb_simple.py index 4c63657f..9637f23d 100644 --- a/pyfpdb/fpdb_simple.py +++ b/pyfpdb/fpdb_simple.py @@ -54,7 +54,8 @@ def checkPositions(positions): pass ### RHH modified to allow for "position 9" here (pos==9 is when you're a dead hand before the BB - if (pos!="B" and pos!="S" and pos!=0 and pos!=1 and pos!=2 and pos!=3 and pos!=4 and pos!=5 and pos!=6 and pos!=7 and pos!=9): + ### eric - position 8 could be valid - if only one blind is posted, but there's still 10 people, ie a sitout is present, and the small is dead... + if not (pos == "B" or pos == "S" or (pos >= 0 and pos <= 9)): raise FpdbError("invalid position found in checkPositions. i: "+str(i)+" position: "+str(pos)) #end def fpdb_simple.checkPositions @@ -892,6 +893,11 @@ def parsePositions (hand, names): sbExists=False if (bb!=-1): bb=recognisePlayerNo(bb, names, "bet") + + print "sb = ", sb, "bb = ", bb + if bb == sb: + sbExists = False + sb = -1 #write blinds into array if (sbExists): @@ -928,6 +934,7 @@ def parsePositions (hand, names): print "parsePositions names:",names print "result:",positions raise FpdbError ("failed to read positions") + print str(positions), "\n" return positions #end def parsePositions @@ -1676,7 +1683,7 @@ def generateHudCacheData(player_ids, base, category, action_types, allIns, actio hudDataPositions.append('C') elif pos>=2 and pos<=4: hudDataPositions.append('M') - elif pos>=5 and pos<=7: + elif pos>=5 and pos<=8: hudDataPositions.append('E') ### RHH Added this elif to handle being a dead hand before the BB (pos==9) elif pos==9: