From 2bd4932a77181c3d41d08faad214c3b6d7c3983b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 24 Oct 2008 15:44:53 -0400 Subject: [PATCH 01/34] Tables discovered via process name, then window name, only going through two nested loops, instead of two nested loops followed by another loop. (can someone test to make sure this actually doesn't break stuff on *nix?) Windows HUD Stats Windows no longer appear in Windows taskbar (now gtk transients for table hud window) --- pyfpdb/HUD_main.py | 16 ++++---- pyfpdb/Hud.py | 92 +++++++++++++++++++++++++++++++++++++++++----- pyfpdb/Tables.py | 92 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 176 insertions(+), 24 deletions(-) diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py index 0bfe7f40..88e87104 100755 --- a/pyfpdb/HUD_main.py +++ b/pyfpdb/HUD_main.py @@ -77,14 +77,14 @@ def process_new_hand(new_hand_id, db_name): hud_dict[table_name].update(new_hand_id, db_connection, config) # otherwise create a new hud else: - table_windows = Tables.discover(config) - for t in table_windows.keys(): - if table_windows[t].name == table_name: - hud_dict[table_name] = Hud.Hud(table_windows[t], max, poker_game, config, db_name) - hud_dict[table_name].create(new_hand_id, config) - hud_dict[table_name].update(new_hand_id, db_connection, config) - break -# print "table name \"%s\" not identified, no hud created" % (table_name) + tablewindow = Tables.discover_table_by_name(config, table_name) + if tablewindow == None: + sys.stderr.write("table name "+table_name+" not found\n") + else: + hud_dict[table_name] = Hud.Hud(tablewindow, max, poker_game, config, db_name) + hud_dict[table_name].create(new_hand_id, config) + hud_dict[table_name].update(new_hand_id, db_connection, config) + db_connection.close_connection() return(1) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index 003e0be1..6d3b1fef 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -23,6 +23,7 @@ Create and manage the hud overlays. ######################################################################## # Standard Library modules import os +import sys # pyGTK modules import pygtk @@ -61,9 +62,10 @@ class Hud: self.main_window = gtk.Window() # self.window.set_decorated(0) self.main_window.set_gravity(gtk.gdk.GRAVITY_STATIC) - self.main_window.set_keep_above(1) - self.main_window.set_title(table.name) + self.main_window.set_keep_above(True) + self.main_window.set_title(table.name + " FPDBHUD") self.main_window.connect("destroy", self.kill_hud) + #self.main_window.set_transient_for(parent.get_toplevel()) self.ebox = gtk.EventBox() self.label = gtk.Label("Close this window to\nkill the HUD for\n %s" % (table.name)) @@ -136,8 +138,57 @@ class Hud: adj = self.adj_seats(hand, config) # create the stat windows - for i in range(1, self.max + 1): - (x, y) = config.supported_sites[self.table.site].layout[self.max].location[adj[i]] + for i in range(1, self.max + 1): + # the below IF always appears to be passed as TRUE, I don't know why. If you have an 8-max game, but + # your config file doesn't understand 8 max, it's a crash. It was even a crash when I tried using the + # full-fledged exception handling blocks. + # - Eric + + if self.max in config.supported_sites[self.table.site].layout: + (x, y) = config.supported_sites[self.table.site].layout[self.max].location[adj[i]] + else: + if i == 1: + x = 684 + y = 61 + elif i == 2: + x = 689 + y = 239 + elif i == 3: + x = 692 + y = 346 + elif i == 4: + x = 586 + y = 393 + elif i == 5: + x = 421 + y = 440 + elif i == 6: + x = 267 + y = 440 + elif i == 7: + x = 0 + y = 361 + elif i == 8: + x = 0 + y = 280 + elif i == 9: + x = 121 + y = 280 + elif i == 10: + x = 46 + y = 30 + + sys.stderr.write("at location "+str(x)+" "+str(y)+"\n") + sys.stderr.write("config:"+str(config)+"\n") + gameslist = config.supported_games + sys.stderr.write("supported games:"+str(gameslist)+"\n") + sys.stderr.write("desired game:"+str(self.poker_game)+"\n") + thisgame = gameslist['holdem'] + sys.stderr.write("this game:"+str(thisgame)+"\n") + # the above code looks absolutely completely useless. The below line was freezing the interpreter, so I added the above lines to try and debug + # which piece of the below line was causing it to lock up. Adding the "thisgame = gameslist['holdem']" line fixed it, for some unknown reason. + # removing any one of the lines above causes the interpreter to freeze for me on the next statement. + # -eric self.stat_windows[i] = Stat_Window(game = config.supported_games[self.poker_game], parent = self, table = self.table, @@ -189,7 +240,15 @@ class Hud: for w in tl_windows: if w[1] == unique_name: - win32gui.SetWindowPos(w[0], win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE|win32con.SWP_NOSIZE) +# win32gui.ShowWindow(w[0], win32con.SW_HIDE) +# style = win32gui.GetWindowLong(w[0], win32con.GWL_EXSTYLE) +# style |= win32con.WS_EX_TOOLWINDOW +# style &= ~win32con.WS_EX_APPWINDOW +# win32gui.SetWindowLong(w[0], win32con.GWL_EXSTYLE, style) +# win32gui.ShowWindow(w[0], win32con.SW_SHOW) + + win32gui.SetWindowPos(w[0], win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE|win32con.SWP_NOSIZE) + # notify_id = (w[0], # 0, # win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP, @@ -262,6 +321,7 @@ class Stat_Window: self.window.set_keep_above(1) self.window.set_title("%s" % seat) self.window.set_property("skip-taskbar-hint", True) + self.window.set_transient_for(parent.main_window) self.grid = gtk.Table(rows = self.game.rows, columns = self.game.cols, homogeneous = False) self.window.add(self.grid) @@ -328,6 +388,7 @@ class Popup_window: self.window.set_title("popup") self.window.set_property("skip-taskbar-hint", True) self.window.set_transient_for(parent.get_toplevel()) + self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT) self.ebox = gtk.EventBox() @@ -440,7 +501,14 @@ class Popup_window: for w in tl_windows: if w[1] == unique_name: - win32gui.SetWindowPos(w[0], win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE|win32con.SWP_NOSIZE) +# win32gui.ShowWindow(w[0], win32con.SW_HIDE) +# style = win32gui.GetWindowLong(w[0], win32con.GWL_EXSTYLE) +# style |= win32con.WS_EX_TOOLWINDOW +# style &= ~win32con.WS_EX_APPWINDOW +# win32gui.SetWindowLong(w[0], win32con.GWL_EXSTYLE, style) +# win32gui.ShowWindow(w[0], win32con.SW_SHOW) + win32gui.SetWindowPos(w[0], win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE|win32con.SWP_NOSIZE) + # notify_id = (w[0], # 0, # win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP, @@ -459,12 +527,16 @@ if __name__== "__main__": main_window.show_all() c = Configuration.Config() - tables = Tables.discover(c) + #tables = Tables.discover(c) + t = Tables.discover_table_by_name(c, "Southend") + if t is None: + print "Table not found." db = Database.Database(c, 'fpdb', 'holdem') - for t in tables: - win = Hud(t, 8, c, db) +# for t in tables: + win = Hud(t, 10, 'holdem', c, db) + win.create(1, c) # t.get_details() - win.update(8300, db, c) + win.update(8300, db, c) gtk.main() diff --git a/pyfpdb/Tables.py b/pyfpdb/Tables.py index cb6209c8..9cbcc384 100644 --- a/pyfpdb/Tables.py +++ b/pyfpdb/Tables.py @@ -33,6 +33,9 @@ import re if os.name == 'nt': import win32gui + import win32process + import win32api + import win32con # FreePokerTools modules import Configuration @@ -57,17 +60,24 @@ class Table_Window: def discover(c): if os.name == 'posix': tables = discover_posix(c) - return tables elif os.name == 'nt': tables = discover_nt(c) - return tables - elif ox.name == 'mac': + elif os.name == 'mac': tables = discover_mac(c) - return tables else: tables = {} return(tables) +def discover_table_by_name(c, tablename): + if os.name == 'posix': + table = discover_posix_by_name(c, tablename) + elif os.name == 'nt': + table = discover_nt_by_name(c, tablename) + elif os.name == 'mac': + table = discover_mac_by_name(c, tablename) + else: table = None + return(table) + def discover_posix(c): """ Poker client table window finder for posix/Linux = XWindows.""" tables = {} @@ -94,8 +104,17 @@ def discover_posix(c): # use this eval thingie to call the title bar decoder specified in the config file eval("%s(tw)" % c.supported_sites[s].decoder) + tables[tw.name] = tw return tables + +def discover_posix_by_name(c, tablename): + tables = discover_posix(c) + for t in tables: + if t.name.find(tablename) > -1: + return t + return None + # # The discover_xx functions query the system and report on the poker clients # currently displayed on the screen. The discover_posix should give you @@ -120,6 +139,7 @@ def discover_posix(c): def win_enum_handler(hwnd, titles): titles[hwnd] = win32gui.GetWindowText(hwnd) + def child_enum_handler(hwnd, children): print hwnd, win32.GetWindowRect(hwnd) @@ -150,7 +170,7 @@ def discover_nt(c): tw.y = int( y ) + tb_height if re.search('Logged In as', titles[hwnd]): tw.site = "PokerStars" - elif re.search('Logged In As', titles[hwnd]): + elif re.search('Logged In As', titles[hwnd]): #wait, what??! tw.site = "Full Tilt" else: tw.site = "Unknown" @@ -159,14 +179,73 @@ def discover_nt(c): eval("%s(tw)" % c.supported_sites[tw.site].decoder) else: tw.name = "Unknown" - tables[tw.name] = tw + tables[len(tables)] = tw return tables +def discover_nt_by_name(c, tablename): + # this is pretty much identical to the 'search all windows for all poker sites' code, but made to dig just for a specific table name + # it could be implemented a bunch better - and we need to not assume the width/height thing that (steffen?) assumed above, we should + # be able to dig up the window's titlebar handle and get it's information, and such .. but.. for now, i guess this will work. + # - eric + b_width = 3 + tb_height = 29 + titles = {} +# tables = discover_nt(c) + win32gui.EnumWindows(win_enum_handler, titles) + for s in c.supported_sites.keys(): + for hwnd in titles.keys(): + processid = win32process.GetWindowThreadProcessId(hwnd) + pshandle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, False, processid[1]) + exe = win32process.GetModuleFileNameEx(pshandle, 0) + if exe.find(c.supported_sites[s].table_finder) == -1: + continue + if titles[hwnd].find(tablename) > -1: + if titles[hwnd].find("History for table:") > -1 or titles[hwnd].find("FPDBHUD") > -1: + continue + tw = Table_Window() + tw.number = hwnd + (x, y, width, height) = win32gui.GetWindowRect(hwnd) + tw.title = titles[hwnd] + tw.width = int(width) - 2 * b_width + tw.height = int(height) - b_width - tb_height + tw.x = int(x) + b_width + tw.y = int(y) + tb_height + tw.site = c.supported_sites[s].site_name + if not tw.site == "Unknown" and not tw.decoder == "Unknown": + eval("%s(tw)" % c.supported_sites[tw.site].decoder) + else: + tw.name = tablename + return tw + + # if we don't find anything by process name, let's search one more time, and call it Unknown ? + for hwnd in titles.keys(): + if titles[hwnd].find(tablename) > -1: + if titles[hwnd].find("History for table:") > -1 or titles[hwnd].find("FPDBHUD") > -1: + continue + tw = Table_Window() + tw.number = hwnd + (x, y, width, height) = win32gui.GetWindowRect(hwnd) + tw.title = titles[hwnd] + tw.width = int(width) - 2 * b_width + tw.height = int(height) - b_width - tb_height + tw.x = int(x) + b_width + tw.y = int(y) + tb_height + tw.site = "Unknown" + tw.name = tablename + return tw + + return None + def discover_mac(c): """ Poker client table window finder for Macintosh.""" tables = {} return tables +def discover_mac_by_name(c, tablename): + # again, i have no mac to test this on, sorry -eric + return discover_mac(c) + + def pokerstars_decode_table(tw): # extract the table name OR the tournament number and table name from the title # other info in title is redundant with data in the database @@ -221,6 +300,7 @@ def fulltilt_decode_table(tw): if __name__=="__main__": c = Configuration.Config() + print discover_table_by_name(c, "Catacaos") tables = discover(c) for t in tables.keys(): From 654b2e0ba920923f78ddc4a027a074d4e257d808 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 24 Oct 2008 16:30:08 -0400 Subject: [PATCH 02/34] trying to fix my repository --- pyfpdb/Hud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index 6d3b1fef..36fb8e8d 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -42,7 +42,7 @@ import Configuration import Stats import Mucked import Database -import HUD_main +import HUD_main class Hud: From 7b604e3bec6bae2cfdddc43536b4cee1d2fcb534 Mon Sep 17 00:00:00 2001 From: eblade Date: Sun, 26 Oct 2008 05:34:36 -0400 Subject: [PATCH 03/34] Table HUD window now child of poker table window --- pyfpdb/Hud.py | 50 +++++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index bf23a619..a2c7ab63 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -35,6 +35,7 @@ import gobject if os.name == 'nt': import win32gui import win32con + import win32api # FreePokerTools modules import Tables # needed for testing only @@ -89,7 +90,13 @@ class Hud: self.main_window.show_all() # set_keep_above(1) for windows - if os.name == 'nt': self.topify_window(self.main_window) + if os.name == 'nt': + self.topify_window(self.main_window) + +# set as child of poker table + window.parentgdkhandle = gtk.gdk.window_foreign_new(long(self.table.number)) + self.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0]) + self.main_window.gdkhandle.set_transient_for(window.parentgdkhandle) def on_button_press(self, widget, event): if event.button == 3: @@ -241,14 +248,20 @@ class Hud: for w in tl_windows: if w[1] == unique_name: -# win32gui.ShowWindow(w[0], win32con.SW_HIDE) -# style = win32gui.GetWindowLong(w[0], win32con.GWL_EXSTYLE) -# style |= win32con.WS_EX_TOOLWINDOW -# style &= ~win32con.WS_EX_APPWINDOW -# win32gui.SetWindowLong(w[0], win32con.GWL_EXSTYLE, style) -# win32gui.ShowWindow(w[0], win32con.SW_SHOW) + #win32gui.ShowWindow(w[0], win32con.SW_HIDE) + #window.parentgdkhandle = gtk.gdk.window_foreign_new(long(self.table.number)) + #self.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0]) + #self.main_window.gdkhandle.set_transient_for(window.parentgdkhandle) + #win32gui.ShowWindow(w[0], win32con.SW_SHOW) + + style = win32gui.GetWindowLong(self.table.number, win32con.GWL_EXSTYLE) + #style |= win32con.WS_EX_TOOLWINDOW + #style &= ~win32con.WS_EX_APPWINDOW + style |= win32con.WS_CLIPCHILDREN + win32gui.SetWindowLong(self.table.number, win32con.GWL_EXSTYLE, style) - win32gui.SetWindowPos(w[0], win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE|win32con.SWP_NOSIZE) + + #win32gui.SetWindowPos(w[0], win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE|win32con.SWP_NOSIZE) # notify_id = (w[0], # 0, @@ -363,16 +376,15 @@ class Stat_Window: for w in tl_windows: if w[1] == unique_name: - win32gui.SetWindowPos(w[0], win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE|win32con.SWP_NOSIZE) -# notify_id = (w[0], -# 0, -# win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP, -# win32con.WM_USER+20, -# 0, -# '') -# win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, notify_id) -# - window.set_title(real_name) + + #win32gui.SetWindowPos(w[0], win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE|win32con.SWP_NOSIZE) + +# style = win32gui.GetWindowLong(w[0], win32con.GWL_EXSTYLE) +# style |= win32con.WS_EX_TOOLWINDOW +# style &= ~win32con.WS_EX_APPWINDOW +# win32gui.SetWindowLong(w[0], win32con.GWL_EXSTYLE, style) + win32gui.ShowWindow(w[0], win32con.SW_SHOW) + window.set_title(real_name) def destroy(*args): # call back for terminating the main eventloop gtk.main_quit() @@ -529,7 +541,7 @@ if __name__== "__main__": c = Configuration.Config() #tables = Tables.discover(c) - t = Tables.discover_table_by_name(c, "Southend") + t = Tables.discover_table_by_name(c, "Corona") if t is None: print "Table not found." db = Database.Database(c, 'fpdb', 'holdem') From d07fe6c5c698f31810a866dc347854d393819ea6 Mon Sep 17 00:00:00 2001 From: eblade Date: Sun, 26 Oct 2008 05:39:43 -0400 Subject: [PATCH 04/34] move re-parenting code back into windows-only topify_window() function, as it is not 100% system independent (more like 99%) --- pyfpdb/Hud.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index a2c7ab63..42579eac 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -93,11 +93,6 @@ class Hud: if os.name == 'nt': self.topify_window(self.main_window) -# set as child of poker table - window.parentgdkhandle = gtk.gdk.window_foreign_new(long(self.table.number)) - self.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0]) - self.main_window.gdkhandle.set_transient_for(window.parentgdkhandle) - def on_button_press(self, widget, event): if event.button == 3: widget.popup(None, None, None, event.button, event.time) @@ -249,9 +244,9 @@ class Hud: for w in tl_windows: if w[1] == unique_name: #win32gui.ShowWindow(w[0], win32con.SW_HIDE) - #window.parentgdkhandle = gtk.gdk.window_foreign_new(long(self.table.number)) - #self.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0]) - #self.main_window.gdkhandle.set_transient_for(window.parentgdkhandle) + window.parentgdkhandle = gtk.gdk.window_foreign_new(long(self.table.number)) + self.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0]) + self.main_window.gdkhandle.set_transient_for(window.parentgdkhandle) #win32gui.ShowWindow(w[0], win32con.SW_SHOW) style = win32gui.GetWindowLong(self.table.number, win32con.GWL_EXSTYLE) From a1c6fa1dc6b626b9f3831e4cdca9131b403d0c40 Mon Sep 17 00:00:00 2001 From: eblade Date: Sun, 26 Oct 2008 06:09:29 -0400 Subject: [PATCH 05/34] Fix posix discover by name typo/i'm a dummy error --- pyfpdb/Tables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/Tables.py b/pyfpdb/Tables.py index e480d4c6..6afbddea 100644 --- a/pyfpdb/Tables.py +++ b/pyfpdb/Tables.py @@ -113,7 +113,7 @@ def discover_posix(c): def discover_posix_by_name(c, tablename): tables = discover_posix(c) for t in tables: - if t.name.find(tablename) > -1: + if tables[t].name.find(tablename) > -1: return t return None From 628f71cf3d34f0947feb70c5a64cf8c43b8fe32f Mon Sep 17 00:00:00 2001 From: eblade Date: Sun, 26 Oct 2008 06:49:47 -0400 Subject: [PATCH 06/34] fix return value for same function i just thought i fixed but didn't all the way --- pyfpdb/Tables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/Tables.py b/pyfpdb/Tables.py index 6afbddea..a5090fd7 100644 --- a/pyfpdb/Tables.py +++ b/pyfpdb/Tables.py @@ -114,7 +114,7 @@ def discover_posix_by_name(c, tablename): tables = discover_posix(c) for t in tables: if tables[t].name.find(tablename) > -1: - return t + return tables[t] return None # From a1499db849de4a084bd00c69fb7d6d88b742dc58 Mon Sep 17 00:00:00 2001 From: Worros Date: Sun, 26 Oct 2008 20:13:30 +0900 Subject: [PATCH 07/34] Fix return type of tables_by_name discovery for posix --- pyfpdb/Tables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/Tables.py b/pyfpdb/Tables.py index 6afbddea..a5090fd7 100644 --- a/pyfpdb/Tables.py +++ b/pyfpdb/Tables.py @@ -114,7 +114,7 @@ def discover_posix_by_name(c, tablename): tables = discover_posix(c) for t in tables: if tables[t].name.find(tablename) > -1: - return t + return tables[t] return None # From 051f04b69f54572efddad165032b9f11aeafb4c1 Mon Sep 17 00:00:00 2001 From: eblade Date: Sun, 26 Oct 2008 15:51:12 -0400 Subject: [PATCH 08/34] trying to get parenting of stats windows to work in nix. --- pyfpdb/Hud.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index 42579eac..28cae1d8 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -92,6 +92,10 @@ class Hud: # set_keep_above(1) for windows if os.name == 'nt': self.topify_window(self.main_window) + else: + window.parentgdkhandle = gtk.gdk.window_foreign_new(long(self.table.number)) + self.main_window.gdkhandle = gtk.gdk.window_foreign_new(window.window.xid) + self.main_window.gdkhandle.set_transient_for(window.parentgdkhandle) def on_button_press(self, widget, event): if event.button == 3: @@ -107,6 +111,7 @@ class Hud: def save_layout(self, *args): new_layout = [] +# todo: have the hud track the poker table's window position regularly, don't forget to update table.x and table.y. for sw in self.stat_windows: loc = self.stat_windows[sw].window.get_position() new_loc = (loc[0] - self.table.x, loc[1] - self.table.y) From 70bdc0bcb46683a192a18b09e82c9c1d46310017 Mon Sep 17 00:00:00 2001 From: eblade Date: Mon, 27 Oct 2008 03:12:12 -0400 Subject: [PATCH 09/34] fix for re-parenting to work in nix, remove decorations from table hud main window --- pyfpdb/Hud.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index 28cae1d8..baafaddf 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -67,11 +67,11 @@ class Hud: self.main_window.set_keep_above(True) self.main_window.set_title(table.name + " FPDBHUD") self.main_window.connect("destroy", self.kill_hud) + self.main_window.set_decorated(False) #self.main_window.set_transient_for(parent.get_toplevel()) self.ebox = gtk.EventBox() - self.label = gtk.Label("Close this window to\nkill the HUD for\n %s\nMinimizing it hides stats." % - (table.name)) + self.label = gtk.Label("Right click to close HUD for %s\nor Save Stat Positions." % (table.name)) self.main_window.add(self.ebox) self.ebox.add(self.label) self.main_window.move(self.table.x, self.table.y) @@ -93,9 +93,12 @@ class Hud: if os.name == 'nt': self.topify_window(self.main_window) else: - window.parentgdkhandle = gtk.gdk.window_foreign_new(long(self.table.number)) - self.main_window.gdkhandle = gtk.gdk.window_foreign_new(window.window.xid) - self.main_window.gdkhandle.set_transient_for(window.parentgdkhandle) + self.main_window.parentgdkhandle = gtk.gdk.window_foreign_new(self.table.number) + self.main_window.gdkhandle = gtk.gdk.window_foreign_new(self.main_window.window.xid) + self.main_window.gdkhandle.set_transient_for(self.main_window.parentgdkhandle) + #window.parentgdkhandle = gtk.gdk.window_foreign_new(self.table.number) + #self.main_window.gdkhandle = gtk.gdk.window_foreign_new(window.window.xid) + #self.main_window.gdkhandle.set_transient_for(window.parentgdkhandle) def on_button_press(self, widget, event): if event.button == 3: From 2bde12a6cf54d11da3dec7735e47ed99c893c84f Mon Sep 17 00:00:00 2001 From: eblade Date: Mon, 27 Oct 2008 03:13:04 -0400 Subject: [PATCH 10/34] remove set keep above on stat windows --- pyfpdb/Hud.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index baafaddf..c4099b5b 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -64,7 +64,7 @@ class Hud: self.main_window = gtk.Window() # self.window.set_decorated(0) self.main_window.set_gravity(gtk.gdk.GRAVITY_STATIC) - self.main_window.set_keep_above(True) + #self.main_window.set_keep_above(True) self.main_window.set_title(table.name + " FPDBHUD") self.main_window.connect("destroy", self.kill_hud) self.main_window.set_decorated(False) @@ -335,7 +335,7 @@ class Stat_Window: self.window = gtk.Window() self.window.set_decorated(0) self.window.set_gravity(gtk.gdk.GRAVITY_STATIC) - self.window.set_keep_above(1) + #self.window.set_keep_above(1) self.window.set_title("%s" % seat) self.window.set_property("skip-taskbar-hint", True) self.window.set_transient_for(parent.main_window) From 5f15a4f9286befff3bc0fa745efa318e25bae13d Mon Sep 17 00:00:00 2001 From: eblade Date: Mon, 27 Oct 2008 06:29:39 -0400 Subject: [PATCH 11/34] Configuration.py: add "bgcolor" and "fgcolor" to node HUD: table hud and stat windows respect "bgcolor" and "fgcolor" on a per site basis Tables: force tw.number to be an int in Unix --- pyfpdb/Configuration.py | 8 ++++++++ pyfpdb/HUD_main.py | 1 - pyfpdb/Hud.py | 21 ++++++++++++++++++--- pyfpdb/Tables.py | 2 +- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index 4e29dba1..c6262c54 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -53,6 +53,14 @@ class Site: self.site_path = node.getAttribute("site_path") self.HH_path = node.getAttribute("HH_path") self.decoder = node.getAttribute("decoder") + + self.hudbgcolor = node.getAttribute("bgcolor") + if self.hudbgcolor == "": + self.hudbgcolor = "#FFFFFF" + self.hudfgcolor = node.getAttribute("fgcolor") + if self.hudfgcolor == "": + self.hudfgcolor = "#000000" + self.layout = {} for layout_node in node.getElementsByTagName('layout'): diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py index 8217deb5..a157cf46 100644 --- a/pyfpdb/HUD_main.py +++ b/pyfpdb/HUD_main.py @@ -29,7 +29,6 @@ Main for FreePokerTools HUD. # to do no hud window for hero # to do things to add to config.xml # to do font and size -# to do bg and fg color # to do opacity # Standard Library modules diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index c4099b5b..940050ac 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -59,9 +59,9 @@ class Hud: self.stat_windows = {} self.popup_windows = {} self.font = pango.FontDescription("Sans 8") - + # Set up a main window for this this instance of the HUD - self.main_window = gtk.Window() + self.main_window = gtk.Window() # self.window.set_decorated(0) self.main_window.set_gravity(gtk.gdk.GRAVITY_STATIC) #self.main_window.set_keep_above(True) @@ -72,8 +72,15 @@ class Hud: self.ebox = gtk.EventBox() self.label = gtk.Label("Right click to close HUD for %s\nor Save Stat Positions." % (table.name)) + + self.label.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(config.supported_sites[self.table.site].hudbgcolor)) + self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(config.supported_sites[self.table.site].hudfgcolor)) + self.main_window.add(self.ebox) self.ebox.add(self.label) + self.ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(config.supported_sites[self.table.site].hudbgcolor)) + self.ebox.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(config.supported_sites[self.table.site].hudfgcolor)) + self.main_window.move(self.table.x, self.table.y) # A popup window for the main window @@ -351,9 +358,17 @@ class Stat_Window: self.label.append([]) for c in range(self.game.cols): self.e_box[r].append( gtk.EventBox() ) + + self.e_box[r][c].modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.config.supported_sites[self.table.site].hudbgcolor)) + self.e_box[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.config.supported_sites[self.table.site].hudfgcolor)) + Stats.do_tip(self.e_box[r][c], 'farts') self.grid.attach(self.e_box[r][c], c, c+1, r, r+1, xpadding = 0, ypadding = 0) self.label[r].append( gtk.Label('xxx') ) + + self.label[r][c].modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.config.supported_sites[self.table.site].hudbgcolor)) + self.label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.config.supported_sites[self.table.site].hudfgcolor)) + 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") @@ -544,7 +559,7 @@ if __name__== "__main__": c = Configuration.Config() #tables = Tables.discover(c) - t = Tables.discover_table_by_name(c, "Corona") + t = Tables.discover_table_by_name(c, "Chelsea") if t is None: print "Table not found." db = Database.Database(c, 'fpdb', 'holdem') diff --git a/pyfpdb/Tables.py b/pyfpdb/Tables.py index a5090fd7..752c5929 100644 --- a/pyfpdb/Tables.py +++ b/pyfpdb/Tables.py @@ -96,7 +96,7 @@ def discover_posix(c): if re.match('[\(\)\d\s]+', mo.group(2)): continue # this is a popup tw = Table_Window() tw.site = c.supported_sites[s].site_name - tw.number = mo.group(1) + tw.number = int(mo.group(1), 0) tw.title = mo.group(2) tw.width = int( mo.group(3) ) tw.height = int( mo.group(4) ) From 64dbe3237dff1740eb0936412eab3c1b9f2c4ad7 Mon Sep 17 00:00:00 2001 From: eblade Date: Mon, 27 Oct 2008 07:12:04 -0400 Subject: [PATCH 12/34] add "hudopacity" to site config, valid settings are potentially from 0.00 to 1.00 --- pyfpdb/Configuration.py | 6 ++++++ pyfpdb/Hud.py | 1 + 2 files changed, 7 insertions(+) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index c6262c54..4690a84c 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -53,6 +53,12 @@ class Site: self.site_path = node.getAttribute("site_path") self.HH_path = node.getAttribute("HH_path") self.decoder = node.getAttribute("decoder") + + self.hudopacity = node.getAttribute("hudopacity") + if self.hudopacity == "": + self.hudopacity = 0.90 + else: + self.hudopacity = float(self.hudopacity) self.hudbgcolor = node.getAttribute("bgcolor") if self.hudbgcolor == "": diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index 940050ac..e9ac814c 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -341,6 +341,7 @@ class Stat_Window: self.window = gtk.Window() self.window.set_decorated(0) + self.window.set_opacity(parent.config.supported_sites[self.table.site].hudopacity) self.window.set_gravity(gtk.gdk.GRAVITY_STATIC) #self.window.set_keep_above(1) self.window.set_title("%s" % seat) From 56d80d785c0fbddbbfe2e420d7446590fab32524 Mon Sep 17 00:00:00 2001 From: Worros Date: Mon, 27 Oct 2008 20:14:08 +0900 Subject: [PATCH 13/34] HUD chmod --- pyfpdb/HUD_main.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 pyfpdb/HUD_main.py diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py old mode 100644 new mode 100755 From 9f84cc93a7bf0a5d441dfb88527eacb9040f282e Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 27 Oct 2008 12:56:09 -0400 Subject: [PATCH 14/34] edits to get the stacked window mods working with X --- pyfpdb/Hud.py | 10 +++++----- pyfpdb/Tables.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index 28cae1d8..f286674d 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -64,7 +64,7 @@ class Hud: self.main_window = gtk.Window() # self.window.set_decorated(0) self.main_window.set_gravity(gtk.gdk.GRAVITY_STATIC) - self.main_window.set_keep_above(True) +# self.main_window.set_keep_above(True) self.main_window.set_title(table.name + " FPDBHUD") self.main_window.connect("destroy", self.kill_hud) #self.main_window.set_transient_for(parent.get_toplevel()) @@ -93,9 +93,9 @@ class Hud: if os.name == 'nt': self.topify_window(self.main_window) else: - window.parentgdkhandle = gtk.gdk.window_foreign_new(long(self.table.number)) - self.main_window.gdkhandle = gtk.gdk.window_foreign_new(window.window.xid) - self.main_window.gdkhandle.set_transient_for(window.parentgdkhandle) + self.main_window.parentgdkhandle = gtk.gdk.window_foreign_new(self.table.number) # gets a gdk handle for poker client + self.main_window.gdkhandle = gtk.gdk.window_foreign_new(self.main_window.window.xid) # gets a gdk handle for the hud table window + self.main_window.gdkhandle.set_transient_for(self.main_window.parentgdkhandle) # def on_button_press(self, widget, event): if event.button == 3: @@ -332,7 +332,7 @@ class Stat_Window: self.window = gtk.Window() self.window.set_decorated(0) self.window.set_gravity(gtk.gdk.GRAVITY_STATIC) - self.window.set_keep_above(1) +# self.window.set_keep_above(1) self.window.set_title("%s" % seat) self.window.set_property("skip-taskbar-hint", True) self.window.set_transient_for(parent.main_window) diff --git a/pyfpdb/Tables.py b/pyfpdb/Tables.py index a5090fd7..752c5929 100644 --- a/pyfpdb/Tables.py +++ b/pyfpdb/Tables.py @@ -96,7 +96,7 @@ def discover_posix(c): if re.match('[\(\)\d\s]+', mo.group(2)): continue # this is a popup tw = Table_Window() tw.site = c.supported_sites[s].site_name - tw.number = mo.group(1) + tw.number = int(mo.group(1), 0) tw.title = mo.group(2) tw.width = int( mo.group(3) ) tw.height = int( mo.group(4) ) From 174b7ecfa08580fe62812e9d02f6bd19eb5573ed Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 28 Oct 2008 09:37:11 -0400 Subject: [PATCH 15/34] permission changes only Please enter the commit message for your changes. --- pyfpdb/HUD_main.py | 0 pyfpdb/fpdb_db.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 pyfpdb/HUD_main.py mode change 100644 => 100755 pyfpdb/fpdb_db.py diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py old mode 100644 new mode 100755 diff --git a/pyfpdb/fpdb_db.py b/pyfpdb/fpdb_db.py old mode 100644 new mode 100755 From 87c82df4b2b81a18889159740b6beb615e61c2b8 Mon Sep 17 00:00:00 2001 From: Worros Date: Wed, 29 Oct 2008 23:35:47 +0900 Subject: [PATCH 16/34] Merge branch 'master' of git://git.assembla.com/free_poker_tools Conflicts: pyfpdb/Hud.py --- pyfpdb/Hud.py | 19 ++++++++----------- pyfpdb/fpdb_import.py | 2 +- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index e9ac814c..2d67c7ca 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -59,12 +59,12 @@ class Hud: self.stat_windows = {} self.popup_windows = {} self.font = pango.FontDescription("Sans 8") - -# Set up a main window for this this instance of the HUD - self.main_window = gtk.Window() + +# Set up a main window for this this instance of the HUD + self.main_window = gtk.Window() # self.window.set_decorated(0) self.main_window.set_gravity(gtk.gdk.GRAVITY_STATIC) - #self.main_window.set_keep_above(True) +# self.main_window.set_keep_above(True) self.main_window.set_title(table.name + " FPDBHUD") self.main_window.connect("destroy", self.kill_hud) self.main_window.set_decorated(False) @@ -100,12 +100,9 @@ class Hud: if os.name == 'nt': self.topify_window(self.main_window) else: - self.main_window.parentgdkhandle = gtk.gdk.window_foreign_new(self.table.number) - self.main_window.gdkhandle = gtk.gdk.window_foreign_new(self.main_window.window.xid) - self.main_window.gdkhandle.set_transient_for(self.main_window.parentgdkhandle) - #window.parentgdkhandle = gtk.gdk.window_foreign_new(self.table.number) - #self.main_window.gdkhandle = gtk.gdk.window_foreign_new(window.window.xid) - #self.main_window.gdkhandle.set_transient_for(window.parentgdkhandle) + self.main_window.parentgdkhandle = gtk.gdk.window_foreign_new(self.table.number) # gets a gdk handle for poker client + self.main_window.gdkhandle = gtk.gdk.window_foreign_new(self.main_window.window.xid) # gets a gdk handle for the hud table window + self.main_window.gdkhandle.set_transient_for(self.main_window.parentgdkhandle) # def on_button_press(self, widget, event): if event.button == 3: @@ -343,7 +340,7 @@ class Stat_Window: self.window.set_decorated(0) self.window.set_opacity(parent.config.supported_sites[self.table.site].hudopacity) self.window.set_gravity(gtk.gdk.GRAVITY_STATIC) - #self.window.set_keep_above(1) +# self.window.set_keep_above(1) self.window.set_title("%s" % seat) self.window.set_property("skip-taskbar-hint", True) self.window.set_transient_for(parent.main_window) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index fb170240..4a855d1d 100755 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -138,7 +138,7 @@ class Importer: # ^^ May not work on windows for dir in self.dirlist: for file in os.listdir(dir): - self.filelist = self.filelist + [dir+os.sep+file] + self.filelist = self.filelist + [os.path.join(dir, file)] self.filelist = list(set(self.filelist)) From f26baac94cc2bc00b844e91a7784c8e0206551d3 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 29 Oct 2008 22:37:05 -0400 Subject: [PATCH 17/34] added some configuration accessors for Hud.py and some cleanup --- pyfpdb/Configuration.py | 53 ++++++++++++++++++++---------- pyfpdb/Hud.py | 72 ++++++++--------------------------------- 2 files changed, 49 insertions(+), 76 deletions(-) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index 4690a84c..6e38d50f 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -53,19 +53,9 @@ class Site: self.site_path = node.getAttribute("site_path") self.HH_path = node.getAttribute("HH_path") self.decoder = node.getAttribute("decoder") - self.hudopacity = node.getAttribute("hudopacity") - if self.hudopacity == "": - self.hudopacity = 0.90 - else: - self.hudopacity = float(self.hudopacity) - self.hudbgcolor = node.getAttribute("bgcolor") - if self.hudbgcolor == "": - self.hudbgcolor = "#FFFFFF" self.hudfgcolor = node.getAttribute("fgcolor") - if self.hudfgcolor == "": - self.hudfgcolor = "#000000" self.layout = {} @@ -88,7 +78,7 @@ class Site: if key == 'layout': continue value = getattr(self, key) if callable(value): continue - temp = temp + ' ' + key + " = " + value + "\n" + temp = temp + ' ' + key + " = " + str(value) + "\n" for layout in self.layout: temp = temp + "%s" % self.layout[layout] @@ -372,6 +362,33 @@ class Config: paths['bulkImport-defaultPath'] = "default" return paths + def get_default_colors(self, site = "PokerStars"): + colors = {} + try: + colors['hudopacity'] = float(self.supported_sites[site].hudopacity) + except: + colors['hudopacity'] = 0.90 + try: + colors['hudbgcolor'] = float(self.supported_sites[site].hudbgcolor) + except: + colors['hudbgcolor'] = "#FFFFFF" + try: + colors['hudfgcolor'] = float(self.supported_sites[site].hudbgcolor) + except: + colors['hudfgcolor'] = "#000000" + return colors + + def get_locations(self, site = "PokerStars", max = "8"): + + try: + locations = self.supported_sites[site].layout[max].location + except: + locations = ( ( 0, 0), (684, 61), (689, 239), (692, 346), + (586, 393), (421, 440), (267, 440), ( 0, 361), + ( 0, 280), (121, 280), ( 46, 30) ) + return locations + + if __name__== "__main__": c = Config() @@ -403,17 +420,19 @@ if __name__== "__main__": print "----------- END MUCKED WINDOW FORMATS -----------" print "\n----------- IMPORT -----------" - print c.imp +# print c.imp print "----------- END IMPORT -----------" print "\n----------- TABLE VIEW -----------" - print c.tv +# print c.tv print "----------- END TABLE VIEW -----------" c.edit_layout("PokerStars", 6, locations=( (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6) )) c.save(file="testout.xml") - print "db = ", c.get_db_parameters() - print "tv = ", c.get_tv_parameters() - print "imp = ", c.get_import_parameters() - print "paths = ", c.get_default_paths("PokerStars") + print "db = ", c.get_db_parameters() +# print "tv = ", c.get_tv_parameters() +# print "imp = ", c.get_import_parameters() + print "paths = ", c.get_default_paths("PokerStars") + print "colors = ", c.get_default_colors("PokerStars") + print "locs = ", c.get_locations("PokerStars", 8) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index dc4ab242..0cb4062b 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -55,6 +55,7 @@ class Hud: self.db_name = db_name self.deleted = False self.stacked = True + self.colors = config.get_default_colors(self.table.site) self.stat_windows = {} self.popup_windows = {} @@ -73,13 +74,13 @@ class Hud: self.ebox = gtk.EventBox() self.label = gtk.Label("Right click to close HUD for %s\nor Save Stat Positions." % (table.name)) - self.label.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(config.supported_sites[self.table.site].hudbgcolor)) - self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(config.supported_sites[self.table.site].hudfgcolor)) + self.label.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudbgcolor'])) + self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor'])) self.main_window.add(self.ebox) self.ebox.add(self.label) - self.ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(config.supported_sites[self.table.site].hudbgcolor)) - self.ebox.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(config.supported_sites[self.table.site].hudfgcolor)) + self.ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudbgcolor'])) + self.ebox.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor'])) self.main_window.move(self.table.x, self.table.y) @@ -153,58 +154,11 @@ class Hud: # windows via calls to the Stat_Window class adj = self.adj_seats(hand, config) + loc = self.config.get_locations(self.table.site, self.max) + # create the stat windows for i in range(1, self.max + 1): - # the below IF always appears to be passed as TRUE, I don't know why. If you have an 8-max game, but - # your config file doesn't understand 8 max, it's a crash. It was even a crash when I tried using the - # full-fledged exception handling blocks. - # - Eric - - if self.max in config.supported_sites[self.table.site].layout: - (x, y) = config.supported_sites[self.table.site].layout[self.max].location[adj[i]] - else: - if i == 1: - x = 684 - y = 61 - elif i == 2: - x = 689 - y = 239 - elif i == 3: - x = 692 - y = 346 - elif i == 4: - x = 586 - y = 393 - elif i == 5: - x = 421 - y = 440 - elif i == 6: - x = 267 - y = 440 - elif i == 7: - x = 0 - y = 361 - elif i == 8: - x = 0 - y = 280 - elif i == 9: - x = 121 - y = 280 - elif i == 10: - x = 46 - y = 30 - - sys.stderr.write("at location "+str(x)+" "+str(y)+"\n") - sys.stderr.write("config:"+str(config)+"\n") - gameslist = config.supported_games - sys.stderr.write("supported games:"+str(gameslist)+"\n") - sys.stderr.write("desired game:"+str(self.poker_game)+"\n") - thisgame = gameslist['holdem'] - sys.stderr.write("this game:"+str(thisgame)+"\n") - # the above code looks absolutely completely useless. The below line was freezing the interpreter, so I added the above lines to try and debug - # which piece of the below line was causing it to lock up. Adding the "thisgame = gameslist['holdem']" line fixed it, for some unknown reason. - # removing any one of the lines above causes the interpreter to freeze for me on the next statement. - # -eric + (x, y) = loc[adj[i]] self.stat_windows[i] = Stat_Window(game = config.supported_games[self.poker_game], parent = self, table = self.table, @@ -338,7 +292,7 @@ class Stat_Window: self.window = gtk.Window() self.window.set_decorated(0) - self.window.set_opacity(parent.config.supported_sites[self.table.site].hudopacity) + self.window.set_opacity(parent.colors['hudopacity']) self.window.set_gravity(gtk.gdk.GRAVITY_STATIC) # self.window.set_keep_above(1) @@ -358,15 +312,15 @@ class Stat_Window: for c in range(self.game.cols): self.e_box[r].append( gtk.EventBox() ) - self.e_box[r][c].modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.config.supported_sites[self.table.site].hudbgcolor)) - self.e_box[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.config.supported_sites[self.table.site].hudfgcolor)) + self.e_box[r][c].modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.colors['hudbgcolor'])) + self.e_box[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.colors['hudfgcolor'])) Stats.do_tip(self.e_box[r][c], 'farts') self.grid.attach(self.e_box[r][c], c, c+1, r, r+1, xpadding = 0, ypadding = 0) self.label[r].append( gtk.Label('xxx') ) - self.label[r][c].modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.config.supported_sites[self.table.site].hudbgcolor)) - self.label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.config.supported_sites[self.table.site].hudfgcolor)) + self.label[r][c].modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.colors['hudbgcolor'])) + self.label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.colors['hudfgcolor'])) self.e_box[r][c].add(self.label[r][c]) self.e_box[r][c].connect("button_press_event", self.button_press_cb) From cf2c7e42670193f9da9ff6c086221156f3a63960 Mon Sep 17 00:00:00 2001 From: eblade Date: Thu, 30 Oct 2008 00:03:28 -0400 Subject: [PATCH 18/34] add lines with "($0 in chips)" to list of things to ignore, as a player with no chips cannot possibly be in the hand, and the lines often contain blank usernames on p4e, which are breaking the parser. --- pyfpdb/fpdb_simple.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyfpdb/fpdb_simple.py b/pyfpdb/fpdb_simple.py index 217b9163..ab442d85 100644 --- a/pyfpdb/fpdb_simple.py +++ b/pyfpdb/fpdb_simple.py @@ -330,6 +330,8 @@ def filterCrap(site, hand, isTourney): toRemove.append(hand[i]) elif (hand[i].find(" out of hand ")!=-1): hand[i]=hand[i][:-56] + elif (hand[i].find("($0 in chips)") != -1): + toRemove.append(hand[i]) elif (hand[i]=="*** HOLE CARDS ***"): toRemove.append(hand[i]) elif (hand[i].endswith("has been disconnected")): From 6eca3fdce7b00d9efdec13102b22e882ffd24d5c Mon Sep 17 00:00:00 2001 From: eblade Date: Thu, 30 Oct 2008 05:30:29 -0400 Subject: [PATCH 19/34] merge in latest ray changes, replace excessive exception handling with a couple of if blocks in get_default_colors - there were definite errors in there not getting cauhgt due to the exception handling --- pyfpdb/Configuration.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index 6e38d50f..ed90bf05 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -364,18 +364,18 @@ class Config: def get_default_colors(self, site = "PokerStars"): colors = {} - try: - colors['hudopacity'] = float(self.supported_sites[site].hudopacity) - except: + if self.supported_sites[site].hudopacity == "": colors['hudopacity'] = 0.90 - try: - colors['hudbgcolor'] = float(self.supported_sites[site].hudbgcolor) - except: + else: + colors['hudopacity'] = float(self.supported_sites[site].hudopacity) + if self.supported_sites[site].hudbgcolor == "": colors['hudbgcolor'] = "#FFFFFF" - try: - colors['hudfgcolor'] = float(self.supported_sites[site].hudbgcolor) - except: + else: + colors['hudbgcolor'] = self.supported_sites[site].hudbgcolor + if self.supported_sites[site].hudfgcolor == "": colors['hudfgcolor'] = "#000000" + else: + colors['hudfgcolor'] = self.supported_sites[site].hudfgcolor return colors def get_locations(self, site = "PokerStars", max = "8"): From e154bdd8f47efdc2486d411578160cf2bb3f90f3 Mon Sep 17 00:00:00 2001 From: eblade Date: Fri, 31 Oct 2008 14:34:41 -0400 Subject: [PATCH 20/34] Add "hudprefix" and "hudsuffix" properties to each of the "STAT" nodes in the config, will display them before/after stats on the HUD, as appropriate. (note that due to the use of a table in the hud display, it can get a little.. ugly.. looking) Add "playername" to list of available stats MIGHT close huds when poker table is closed in Nix. It doesn't in Windows, but it should. --- pyfpdb/Hud.py | 13 +++++++++---- pyfpdb/Stats.py | 10 ++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index 1d50022e..f1d0cfae 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -102,7 +102,9 @@ class Hud: else: self.main_window.parentgdkhandle = gtk.gdk.window_foreign_new(self.table.number) # gets a gdk handle for poker client self.main_window.gdkhandle = gtk.gdk.window_foreign_new(self.main_window.window.xid) # gets a gdk handle for the hud table window - self.main_window.gdkhandle.set_transient_for(self.main_window.parentgdkhandle) # + self.main_window.gdkhandle.set_transient_for(self.main_window.parentgdkhandle) # + + self.main_window.set_destroy_with_parent(True) def on_button_press(self, widget, event): if event.button == 3: @@ -186,8 +188,10 @@ class Hud: self.stat_windows[stat_dict[s]['seat']].player_id = stat_dict[s]['player_id'] for r in range(0, config.supported_games[self.poker_game].rows): for c in range(0, config.supported_games[self.poker_game].cols): + 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]) - self.stat_windows[stat_dict[s]['seat']].label[r][c].set_text(number[1]) + statstring = this_stat.hudprefix + str(number[1]) + this_stat.hudsuffix + 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] Stats.do_tip(self.stat_windows[stat_dict[s]['seat']].e_box[r][c], tip) @@ -266,7 +270,7 @@ class Stat_Window: Popup_window(widget, self) return False - def double_click(self, widget, event, *args): + def double_click(self, widget, event, *args): self.toggle_decorated(widget) def toggle_decorated(self, widget): @@ -291,7 +295,6 @@ class Stat_Window: self.window = gtk.Window() self.window.set_decorated(0) - self.window.set_opacity(parent.colors['hudopacity']) self.window.set_gravity(gtk.gdk.GRAVITY_STATIC) self.window.set_title("%s" % seat) @@ -324,6 +327,8 @@ class Stat_Window: self.e_box[r][c].connect("button_press_event", self.button_press_cb) # font = pango.FontDescription("Sans 8") self.label[r][c].modify_font(font) + + self.window.set_opacity(parent.colors['hudopacity']) self.window.realize self.window.move(self.x, self.y) self.window.show_all() diff --git a/pyfpdb/Stats.py b/pyfpdb/Stats.py index 3531c017..07c69662 100644 --- a/pyfpdb/Stats.py +++ b/pyfpdb/Stats.py @@ -58,6 +58,7 @@ def do_tip(widget, tip): def do_stat(stat_dict, player = 24, stat = 'vpip'): return eval("%(stat)s(stat_dict, %(player)d)" % {'stat': stat, 'player': player}) + # OK, for reference the tuple returned by the stat is: # 0 - The stat, raw, no formating, eg 0.33333333 # 1 - formatted stat with appropriate precision and punctuation, eg 33% @@ -68,6 +69,15 @@ def do_stat(stat_dict, player = 24, stat = 'vpip'): ########################################### # functions that return individual stats + +def playername(stat_dict, player): + return (stat_dict[player]['screen_name'], + stat_dict[player]['screen_name'], + stat_dict[player]['screen_name'], + stat_dict[player]['screen_name'], + stat_dict[player]['screen_name'], + stat_dict[player]['screen_name']) + def vpip(stat_dict, player): """ Voluntarily put $ in the pot.""" stat = 0.0 From b5ec60f5fac97949671cd3491fcf163affebae2b Mon Sep 17 00:00:00 2001 From: eblade Date: Sun, 2 Nov 2008 05:20:25 -0500 Subject: [PATCH 21/34] forgot to commit configuration.py last time --- pyfpdb/Configuration.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index ed90bf05..4ee691eb 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -109,6 +109,8 @@ class Game: stat.tip = stat_node.getAttribute("tip") stat.click = stat_node.getAttribute("click") stat.popup = stat_node.getAttribute("popup") + stat.hudprefix = stat_node.getAttribute("hudprefix") + stat.hudsuffix = stat_node.getAttribute("hudsuffix") self.stats[stat.stat_name] = stat From 0f10f87373c658304186162e9017f241fa794e0c Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 2 Nov 2008 22:58:55 -0500 Subject: [PATCH 22/34] changes to make consolidated config files happier --- pyfpdb/Configuration.py | 91 ++++++++++++++++++++++++++++------- pyfpdb/HUD_config.xml.example | 2 +- 2 files changed, 75 insertions(+), 18 deletions(-) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index 4ee691eb..50b5a287 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -205,24 +205,19 @@ class Config: sys.stderr.write("Configuration file %s not found. Using defaults." % (file)) file = None -# if "file" is invalid or None, we look for a HUD_config in the cwd if file == None: # configuration file path not passed or invalid - if os.path.exists('HUD_config.xml'): # there is a HUD_config in the cwd - file = 'HUD_config.xml' # so we use it - else: # no HUD_config in the cwd, look where it should be in the first place -# find the path to the default HUD_config for the current os - if os.name == 'posix': - config_path = os.path.join(os.path.expanduser("~"), '.fpdb', 'HUD_config.xml') - elif os.name == 'nt': - config_path = os.path.join(os.environ["APPDATA"], 'fpdb', 'HUD_config.xml') - else: config_path = False - - if config_path and os.path.exists(config_path): - file = config_path - else: - print "No HUD_config_xml found. Exiting" - sys.stderr.write("No HUD_config_xml found. Exiting") - sys.exit() + file = self.find_config() #Look for a config file in the normal places + + if file == None: # no config file in the normal places + file = self.find_example_config() #Look for an example file to edit + + if file == None: # that didn't work either, just die + print "No HUD_config_xml found. Exiting" + sys.stderr.write("No HUD_config_xml found. Exiting") + sys.exit() + +# Parse even if there was no real config file found and we are using the example +# If using the example, we'll edit it later try: print "Reading configuration file %s\n" % (file) doc = xml.dom.minidom.parse(file) @@ -274,6 +269,68 @@ class Config: tv = Tv(node = tv_node) self.tv = tv + db = self.get_db_parameters('fpdb') + if db['db-password'] == 'YOUR MYSQL PASSWORD': + df_file = self.find_default_conf() + if df_file == None: # this is bad + pass + else: + df_parms = self.read_default_conf(df_file) + self.supported_databases['fpdb'].db_pass = df_parms['db-password'] + self.supported_databases['fpdb'].db_ip = df_parms['db-host'] + self.supported_databases['fpdb'].db_user = df_parms['db-user'] + + def find_config(self): + if os.path.exists('HUD_config.xml'): # there is a HUD_config in the cwd + file = 'HUD_config.xml' # so we use it + else: # no HUD_config in the cwd, look where it should be in the first place +# find the path to the default HUD_config for the current os + if os.name == 'posix': + config_path = os.path.join(os.path.expanduser("~"), '.fpdb', 'HUD_config.xml') + elif os.name == 'nt': + config_path = os.path.join(os.environ["APPDATA"], 'fpdb', 'HUD_config.xml') + else: config_path = False + + if config_path and os.path.exists(config_path): + file = config_path + else: + file = None + return file + + def find_default_conf(self): + if os.name == 'posix': + config_path = os.path.join(os.path.expanduser("~"), '.fpdb', 'default.conf') + elif os.name == 'nt': + config_path = os.path.join(os.environ["APPDATA"], 'fpdb', 'default.conf') + else: config_path = False + + if config_path and os.path.exists(config_path): + file = config_path + else: + file = None + return file + + def read_default_conf(self, file): + parms = {} + fh = open(file, "r") + for line in fh: + line = string.strip(line) + (key, value) = line.split('=') + parms[key] = value + fh.close + return parms + + def find_example_config(self): + if os.path.exists('HUD_config.xml.example'): # there is a HUD_config in the cwd + file = 'HUD_config.xml.example' # so we use it + print "No HUD_config.xml found, using HUD_config.xml.example.\n", \ + "A HUD_config.xml will be written. You will probably have to edit it." + sys.stderr.write("No HUD_config.xml found, using HUD_config.xml.example.\n" + \ + "A HUD_config.xml will be written. You will probably have to edit it.") + else: + file = None + return file + def get_site_node(self, site): for site_node in self.doc.getElementsByTagName("site"): if site_node.getAttribute("site_name") == site: diff --git a/pyfpdb/HUD_config.xml.example b/pyfpdb/HUD_config.xml.example index abdf7618..be43765e 100644 --- a/pyfpdb/HUD_config.xml.example +++ b/pyfpdb/HUD_config.xml.example @@ -2,7 +2,7 @@ - + From 79ddee8971c38c2499f264b4136a3042c2caaa9e Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 4 Nov 2008 22:40:03 +1300 Subject: [PATCH 23/34] Add converter attribute to support additional sites --- pyfpdb/Configuration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index 50b5a287..3505b5c1 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -56,7 +56,7 @@ class Site: self.hudopacity = node.getAttribute("hudopacity") self.hudbgcolor = node.getAttribute("bgcolor") self.hudfgcolor = node.getAttribute("fgcolor") - + self.converter = node.getAttribute("converter") self.layout = {} for layout_node in node.getElementsByTagName('layout'): From 2ecfbf6c2d3261abe9ef02bd47a16bdc88e1a00d Mon Sep 17 00:00:00 2001 From: eblade Date: Tue, 4 Nov 2008 05:02:41 -0500 Subject: [PATCH 24/34] fpdb_import: auto-import bases it's decisions to check files on file-size changes rather than mtime - could you guys check it out in nix and other poker sites, and tell me if that breaks anything? HUD: if update() errors due to not enough stat windows being available (ie, your broken site converter tells us we have a 6 max table, but there are people in seats 7-10), it will re-assess the table as a 10-max add StatWindow.relocate(x,y) --- pyfpdb/Hud.py | 18 ++++++++++++++++-- pyfpdb/fpdb_import.py | 7 ++++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index f1d0cfae..9dca15d8 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -160,7 +160,10 @@ class Hud: # create the stat windows for i in range(1, self.max + 1): (x, y) = loc[adj[i]] - self.stat_windows[i] = Stat_Window(game = config.supported_games[self.poker_game], + if self.stat_windows.has_key(i): + self.stat_windows[i].relocate(x, y) + else: + self.stat_windows[i] = Stat_Window(game = config.supported_games[self.poker_game], parent = self, table = self.table, x = x, @@ -185,7 +188,13 @@ class Hud: def update(self, hand, config, stat_dict): self.hand = hand # this is the last hand, so it is available later for s in stat_dict.keys(): - self.stat_windows[stat_dict[s]['seat']].player_id = stat_dict[s]['player_id'] + try: + self.stat_windows[stat_dict[s]['seat']].player_id = stat_dict[s]['player_id'] + except: # omg, we have more seats than stat windows .. damn poker sites with incorrect max seating info .. let's force 10 here + self.max = 10 + self.create(hand, config) + self.stat_windows[stat_dict[s]['seat']].player_id = stat_dict[s]['player_id'] + for r in range(0, config.supported_games[self.poker_game].rows): for c in range(0, config.supported_games[self.poker_game].cols): this_stat = config.supported_games[self.poker_game].stats[self.stats[r][c]] @@ -283,6 +292,11 @@ class Stat_Window: else: top.set_decorated(1) top.move(x, y) + + def relocate(self, x, y): + self.x = x + self.table.x + self.y = y + self.table.y + self.window.move(self.x, self.y) def __init__(self, parent, game, table, seat, x, y, player_id, font): self.parent = parent # Hud object that this stat window belongs to diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index 4a855d1d..b5c1dd3e 100755 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -147,12 +147,13 @@ class Importer: try: lastupdate = self.updated[file] # print "Is " + str(stat_info.st_mtime) + " > " + str(lastupdate) - if stat_info.st_mtime > lastupdate: + #if stat_info.st_mtime > lastupdate: + if stat_info.st_size > lastupdate: self.import_file_dict(file) - self.updated[file] = time() + self.updated[file] = stat_info.st_size except: # print "Adding " + str(file) + " at approx " + str(time()) - self.updated[file] = time() + self.updated[file] = 0 # This is now an internal function that should not be called directly. def import_file_dict(self, file): From 093302e76d9284e745d005df8b081a1d5e40f1d8 Mon Sep 17 00:00:00 2001 From: Worros Date: Wed, 5 Nov 2008 10:39:27 +1300 Subject: [PATCH 25/34] Fix(?) problem with HUD only starting after 2 hands have been entered. Import code will now import_file_dict() on every file it initially finds that was modified in the last minute. Not perfect, as a lot of hands can take longer than that. --- pyfpdb/fpdb_import.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index 4a855d1d..d7fa5026 100755 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -110,7 +110,7 @@ class Importer: self.filelist = list(set(self.filelist)) #Add a directory of files to filelist - def addImportDirectory(self,dir,monitor = False): + def addImportDirectory(self,dir,monitor = False, filter = "passthrough"): if os.path.isdir(dir): if monitor == True: self.monitor = True @@ -146,13 +146,15 @@ class Importer: stat_info = os.stat(file) try: lastupdate = self.updated[file] -# print "Is " + str(stat_info.st_mtime) + " > " + str(lastupdate) if stat_info.st_mtime > lastupdate: self.import_file_dict(file) self.updated[file] = time() except: -# print "Adding " + str(file) + " at approx " + str(time()) self.updated[file] = time() + # This codepath only runs first time the file is found, if modified in the last + # minute run an immediate import. + if (time() - stat_info.st_mtime) < 60: + self.import_file_dict(file) # This is now an internal function that should not be called directly. def import_file_dict(self, file): From b0be7c5b7198dde95b923e22af4076f7f2fdcc81 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 5 Nov 2008 05:49:05 -0500 Subject: [PATCH 26/34] cleanup and new get/set for db parameters --- pyfpdb/Configuration.py | 55 ++++++++++++++++++++++++++++------- pyfpdb/HUD_config.xml.example | 2 +- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index 50b5a287..7f04d971 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -199,6 +199,7 @@ class Config: # "file" is a path to an xml file with the fpdb/HUD configuration # we check the existence of "file" and try to recover if it doesn't exist + self.default_config_path = self.get_default_config_path() if not file == None: # configuration file path has been passed if not os.path.exists(file): print "Configuration file %s not found. Using defaults." % (file) @@ -210,6 +211,8 @@ class Config: if file == None: # no config file in the normal places file = self.find_example_config() #Look for an example file to edit + if not file == None: + pass if file == None: # that didn't work either, just die print "No HUD_config_xml found. Exiting" @@ -276,27 +279,34 @@ class Config: pass else: df_parms = self.read_default_conf(df_file) - self.supported_databases['fpdb'].db_pass = df_parms['db-password'] - self.supported_databases['fpdb'].db_ip = df_parms['db-host'] - self.supported_databases['fpdb'].db_user = df_parms['db-user'] + self.set_db_parameters(db_name = 'fpdb', db_ip = df_parms['db-host'], + db_user = df_parms['db-user'], + db_pass = df_parms['db-password']) + self.save(file=os.path.join(self.default_config_path, "HUD_config.xml")) + def find_config(self): + """Looks in cwd and in self.default_config_path for a config file.""" if os.path.exists('HUD_config.xml'): # there is a HUD_config in the cwd file = 'HUD_config.xml' # so we use it else: # no HUD_config in the cwd, look where it should be in the first place -# find the path to the default HUD_config for the current os - if os.name == 'posix': - config_path = os.path.join(os.path.expanduser("~"), '.fpdb', 'HUD_config.xml') - elif os.name == 'nt': - config_path = os.path.join(os.environ["APPDATA"], 'fpdb', 'HUD_config.xml') - else: config_path = False - - if config_path and os.path.exists(config_path): + config_path = os.path.join(self.default_config_path, 'HUD_config.xml') + if os.path.exists(config_path): file = config_path else: file = None return file + def get_default_config_path(self): + """Returns the path where the fpdb config file _should_ be stored.""" + if os.name == 'posix': + config_path = os.path.join(os.path.expanduser("~"), '.fpdb') + elif os.name == 'nt': + config_path = os.path.join(os.environ["APPDATA"], 'fpdb') + else: config_path = None + return config_path + + def find_default_conf(self): if os.name == 'posix': config_path = os.path.join(os.path.expanduser("~"), '.fpdb', 'default.conf') @@ -336,6 +346,12 @@ class Config: if site_node.getAttribute("site_name") == site: return site_node + def get_db_node(self, db_name): + for db_node in self.doc.getElementsByTagName("database"): + if db_node.getAttribute("db_name") == db_name: + return db_node + return None + def get_layout_node(self, site_node, layout): for layout_node in site_node.getElementsByTagName("layout"): if layout_node.getAttribute("max") == None: @@ -389,6 +405,23 @@ class Config: pass return db + def set_db_parameters(self, db_name = 'fpdb', db_ip = None, db_user = None, + db_pass = None, db_server = None, db_type = None): + db_node = self.get_db_node(db_name) + if not db_node == None: + if not db_ip == None: db_node.setAttribute("db_ip", db_ip) + if not db_user == None: db_node.setAttribute("db_user", db_user) + if not db_pass == None: db_node.setAttribute("db_pass", db_pass) + if not db_server == None: db_node.setAttribute("db_server", db_server) + if not db_type == None: db_node.setAttribute("db_type", db_type) + if self.supported_databases.has_key(db_name): + if not db_ip == None: self.supported_databases[db_name].dp_ip = db_ip + if not db_user == None: self.supported_databases[db_name].dp_user = db_user + if not db_pass == None: self.supported_databases[db_name].dp_pass = db_pass + if not db_server == None: self.supported_databases[db_name].dp_server = db_server + if not db_type == None: self.supported_databases[db_name].dp_type = db_type + return + def get_tv_parameters(self): tv = {} try: diff --git a/pyfpdb/HUD_config.xml.example b/pyfpdb/HUD_config.xml.example index be43765e..abdf7618 100644 --- a/pyfpdb/HUD_config.xml.example +++ b/pyfpdb/HUD_config.xml.example @@ -2,7 +2,7 @@ - + From 92381254e84526ed3a7d4d9e222486ca2eae7857 Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 6 Nov 2008 00:36:24 +1300 Subject: [PATCH 27/34] Change the filelist and dirlist type to be a hash of lists, delete postgres sql schema dirlist is in the form: {'Site': [ "/path/to/dir", "filter" ] } Where filter will be the plugin to convert to stars/fpdb hand history file. filelist is in the form: {'file': [ "site", "filter" ] } --- pyfpdb/GuiAutoImport.py | 4 +- pyfpdb/fpdb_import.py | 33 +++--- pyfpdb/schema.postgres.sql | 218 ------------------------------------- 3 files changed, 15 insertions(+), 240 deletions(-) delete mode 100644 pyfpdb/schema.postgres.sql diff --git a/pyfpdb/GuiAutoImport.py b/pyfpdb/GuiAutoImport.py index 7a6313cc..916170f0 100644 --- a/pyfpdb/GuiAutoImport.py +++ b/pyfpdb/GuiAutoImport.py @@ -110,8 +110,8 @@ class GuiAutoImport (threading.Thread): self.tiltpath=self.tiltDirPath.get_text() # Add directory to importer object. - self.importer.addImportDirectory(self.starspath, True) - self.importer.addImportDirectory(self.tiltpath, True) + self.importer.addImportDirectory(self.starspath, True, "PokerStars", "passthrough") + self.importer.addImportDirectory(self.tiltpath, True, "FullTilt", "passthrough") self.do_import() interval=int(self.intervalEntry.get_text()) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index d7fa5026..ffa06cff 100755 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -47,8 +47,8 @@ class Importer: self.caller=caller self.db = None self.cursor = None - self.filelist = [] - self.dirlist = [] + self.filelist = {} + self.dirlist = {} self.monitor = False self.updated = {} #Time last import was run {file:mtime} self.callHud = False @@ -100,29 +100,25 @@ class Importer: # self.updated = time() def clearFileList(self): - self.filelist = [] + self.filelist = {} #Add an individual file to filelist - def addImportFile(self, filename): + def addImportFile(self, filename, site = "default", filter = "passthrough"): #TODO: test it is a valid file - self.filelist = self.filelist + [filename] - #Remove duplicates - self.filelist = list(set(self.filelist)) + self.filelist[filename] = [site] + [filter] #Add a directory of files to filelist - def addImportDirectory(self,dir,monitor = False, filter = "passthrough"): + #Only one import directory per site supported. + #dirlist is a hash of lists: + #dirlist{ 'PokerStars' => ["/path/to/import/", "filtername"] } + def addImportDirectory(self,dir,monitor = False, site = "default", filter = "passthrough"): if os.path.isdir(dir): if monitor == True: self.monitor = True - self.dirlist = self.dirlist + [dir] + self.dirlist[site] = [dir] + [filter] for file in os.listdir(dir): - if os.path.isdir(file): - print "BulkImport is not recursive - please select the final directory in which the history files are" - else: - self.filelist = self.filelist + [os.path.join(dir, file)] - #Remove duplicates - self.filelist = list(set(self.filelist)) + self.addImportFile(os.path.join(dir, file), site, filter) else: print "Warning: Attempted to add: '" + str(dir) + "' as an import directory" @@ -136,11 +132,8 @@ class Importer: #Check for new files in directory #todo: make efficient - always checks for new file, should be able to use mtime of directory # ^^ May not work on windows - for dir in self.dirlist: - for file in os.listdir(dir): - self.filelist = self.filelist + [os.path.join(dir, file)] - - self.filelist = list(set(self.filelist)) + for site in self.dirlist: + self.addImportDirectory(self.dirlist[site][0], False, site, self.dirlist[site][1]) for file in self.filelist: stat_info = os.stat(file) diff --git a/pyfpdb/schema.postgres.sql b/pyfpdb/schema.postgres.sql deleted file mode 100644 index 2affb1c6..00000000 --- a/pyfpdb/schema.postgres.sql +++ /dev/null @@ -1,218 +0,0 @@ - -DROP TABLE IF EXISTS Settings CASCADE; -CREATE TABLE Settings (version SMALLINT); - -DROP TABLE IF EXISTS Sites CASCADE; -CREATE TABLE Sites ( - id SERIAL UNIQUE, PRIMARY KEY (id), - name varchar(32), - currency char(3)); - -DROP TABLE IF EXISTS Gametypes CASCADE; -CREATE TABLE Gametypes ( - id SERIAL UNIQUE, PRIMARY KEY (id), - siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id), - type char(4), - base char(4), - category varchar(9), - limitType char(2), - hiLo char(1), - smallBlind int, - bigBlind int, - smallBet int, - bigBet int); - -DROP TABLE IF EXISTS Players CASCADE; -CREATE TABLE Players ( - id SERIAL UNIQUE, PRIMARY KEY (id), - name VARCHAR(32), - siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id), - comment text, - commentTs timestamp without time zone); - -DROP TABLE IF EXISTS Autorates CASCADE; -CREATE TABLE Autorates ( - id BIGSERIAL UNIQUE, PRIMARY KEY (id), - playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id), - gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id), - description varchar(50), - shortDesc char(8), - ratingTime timestamp without time zone, - handCount int); - -DROP TABLE IF EXISTS Hands CASCADE; -CREATE TABLE Hands ( - id BIGSERIAL UNIQUE, PRIMARY KEY (id), - tableName VARCHAR(20), - siteHandNo BIGINT, - gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id), - handStart timestamp without time zone, - importTime timestamp without time zone, - seats SMALLINT, - maxSeats SMALLINT, - comment TEXT, - commentTs timestamp without time zone); - -DROP TABLE IF EXISTS BoardCards CASCADE; -CREATE TABLE BoardCards ( - id BIGSERIAL UNIQUE, PRIMARY KEY (id), - handId BIGINT, FOREIGN KEY (handId) REFERENCES Hands(id), - card1Value smallint, - card1Suit char(1), - card2Value smallint, - card2Suit char(1), - card3Value smallint, - card3Suit char(1), - card4Value smallint, - card4Suit char(1), - card5Value smallint, - card5Suit char(1)); - -DROP TABLE IF EXISTS TourneyTypes CASCADE; -CREATE TABLE TourneyTypes ( - id SERIAL, PRIMARY KEY (id), - siteId INT, FOREIGN KEY (siteId) REFERENCES Sites(id), - buyin INT, - fee INT, - knockout INT, - rebuyOrAddon BOOLEAN); - -DROP TABLE IF EXISTS Tourneys CASCADE; -CREATE TABLE Tourneys ( - id SERIAL UNIQUE, PRIMARY KEY (id), - tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id), - siteTourneyNo BIGINT, - entries INT, - prizepool INT, - startTime timestamp without time zone, - comment TEXT, - commentTs timestamp without time zone); - -DROP TABLE IF EXISTS TourneysPlayers CASCADE; -CREATE TABLE TourneysPlayers ( - id BIGSERIAL UNIQUE, PRIMARY KEY (id), - tourneyId INT, FOREIGN KEY (tourneyId) REFERENCES Tourneys(id), - playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id), - payinAmount INT, - rank INT, - winnings INT, - comment TEXT, - commentTs timestamp without time zone); - -DROP TABLE IF EXISTS HandsPlayers CASCADE; -CREATE TABLE HandsPlayers ( - id BIGSERIAL UNIQUE, PRIMARY KEY (id), - handId BIGINT, FOREIGN KEY (handId) REFERENCES Hands(id), - playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id), - startCash INT, - position CHAR(1), - seatNo SMALLINT, - ante INT, - - card1Value smallint, - card1Suit char(1), - card2Value smallint, - card2Suit char(1), - card3Value smallint, - card3Suit char(1), - card4Value smallint, - card4Suit char(1), - card5Value smallint, - card5Suit char(1), - card6Value smallint, - card6Suit char(1), - card7Value smallint, - card7Suit char(1), - - winnings int, - rake int, - comment text, - commentTs timestamp without time zone, - tourneysPlayersId BIGINT, FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id)); - -DROP TABLE IF EXISTS HandsActions CASCADE; -CREATE TABLE HandsActions ( - id BIGSERIAL UNIQUE, PRIMARY KEY (id), - handPlayerId BIGINT, FOREIGN KEY (handPlayerId) REFERENCES HandsPlayers(id), - street SMALLINT, - actionNo SMALLINT, - action CHAR(5), - allIn BOOLEAN, - amount INT, - comment TEXT, - commentTs timestamp without time zone); - -DROP TABLE IF EXISTS HudCache CASCADE; -CREATE TABLE HudCache ( - id BIGSERIAL UNIQUE, PRIMARY KEY (id), - gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id), - playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id), - activeSeats SMALLINT, - position CHAR(1), - tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id), - - HDs INT, - street0VPI INT, - street0Aggr INT, - street0_3B4BChance INT, - street0_3B4BDone INT, - street1Seen INT, - street2Seen INT, - street3Seen INT, - street4Seen INT, - sawShowdown INT, - street1Aggr INT, - street2Aggr INT, - street3Aggr INT, - street4Aggr INT, - otherRaisedStreet1 INT, - otherRaisedStreet2 INT, - otherRaisedStreet3 INT, - otherRaisedStreet4 INT, - foldToOtherRaisedStreet1 INT, - foldToOtherRaisedStreet2 INT, - foldToOtherRaisedStreet3 INT, - foldToOtherRaisedStreet4 INT, - wonWhenSeenStreet1 FLOAT, - wonAtSD FLOAT, - - stealAttemptChance INT, - stealAttempted INT, - foldBbToStealChance INT, - foldedBbToSteal INT, - foldSbToStealChance INT, - foldedSbToSteal INT, - - street1CBChance INT, - street1CBDone INT, - street2CBChance INT, - street2CBDone INT, - street3CBChance INT, - street3CBDone INT, - street4CBChance INT, - street4CBDone INT, - - foldToStreet1CBChance INT, - foldToStreet1CBDone INT, - foldToStreet2CBChance INT, - foldToStreet2CBDone INT, - foldToStreet3CBChance INT, - foldToStreet3CBDone INT, - foldToStreet4CBChance INT, - foldToStreet4CBDone INT, - - totalProfit INT, - - street1CheckCallRaiseChance INT, - street1CheckCallRaiseDone INT, - street2CheckCallRaiseChance INT, - street2CheckCallRaiseDone INT, - street3CheckCallRaiseChance INT, - street3CheckCallRaiseDone INT, - street4CheckCallRaiseChance INT, - street4CheckCallRaiseDone INT); - -INSERT INTO Settings VALUES (118); -INSERT INTO Sites ("name", currency) VALUES ('Full Tilt Poker', 'USD'); -INSERT INTO Sites ("name", currency) VALUES ('PokerStars', 'USD'); -INSERT INTO TourneyTypes (buyin, fee, knockout, rebuyOrAddon) VALUES (0, 0, 0, FALSE); From 8191db648740e8766def07a80a4fb2105f71da56 Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 6 Nov 2008 06:57:15 +1300 Subject: [PATCH 28/34] Add new parameters to HUD_config.xml.example in prep for HH filter plugins --- pyfpdb/HUD_config.xml.example | 39 +++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/pyfpdb/HUD_config.xml.example b/pyfpdb/HUD_config.xml.example index abdf7618..aeeaa219 100644 --- a/pyfpdb/HUD_config.xml.example +++ b/pyfpdb/HUD_config.xml.example @@ -2,7 +2,7 @@ - + @@ -49,7 +49,42 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 22831cc8c6173dffdf22bcc42d8a5cb3b61d97a8 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 5 Nov 2008 15:04:04 -0500 Subject: [PATCH 29/34] added get_converter to support Carl's importer change --- pyfpdb/Configuration.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index 01521fb0..bdc5f356 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -480,7 +480,10 @@ class Config: ( 0, 280), (121, 280), ( 46, 30) ) return locations - + def get_converter(self, site): + if not self.supported_sites.has_key(site): + return None + return self.supported_sites[site].converter if __name__== "__main__": c = Config() @@ -528,3 +531,4 @@ if __name__== "__main__": print "paths = ", c.get_default_paths("PokerStars") print "colors = ", c.get_default_colors("PokerStars") print "locs = ", c.get_locations("PokerStars", 8) + print "converter = ", c.get_converter("Everleaf") From a41aec44dde9660b0dc47ed7a3a7949eacd99439 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 5 Nov 2008 16:52:47 -0500 Subject: [PATCH 30/34] added set/get _sit_parameters to Config + removed keep_above in Hud --- pyfpdb/Configuration.py | 50 ++++++++++++++++++++++++++++++++++++++--- pyfpdb/Hud.py | 2 +- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index bdc5f356..5e599d4b 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -480,10 +480,52 @@ class Config: ( 0, 280), (121, 280), ( 46, 30) ) return locations - def get_converter(self, site): + def get_site_parameters(self, site): + """Returns a dict of the site parameters for the specified site""" if not self.supported_sites.has_key(site): return None - return self.supported_sites[site].converter + parms = {} + parms["converter"] = self.supported_sites[site].converter + parms["decoder"] = self.supported_sites[site].decoder + parms["hudbgcolor"] = self.supported_sites[site].hudbgcolor + parms["hudfgcolor"] = self.supported_sites[site].hudfgcolor + parms["hudopacity"] = self.supported_sites[site].hudopacity + parms["screen_name"] = self.supported_sites[site].screen_name + parms["site_path"] = self.supported_sites[site].site_path + parms["table_finder"] = self.supported_sites[site].table_finder + parms["HH_path"] = self.supported_sites[site].HH_path + return parms + + def set_site_parameters(self, site_name, converter = None, decoder = None, + hudbgcolor = None, hudfgcolor = None, + hudopacity = None, screen_name = None, + site_path = None, table_finder = None, + HH_path = None): + """Sets the specified site parameters for the specified site.""" + site_node = self.get_site_node(site_name) + if not db_node == None: + if not converter == None: site_node.setAttribute("converter", converter) + if not decoder == None: site_node.setAttribute("decoder", decoder) + if not hudbgcolor == None: site_node.setAttribute("hudbgcolor", hudbgcolor) + if not hudfgcolor == None: site_node.setAttribute("hudfgcolor", hudfgcolor) + if not hudopacity == None: site_node.setAttribute("hudopacity", hudopacity) + if not screen_name == None: site_node.setAttribute("screen_name", screen_name) + if not site_path == None: site_node.setAttribute("site_path", site_path) + if not table_finder == None: site_node.setAttribute("table_finder", table_finder) + if not HH_path == None: site_node.setAttribute("HH_path", HH_path) + + if self.supported_databases.has_key(db_name): + if not converter == None: self.supported_sites[site].converter = converter + if not decoder == None: self.supported_sites[site].decoder = decoder + if not hudbgcolor == None: self.supported_sites[site].hudbgcolor = hudbgcolor + if not hudfgcolor == None: self.supported_sites[site].hudfgcolor = hudfgcolor + if not hudopacity == None: self.supported_sites[site].hudopacity = hudopacity + if not screen_name == None: self.supported_sites[site].screen_name = screen_name + if not site_path == None: self.supported_sites[site].site_path = site_path + if not table_finder == None: self.supported_sites[site].table_finder = table_finder + if not HH_path == None: self.supported_sites[site].HH_path = HH_path + return + if __name__== "__main__": c = Config() @@ -531,4 +573,6 @@ if __name__== "__main__": print "paths = ", c.get_default_paths("PokerStars") print "colors = ", c.get_default_colors("PokerStars") print "locs = ", c.get_locations("PokerStars", 8) - print "converter = ", c.get_converter("Everleaf") + for site in c.supported_sites.keys(): + print "site = ", site, + print c.get_site_parameters(site) \ No newline at end of file diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index 9dca15d8..ebea595a 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -385,7 +385,7 @@ class Popup_window: self.window = gtk.Window() self.window.set_decorated(0) self.window.set_gravity(gtk.gdk.GRAVITY_STATIC) - self.window.set_keep_above(1) +# self.window.set_keep_above(1) self.window.set_title("popup") self.window.set_property("skip-taskbar-hint", True) self.window.set_transient_for(parent.get_toplevel()) From a29372a756cdd8c843d912b1358f33b331f6435a Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 6 Nov 2008 12:14:46 +1300 Subject: [PATCH 31/34] Fix copy-paste error in Stat.py for a_freq_3 function. Hat tip to sqlcoder on sourceforge. --- pyfpdb/Stats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/Stats.py b/pyfpdb/Stats.py index 07c69662..7bb9a8c5 100644 --- a/pyfpdb/Stats.py +++ b/pyfpdb/Stats.py @@ -382,7 +382,7 @@ def a_freq_3(stat_dict, player): '%3.1f' % (100*stat) + '%', 'a3=%3.1f' % (100*stat) + '%', 'a_fq_3=%3.1f' % (100*stat) + '%', - '(%d/%d)' % (stat_dict[player]['aggr_1'], stat_dict[player]['saw_1']), + '(%d/%d)' % (stat_dict[player]['aggr_3'], stat_dict[player]['saw_3']), 'Aggression Freq river/6th' ) except: From cf1efb8d27cf3f1e2a03d25a71fe1af0c2a72e84 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 5 Nov 2008 22:44:29 -0500 Subject: [PATCH 32/34] transaction isolation code suggested by sql_coder on the forums --- pyfpdb/Database.py | 4 ++++ pyfpdb/HUD_main.py | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 63de54b2..4039b256 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -59,6 +59,10 @@ class Database: user = c.supported_databases[db_name].db_user, passwd = c.supported_databases[db_name].db_pass, db = c.supported_databases[db_name].db_name) + cur_iso = self.connection.cursor() + cur_iso.execute('SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED') + cur_iso.close() + except: print "Error opening database connection %s. See error log file." % (file) traceback.print_exc(file=sys.stderr) diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py index a157cf46..b1955a6b 100755 --- a/pyfpdb/HUD_main.py +++ b/pyfpdb/HUD_main.py @@ -89,6 +89,7 @@ def update_HUD(new_hand_id, table_name, config, stat_dict): def read_stdin(): # This is the thread function global hud_dict + db_connection = Database.Database(config, db_name, 'temp') while True: # wait for a new hand number on stdin new_hand_id = sys.stdin.readline() new_hand_id = string.rstrip(new_hand_id) @@ -101,10 +102,8 @@ def read_stdin(): # This is the thread function del(hud_dict[h]) # connect to the db and get basic info about the new hand - db_connection = Database.Database(config, db_name, 'temp') (table_name, max, poker_game) = db_connection.get_table_name(new_hand_id) stat_dict = db_connection.get_stats_from_hand(new_hand_id) - db_connection.close_connection() # if a hud for this table exists, just update it if hud_dict.has_key(table_name): From c330bd772b6de8a5304bd8629cd116ed009bf517 Mon Sep 17 00:00:00 2001 From: eblade Date: Thu, 6 Nov 2008 06:26:25 -0500 Subject: [PATCH 33/34] add .exe to PokerStars tablefinder in default config, change some things for the "everleaf" entry --- pyfpdb/HUD_config.xml.example | 53 +++++++++++++++-------------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/pyfpdb/HUD_config.xml.example b/pyfpdb/HUD_config.xml.example index aeeaa219..3a595fe2 100644 --- a/pyfpdb/HUD_config.xml.example +++ b/pyfpdb/HUD_config.xml.example @@ -2,7 +2,7 @@ - + @@ -84,39 +84,30 @@ - - - - - - - - - - + + + + + + + + - - - - - - - + + + + + + + + + + + - + - - - - - - - - - - - - + From 27c6c4884edb55bee25cd2deb4b7c0034698b53b Mon Sep 17 00:00:00 2001 From: eblade Date: Thu, 6 Nov 2008 06:58:28 -0500 Subject: [PATCH 34/34] stat popups attach themselves to the stat window as children, have proper colors --- pyfpdb/Hud.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index ebea595a..2712c55b 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -399,6 +399,14 @@ class Popup_window: # need an event box so we can respond to clicks self.window.add(self.ebox) self.ebox.add(self.lab) + + self.ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudbgcolor'])) + self.ebox.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudfgcolor'])) + self.window.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudbgcolor'])) + self.window.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(stat_window.parent.colors['hudfgcolor'])) + 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 # figure out the row, col address of the click that activated the popup @@ -440,6 +448,9 @@ class Popup_window: self.lab.set_text(pu_text) self.window.show_all() + + self.window.set_transient_for(stat_window.main_window) + # set_keep_above(1) for windows if os.name == 'nt': self.topify_window(self.window)