Merge branch 'master' of git://git.assembla.com/fpdb-eric
This commit is contained in:
commit
d994f04e01
|
@ -154,8 +154,11 @@ class GuiAutoImport (threading.Thread):
|
|||
else: # toggled off
|
||||
self.doAutoImportBool = False # do_import will return this and stop the gobject callback timer
|
||||
print "Stopping autoimport"
|
||||
print >>self.pipe_to_hud.stdin, "\n"
|
||||
#self.pipe_to_hud.communicate('\n') # waits for process to terminate
|
||||
if self.pipe_to_hud.poll() is not None:
|
||||
print "HUD already terminated"
|
||||
else:
|
||||
#print >>self.pipe_to_hud.stdin, "\n"
|
||||
self.pipe_to_hud.communicate('\n') # waits for process to terminate
|
||||
self.pipe_to_hud = None
|
||||
self.startButton.set_label(u'Start Autoimport')
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ import Hud
|
|||
|
||||
# global dict for keeping the huds
|
||||
hud_dict = {}
|
||||
eb = 0 # our former event-box
|
||||
|
||||
db_connection = 0;
|
||||
config = 0;
|
||||
|
@ -61,11 +62,18 @@ def destroy(*args): # call back for terminating the main eventloop
|
|||
|
||||
def create_HUD(new_hand_id, table, db_name, table_name, max, poker_game, db_connection, config, stat_dict):
|
||||
global hud_dict
|
||||
global eb
|
||||
def idle_func():
|
||||
global hud_dict
|
||||
global eb
|
||||
gtk.gdk.threads_enter()
|
||||
try:
|
||||
newlabel = gtk.Label(table_name)
|
||||
eb.add(newlabel)
|
||||
newlabel.show()
|
||||
|
||||
hud_dict[table_name] = Hud.Hud(table, max, poker_game, config, db_connection)
|
||||
hud_dict[table_name].tablehudlabel = newlabel
|
||||
hud_dict[table_name].create(new_hand_id, config)
|
||||
for m in hud_dict[table_name].aux_windows:
|
||||
m.update_data(new_hand_id, db_connection)
|
||||
|
@ -92,6 +100,7 @@ def update_HUD(new_hand_id, table_name, config, stat_dict):
|
|||
|
||||
def read_stdin(): # This is the thread function
|
||||
global hud_dict
|
||||
global eb
|
||||
|
||||
db_connection = Database.Database(config, db_name, 'temp')
|
||||
tourny_finder = re.compile('(\d+) (\d+)')
|
||||
|
@ -105,6 +114,7 @@ def read_stdin(): # This is the thread function
|
|||
# delete hud_dict entries for any HUD destroyed since last iteration
|
||||
for h in hud_dict.keys():
|
||||
if hud_dict[h].deleted:
|
||||
eb.remove(hud_dict[h].tablehudlabel)
|
||||
del(hud_dict[h])
|
||||
|
||||
# get basic info about the new hand from the db
|
||||
|
@ -162,10 +172,11 @@ if __name__== "__main__":
|
|||
|
||||
main_window = gtk.Window()
|
||||
main_window.connect("destroy", destroy)
|
||||
eb = gtk.EventBox()
|
||||
eb = gtk.VBox()
|
||||
label = gtk.Label('Closing this window will exit from the HUD.')
|
||||
eb.add(label)
|
||||
main_window.add(eb)
|
||||
|
||||
main_window.set_title("HUD Main Window")
|
||||
main_window.show_all()
|
||||
|
||||
|
|
|
@ -576,5 +576,7 @@ class Pot(object):
|
|||
elif len(self.pots) == 3:
|
||||
return "Total pot $%.2f Main pot $%.2f. Side pot-1 $%2.2f. Side pot-2 $%.2f." % (self.total, self.pots[0], self.pots[1], self.pots[2])
|
||||
else:
|
||||
return "too many pots.. fix me.", self.pots
|
||||
return "maybe no pot.. or too many pots.. no small blind and walk in bb?."
|
||||
# I don't know stars format for a walk in the bb when sb doesn't post.
|
||||
# The thing to do here is raise a Hand error like fpdb import does and file it into errors.txt
|
||||
|
||||
|
|
|
@ -68,28 +68,31 @@ class Hud:
|
|||
else:
|
||||
print "Setting font to ", font + " " + font_size
|
||||
self.font = pango.FontDescription(font + " " + font_size)
|
||||
|
||||
# do we need to add some sort of condition here for dealing with a request for a font that doesn't exist?
|
||||
|
||||
# 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_title(table.name + " FPDBHUD")
|
||||
self.main_window.connect("destroy", self.kill_hud)
|
||||
self.main_window.set_decorated(False)
|
||||
self.main_window.set_opacity(self.colors["hudopacity"])
|
||||
#self.main_window.set_transient_for(parent.get_toplevel())
|
||||
|
||||
self.ebox = gtk.EventBox()
|
||||
# self.label = gtk.Label("Right click to close HUD for %s\nor Save Stat Positions." % (table.name))
|
||||
self.label = gtk.Label("FPDB Menu (Right Click)\nLeft-drag to move")
|
||||
|
||||
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.backgroundcolor = gtk.gdk.color_parse(self.colors['hudbgcolor'])
|
||||
self.foregroundcolor = gtk.gdk.color_parse(self.colors['hudfgcolor'])
|
||||
|
||||
self.label.modify_bg(gtk.STATE_NORMAL, self.backgroundcolor)
|
||||
self.label.modify_fg(gtk.STATE_NORMAL, self.foregroundcolor)
|
||||
|
||||
self.main_window.add(self.ebox)
|
||||
self.ebox.add(self.label)
|
||||
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.ebox.modify_bg(gtk.STATE_NORMAL, self.backgroundcolor)
|
||||
self.ebox.modify_fg(gtk.STATE_NORMAL, self.foregroundcolor)
|
||||
|
||||
self.main_window.move(self.table.x, self.table.y)
|
||||
|
||||
|
@ -118,24 +121,21 @@ class Hud:
|
|||
self.ebox.connect_object("button-press-event", self.on_button_press, self.menu)
|
||||
|
||||
self.main_window.show_all()
|
||||
# set_keep_above(1) for windows
|
||||
|
||||
if os.name == 'nt':
|
||||
self.topify_window(self.main_window)
|
||||
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.set_destroy_with_parent(True)
|
||||
|
||||
|
||||
def update_table_position(self):
|
||||
# self.main_window.parentgdkhandle = gtk.gdk.window_foreign_new(self.table.number)
|
||||
# if self.main_window.parentgdkhandle == None:
|
||||
if os.name == 'nt':
|
||||
if not win32gui.IsWindow(self.table.number):
|
||||
self.kill_hud()
|
||||
return False
|
||||
|
||||
# anyone know how to do this in unix, or better yet, trap the X11 error that is triggered when executing the get_origin() for a closed window?
|
||||
|
||||
(x, y) = self.main_window.parentgdkhandle.get_origin()
|
||||
if self.table.x != x or self.table.y != y:
|
||||
self.table.x = x
|
||||
|
@ -146,8 +146,7 @@ class Hud:
|
|||
for i in range(1, self.max + 1):
|
||||
(x, y) = loc[adj[i]]
|
||||
if self.stat_windows.has_key(i):
|
||||
self.stat_windows[i].relocate(x, y)
|
||||
|
||||
self.stat_windows[i].relocate(x, y)
|
||||
return True
|
||||
|
||||
def on_button_press(self, widget, event):
|
||||
|
@ -176,7 +175,6 @@ class Hud:
|
|||
|
||||
def save_layout(self, *args):
|
||||
new_layout = [(0, 0)] * self.max
|
||||
# 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)
|
||||
|
@ -267,8 +265,9 @@ 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":
|
||||
if statstring != "xxx": # is there a way to tell if this particular stat window is visible already, or no?
|
||||
self.stat_windows[stat_dict[s]['seat']].window.show_all()
|
||||
self.reposition_windows()
|
||||
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)
|
||||
|
@ -291,29 +290,13 @@ class Hud:
|
|||
|
||||
for w in tl_windows:
|
||||
if w[1] == unique_name:
|
||||
#win32gui.ShowWindow(w[0], win32con.SW_HIDE)
|
||||
self.main_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(self.main_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)
|
||||
|
||||
# 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)
|
||||
|
||||
class Stat_Window:
|
||||
|
@ -335,7 +318,6 @@ class Stat_Window:
|
|||
|
||||
if event.button == 2: # middle button event
|
||||
self.window.hide()
|
||||
# print "middle button clicked"
|
||||
pass
|
||||
|
||||
if event.button == 1: # left button event
|
||||
|
@ -349,7 +331,6 @@ class Stat_Window:
|
|||
# Callback from the timeout in the single-click finding part of the
|
||||
# button press call back. This needs to be modified to get all the
|
||||
# arguments from the call.
|
||||
# print "left button clicked"
|
||||
self.sb_click = 0
|
||||
Popup_window(widget, self)
|
||||
return False
|
||||
|
@ -404,19 +385,18 @@ 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.colors['hudbgcolor']))
|
||||
self.e_box[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.colors['hudfgcolor']))
|
||||
self.e_box[r][c].modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
||||
self.e_box[r][c].modify_fg(gtk.STATE_NORMAL, parent.foregroundcolor)
|
||||
|
||||
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.colors['hudbgcolor']))
|
||||
self.label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(parent.colors['hudfgcolor']))
|
||||
self.label[r][c].modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
||||
self.label[r][c].modify_fg(gtk.STATE_NORMAL, parent.foregroundcolor)
|
||||
|
||||
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(self.font)
|
||||
self.label[r][c].modify_font(font)
|
||||
|
||||
self.window.set_opacity(parent.colors['hudopacity'])
|
||||
|
@ -436,7 +416,6 @@ 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_title("popup")
|
||||
self.window.set_property("skip-taskbar-hint", True)
|
||||
self.window.set_transient_for(parent.get_toplevel())
|
||||
|
@ -451,15 +430,13 @@ class Popup_window:
|
|||
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.ebox.modify_bg(gtk.STATE_NORMAL, stat_window.parent.backgroundcolor)
|
||||
self.ebox.modify_fg(gtk.STATE_NORMAL, stat_window.parent.foregroundcolor)
|
||||
self.window.modify_bg(gtk.STATE_NORMAL, stat_window.parent.backgroundcolor)
|
||||
self.window.modify_fg(gtk.STATE_NORMAL, stat_window.parent.foregroundcolor)
|
||||
self.lab.modify_bg(gtk.STATE_NORMAL, stat_window.parent.backgroundcolor)
|
||||
self.lab.modify_fg(gtk.STATE_NORMAL, stat_window.parent.foregroundcolor)
|
||||
|
||||
# self.window.realize()
|
||||
|
||||
# figure out the row, col address of the click that activated the popup
|
||||
row = 0
|
||||
col = 0
|
||||
|
@ -502,8 +479,8 @@ class Popup_window:
|
|||
|
||||
self.window.set_transient_for(stat_window.window)
|
||||
|
||||
# set_keep_above(1) for windows
|
||||
if os.name == 'nt': self.topify_window(self.window)
|
||||
if os.name == 'nt':
|
||||
self.topify_window(self.window)
|
||||
|
||||
def button_press_cb(self, widget, event, *args):
|
||||
# This handles all callbacks from button presses on the event boxes in
|
||||
|
@ -521,11 +498,9 @@ class Popup_window:
|
|||
|
||||
if event.button == 2: # middle button event
|
||||
pass
|
||||
# print "middle button clicked"
|
||||
|
||||
if event.button == 3: # right button event
|
||||
pass
|
||||
# print "right button clicked"
|
||||
|
||||
def single_click(self, widget):
|
||||
# Callback from the timeout in the single-click finding part of the
|
||||
|
@ -564,22 +539,8 @@ class Popup_window:
|
|||
|
||||
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.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)
|
||||
|
||||
if __name__== "__main__":
|
||||
|
|
|
@ -281,13 +281,7 @@ def steal(stat_dict, player):
|
|||
'% steal attempted'
|
||||
)
|
||||
except:
|
||||
return (stat,
|
||||
'%3.1f' % (0) + '%',
|
||||
'st=%3.1f' % (0) + '%',
|
||||
'steal=%3.1f' % (0) + '%',
|
||||
'(%d/%d)' % (0, 0),
|
||||
'% steal attempted'
|
||||
)
|
||||
return (stat, 'NA', 'st=NA', 'steal=NA', '(0/0)', '% steal attempted')
|
||||
|
||||
def f_SB_steal(stat_dict, player):
|
||||
""" Folded SB to steal."""
|
||||
|
@ -306,7 +300,7 @@ def f_SB_steal(stat_dict, player):
|
|||
'NA',
|
||||
'fSB=NA',
|
||||
'fSB_s=NA',
|
||||
'0/0',
|
||||
'(0/0)',
|
||||
'% folded SB to steal')
|
||||
|
||||
def f_BB_steal(stat_dict, player):
|
||||
|
@ -326,7 +320,7 @@ def f_BB_steal(stat_dict, player):
|
|||
'NA',
|
||||
'fBB=NA',
|
||||
'fBB_s=NA',
|
||||
'0/0',
|
||||
'(0/0)',
|
||||
'% folded BB to steal')
|
||||
|
||||
def three_B_0(stat_dict, player):
|
||||
|
|
|
@ -152,7 +152,7 @@ def discover_posix_by_name(c, tablename):
|
|||
info = decode_xwininfo(c, listing)
|
||||
if not info['name'] == tablename: continue
|
||||
return info
|
||||
return False
|
||||
return None
|
||||
|
||||
def discover_posix_tournament(c, t_number, s_number):
|
||||
"""Finds the X window for a client, given tournament and table nos."""
|
||||
|
@ -160,7 +160,7 @@ def discover_posix_tournament(c, t_number, s_number):
|
|||
for listing in os.popen('xwininfo -root -tree').readlines():
|
||||
if re.search(search_string, listing):
|
||||
return decode_xwininfo(c, listing)
|
||||
return False
|
||||
return None
|
||||
|
||||
def decode_xwininfo(c, info_string):
|
||||
"""Gets window parameters from xwinifo string--XWindows."""
|
||||
|
@ -231,7 +231,7 @@ def discover_nt_by_name(c, tablename):
|
|||
if titles[hwnd].find("HUD:") > -1: continue
|
||||
if titles[hwnd].find("Chat:") > -1: continue
|
||||
return decode_windows(c, titles[hwnd], hwnd)
|
||||
return False
|
||||
return None
|
||||
|
||||
def discover_nt_tournament(c, tour_number, tab_number):
|
||||
"""Finds the Windows window handle for the given tournament/table."""
|
||||
|
@ -242,7 +242,7 @@ def discover_nt_tournament(c, tour_number, tab_number):
|
|||
for hwnd in titles.keys():
|
||||
if re.search(search_string, titles[hwnd]):
|
||||
return decode_windows(c, titles[hwnd], hwnd)
|
||||
return False
|
||||
return None
|
||||
|
||||
def get_nt_exe(hwnd):
|
||||
"""Finds the name of the executable that the given window handle belongs to."""
|
||||
|
|
|
@ -282,14 +282,12 @@ class Importer:
|
|||
self.fdb.db.commit()
|
||||
self.handsId=handsId
|
||||
return handsId
|
||||
#end def import_file_dict
|
||||
|
||||
def parseTourneyHistory(self):
|
||||
print "Tourney history parser stub"
|
||||
#Find tournament boundaries.
|
||||
#print self.foabs
|
||||
|
||||
|
||||
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."
|
||||
|
|
|
@ -329,6 +329,307 @@ def analyzeDB(fdb):
|
|||
#end def analyzeDB
|
||||
|
||||
|
||||
# Data Structures for index and foreign key creation
|
||||
# drop_code is an int with possible values: 0 - don't drop for bulk import
|
||||
# 1 - drop during bulk import
|
||||
# db differences:
|
||||
# - note that mysql automatically creates indexes on constrained columns when
|
||||
# foreign keys are created, while postgres does not. Hence the much longer list
|
||||
# of indexes is required for postgres.
|
||||
# all primary keys are left on all the time
|
||||
#
|
||||
# table column drop_code
|
||||
|
||||
indexes = [
|
||||
[ ] # no db with index 0
|
||||
, [ ] # no db with index 1
|
||||
, [ # indexes for mysql (list index 2)
|
||||
{'tab':'Players', 'col':'name', 'drop':0}
|
||||
, {'tab':'Hands', 'col':'siteHandNo', 'drop':0}
|
||||
, {'tab':'Tourneys', 'col':'siteTourneyNo', 'drop':0}
|
||||
]
|
||||
, [ # indexes for postgres (list index 3)
|
||||
{'tab':'Boardcards', 'col':'handId', 'drop':0}
|
||||
, {'tab':'Gametypes', 'col':'siteId', 'drop':0}
|
||||
, {'tab':'Hands', 'col':'gametypeId', 'drop':1}
|
||||
, {'tab':'Hands', 'col':'siteHandNo', 'drop':0}
|
||||
, {'tab':'HandsActions', 'col':'handplayerId', 'drop':0}
|
||||
, {'tab':'HandsPlayers', 'col':'handId', 'drop':1}
|
||||
, {'tab':'HandsPlayers', 'col':'playerId', 'drop':1}
|
||||
, {'tab':'HandsPlayers', 'col':'tourneysPlayersId', 'drop':0}
|
||||
, {'tab':'HudCache', 'col':'gametypeId', 'drop':1}
|
||||
, {'tab':'HudCache', 'col':'playerId', 'drop':0}
|
||||
, {'tab':'HudCache', 'col':'tourneyTypeId', 'drop':0}
|
||||
, {'tab':'Players', 'col':'siteId', 'drop':1}
|
||||
, {'tab':'Players', 'col':'name', 'drop':0}
|
||||
, {'tab':'Tourneys', 'col':'tourneyTypeId', 'drop':1}
|
||||
, {'tab':'Tourneys', 'col':'siteTourneyNo', 'drop':0}
|
||||
, {'tab':'TourneysPlayers', 'col':'playerId', 'drop':0}
|
||||
, {'tab':'TourneysPlayers', 'col':'tourneyId', 'drop':0}
|
||||
, {'tab':'TourneyTypes', 'col':'siteId', 'drop':0}
|
||||
]
|
||||
]
|
||||
|
||||
foreignKeys = [
|
||||
[ ] # no db with index 0
|
||||
, [ ] # no db with index 1
|
||||
, [ # foreign keys for mysql
|
||||
{'fktab':'Hands', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
|
||||
, {'fktab':'HandsPlayers', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1}
|
||||
, {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1}
|
||||
, {'fktab':'HandsActions', 'fkcol':'handPlayerId', 'rtab':'HandsPlayers', 'rcol':'id', 'drop':1}
|
||||
, {'fktab':'HudCache', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
|
||||
, {'fktab':'HudCache', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':0}
|
||||
, {'fktab':'HudCache', 'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes', 'rcol':'id', 'drop':1}
|
||||
]
|
||||
, [ # foreign keys for postgres
|
||||
{'fktab':'Hands', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
|
||||
, {'fktab':'HandsPlayers', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1}
|
||||
, {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1}
|
||||
, {'fktab':'HandsActions', 'fkcol':'handPlayerId', 'rtab':'HandsPlayers', 'rcol':'id', 'drop':1}
|
||||
, {'fktab':'HudCache', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
|
||||
, {'fktab':'HudCache', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':0}
|
||||
, {'fktab':'HudCache', 'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes', 'rcol':'id', 'drop':1}
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
# MySQL Notes:
|
||||
# "FOREIGN KEY (handId) REFERENCES Hands(id)" - requires index on Hands.id
|
||||
# - creates index handId on <thistable>.handId
|
||||
# alter table t drop foreign key fk
|
||||
# alter table t add foreign key (fkcol) references tab(rcol)
|
||||
# alter table t add constraint c foreign key (fkcol) references tab(rcol)
|
||||
# (fkcol is used for foreigh key name)
|
||||
|
||||
# mysql to list indexes:
|
||||
# SELECT table_name, index_name, non_unique, column_name
|
||||
# FROM INFORMATION_SCHEMA.STATISTICS
|
||||
# WHERE table_name = 'tbl_name'
|
||||
# AND table_schema = 'db_name'
|
||||
# ORDER BY table_name, index_name, seq_in_index
|
||||
#
|
||||
# ALTER TABLE Tourneys ADD INDEX siteTourneyNo(siteTourneyNo)
|
||||
# ALTER TABLE tab DROP INDEX idx
|
||||
|
||||
# mysql to list fks:
|
||||
# SELECT constraint_name, table_name, column_name, referenced_table_name, referenced_column_name
|
||||
# FROM information_schema.KEY_COLUMN_USAGE
|
||||
# WHERE REFERENCED_TABLE_SCHEMA = (your schema name here)
|
||||
# AND REFERENCED_TABLE_NAME is not null
|
||||
# ORDER BY TABLE_NAME, COLUMN_NAME;
|
||||
|
||||
# this may indicate missing object
|
||||
# _mysql_exceptions.OperationalError: (1025, "Error on rename of '.\\fpdb\\hands' to '.\\fpdb\\#sql2-7f0-1b' (errno: 152)")
|
||||
|
||||
|
||||
# PG notes:
|
||||
|
||||
# To add a foreign key constraint to a table:
|
||||
# ALTER TABLE tab ADD CONSTRAINT c FOREIGN KEY (col) REFERENCES t2(col2) MATCH FULL;
|
||||
# ALTER TABLE tab DROP CONSTRAINT zipchk
|
||||
#
|
||||
# Note: index names must be unique across a schema
|
||||
# CREATE INDEX idx ON tab(col)
|
||||
# DROP INDEX idx
|
||||
|
||||
def prepareBulkImport(fdb):
|
||||
"""Drop some indexes/foreign keys to prepare for bulk import.
|
||||
Currently keeping the standalone indexes as needed to import quickly"""
|
||||
# fdb is a fpdb_db object including backend, db, cursor, sql variables
|
||||
if fdb.backend == PGSQL:
|
||||
fdb.db.set_isolation_level(0) # allow table/index operations to work
|
||||
for fk in foreignKeys[fdb.backend]:
|
||||
if fk['drop'] == 1:
|
||||
if fdb.backend == MYSQL_INNODB:
|
||||
fdb.cursor.execute("SELECT constraint_name " +
|
||||
"FROM information_schema.KEY_COLUMN_USAGE " +
|
||||
#"WHERE REFERENCED_TABLE_SCHEMA = 'fpdb'
|
||||
"WHERE 1=1 " +
|
||||
"AND table_name = %s AND column_name = %s " +
|
||||
"AND referenced_table_name = %s " +
|
||||
"AND referenced_column_name = %s ",
|
||||
(fk['fktab'], fk['fkcol'], fk['rtab'], fk['rcol']) )
|
||||
cons = fdb.cursor.fetchone()
|
||||
print "preparebulk: cons=", cons
|
||||
if cons:
|
||||
print "dropping mysql fk", cons[0], fk['fktab'], fk['fkcol']
|
||||
try:
|
||||
fdb.cursor.execute("alter table " + fk['fktab'] + " drop foreign key " + cons[0])
|
||||
except:
|
||||
pass
|
||||
elif fdb.backend == PGSQL:
|
||||
print "dropping pg fk", fk['fktab'], fk['fkcol']
|
||||
try:
|
||||
fdb.cursor.execute("alter table " + fk['fktab'] + " drop constraint "
|
||||
+ fk['fktab'] + '_' + fk['fkcol'] + '_fkey')
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
print "Only MySQL and Postgres supported so far"
|
||||
return -1
|
||||
|
||||
for idx in indexes[fdb.backend]:
|
||||
if idx['drop'] == 1:
|
||||
if fdb.backend == MYSQL_INNODB:
|
||||
print "dropping mysql index ", idx['tab'], idx['col']
|
||||
try:
|
||||
fdb.cursor.execute( "alter table %s drop index %s", (idx['tab'],idx['col']) )
|
||||
except:
|
||||
pass
|
||||
elif fdb.backend == PGSQL:
|
||||
print "dropping pg index ", idx['tab'], idx['col']
|
||||
# mod to use tab_col for index name?
|
||||
try:
|
||||
fdb.cursor.execute( "drop index %s_%s_idx" % (idx['tab'],idx['col']) )
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
print "Only MySQL and Postgres supported so far"
|
||||
return -1
|
||||
|
||||
if fdb.backend == PGSQL:
|
||||
fdb.db.set_isolation_level(1) # go back to normal isolation level
|
||||
fdb.db.commit() # seems to clear up errors if there were any in postgres
|
||||
#end def prepareBulkImport
|
||||
|
||||
def afterBulkImport(fdb):
|
||||
"""Re-create any dropped indexes/foreign keys after bulk import"""
|
||||
# fdb is a fpdb_db object including backend, db, cursor, sql variables
|
||||
if fdb.backend == PGSQL:
|
||||
fdb.db.set_isolation_level(0) # allow table/index operations to work
|
||||
for fk in foreignKeys[fdb.backend]:
|
||||
if fk['drop'] == 1:
|
||||
if fdb.backend == MYSQL_INNODB:
|
||||
fdb.cursor.execute("SELECT constraint_name " +
|
||||
"FROM information_schema.KEY_COLUMN_USAGE " +
|
||||
#"WHERE REFERENCED_TABLE_SCHEMA = 'fpdb'
|
||||
"WHERE 1=1 " +
|
||||
"AND table_name = %s AND column_name = %s " +
|
||||
"AND referenced_table_name = %s " +
|
||||
"AND referenced_column_name = %s ",
|
||||
(fk['fktab'], fk['fkcol'], fk['rtab'], fk['rcol']) )
|
||||
cons = fdb.cursor.fetchone()
|
||||
print "afterbulk: cons=", cons
|
||||
if cons:
|
||||
pass
|
||||
else:
|
||||
print "creating fk ", fk['fktab'], fk['fkcol'], "->", fk['rtab'], fk['rcol']
|
||||
try:
|
||||
fdb.cursor.execute("alter table " + fk['fktab'] + " add foreign key ("
|
||||
+ fk['fkcol'] + ") references " + fk['rtab'] + "("
|
||||
+ fk['rcol'] + ")")
|
||||
except:
|
||||
pass
|
||||
elif fdb.backend == PGSQL:
|
||||
print "creating fk ", fk['fktab'], fk['fkcol'], "->", fk['rtab'], fk['rcol']
|
||||
try:
|
||||
fdb.cursor.execute("alter table " + fk['fktab'] + " add constraint "
|
||||
+ fk['fktab'] + '_' + fk['fkcol'] + '_fkey'
|
||||
+ " foreign key (" + fk['fkcol']
|
||||
+ ") references " + fk['rtab'] + "(" + fk['rcol'] + ")")
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
print "Only MySQL and Postgres supported so far"
|
||||
return -1
|
||||
|
||||
for idx in indexes[fdb.backend]:
|
||||
if idx['drop'] == 1:
|
||||
if fdb.backend == MYSQL_INNODB:
|
||||
print "creating mysql index ", idx['tab'], idx['col']
|
||||
try:
|
||||
fdb.cursor.execute( "alter table %s add index %s(%s)"
|
||||
, (idx['tab'],idx['col'],idx['col']) )
|
||||
except:
|
||||
pass
|
||||
elif fdb.backend == PGSQL:
|
||||
# mod to use tab_col for index name?
|
||||
print "creating pg index ", idx['tab'], idx['col']
|
||||
try:
|
||||
print "create index %s_%s_idx on %s(%s)" % (idx['tab'], idx['col'], idx['tab'], idx['col'])
|
||||
fdb.cursor.execute( "create index %s_%s_idx on %s(%s)"
|
||||
% (idx['tab'], idx['col'], idx['tab'], idx['col']) )
|
||||
except:
|
||||
print " ERROR! :-("
|
||||
pass
|
||||
else:
|
||||
print "Only MySQL and Postgres supported so far"
|
||||
return -1
|
||||
|
||||
if fdb.backend == PGSQL:
|
||||
fdb.db.set_isolation_level(1) # go back to normal isolation level
|
||||
fdb.db.commit() # seems to clear up errors if there were any in postgres
|
||||
#end def afterBulkImport
|
||||
|
||||
def createAllIndexes(fdb):
|
||||
"""Create new indexes"""
|
||||
if fdb.backend == PGSQL:
|
||||
fdb.db.set_isolation_level(0) # allow table/index operations to work
|
||||
for idx in indexes[fdb.backend]:
|
||||
if fdb.backend == MYSQL_INNODB:
|
||||
print "creating mysql index ", idx['tab'], idx['col']
|
||||
try:
|
||||
fdb.cursor.execute( "alter table %s add index %s(%s)"
|
||||
, (idx['tab'],idx['col'],idx['col']) )
|
||||
except:
|
||||
pass
|
||||
elif fdb.backend == PGSQL:
|
||||
# mod to use tab_col for index name?
|
||||
print "creating pg index ", idx['tab'], idx['col']
|
||||
try:
|
||||
print "create index %s_%s_idx on %s(%s)" % (idx['tab'], idx['col'], idx['tab'], idx['col'])
|
||||
fdb.cursor.execute( "create index %s_%s_idx on %s(%s)"
|
||||
% (idx['tab'], idx['col'], idx['tab'], idx['col']) )
|
||||
except:
|
||||
print " ERROR! :-("
|
||||
pass
|
||||
else:
|
||||
print "Only MySQL and Postgres supported so far"
|
||||
return -1
|
||||
if fdb.backend == PGSQL:
|
||||
fdb.db.set_isolation_level(1) # go back to normal isolation level
|
||||
#end def createAllIndexes
|
||||
|
||||
def dropAllIndexes(fdb):
|
||||
"""Drop all standalone indexes (i.e. not including primary keys or foreign keys)
|
||||
using list of indexes in indexes data structure"""
|
||||
# maybe upgrade to use data dictionary?? (but take care to exclude PK and FK)
|
||||
if fdb.backend == PGSQL:
|
||||
fdb.db.set_isolation_level(0) # allow table/index operations to work
|
||||
for idx in indexes[fdb.backend]:
|
||||
if fdb.backend == MYSQL_INNODB:
|
||||
print "dropping mysql index ", idx['tab'], idx['col']
|
||||
try:
|
||||
fdb.cursor.execute( "alter table %s drop index %s"
|
||||
, (idx['tab'],idx['col']) )
|
||||
except:
|
||||
pass
|
||||
elif fdb.backend == PGSQL:
|
||||
print "dropping pg index ", idx['tab'], idx['col']
|
||||
# mod to use tab_col for index name?
|
||||
try:
|
||||
fdb.cursor.execute( "drop index %s_%s_idx"
|
||||
% (idx['tab'],idx['col']) )
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
print "Only MySQL and Postgres supported so far"
|
||||
return -1
|
||||
if fdb.backend == PGSQL:
|
||||
fdb.db.set_isolation_level(1) # go back to normal isolation level
|
||||
#end def dropAllIndexes
|
||||
|
||||
def analyzeDB(fdb):
|
||||
"""Do whatever the DB can offer to update index/table statistics"""
|
||||
if fdb.backend == PGSQL:
|
||||
fdb.db.set_isolation_level(0) # allow vacuum to work
|
||||
try:
|
||||
fdb.cursor.execute("vacuum analyze")
|
||||
except:
|
||||
print "Error during vacuum"
|
||||
fdb.db.set_isolation_level(1) # go back to normal isolation level
|
||||
#end def analyzeDB
|
||||
|
||||
class DuplicateError(Exception):
|
||||
def __init__(self, value):
|
||||
|
@ -341,7 +642,7 @@ class FpdbError(Exception):
|
|||
self.value = value
|
||||
def __str__(self):
|
||||
return repr(self.value)
|
||||
|
||||
|
||||
# gets value for last auto-increment key generated
|
||||
# returns -1 if a problem occurs
|
||||
def getLastInsertId(backend, conn, cursor):
|
||||
|
@ -382,18 +683,19 @@ def calcPayin(count, buyin, fee):
|
|||
#end def calcPayin
|
||||
|
||||
def checkPositions(positions):
|
||||
"""verifies that these positions are valid"""
|
||||
for i in range (len(positions)):
|
||||
pos=positions[i]
|
||||
try:#todo: use type recognition instead of error
|
||||
if (len(pos)!=1):
|
||||
raise FpdbError("invalid position found in checkPositions. i: "+str(i)+" position: "+pos) #dont need to str() here
|
||||
except TypeError:#->not string->is int->fine
|
||||
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 != 8 and pos!=9):
|
||||
raise FpdbError("invalid position found in checkPositions. i: "+str(i)+" position: "+str(pos))
|
||||
"""verifies that these positions are valid"""
|
||||
for i in range (len(positions)):
|
||||
pos=positions[i]
|
||||
try:#todo: use type recognition instead of error
|
||||
if (len(pos)!=1):
|
||||
raise FpdbError("invalid position found in checkPositions. i: "+str(i)+" position: "+pos) #dont need to str() here
|
||||
except TypeError:#->not string->is int->fine
|
||||
pass
|
||||
|
||||
### RHH modified to allow for "position 9" here (pos==9 is when you're a dead hand before the BB
|
||||
### 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
|
||||
|
||||
#classifies each line for further processing in later code. Manipulates the passed arrays.
|
||||
|
@ -1207,67 +1509,83 @@ def parseNames(lines):
|
|||
|
||||
#returns an array with the positions of the respective players
|
||||
def parsePositions (hand, names):
|
||||
#prep array
|
||||
positions=[]
|
||||
for i in range(len(names)):
|
||||
positions.append(-1)
|
||||
|
||||
#find blinds
|
||||
sb,bb=-1,-1
|
||||
for i in range (len(hand)):
|
||||
if (sb==-1 and hand[i].find("small blind")!=-1 and hand[i].find("dead small blind")==-1):
|
||||
sb=hand[i]
|
||||
#print "sb:",sb
|
||||
if (bb==-1 and hand[i].find("big blind")!=-1 and hand[i].find("dead big blind")==-1):
|
||||
bb=hand[i]
|
||||
#print "bb:",bb
|
||||
|
||||
#identify blinds
|
||||
#print "parsePositions before recognising sb/bb. names:",names
|
||||
sbExists=True
|
||||
if (sb!=-1):
|
||||
sb=recognisePlayerNo(sb, names, "bet")
|
||||
else:
|
||||
sbExists=False
|
||||
if (bb!=-1):
|
||||
bb=recognisePlayerNo(bb, names, "bet")
|
||||
|
||||
#write blinds into array
|
||||
if (sbExists):
|
||||
positions[sb]="S"
|
||||
positions[bb]="B"
|
||||
|
||||
#fill up rest of array
|
||||
if (sbExists):
|
||||
arraypos=sb-1
|
||||
else:
|
||||
arraypos=bb-1
|
||||
distFromBtn=0
|
||||
while (arraypos>=0 and arraypos != bb):
|
||||
#print "parsePositions first while, arraypos:",arraypos,"positions:",positions
|
||||
positions[arraypos]=distFromBtn
|
||||
arraypos-=1
|
||||
distFromBtn+=1
|
||||
|
||||
### RHH - Changed to set the null seats before BB to "9"
|
||||
i=bb-1
|
||||
while positions[i] < 0:
|
||||
positions[i]=9
|
||||
i-=1
|
||||
|
||||
arraypos=len(names)-1
|
||||
if (bb!=0 or (bb==0 and sbExists==False)):
|
||||
while (arraypos>bb):
|
||||
positions[arraypos]=distFromBtn
|
||||
arraypos-=1
|
||||
distFromBtn+=1
|
||||
|
||||
for i in range (len(names)):
|
||||
if positions[i]==-1:
|
||||
print "parsePositions names:",names
|
||||
print "result:",positions
|
||||
raise FpdbError ("failed to read positions")
|
||||
return positions
|
||||
#prep array
|
||||
positions=[]
|
||||
for i in range(len(names)):
|
||||
positions.append(-1)
|
||||
|
||||
#find blinds
|
||||
sb,bb=-1,-1
|
||||
for i in range (len(hand)):
|
||||
if (sb==-1 and hand[i].find("small blind")!=-1 and hand[i].find("dead small blind")==-1):
|
||||
sb=hand[i]
|
||||
#print "sb:",sb
|
||||
if (bb==-1 and hand[i].find("big blind")!=-1 and hand[i].find("dead big blind")==-1):
|
||||
bb=hand[i]
|
||||
#print "bb:",bb
|
||||
|
||||
#identify blinds
|
||||
#print "parsePositions before recognising sb/bb. names:",names
|
||||
sbExists=True
|
||||
if (sb!=-1):
|
||||
sb=recognisePlayerNo(sb, names, "bet")
|
||||
else:
|
||||
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):
|
||||
positions[sb]="S"
|
||||
positions[bb]="B"
|
||||
|
||||
|
||||
#fill up rest of array
|
||||
if (sbExists):
|
||||
arraypos=sb-1
|
||||
else:
|
||||
arraypos=bb-1
|
||||
distFromBtn=0
|
||||
while (arraypos>=0 and arraypos != bb):
|
||||
#print "parsePositions first while, arraypos:",arraypos,"positions:",positions
|
||||
positions[arraypos]=distFromBtn
|
||||
arraypos-=1
|
||||
distFromBtn+=1
|
||||
|
||||
# eric - this takes into account dead seats between blinds
|
||||
if sbExists:
|
||||
i = bb - 1
|
||||
while positions[i] < 0 and i != sb:
|
||||
positions[i] = 9
|
||||
i -= 1
|
||||
### RHH - Changed to set the null seats before BB to "9"
|
||||
if sbExists:
|
||||
i = sb-1
|
||||
else:
|
||||
i = bb-1
|
||||
while positions[i] < 0:
|
||||
positions[i]=9
|
||||
i-=1
|
||||
|
||||
arraypos=len(names)-1
|
||||
if (bb!=0 or (bb==0 and sbExists==False) or (bb == 1 and sb != arraypos) ):
|
||||
while (arraypos>bb and arraypos > sb):
|
||||
positions[arraypos]=distFromBtn
|
||||
arraypos-=1
|
||||
distFromBtn+=1
|
||||
|
||||
for i in range (len(names)):
|
||||
if positions[i]==-1:
|
||||
print "parsePositions names:",names
|
||||
print "result:",positions
|
||||
raise FpdbError ("failed to read positions")
|
||||
# print str(positions), "\n"
|
||||
return positions
|
||||
#end def parsePositions
|
||||
|
||||
#simply parses the rake amount and returns it as an int
|
||||
|
@ -2048,7 +2366,7 @@ sure to also change the following storage method and table_viewer.prepare_data i
|
|||
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:
|
||||
|
|
Loading…
Reference in New Issue
Block a user