Merge branch 'master' into siteneutral

Conflicts:

	pyfpdb/fpdb_import.py
	pyfpdb/fpdb_parse_logic.py
	pyfpdb/fpdb_simple.py
This commit is contained in:
Worros 2009-03-20 00:27:08 +09:00
commit 444e780f29
14 changed files with 662 additions and 675 deletions

106
pyfpdb/Configuration.py Normal file → Executable file
View File

@ -32,6 +32,13 @@ import shutil
import xml.dom.minidom import xml.dom.minidom
from xml.dom.minidom import Node from xml.dom.minidom import Node
def fix_tf(x):
if x == "1" or x == 1 or string.lower(x) == "true" or string.lower(x) == "t":
return True
if x == "0" or x == 0 or string.lower(x) == "false" or string.lower(x) == "f":
return False
return False
class Layout: class Layout:
def __init__(self, node): def __init__(self, node):
@ -205,9 +212,18 @@ class Import:
self.interval = node.getAttribute("interval") self.interval = node.getAttribute("interval")
self.callFpdbHud = node.getAttribute("callFpdbHud") self.callFpdbHud = node.getAttribute("callFpdbHud")
self.hhArchiveBase = node.getAttribute("hhArchiveBase") self.hhArchiveBase = node.getAttribute("hhArchiveBase")
if node.hasAttribute("saveActions"):
self.saveActions = fix_tf(node.getAttribute("saveActions"))
else:
self.saveActions = True
if node.hasAttribute("fastStoreHudCache"):
self.fastStoreHudCache = fix_tf(node.getAttribute("fastStoreHudCache"))
else:
self.fastStoreHudCache = False
def __str__(self): def __str__(self):
return " interval = %s\n callFpdbHud = %s\n hhArchiveBase = %s" % (self.interval, self.callFpdbHud, self.hhArchiveBase) return " interval = %s\n callFpdbHud = %s\n hhArchiveBase = %s\n saveActions = %s\n fastStoreHudCache = %s\n" \
% (self.interval, self.callFpdbHud, self.hhArchiveBase, self.saveActions, self.saveActions)
class Tv: class Tv:
def __init__(self, node): def __init__(self, node):
@ -391,6 +407,11 @@ class Config:
return layout_node return layout_node
def get_location_node(self, layout_node, seat): def get_location_node(self, layout_node, seat):
if seat == "common":
for location_node in layout_node.getElementsByTagName("location"):
if location_node.hasAttribute("common"):
return location_node
else:
for location_node in layout_node.getElementsByTagName("location"): for location_node in layout_node.getElementsByTagName("location"):
if int( location_node.getAttribute("seat") ) == int( seat ): if int( location_node.getAttribute("seat") ) == int( seat ):
return location_node return location_node
@ -420,29 +441,42 @@ class Config:
def edit_aux_layout(self, aux_name, max, width = None, height = None, locations = None): def edit_aux_layout(self, aux_name, max, width = None, height = None, locations = None):
aux_node = self.get_aux_node(aux_name) aux_node = self.get_aux_node(aux_name)
layout_node = self.get_layout_node(aux_node, max) layout_node = self.get_layout_node(aux_node, max)
if layout_node == None: return if layout_node == None:
for i in range(1, max + 1): print "aux node not found"
return
print "editing locations =", locations
for (i, pos) in locations.iteritems():
location_node = self.get_location_node(layout_node, i) location_node = self.get_location_node(layout_node, i)
location_node.setAttribute("x", str( locations[i-1][0] )) location_node.setAttribute("x", str( locations[i][0] ))
location_node.setAttribute("y", str( locations[i-1][1] )) location_node.setAttribute("y", str( locations[i][1] ))
self.aux_windows[aux_name].layout[max].location[i] = ( locations[i-1][0], locations[i-1][1] ) if i == "common":
self.aux_windows[aux_name].layout[max].common = ( locations[i][0], locations[i][1] )
else:
self.aux_windows[aux_name].layout[max].location[i] = ( locations[i][0], locations[i][1] )
def get_db_parameters(self, name = None): def get_db_parameters(self, name = None):
if name == None: name = 'fpdb' if name == None: name = 'fpdb'
db = {} db = {}
try: try: db['db-databaseName'] = name
db['db-databaseName'] = name except: pass
db['db-host'] = self.supported_databases[name].db_ip
db['db-user'] = self.supported_databases[name].db_user try: db['db-host'] = self.supported_databases[name].db_ip
db['db-password'] = self.supported_databases[name].db_pass except: pass
db['db-server'] = self.supported_databases[name].db_server
try: db['db-user'] = self.supported_databases[name].db_user
except: pass
try: db['db-password'] = self.supported_databases[name].db_pass
except: pass
try: db['db-server'] = self.supported_databases[name].db_server
except: pass
if string.lower(self.supported_databases[name].db_server) == 'mysql': if string.lower(self.supported_databases[name].db_server) == 'mysql':
db['db-backend'] = 2 db['db-backend'] = 2
elif string.lower(self.supported_databases[name].db_server) == 'postgresql': elif string.lower(self.supported_databases[name].db_server) == 'postgresql':
db['db-backend'] = 3 db['db-backend'] = 3
else: db['db-backend'] = None # this is big trouble else: db['db-backend'] = None # this is big trouble
except:
pass
return db return db
def set_db_parameters(self, db_name = 'fpdb', db_ip = None, db_user = None, def set_db_parameters(self, db_name = 'fpdb', db_ip = None, db_user = None,
@ -464,26 +498,32 @@ class Config:
def get_tv_parameters(self): def get_tv_parameters(self):
tv = {} tv = {}
try: try: tv['combinedStealFold'] = self.tv.combinedStealFold
tv['combinedStealFold'] = self.tv.combinedStealFold except: tv['combinedStealFold'] = True
tv['combined2B3B'] = self.tv.combined2B3B
tv['combinedPostflop'] = self.tv.combinedPostflop try: tv['combined2B3B'] = self.tv.combined2B3B
except: # Default tv parameters except: tv['combined2B3B'] = True
tv['combinedStealFold'] = True
tv['combined2B3B'] = True try: tv['combinedPostflop'] = self.tv.combinedPostflop
tv['combinedPostflop'] = True except: tv['combinedPostflop'] = True
return tv return tv
def get_import_parameters(self): def get_import_parameters(self):
imp = {} imp = {}
try: try: imp['callFpdbHud'] = self.imp.callFpdbHud
imp['callFpdbHud'] = self.imp.callFpdbHud except: imp['callFpdbHud'] = True
imp['interval'] = self.imp.interval
imp['hhArchiveBase'] = self.imp.hhArchiveBase try: imp['interval'] = self.imp.interval
except: # Default params except: imp['interval'] = 10
imp['callFpdbHud'] = True
imp['interval'] = 10 try: imp['hhArchiveBase'] = self.imp.hhArchiveBase
imp['hhArchiveBase'] = "~/.fpdb/HandHistories/" except: imp['hhArchiveBase'] = "~/.fpdb/HandHistories/"
try: imp['saveActions'] = self.imp.saveActions
except: imp['saveActions'] = True
try: imp['fastStoreHudCache'] = self.imp.fastStoreHudCache
except: imp['fastStoreHudCache'] = True
return imp return imp
def get_default_paths(self, site = "PokerStars"): def get_default_paths(self, site = "PokerStars"):
@ -689,9 +729,9 @@ if __name__== "__main__":
print c.get_aux_parameters(mw) print c.get_aux_parameters(mw)
print "mucked locations =", c.get_aux_locations('mucked', 9) print "mucked locations =", c.get_aux_locations('mucked', 9)
c.edit_aux_layout('mucked', 9, locations = [(487, 113), (555, 469), (572, 276), (522, 345), # c.edit_aux_layout('mucked', 9, locations = [(487, 113), (555, 469), (572, 276), (522, 345),
(333, 354), (217, 341), (150, 273), (150, 169), (230, 115)]) # (333, 354), (217, 341), (150, 273), (150, 169), (230, 115)])
print "mucked locations =", c.get_aux_locations('mucked', 9) # print "mucked locations =", c.get_aux_locations('mucked', 9)
for site in c.supported_sites.keys(): for site in c.supported_sites.keys():
print "site = ", site, print "site = ", site,

View File

@ -213,7 +213,7 @@ if __name__ == '__main__':
parser = OptionParser() parser = OptionParser()
parser.add_option("-f", "--file", dest="filename", help="Input file in quiet mode", metavar="FILE") parser.add_option("-f", "--file", dest="filename", help="Input file in quiet mode", metavar="FILE")
parser.add_option("-q", "--quiet", action="store_false", dest="gui", default=True, help="don't start gui") parser.add_option("-q", "--quiet", action="store_false", dest="gui", default=True, help="don't start gui")
parser.add_option("-x", "--convert", dest="filtername", help="Conversion filter", default="passthrough")
(options, sys.argv) = parser.parse_args() (options, sys.argv) = parser.parse_args()
config = Configuration.Config() config = Configuration.Config()
@ -240,7 +240,7 @@ if __name__ == '__main__':
importer = fpdb_import.Importer(False,settings, config) importer = fpdb_import.Importer(False,settings, config)
importer.setDropIndexes("auto") importer.setDropIndexes("auto")
importer.setFailOnError(True) importer.setFailOnError(True)
importer.addImportFile(options.filename) importer.addImportFile(options.filename, filter=options.filtername)
importer.setCallHud(False) importer.setCallHud(False)
importer.runImport() importer.runImport()
importer.clearFileList() importer.clearFileList()

View File

@ -123,7 +123,7 @@ class HUD_main(object):
gtk.gdk.threads_enter() gtk.gdk.threads_enter()
try: try:
self.hud_dict[table_name].update(new_hand_id, config) self.hud_dict[table_name].update(new_hand_id, config)
map(lambda aw: aw.update_gui(new_hand_id), self.hud_dict[table_name].aux_windows) [aw.update_gui(new_hand_id) for aw in self.hud_dict[table_name].aux_windows]
return False return False
finally: finally:
gtk.gdk.threads_leave() gtk.gdk.threads_leave()
@ -172,8 +172,7 @@ class HUD_main(object):
if temp_key in self.hud_dict: if temp_key in self.hud_dict:
self.hud_dict[temp_key].stat_dict = stat_dict self.hud_dict[temp_key].stat_dict = stat_dict
self.hud_dict[temp_key].cards = cards self.hud_dict[temp_key].cards = cards
for aw in self.hud_dict[temp_key].aux_windows: [aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[temp_key].aux_windows]
aw.update_data(new_hand_id, self.db_connection)
self.update_HUD(new_hand_id, temp_key, self.config) self.update_HUD(new_hand_id, temp_key, self.config)
# Or create a new HUD # Or create a new HUD

View File

@ -504,6 +504,14 @@ Card ranks will be uppercased
if self.shown: if self.shown:
print >>fh, _("*** SHOW DOWN ***") print >>fh, _("*** SHOW DOWN ***")
for name in self.shown: for name in self.shown:
# TODO: legacy importer can't handle only one holecard here, make sure there are 2 for holdem, 4 for omaha
# TOOD: If HoldHand subclass supports more than omahahi, omahahilo, holdem, add them here
numOfHoleCardsNeeded = None
if self.gametype['category'] in ('omahahi','omahahilo'):
numOfHoleCardsNeeded = 4
elif self.gametype['category'] in ('holdem'):
numOfHoleCardsNeeded = 2
if len(self.holecards[name]['PREFLOP']) == numOfHoleCardsNeeded:
print >>fh, _("%s shows [%s] (a hand...)" % (name, " ".join(self.holecards[name]['PREFLOP']))) print >>fh, _("%s shows [%s] (a hand...)" % (name, " ".join(self.holecards[name]['PREFLOP'])))
# Current PS format has the lines: # Current PS format has the lines:

View File

@ -196,12 +196,12 @@ class Hud:
s.window.destroy() s.window.destroy()
self.stat_windows = {} self.stat_windows = {}
# also kill any aux windows # also kill any aux windows
map(lambda m: m.destroy(), self.aux_windows) [aux.destroy() for aux in self.aux_windows]
self.aux_windows = [] self.aux_windows = []
def reposition_windows(self, *args): def reposition_windows(self, *args):
if self.stat_windows and len(self.stat_windows > 0): if self.stat_windows != {} and len(self.stat_windows) > 0:
map(lambda x: x.window.move(x.x, x.y), self.stat_windows) map(lambda x: x.window.move(x.x, x.y), self.stat_windows.itervalues())
return True return True
def debug_stat_windows(self, *args): def debug_stat_windows(self, *args):
@ -216,6 +216,10 @@ class Hud:
new_loc = (loc[0] - self.table.x, loc[1] - self.table.y) new_loc = (loc[0] - self.table.x, loc[1] - self.table.y)
new_layout[self.stat_windows[sw].adj - 1] = new_loc new_layout[self.stat_windows[sw].adj - 1] = new_loc
self.config.edit_layout(self.table.site, self.max, locations = new_layout) self.config.edit_layout(self.table.site, self.max, locations = new_layout)
# ask each aux to save its layout back to the config object
[aux.save_layout() for aux in self.aux_windows]
# save the config object back to the file
print "saving new xml file"
self.config.save() self.config.save()
def adj_seats(self, hand, config): def adj_seats(self, hand, config):
@ -346,6 +350,8 @@ class Hud:
style = win32gui.GetWindowLong(self.table.number, win32con.GWL_EXSTYLE) style = win32gui.GetWindowLong(self.table.number, win32con.GWL_EXSTYLE)
style |= win32con.WS_CLIPCHILDREN style |= win32con.WS_CLIPCHILDREN
win32gui.SetWindowLong(self.table.number, win32con.GWL_EXSTYLE, style) win32gui.SetWindowLong(self.table.number, win32con.GWL_EXSTYLE, style)
break
window.set_title(real_name) window.set_title(real_name)
class Stat_Window: class Stat_Window:
@ -570,6 +576,7 @@ class Popup_window:
style = win32gui.GetWindowLong(self.table.number, win32con.GWL_EXSTYLE) style = win32gui.GetWindowLong(self.table.number, win32con.GWL_EXSTYLE)
style |= win32con.WS_CLIPCHILDREN style |= win32con.WS_CLIPCHILDREN
win32gui.SetWindowLong(self.table.number, win32con.GWL_EXSTYLE, style) win32gui.SetWindowLong(self.table.number, win32con.GWL_EXSTYLE, style)
break
window.set_title(real_name) window.set_title(real_name)

View File

@ -49,6 +49,9 @@ class Aux_Window:
def create(self, *parms): def create(self, *parms):
pass pass
def save_layout(self, *args):
pass
def destroy(self): def destroy(self):
self.container.destroy() self.container.destroy()
@ -312,12 +315,13 @@ class Flop_Mucked(Aux_Window):
def __init__(self, hud, config, params): def __init__(self, hud, config, params):
self.hud = hud # hud object that this aux window supports self.hud = hud # hud object that this aux window supports
self.config = config # configuration object for this aux window to use self.config = config # configuration object for this aux window to use
self.params = params # hash aux params from config self.params = params # dict aux params from config
self.positions = {} # dict of window positions
self.displayed_cards = False
self.card_images = self.get_card_images() self.card_images = self.get_card_images()
def create(self): def create(self):
self.adj = self.hud.adj_seats(0, self.config)
adj = self.hud.adj_seats(0, self.config)
loc = self.config.get_aux_locations(self.params['name'], int(self.hud.max)) loc = self.config.get_aux_locations(self.params['name'], int(self.hud.max))
self.m_windows = {} # windows to put the card images in self.m_windows = {} # windows to put the card images in
@ -328,7 +332,7 @@ class Flop_Mucked(Aux_Window):
if i == 'common': if i == 'common':
(x, y) = self.params['layout'][self.hud.max].common (x, y) = self.params['layout'][self.hud.max].common
else: else:
(x, y) = loc[adj[i]] (x, y) = loc[self.adj[i]]
self.m_windows[i] = gtk.Window() self.m_windows[i] = gtk.Window()
self.m_windows[i].set_decorated(False) self.m_windows[i].set_decorated(False)
self.m_windows[i].set_property("skip-taskbar-hint", True) self.m_windows[i].set_property("skip-taskbar-hint", True)
@ -340,6 +344,7 @@ class Flop_Mucked(Aux_Window):
self.seen_cards[i] = gtk.image_new_from_pixbuf(self.card_images[('B', 'H')]) self.seen_cards[i] = gtk.image_new_from_pixbuf(self.card_images[('B', 'H')])
self.eb[i].add(self.seen_cards[i]) self.eb[i].add(self.seen_cards[i])
self.m_windows[i].move(int(x) + self.hud.table.x, int(y) + self.hud.table.y) self.m_windows[i].move(int(x) + self.hud.table.x, int(y) + self.hud.table.y)
self.positions[i] = (int(x) + self.hud.table.x, int(y) + self.hud.table.y)
self.m_windows[i].set_opacity(float(self.params['opacity'])) self.m_windows[i].set_opacity(float(self.params['opacity']))
self.m_windows[i].show_all() self.m_windows[i].show_all()
self.m_windows[i].hide() self.m_windows[i].hide()
@ -350,11 +355,9 @@ class Flop_Mucked(Aux_Window):
def update_gui(self, new_hand_id): def update_gui(self, new_hand_id):
"""Prepare and show the mucked cards.""" """Prepare and show the mucked cards."""
pos = {} if self.displayed_cards:
for i, w in self.m_windows.iteritems():
pos[i] = w.get_position() # I hate this. I don't know why I have to save position and then move back
self.hide_mucked_cards() self.hide_mucked_cards()
displayed_cards = False self.displayed_cards = False
for (i, cards) in self.hud.cards.iteritems(): for (i, cards) in self.hud.cards.iteritems():
if self.has_cards(cards): if self.has_cards(cards):
# scratch is a working pixbuf, used to assemble the image # scratch is a working pixbuf, used to assemble the image
@ -370,11 +373,12 @@ class Flop_Mucked(Aux_Window):
x = x + int(self.params['card_wd']) x = x + int(self.params['card_wd'])
self.seen_cards[i].set_from_pixbuf(scratch) self.seen_cards[i].set_from_pixbuf(scratch)
# self.m_windows[i].show_all() # self.m_windows[i].show_all()
self.m_windows[i].move(pos[i][0], pos[i][1]) # here is where I move back self.m_windows[i].resize(1,1)
self.m_windows[i].present() self.m_windows[i].present()
displayed_cards = True self.m_windows[i].move(self.positions[i][0], self.positions[i][1]) # here is where I move back
self.displayed_cards = True
if displayed_cards and float(self.params['timeout']) > 0: if self.displayed_cards and float(self.params['timeout']) > 0:
gobject.timeout_add(int(1000*float(self.params['timeout'])), self.hide_mucked_cards) gobject.timeout_add(int(1000*float(self.params['timeout'])), self.hide_mucked_cards)
def destroy(self): def destroy(self):
@ -385,8 +389,10 @@ class Flop_Mucked(Aux_Window):
def hide_mucked_cards(self): def hide_mucked_cards(self):
"""Hide the mucked card windows.""" """Hide the mucked card windows."""
# this is the callback from the timeout # this is the callback from the timeout
for w in self.m_windows.values(): for (i, w) in self.m_windows.iteritems():
self.positions[i] = w.get_position()
w.hide() w.hide()
self.displayed_cards = False
return False # this tells the system to NOT run this timeout again return False # this tells the system to NOT run this timeout again
def button_press_cb(self, widget, event, *args): def button_press_cb(self, widget, event, *args):
@ -403,17 +409,16 @@ class Flop_Mucked(Aux_Window):
def save_layout(self, *args): def save_layout(self, *args):
"""Save new layout back to the aux element in the config file.""" """Save new layout back to the aux element in the config file."""
# similar to same method in stat_windows new_locs = {}
new_layout = [(0, 0)] * self.hud.max print "adj =", self.adj
for (i, w) in self.m_windows.iteritems(): for (i, pos) in self.positions.iteritems():
(x, y) = w.get_position() if i != 'common':
new_loc = (x - self.hud.table.x, y - self.hud.table.y) new_locs[self.adj[int(i)]] = (pos[0] - self.hud.table.x, pos[1] - self.hud.table.y)
if i != "common":
new_layout[self.hud.stat_windows[int(i)].adj - 1] = new_loc
else: else:
pass new_locs[i] = (pos[0] - self.hud.table.x, pos[1] - self.hud.table.y)
self.config.edit_layout(self.table.site, self.max, locations = new_layout) print "old locations =", self.params['layout'][self.hud.max]
self.config.save() print "saving locations =", new_locs
self.config.edit_aux_layout(self.params['name'], self.hud.max, locations = new_locs)
if __name__== "__main__": if __name__== "__main__":

View File

@ -26,7 +26,7 @@ from HandHistoryConverter import *
class PokerStars(HandHistoryConverter): class PokerStars(HandHistoryConverter):
# Static regexes # Static regexes
re_GameInfo = re.compile("PokerStars Game #(?P<HID>[0-9]+):\s+(HORSE)? \(?(?P<GAME>Hold\'em|Razz|7 Card Stud|Omaha Hi/Lo|Badugi) (?P<LIMIT>No Limit|Limit|Pot Limit),? \(?(?P<CURRENCY>\$|)?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+)\) - (?P<DATETIME>.*$)", re.MULTILINE) re_GameInfo = re.compile("PokerStars Game #(?P<HID>[0-9]+):\s+(HORSE)? \(?(?P<GAME>Hold\'em|Razz|7 Card Stud|Omaha|Omaha Hi/Lo|Badugi) (?P<LIMIT>No Limit|Limit|Pot Limit),? \(?(?P<CURRENCY>\$|)?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+)\) - (?P<DATETIME>.*$)", re.MULTILINE)
re_SplitHands = re.compile('\n\n+') re_SplitHands = re.compile('\n\n+')
re_HandInfo = re.compile("^Table \'(?P<TABLE>[- a-zA-Z]+)\'(?P<TABLEATTRIBUTES>.+?$)?", re.MULTILINE) re_HandInfo = re.compile("^Table \'(?P<TABLE>[- a-zA-Z]+)\'(?P<TABLEATTRIBUTES>.+?$)?", re.MULTILINE)
re_Button = re.compile('Seat #(?P<BUTTON>\d+) is the button', re.MULTILINE) re_Button = re.compile('Seat #(?P<BUTTON>\d+) is the button', re.MULTILINE)
@ -89,7 +89,7 @@ follow : whether to tail -f the input"""
limits = { 'No Limit':'nl', 'Pot Limit':'pl', 'Limit':'fl' } limits = { 'No Limit':'nl', 'Pot Limit':'pl', 'Limit':'fl' }
games = { # base, category games = { # base, category
"Hold'em" : ('hold','holdem'), "Hold'em" : ('hold','holdem'),
'Omaha Hi' : ('hold','omahahi'), 'Omaha' : ('hold','omahahi'),
'Omaha Hi/Lo' : ('hold','omahahilo'), 'Omaha Hi/Lo' : ('hold','omahahilo'),
'Razz' : ('stud','razz'), 'Razz' : ('stud','razz'),
'7 Card Stud' : ('stud','studhi'), '7 Card Stud' : ('stud','studhi'),

View File

@ -81,23 +81,13 @@ class fpdb:
def display_tab(self, new_tab_name): def display_tab(self, new_tab_name):
"""displays the indicated tab""" """displays the indicated tab"""
#print "start of display_tab, len(self.tab_names):",len(self.tab_names) #print "start of display_tab, len(self.tab_names):",len(self.tab_names)
tab_no=-1 tab_no = -1
#if len(self.tab_names)>1: for i, name in enumerate(self.tab_names):
for i in range(len(self.tab_names)): if name == new_tab_name:
#print "display_tab, new_tab_name:",new_tab_name," self.tab_names[i]:", self.tab_names[i] tab_no = i
if (new_tab_name==self.tab_names[i]): break
tab_no=i
#self.tab_buttons[i].set_active(False)
#else:
# tab_no=0
#current_tab_no=-1 if tab_no == -1:
for i in range(len(self.tab_names)):
if self.current_tab==self.tabs[i]:
#self.tab_buttons[i].set_active(False)
pass
if tab_no==-1:
raise fpdb_simple.FpdbError("invalid tab_no") raise fpdb_simple.FpdbError("invalid tab_no")
else: else:
self.main_vbox.remove(self.current_tab) self.main_vbox.remove(self.current_tab)
@ -199,12 +189,13 @@ class fpdb:
def dia_recreate_tables(self, widget, data): def dia_recreate_tables(self, widget, data):
"""Dialogue that asks user to confirm that he wants to delete and recreate the tables""" """Dialogue that asks user to confirm that he wants to delete and recreate the tables"""
self.obtain_global_lock() self.obtain_global_lock()
dia_confirm=gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING,
dia_confirm = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING,
buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm deleting and recreating tables") buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm deleting and recreating tables")
diastring=("Please confirm that you want to (re-)create the tables. If there already are tables in the database "+self.db.database+" on "+self.db.host+" they will be deleted.") diastring = "Please confirm that you want to (re-)create the tables. If there already are tables in the database "+self.db.database+" on "+self.db.host+" they will be deleted."
dia_confirm.format_secondary_text(diastring)#todo: make above string with bold for db, host and deleted dia_confirm.format_secondary_text(diastring)#todo: make above string with bold for db, host and deleted
response=dia_confirm.run() response = dia_confirm.run()
dia_confirm.destroy() dia_confirm.destroy()
if response == gtk.RESPONSE_YES: if response == gtk.RESPONSE_YES:
self.db.recreate_tables() self.db.recreate_tables()

View File

@ -23,12 +23,12 @@ import FpdbSQLQueries
class fpdb_db: class fpdb_db:
def __init__(self): def __init__(self):
"""Simple constructor, doesnt really do anything""" """Simple constructor, doesnt really do anything"""
self.db=None self.db = None
self.cursor=None self.cursor = None
self.sql = {} self.sql = {}
self.MYSQL_INNODB=2 self.MYSQL_INNODB = 2
self.PGSQL=3 self.PGSQL = 3
self.SQLITE=4 self.SQLITE = 4
#end def __init__ #end def __init__
def do_connect(self, config=None): def do_connect(self, config=None):
@ -37,10 +37,7 @@ class fpdb_db:
raise FpdbError('Configuration not defined') raise FpdbError('Configuration not defined')
self.settings = {} self.settings = {}
if (os.sep=="/"): self.settings['os'] = "linuxmac" if os.name != "nt" else "windows"
self.settings['os']="linuxmac"
else:
self.settings['os']="windows"
self.settings.update(config.get_db_parameters()) self.settings.update(config.get_db_parameters())
self.connect(self.settings['db-backend'], self.connect(self.settings['db-backend'],

View File

@ -51,8 +51,8 @@ class Importer:
def __init__(self, caller, settings, config): def __init__(self, caller, settings, config):
"""Constructor""" """Constructor"""
self.settings=settings self.settings = settings
self.caller=caller self.caller = caller
self.config = config self.config = config
self.fdb = None self.fdb = None
self.cursor = None self.cursor = None
@ -188,6 +188,7 @@ class Importer:
self.addImportDirectory(self.dirlist[site][0], False, site, self.dirlist[site][1]) self.addImportDirectory(self.dirlist[site][0], False, site, self.dirlist[site][1])
for file in self.filelist: for file in self.filelist:
if os.path.exists(file):
stat_info = os.stat(file) stat_info = os.stat(file)
try: try:
lastupdate = self.updated[file] lastupdate = self.updated[file]
@ -205,7 +206,8 @@ class Importer:
# TODO we also test if directory, why? # TODO we also test if directory, why?
#if os.path.isdir(file): #if os.path.isdir(file):
#self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1]) #self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1])
else:
removeFromFileList[file] = True
self.addToDirList = filter(lambda x: self.addImportDirectory(x, True, self.addToDirList[x][0], self.addToDirList[x][1]), self.addToDirList) self.addToDirList = filter(lambda x: self.addImportDirectory(x, True, self.addToDirList[x][0], self.addToDirList[x][1]), self.addToDirList)
for file in self.removeFromFileList: for file in self.removeFromFileList:
@ -251,7 +253,6 @@ class Importer:
print "Unknown filter filter_name:'%s' in filter:'%s'" %(filter_name, filter) print "Unknown filter filter_name:'%s' in filter:'%s'" %(filter_name, filter)
return return
#This will barf if conv.getStatus != True #This will barf if conv.getStatus != True
return (stored, duplicates, partial, errors, ttime) return (stored, duplicates, partial, errors, ttime)
@ -284,7 +285,13 @@ class Importer:
print "DEBUG: import_fpdb_file: failed on self.lines[0]: '%s' '%s' '%s' '%s' " %( file, site, self.lines, loc) print "DEBUG: import_fpdb_file: failed on self.lines[0]: '%s' '%s' '%s' '%s' " %( file, site, self.lines, loc)
return (0,0,0,1,0) return (0,0,0,1,0)
# site=fpdb_simple.recogniseSite(firstline) if firstline.find("Tournament Summary")!=-1:
print "TODO: implement importing tournament summaries"
#self.faobs = readfile(inputFile)
#self.parseTourneyHistory()
return 0
site=fpdb_simple.recogniseSite(firstline)
category=fpdb_simple.recogniseCategory(firstline) category=fpdb_simple.recogniseCategory(firstline)
startpos=0 startpos=0
@ -315,7 +322,7 @@ class Importer:
try: try:
handsId=fpdb_parse_logic.mainParser(self.settings['db-backend'], self.fdb.db handsId=fpdb_parse_logic.mainParser(self.settings['db-backend'], self.fdb.db
,self.fdb.cursor, category, hand) ,self.fdb.cursor, site, category, hand, self.config)
self.fdb.db.commit() self.fdb.db.commit()
stored+=1 stored+=1

View File

@ -21,46 +21,45 @@ import fpdb_simple
import fpdb_save_to_db import fpdb_save_to_db
#parses a holdem hand #parses a holdem hand
def mainParser(backend, db, cursor, category, hand): def mainParser(backend, db, cursor, category, hand, config):
category=fpdb_simple.recogniseCategory(hand[0]) category = fpdb_simple.recogniseCategory(hand[0])
if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
base="hold" base = "hold" if category == "holdem" or category == "omahahi" or category == "omahahilo" else "stud"
else:
base="stud"
#part 0: create the empty arrays #part 0: create the empty arrays
lineTypes=[] #char, valid values: header, name, cards, action, win, rake, ignore lineTypes = [] #char, valid values: header, name, cards, action, win, rake, ignore
lineStreets=[] #char, valid values: (predeal, preflop, flop, turn, river) lineStreets = [] #char, valid values: (predeal, preflop, flop, turn, river)
cardValues, cardSuits, boardValues, boardSuits, antes, actionTypes, allIns, actionAmounts, actionNos, actionTypeByNo, seatLines, winnings, rakes=[],[],[],[],[],[],[],[],[],[],[],[],[] cardValues, cardSuits, boardValues, boardSuits, antes, actionTypes, allIns, actionAmounts, actionNos, actionTypeByNo, seatLines, winnings, rakes=[],[],[],[],[],[],[],[],[],[],[],[],[]
#part 1: read hand no and check for duplicate #part 1: read hand no and check for duplicate
siteHandNo=fpdb_simple.parseSiteHandNo(hand[0]) siteHandNo = fpdb_simple.parseSiteHandNo(hand[0])
handStartTime=fpdb_simple.parseHandStartTime(hand[0]) handStartTime = fpdb_simple.parseHandStartTime(hand[0])
siteID=fpdb_simple.recogniseSiteID() siteID = fpdb_simple.recogniseSiteID()
#print "parse logic, siteID:",siteID,"site:",site #print "parse logic, siteID:",siteID,"site:",site
isTourney=fpdb_simple.isTourney(hand[0]) isTourney = fpdb_simple.isTourney(hand[0])
smallBlindLine=0 smallBlindLine = 0
for i in range(len(hand)): for i, line in enumerate(hand):
if 'posts small blind' in hand[i] or 'posts the small blind' in hand[i]: if 'posts small blind' in line or 'posts the small blind' in line:
if hand[i][-2:] == "$0": if line[-2:] == "$0": continue
continue smallBlindLine = i
smallBlindLine=i
#print "found small blind line:",smallBlindLine
break break
#print "small blind line:",smallBlindLine #print "small blind line:",smallBlindLine
gametypeID=fpdb_simple.recogniseGametypeID(backend, db, cursor, hand[0], hand[smallBlindLine], siteID, category, isTourney)
if isTourney:
siteTourneyNo=fpdb_simple.parseTourneyNo(hand[0])
buyin=fpdb_simple.parseBuyin(hand[0])
fee=fpdb_simple.parseFee(hand[0])
entries=-1 #todo: parse this
prizepool=-1 #todo: parse this
knockout=0
tourneyStartTime=handStartTime #todo: read tourney start time
rebuyOrAddon=fpdb_simple.isRebuyOrAddon(hand[0])
tourneyTypeId=fpdb_simple.recogniseTourneyTypeId(cursor, siteID, buyin, fee, knockout, rebuyOrAddon) gametypeID = fpdb_simple.recogniseGametypeID(backend, db, cursor, hand[0], hand[smallBlindLine], siteID, category, isTourney)
if isTourney:
siteTourneyNo = fpdb_simple.parseTourneyNo(hand[0])
buyin = fpdb_simple.parseBuyin(hand[0])
fee = fpdb_simple.parseFee(hand[0])
entries = -1 #todo: parse this
prizepool = -1 #todo: parse this
knockout = 0
tourneyStartTime= handStartTime #todo: read tourney start time
rebuyOrAddon = fpdb_simple.isRebuyOrAddon(hand[0])
tourneyTypeId = fpdb_simple.recogniseTourneyTypeId(cursor, siteID, buyin, fee, knockout, rebuyOrAddon)
fpdb_simple.isAlreadyInDB(cursor, gametypeID, siteHandNo) fpdb_simple.isAlreadyInDB(cursor, gametypeID, siteHandNo)
#part 2: classify lines by type (e.g. cards, action, win, sectionchange) and street #part 2: classify lines by type (e.g. cards, action, win, sectionchange) and street
@ -68,94 +67,90 @@ def mainParser(backend, db, cursor, category, hand):
#part 3: read basic player info #part 3: read basic player info
#3a read player names, startcashes #3a read player names, startcashes
for i in range (len(hand)): #todo: use maxseats+1 here. for i, line in enumerate(hand):
if (lineTypes[i]=="name"): if lineTypes[i] == "name":
seatLines.append(hand[i]) seatLines.append(line)
names=fpdb_simple.parseNames(seatLines)
names = fpdb_simple.parseNames(seatLines)
playerIDs = fpdb_simple.recognisePlayerIDs(cursor, names, siteID) playerIDs = fpdb_simple.recognisePlayerIDs(cursor, names, siteID)
tmp=fpdb_simple.parseCashesAndSeatNos(seatLines) tmp = fpdb_simple.parseCashesAndSeatNos(seatLines)
startCashes=tmp['startCashes'] startCashes = tmp['startCashes']
seatNos=tmp['seatNos'] seatNos = tmp['seatNos']
fpdb_simple.createArrays(category, len(names), cardValues, cardSuits, antes, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, actionTypeByNo) fpdb_simple.createArrays(category, len(names), cardValues, cardSuits, antes, winnings, rakes, actionTypes, allIns, actionAmounts, actionNos, actionTypeByNo)
#3b read positions #3b read positions
if base=="hold": if base == "hold":
positions = fpdb_simple.parsePositions (hand, names) positions = fpdb_simple.parsePositions(hand, names)
#part 4: take appropriate action for each line based on linetype #part 4: take appropriate action for each line based on linetype
for i in range(len(hand)): for i, line in enumerate(hand):
if (lineTypes[i]=="cards"): if lineTypes[i] == "cards":
fpdb_simple.parseCardLine (category, lineStreets[i], hand[i], names, cardValues, cardSuits, boardValues, boardSuits) fpdb_simple.parseCardLine(category, lineStreets[i], line, names, cardValues, cardSuits, boardValues, boardSuits)
#if category=="studhilo": #if category=="studhilo":
# print "hand[i]:", hand[i] # print "hand[i]:", hand[i]
# print "cardValues:", cardValues # print "cardValues:", cardValues
# print "cardSuits:", cardSuits # print "cardSuits:", cardSuits
elif (lineTypes[i]=="action"): elif lineTypes[i] == "action":
fpdb_simple.parseActionLine (base, isTourney, hand[i], lineStreets[i], playerIDs, names, actionTypes, allIns, actionAmounts, actionNos, actionTypeByNo) fpdb_simple.parseActionLine(base, isTourney, line, lineStreets[i], playerIDs, names, actionTypes, allIns, actionAmounts, actionNos, actionTypeByNo)
elif (lineTypes[i]=="win"): elif lineTypes[i] == "win":
fpdb_simple.parseWinLine (hand[i], names, winnings, isTourney) fpdb_simple.parseWinLine(line, names, winnings, isTourney)
elif (lineTypes[i]=="rake"): elif lineTypes[i] == "rake":
if isTourney: totalRake = 0 if isTourney else fpdb_simple.parseRake(line)
totalRake=0
else:
totalRake=fpdb_simple.parseRake(hand[i])
fpdb_simple.splitRake(winnings, rakes, totalRake) fpdb_simple.splitRake(winnings, rakes, totalRake)
elif (lineTypes[i]=="header" or lineTypes[i]=="rake" or lineTypes[i]=="name" or lineTypes[i]=="ignore"): elif lineTypes[i]=="header" or lineTypes[i]=="rake" or lineTypes[i]=="name" or lineTypes[i]=="ignore":
pass pass
elif (lineTypes[i]=="ante"): elif lineTypes[i]=="ante":
fpdb_simple.parseAnteLine(hand[i], isTourney, names, antes) fpdb_simple.parseAnteLine(line, isTourney, names, antes)
elif (lineTypes[i]=="table"): elif lineTypes[i]=="table":
tableResult=fpdb_simple.parseTableLine(base, hand[i]) tableResult=fpdb_simple.parseTableLine(base, line)
else: else:
raise fpdb_simple.FpdbError("unrecognised lineType:"+lineTypes[i]) raise fpdb_simple.FpdbError("unrecognised lineType:"+lineTypes[i])
maxSeats=tableResult['maxSeats']
tableName=tableResult['tableName'] maxSeats = tableResult['maxSeats']
tableName = tableResult['tableName']
#print "before part5, antes:", antes #print "before part5, antes:", antes
#part 5: final preparations, then call fpdb_save_to_db.* with #part 5: final preparations, then call fpdb_save_to_db.* with
# the arrays as they are - that file will fill them. # the arrays as they are - that file will fill them.
fpdb_simple.convertCardValues(cardValues) fpdb_simple.convertCardValues(cardValues)
if base=="hold": if base == "hold":
fpdb_simple.convertCardValuesBoard(boardValues) fpdb_simple.convertCardValuesBoard(boardValues)
fpdb_simple.convertBlindBet(actionTypes, actionAmounts) fpdb_simple.convertBlindBet(actionTypes, actionAmounts)
fpdb_simple.checkPositions(positions) fpdb_simple.checkPositions(positions)
cursor.execute("SELECT limitType FROM Gametypes WHERE id=%s",(gametypeID, )) cursor.execute("SELECT limitType FROM Gametypes WHERE id=%s",(gametypeID, ))
limit_type=cursor.fetchone()[0] limit_type = cursor.fetchone()[0]
fpdb_simple.convert3B4B(category, limit_type, actionTypes, actionAmounts) fpdb_simple.convert3B4B(category, limit_type, actionTypes, actionAmounts)
totalWinnings=0 totalWinnings = sum(winnings)
for i in range(len(winnings)):
totalWinnings+=winnings[i]
if base=="hold": # if hold'em, use positions and not antes, if stud do not use positions, use antes
hudImportData=fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes if base == "hold":
hudImportData = fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes
, allIns, actionTypeByNo, winnings, totalWinnings, positions , allIns, actionTypeByNo, winnings, totalWinnings, positions
, actionTypes, actionAmounts, None) , actionTypes, actionAmounts, None)
else: else:
hudImportData=fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes hudImportData = fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes
, allIns, actionTypeByNo, winnings, totalWinnings, None , allIns, actionTypeByNo, winnings, totalWinnings, None
, actionTypes, actionAmounts, antes) , actionTypes, actionAmounts, antes)
if isTourney: if isTourney:
ranks=[] ranks = map(lambda x: 0, names) # create an array of 0's equal to the length of names
for i in range (len(names)): payin_amounts = fpdb_simple.calcPayin(len(names), buyin, fee)
ranks.append(0)
payin_amounts=fpdb_simple.calcPayin(len(names), buyin, fee)
if base=="hold": if base == "hold":
result = fpdb_save_to_db.tourney_holdem_omaha( result = fpdb_save_to_db.tourney_holdem_omaha(
backend, db, cursor, base, category, siteTourneyNo, buyin config, backend, db, cursor, base, category, siteTourneyNo, buyin
, fee, knockout, entries, prizepool, tourneyStartTime , fee, knockout, entries, prizepool, tourneyStartTime
, payin_amounts, ranks, tourneyTypeId, siteID, siteHandNo , payin_amounts, ranks, tourneyTypeId, siteID, siteHandNo
, gametypeID, handStartTime, names, playerIDs, startCashes , gametypeID, handStartTime, names, playerIDs, startCashes
, positions, cardValues, cardSuits, boardValues, boardSuits , positions, cardValues, cardSuits, boardValues, boardSuits
, winnings, rakes, actionTypes, allIns, actionAmounts , winnings, rakes, actionTypes, allIns, actionAmounts
, actionNos, hudImportData, maxSeats, tableName, seatNos) , actionNos, hudImportData, maxSeats, tableName, seatNos)
elif base=="stud": elif base == "stud":
result = fpdb_save_to_db.tourney_stud( result = fpdb_save_to_db.tourney_stud(
backend, db, cursor, base, category, siteTourneyNo config, backend, db, cursor, base, category, siteTourneyNo
, buyin, fee, knockout, entries, prizepool, tourneyStartTime , buyin, fee, knockout, entries, prizepool, tourneyStartTime
, payin_amounts, ranks, tourneyTypeId, siteID, siteHandNo , payin_amounts, ranks, tourneyTypeId, siteID, siteHandNo
, gametypeID, handStartTime, names, playerIDs, startCashes , gametypeID, handStartTime, names, playerIDs, startCashes
@ -163,19 +158,19 @@ def mainParser(backend, db, cursor, category, hand):
, allIns, actionAmounts, actionNos, hudImportData, maxSeats , allIns, actionAmounts, actionNos, hudImportData, maxSeats
, tableName, seatNos) , tableName, seatNos)
else: else:
raise fpdb_simple.FpdbError ("unrecognised category") raise fpdb_simple.FpdbError("unrecognised category")
else: else:
if base=="hold": if base == "hold":
result = fpdb_save_to_db.ring_holdem_omaha( result = fpdb_save_to_db.ring_holdem_omaha(
backend, db, cursor, base, category, siteHandNo config, backend, db, cursor, base, category, siteHandNo
, gametypeID, handStartTime, names, playerIDs , gametypeID, handStartTime, names, playerIDs
, startCashes, positions, cardValues, cardSuits , startCashes, positions, cardValues, cardSuits
, boardValues, boardSuits, winnings, rakes , boardValues, boardSuits, winnings, rakes
, actionTypes, allIns, actionAmounts, actionNos , actionTypes, allIns, actionAmounts, actionNos
, hudImportData, maxSeats, tableName, seatNos) , hudImportData, maxSeats, tableName, seatNos)
elif base=="stud": elif base == "stud":
result = fpdb_save_to_db.ring_stud( result = fpdb_save_to_db.ring_stud(
backend, db, cursor, base, category, siteHandNo, gametypeID config, backend, db, cursor, base, category, siteHandNo, gametypeID
, handStartTime, names, playerIDs, startCashes, antes , handStartTime, names, playerIDs, startCashes, antes
, cardValues, cardSuits, winnings, rakes, actionTypes, allIns , cardValues, cardSuits, winnings, rakes, actionTypes, allIns
, actionAmounts, actionNos, hudImportData, maxSeats, tableName , actionAmounts, actionNos, hudImportData, maxSeats, tableName

View File

@ -22,29 +22,35 @@ from time import time
import fpdb_simple import fpdb_simple
MYSQL_INNODB=2 MYSQL_INNODB = 2
PGSQL=3 PGSQL = 3
SQLITE=4 SQLITE = 4
fastStoreHudCache=False # set this to True to test the new storeHudCache routine fastStoreHudCache = True # set this to True to test the new storeHudCache routine
saveActions=True # set this to False to avoid storing action data saveActions = False # set this to False to avoid storing action data
# Pros: speeds up imports # Pros: speeds up imports
# Cons: no action data is saved, so you need to keep the hand histories # Cons: no action data is saved, so you need to keep the hand histories
# variance not available on stats page # variance not available on stats page
#stores a stud/razz hand into the database #stores a stud/razz hand into the database
def ring_stud(backend, db, cursor, base, category, site_hand_no, gametype_id, hand_start_time def ring_stud(config, backend, db, cursor, base, category, site_hand_no, gametype_id, hand_start_time
,names, player_ids, start_cashes, antes, card_values, card_suits, winnings, rakes ,names, player_ids, start_cashes, antes, card_values, card_suits, winnings, rakes
,action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName ,action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName
,seatNos): ,seatNos):
import_options = config.get_import_parameters()
saveActions = True if import_options['saveActions'] == 'True' else False
fastStoreHudCache = True if import_options['fastStoreHudCache'] == 'True' else False
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits) fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
hands_id=fpdb_simple.storeHands(backend, db, cursor, site_hand_no, gametype_id hands_id = fpdb_simple.storeHands(backend, db, cursor, site_hand_no, gametype_id
,hand_start_time, names, tableName, maxSeats) ,hand_start_time, names, tableName, maxSeats)
#print "before calling store_hands_players_stud, antes:", antes #print "before calling store_hands_players_stud, antes:", antes
hands_players_ids=fpdb_simple.store_hands_players_stud(backend, db, cursor, hands_id, player_ids hands_players_ids = fpdb_simple.store_hands_players_stud(backend, db, cursor, hands_id, player_ids
,start_cashes, antes, card_values ,start_cashes, antes, card_values
,card_suits, winnings, rakes, seatNos) ,card_suits, winnings, rakes, seatNos)
@ -56,21 +62,26 @@ def ring_stud(backend, db, cursor, base, category, site_hand_no, gametype_id, ha
return hands_id return hands_id
#end def ring_stud #end def ring_stud
def ring_holdem_omaha(backend, db, cursor, base, category, site_hand_no, gametype_id def ring_holdem_omaha(config, backend, db, cursor, base, category, site_hand_no, gametype_id
,hand_start_time, names, player_ids, start_cashes, positions, card_values ,hand_start_time, names, player_ids, start_cashes, positions, card_values
,card_suits, board_values, board_suits, winnings, rakes, action_types, allIns ,card_suits, board_values, board_suits, winnings, rakes, action_types, allIns
,action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos): ,action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
"""stores a holdem/omaha hand into the database""" """stores a holdem/omaha hand into the database"""
import_options = config.get_import_parameters()
saveActions = True if import_options['saveActions'] == 'True' else False
fastStoreHudCache = True if import_options['fastStoreHudCache'] == 'True' else False
t0 = time() t0 = time()
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits) fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
t1 = time() t1 = time()
fpdb_simple.fill_board_cards(board_values, board_suits) fpdb_simple.fill_board_cards(board_values, board_suits)
t2 = time() t2 = time()
hands_id=fpdb_simple.storeHands(backend, db, cursor, site_hand_no, gametype_id hands_id = fpdb_simple.storeHands(backend, db, cursor, site_hand_no, gametype_id
,hand_start_time, names, tableName, maxSeats) ,hand_start_time, names, tableName, maxSeats)
t3 = time() t3 = time()
hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha( hands_players_ids = fpdb_simple.store_hands_players_holdem_omaha(
backend, db, cursor, category, hands_id, player_ids, start_cashes backend, db, cursor, category, hands_id, player_ids, start_cashes
, positions, card_values, card_suits, winnings, rakes, seatNos) , positions, card_values, card_suits, winnings, rakes, seatNos)
t4 = time() t4 = time()
@ -89,7 +100,7 @@ def ring_holdem_omaha(backend, db, cursor, base, category, site_hand_no, gametyp
return hands_id return hands_id
#end def ring_holdem_omaha #end def ring_holdem_omaha
def tourney_holdem_omaha(backend, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout def tourney_holdem_omaha(config, backend, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout
,entries, prizepool, tourney_start, payin_amounts, ranks, tourneyTypeId ,entries, prizepool, tourney_start, payin_amounts, ranks, tourneyTypeId
,siteId #end of tourney specific params ,siteId #end of tourney specific params
,site_hand_no, gametype_id, hand_start_time, names, player_ids ,site_hand_no, gametype_id, hand_start_time, names, player_ids
@ -97,16 +108,21 @@ def tourney_holdem_omaha(backend, db, cursor, base, category, siteTourneyNo, buy
,board_suits, winnings, rakes, action_types, allIns, action_amounts ,board_suits, winnings, rakes, action_types, allIns, action_amounts
,actionNos, hudImportData, maxSeats, tableName, seatNos): ,actionNos, hudImportData, maxSeats, tableName, seatNos):
"""stores a tourney holdem/omaha hand into the database""" """stores a tourney holdem/omaha hand into the database"""
import_options = config.get_import_parameters()
saveActions = True if import_options['saveActions'] == 'True' else False
fastStoreHudCache = True if import_options['fastStoreHudCache'] == 'True' else False
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits) fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
fpdb_simple.fill_board_cards(board_values, board_suits) fpdb_simple.fill_board_cards(board_values, board_suits)
tourney_id=fpdb_simple.store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, tourney_start) tourney_id = fpdb_simple.store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, tourney_start)
tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks, winnings) tourneys_players_ids = fpdb_simple.store_tourneys_players(cursor, tourney_id, player_ids, payin_amounts, ranks, winnings)
hands_id=fpdb_simple.storeHands(backend, db, cursor, site_hand_no, gametype_id hands_id = fpdb_simple.storeHands(backend, db, cursor, site_hand_no, gametype_id
,hand_start_time, names, tableName, maxSeats) ,hand_start_time, names, tableName, maxSeats)
hands_players_ids=fpdb_simple.store_hands_players_holdem_omaha_tourney( hands_players_ids = fpdb_simple.store_hands_players_holdem_omaha_tourney(
backend, db, cursor, category, hands_id, player_ids, start_cashes, positions backend, db, cursor, category, hands_id, player_ids, start_cashes, positions
, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids) , card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids)
@ -123,21 +139,26 @@ def tourney_holdem_omaha(backend, db, cursor, base, category, siteTourneyNo, buy
return hands_id return hands_id
#end def tourney_holdem_omaha #end def tourney_holdem_omaha
def tourney_stud(backend, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries def tourney_stud(config, backend, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries
,prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteId ,prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteId
,siteHandNo, gametypeId, handStartTime, names, playerIds, startCashes, antes ,siteHandNo, gametypeId, handStartTime, names, playerIds, startCashes, antes
,cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts ,cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts
,actionNos, hudImportData, maxSeats, tableName, seatNos): ,actionNos, hudImportData, maxSeats, tableName, seatNos):
#stores a tourney stud/razz hand into the database #stores a tourney stud/razz hand into the database
import_options = config.get_import_parameters()
saveActions = True if import_options['saveActions'] == 'True' else False
fastStoreHudCache = True if import_options['fastStoreHudCache'] == 'True' else False
fpdb_simple.fillCardArrays(len(names), base, category, cardValues, cardSuits) fpdb_simple.fillCardArrays(len(names), base, category, cardValues, cardSuits)
tourney_id=fpdb_simple.store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, tourneyStartTime) tourney_id = fpdb_simple.store_tourneys(cursor, tourneyTypeId, siteTourneyNo, entries, prizepool, tourneyStartTime)
tourneys_players_ids=fpdb_simple.store_tourneys_players(cursor, tourney_id, playerIds, payin_amounts, ranks, winnings) tourneys_players_ids = fpdb_simple.store_tourneys_players(cursor, tourney_id, playerIds, payin_amounts, ranks, winnings)
hands_id=fpdb_simple.storeHands(backend, db, cursor, siteHandNo, gametypeId, handStartTime, names, tableName, maxSeats) hands_id = fpdb_simple.storeHands(backend, db, cursor, siteHandNo, gametypeId, handStartTime, names, tableName, maxSeats)
hands_players_ids=fpdb_simple.store_hands_players_stud_tourney(backend, db, cursor, hands_id hands_players_ids = fpdb_simple.store_hands_players_stud_tourney(backend, db, cursor, hands_id
, playerIds, startCashes, antes, cardValues, cardSuits , playerIds, startCashes, antes, cardValues, cardSuits
, winnings, rakes, seatNos, tourneys_players_ids) , winnings, rakes, seatNos, tourneys_players_ids)

View File

@ -18,14 +18,17 @@
#This file contains simple functions for fpdb #This file contains simple functions for fpdb
import datetime import datetime
import time
import re import re
PS=1 PS = 1
FTP=2 FTP = 2
# TODO: these constants are also used in fpdb_save_to_db and others, is there a way to do like C #define, and #include ?
MYSQL_INNODB = 2
PGSQL = 3
SQLITE = 4
MYSQL_INNODB=2
PGSQL=3
SQLITE=4
# Data Structures for index and foreign key creation # Data Structures for index and foreign key creation
# drop_code is an int with possible values: 0 - don't drop for bulk import # drop_code is an int with possible values: 0 - don't drop for bulk import
# 1 - drop during bulk import # 1 - drop during bulk import
@ -156,6 +159,7 @@ def prepareBulkImport(fdb):
except: except:
pass pass
elif fdb.backend == PGSQL: elif fdb.backend == PGSQL:
# DON'T FORGET TO RECREATE THEM!!
print "dropping pg fk", fk['fktab'], fk['fkcol'] print "dropping pg fk", fk['fktab'], fk['fkcol']
try: try:
fdb.cursor.execute("alter table " + fk['fktab'] + " drop constraint " fdb.cursor.execute("alter table " + fk['fktab'] + " drop constraint "
@ -175,10 +179,14 @@ def prepareBulkImport(fdb):
except: except:
pass pass
elif fdb.backend == PGSQL: elif fdb.backend == PGSQL:
# DON'T FORGET TO RECREATE THEM!!
print "Index dropping disabled for postgresql."
print "dropping pg index ", idx['tab'], idx['col'] print "dropping pg index ", idx['tab'], idx['col']
# mod to use tab_col for index name? # mod to use tab_col for index name?
try: try:
print "drop index %s_%s_idx" % (idx['tab'],idx['col'])
fdb.cursor.execute( "drop index %s_%s_idx" % (idx['tab'],idx['col']) ) fdb.cursor.execute( "drop index %s_%s_idx" % (idx['tab'],idx['col']) )
print "dropped pg index ", idx['tab'], idx['col']
except: except:
pass pass
else: else:
@ -241,6 +249,7 @@ def afterBulkImport(fdb):
except: except:
pass pass
elif fdb.backend == PGSQL: elif fdb.backend == PGSQL:
# pass
# mod to use tab_col for index name? # mod to use tab_col for index name?
print "creating pg index ", idx['tab'], idx['col'] print "creating pg index ", idx['tab'], idx['col']
try: try:
@ -380,25 +389,18 @@ def calcPayin(count, buyin, fee):
#end def calcPayin #end def calcPayin
def checkPositions(positions): def checkPositions(positions):
"""verifies that these positions are valid""" """ verify positions are valid """
for i in xrange(len(positions)): for p in positions:
pos=positions[i] if not (p == "B" or p == "S" or (p >= 0 and p <= 9)):
try:#todo: use type recognition instead of error raise FpdbError("invalid position '" + p + "' found in checkPositions")
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 ### 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... ### 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. #classifies each line for further processing in later code. Manipulates the passed arrays.
def classifyLines(hand, category, lineTypes, lineStreets): def classifyLines(hand, category, lineTypes, lineStreets):
currentStreet="predeal" currentStreet = "predeal"
done=False #set this to true once we reach the last relevant line (the summary, except rake, is all repeats) done = False #set this to true once we reach the last relevant line (the summary, except rake, is all repeats)
for i, line in enumerate(hand): for i, line in enumerate(hand):
if done: if done:
if "[" not in line or "mucked [" not in line: if "[" not in line or "mucked [" not in line:
@ -409,20 +411,14 @@ def classifyLines(hand, category, lineTypes, lineStreets):
lineTypes.append("cards") lineTypes.append("cards")
elif i == 0: elif i == 0:
lineTypes.append("header") lineTypes.append("header")
elif line.startswith("Table '"):
lineTypes.append("table")
elif line.startswith("Seat ") and ( ("in chips" in line) or "($" in line): elif line.startswith("Seat ") and ( ("in chips" in line) or "($" in line):
lineTypes.append("name") lineTypes.append("name")
elif isActionLine(line): elif isActionLine(line):
lineTypes.append("action") lineTypes.append("action")
if " posts " in line or " posts the " in line: if " posts " in line or " posts the " in line:
currentStreet="preflop" currentStreet="preflop"
elif isWinLine(line):
lineTypes.append("win")
elif line.startswith("Total pot ") and "Rake" in line:
lineTypes.append("rake")
done=True
elif "*** SHOW DOWN ***" in line or "*** SUMMARY ***" in line:
lineTypes.append("ignore")
#print "in classifyLine, showdown or summary"
elif " antes " in line or " posts the ante " in line: elif " antes " in line or " posts the ante " in line:
lineTypes.append("ante") lineTypes.append("ante")
elif line.startswith("*** FLOP *** ["): elif line.startswith("*** FLOP *** ["):
@ -449,10 +445,16 @@ def classifyLines(hand, category, lineTypes, lineStreets):
elif line.startswith("*** 7") or line == "*** RIVER ***": elif line.startswith("*** 7") or line == "*** RIVER ***":
lineTypes.append("ignore") lineTypes.append("ignore")
currentStreet=4 currentStreet=4
elif isWinLine(line):
lineTypes.append("win")
elif line.startswith("Total pot ") and "Rake" in line:
lineTypes.append("rake")
done=True
elif "*** SHOW DOWN ***" in line or "*** SUMMARY ***" in line:
lineTypes.append("ignore")
#print "in classifyLine, showdown or summary"
elif " shows [" in line: elif " shows [" in line:
lineTypes.append("cards") lineTypes.append("cards")
elif line.startswith("Table '"):
lineTypes.append("table")
else: else:
raise FpdbError("unrecognised linetype in:"+hand[i]) raise FpdbError("unrecognised linetype in:"+hand[i])
lineStreets.append(currentStreet) lineStreets.append(currentStreet)
@ -508,68 +510,45 @@ def convertCardValues(arr):
map(convertCardValuesBoard, arr) map(convertCardValuesBoard, arr)
#end def convertCardValues #end def convertCardValues
card_map = { "2": 2, "3" : 3, "4" : 4, "5" : 5, "6" : 6, "7" : 7, "8" : 8, "9" : 9, "T" : 10, "J" : 11, "Q" : 12, "K" : 13, "A" : 14}
#converts the strings in the given array to ints (changes the passed array, no returning). see table design for conversion details #converts the strings in the given array to ints (changes the passed array, no returning). see table design for conversion details
def convertCardValuesBoard(arr): def convertCardValuesBoard(arr):
for i in xrange(len(arr)): for i in xrange(len(arr)):
if (arr[i]=="A"): arr[i] = card_map[arr[i]]
arr[i]=14
elif (arr[i]=="K"):
arr[i]=13
elif (arr[i]=="Q"):
arr[i]=12
elif (arr[i]=="J"):
arr[i]=11
elif (arr[i]=="T"):
arr[i]=10
else:
arr[i]=int(arr[i])
#end def convertCardValuesBoard #end def convertCardValuesBoard
#this creates the 2D/3D arrays. manipulates the passed arrays instead of returning. #this creates the 2D/3D arrays. manipulates the passed arrays instead of returning.
def createArrays(category, seats, card_values, card_suits, antes, winnings, rakes, action_types, allIns, action_amounts, actionNos, actionTypeByNo): def createArrays(category, seats, card_values, card_suits, antes, winnings, rakes, action_types, allIns, action_amounts, actionNos, actionTypeByNo):
for i in xrange(seats):#create second dimension arrays for i in xrange(seats):#create second dimension arrays
tmp=[] card_values.append( [] )
card_values.append(tmp) card_suits.append( [] )
tmp=[]
card_suits.append(tmp)
antes.append(0) antes.append(0)
winnings.append(0) winnings.append(0)
rakes.append(0) rakes.append(0)
if (category=="holdem" or category=="omahahi" or category=="omahahilo"): streetCount = 4 if category == "holdem" or category == "omahahi" or category == "omahahilo" else 5
streetCount=4
else:
streetCount=5
for i in xrange(streetCount): #build the first dimension array, for streets for i in xrange(streetCount): #build the first dimension array, for streets
tmp=[] action_types.append([])
action_types.append(tmp) allIns.append([])
tmp=[] action_amounts.append([])
allIns.append(tmp) actionNos.append([])
tmp=[] actionTypeByNo.append([])
action_amounts.append(tmp)
tmp=[]
actionNos.append(tmp)
tmp=[]
actionTypeByNo.append(tmp)
for j in xrange (seats): #second dimension arrays: players for j in xrange (seats): #second dimension arrays: players
tmp=[] action_types[i].append([])
action_types[i].append(tmp) allIns[i].append([])
tmp=[] action_amounts[i].append([])
allIns[i].append(tmp) actionNos[i].append([])
tmp=[] # if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
action_amounts[i].append(tmp) # pass
tmp=[] if category=="razz" or category=="studhi" or category=="studhilo":#need to fill card arrays.
actionNos[i].append(tmp)
if (category=="holdem" or category=="omahahi" or category=="omahahilo"):
pass
elif (category=="razz" or category=="studhi" or category=="studhilo"):#need to fill card arrays.
for i in xrange(seats): for i in xrange(seats):
for j in xrange (7): for j in xrange(7):
card_values[i].append(0) card_values[i].append(0)
card_suits[i].append("x") card_suits[i].append("x")
else: # else:
raise FpdbError("invalid category") # raise FpdbError("invalid category")
#end def createArrays #end def createArrays
def fill_board_cards(board_values, board_suits): def fill_board_cards(board_values, board_suits):
@ -582,16 +561,16 @@ def fill_board_cards(board_values, board_suits):
def fillCardArrays(player_count, base, category, card_values, card_suits): def fillCardArrays(player_count, base, category, card_values, card_suits):
"""fills up the two card arrays""" """fills up the two card arrays"""
if (category=="holdem"): if (category=="holdem"):
cardCount=2 cardCount = 2
elif (category=="omahahi" or category=="omahahilo"): elif (category=="omahahi" or category=="omahahilo"):
cardCount=4 cardCount = 4
elif base=="stud": elif base=="stud":
cardCount=7 cardCount = 7
else: else:
raise fpdb_simple.FpdbError ("invalid category:", category) raise fpdb_simple.FpdbError("invalid category:", category)
for i in xrange (player_count): for i in xrange(player_count):
while (len(card_values[i])<cardCount): while (len(card_values[i]) < cardCount):
card_values[i].append(0) card_values[i].append(0)
card_suits[i].append("x") card_suits[i].append("x")
#end def fillCardArrays #end def fillCardArrays
@ -603,132 +582,128 @@ def filterAnteBlindFold(hand):
#todo: in tourneys this should not be removed but #todo: in tourneys this should not be removed but
#print "start of filterAnteBlindFold" #print "start of filterAnteBlindFold"
pre3rd=[] pre3rd=[]
for i in xrange (len(hand)): for i, line in enumerate(hand):
if (hand[i].startswith("*** 3") or hand[i].startswith("*** HOLE")): if line.startswith("*** 3") or line.startswith("*** HOLE"):
pre3rd=hand[0:i] pre3rd = hand[0:i]
foldeeName=None foldeeName=None
for i in xrange (len(pre3rd)): for line in pre3rd:
if (pre3rd[i].endswith("folds") or pre3rd[i].endswith("is sitting out") or pre3rd[i].endswith(" stands up")): #found ante fold or timeout if line.endswith("folds") or line.endswith("is sitting out") or line.endswith(" stands up"): #found ante fold or timeout
pos=pre3rd[i].find (" folds") pos = line.find(" folds")
foldeeName=pre3rd[i][0:pos] foldeeName = line[0:pos]
if pos == -1 and pre3rd[i].find(" in chips)")==-1: if pos == -1 and " in chips)" not in line:
pos=pre3rd[i].find (" is sitting out") pos = line.find(" is sitting out")
foldeeName=pre3rd[i][0:pos] foldeeName = line[0:pos]
if pos==-1: if pos == -1:
pos=pre3rd[i].find (" stands up") pos = line.find(" stands up")
foldeeName=pre3rd[i][0:pos] foldeeName = line[0:pos]
if pos==-1:#this one is for PS tourney if pos == -1:
pos1=pre3rd[i].find (": ")+2 pos1 = line.find(": ") + 2
pos2=pre3rd[i].find (" (") pos2 = line.find(" (")
foldeeName=pre3rd[i][pos1:pos2] foldeeName = line[pos1:pos2]
if foldeeName!=None: if foldeeName!=None:
#print "filterAnteBlindFold, foldeeName:",foldeeName #print "filterAnteBlindFold, foldeeName:",foldeeName
toRemove=[] for i, line in enumerate(hand):
for i in xrange(len(hand)): #using hand again to filter from all streets, just in case. if foldeeName in line:
#todo: this will break it if sittin out BB wins a hand hand[i] = None
if (hand[i].find(foldeeName)!=-1):
toRemove.append(hand[i])
for i in xrange(len(toRemove)): hand = [line for line in hand if line]
hand.remove(toRemove[i])
#end def filterAnteFold #end def filterAnteFold
def stripEOLspaces(str):
if str[-1] == ' ':
str = str[:-1]
if str[-1] == ' ':
str = str[:-1]
return str
#removes useless lines as well as trailing spaces #removes useless lines as well as trailing spaces
def filterCrap(hand, isTourney): def filterCrap(hand, isTourney):
#remove two trailing spaces at end of line #remove two trailing spaces at end of line
for i in xrange (len(hand)): hand = [stripEOLspaces(line) for line in hand]
if (hand[i][-1]==' '):
hand[i]=hand[i][:-1]
if (hand[i][-1]==' '):
hand[i]=hand[i][:-1]
#print "hand after trailing space removal in filterCrap:",hand #print "hand after trailing space removal in filterCrap:",hand
#general variable position word filter/string filter #general variable position word filter/string filter
toRemove=[]
for i in xrange (len(hand)): for i in xrange (len(hand)):
if (hand[i].startswith("Board [")): if (hand[i].startswith("Board [")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].find(" out of hand ")!=-1): elif (hand[i].find(" out of hand ")!=-1):
hand[i]=hand[i][:-56] hand[i]=hand[i][:-56]
elif (hand[i].find("($0 in chips)") != -1): elif (hand[i].find("($0 in chips)") != -1):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i]=="*** HOLE CARDS ***"): elif (hand[i]=="*** HOLE CARDS ***"):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("has been disconnected")): elif (hand[i].endswith("has been disconnected")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("has requested TIME")): elif (hand[i].endswith("has requested TIME")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("has returned")): elif (hand[i].endswith("has returned")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("will be allowed to play after the button")): elif (hand[i].endswith("will be allowed to play after the button")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("has timed out")): elif (hand[i].endswith("has timed out")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("has timed out while disconnected")): elif (hand[i].endswith("has timed out while disconnected")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("has timed out while being disconnected")): elif (hand[i].endswith("has timed out while being disconnected")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("is connected")): elif (hand[i].endswith("is connected")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("is disconnected")): elif (hand[i].endswith("is disconnected")):
toRemove.append(hand[i]) toRemove.append(hand[i])
elif (hand[i].find(" is low with [")!=-1): elif (hand[i].find(" is low with [")!=-1):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith(" mucks")): elif (hand[i].endswith(" mucks")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith(": mucks hand")): elif (hand[i].endswith(": mucks hand")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i]=="No low hand qualified"): elif (hand[i]=="No low hand qualified"):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i]=="Pair on board - a double bet is allowed"): elif (hand[i]=="Pair on board - a double bet is allowed"):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].find(" shows ")!=-1 and hand[i].find("[")==-1): elif (hand[i].find(" shows ")!=-1 and hand[i].find("[")==-1):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].startswith("The button is in seat #")): elif (hand[i].startswith("The button is in seat #")):
toRemove.append(hand[i]) hand[i] = False
#above is alphabetic, reorder below if bored #above is alphabetic, reorder below if bored
elif (hand[i].startswith("Time has expired")): elif (hand[i].startswith("Time has expired")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("has reconnected")): elif (hand[i].endswith("has reconnected")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("seconds left to act")): elif (hand[i].endswith("seconds left to act")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("seconds to reconnect")): elif (hand[i].endswith("seconds to reconnect")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("was removed from the table for failing to post")): elif (hand[i].endswith("was removed from the table for failing to post")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].find("joins the table at seat ")!=-1): elif (hand[i].find("joins the table at seat ")!=-1):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("leaves the table")): elif (hand[i].endswith("leaves the table")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].find("is high with ")!=-1): elif (hand[i].find("is high with ")!=-1):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("doesn't show hand")): elif (hand[i].endswith("doesn't show hand")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith("is being treated as all-in")): elif (hand[i].endswith("is being treated as all-in")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].find(" adds $")!=-1): elif (hand[i].find(" adds $")!=-1):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i]=="Betting is capped"): elif (hand[i]=="Betting is capped"):
toRemove.append(hand[i]) hand[i] = False
#site specific variable position filter #site specific variable position filter
elif (hand[i].find(" said, \"")!=-1): elif (hand[i].find(" said, \"")!=-1):
toRemove.append(hand[i]) hand[i] = False
if isTourney: if isTourney:
if (hand[i].endswith(" is sitting out") and (not hand[i].startswith("Seat "))): if (hand[i].endswith(" is sitting out") and (not hand[i].startswith("Seat "))):
toRemove.append(hand[i]) hand[i] = False
else: elif:
if (hand[i].endswith(": sits out")): if (hand[i].endswith(": sits out")):
toRemove.append(hand[i]) hand[i] = False
elif (hand[i].endswith(" is sitting out")): elif (hand[i].endswith(" is sitting out")):
toRemove.append(hand[i]) hand[i] = False
hand = [line for line in hand if line] # python docs say this is identical to filter(None, list)
for i in xrange (len(toRemove)):
#print "removing in filterCr:",toRemove[i]
hand.remove(toRemove[i])
#print "done with filterCrap, hand:", hand #print "done with filterCrap, hand:", hand
return hand return hand
@ -738,52 +713,36 @@ def filterCrap(hand, isTourney):
def float2int (string): def float2int (string):
pos=string.find(",") pos=string.find(",")
if (pos!=-1): #remove , the thousand seperator if (pos!=-1): #remove , the thousand seperator
string=string[0:pos]+string[pos+1:] string = "%s%s" % (string[0:pos], string[pos+1:])
pos=string.find(".") pos=string.find(".")
if (pos!=-1): #remove decimal point if (pos!=-1): #remove decimal point
string=string[0:pos]+string[pos+1:] string = "%s%s" % (string[0:pos], string[pos+1:])
result = int(string) result = int(string)
if pos==-1: #no decimal point - was in full dollars - need to multiply with 100 if pos == -1: #no decimal point - was in full dollars - need to multiply with 100
result*=100 result*=100
return result return result
#end def float2int #end def float2int
ActionLines = ( "calls $", ": calls ", "brings in for", "completes it to", "posts small blind",
"posts the small blind", "posts big blind", "posts the big blind",
"posts small & big blinds", "posts $", "posts a dead", "bets $",
": bets ", "raises")
#returns boolean whether the passed line is an action line #returns boolean whether the passed line is an action line
def isActionLine(line): def isActionLine(line):
if (line.endswith("folds")): if (line.endswith("folds")):
return True return True
elif (line.endswith("checks")): elif (line.endswith("checks")):
return True return True
elif (line.find("calls $")!=-1 or line.find(": calls ")!=-1):
return True
elif (line.find("brings in for")!=-1):
return True
elif (line.find("completes it to")!=-1):
return True
elif (line.find("posts small blind")!=-1):
return True
elif (line.find("posts the small blind")!=-1):
return True
elif (line.find("posts big blind")!=-1):
return True
elif (line.find("posts the big blind")!=-1):
return True
elif (line.find("posts small & big blinds")!=-1):
return True
elif (line.find(" posts $")!=-1): #this reads voluntary blind pay in FTP Holdem
return True
elif (line.find(" posts a dead ")!=-1): #this reads voluntary blind pay in FTP Holdem
return True
elif (line.find("bets $")!=-1 or line.find(": bets ")!=-1):
return True
elif (line.find("raises")!=-1):
return True
elif (line.startswith("Uncalled bet")): elif (line.startswith("Uncalled bet")):
return True return True
else:
return False return len( [ x for x in ActionLines if x in line]) > 0
# ret = any(True for searchstr in ActionLines if searchstr in line)
# ret = len( [ x for x in ActionLines if line.find(x) > -1] ) > 0
# ret = any(searchstr in line for searchstr in ActionLines)
#end def isActionLine #end def isActionLine
#returns whether this is a duplicate #returns whether this is a duplicate
@ -802,46 +761,14 @@ def isRebuyOrAddon(topline):
#returns whether the passed topline indicates a tournament or not #returns whether the passed topline indicates a tournament or not
def isTourney(topline): def isTourney(topline):
if (topline.find("Tournament")!=-1): return "Tournament" in topline
return True
else:
return False
#end def isTourney #end def isTourney
WinLines = ( "wins the pot", "ties for the ", "wins side pot", "wins the low main pot", "wins the high main pot",
"wins the high pot", "wins the high side pot", "wins the main pot", "wins the side pot", "collected" )
#returns boolean whether the passed line is a win line #returns boolean whether the passed line is a win line
def isWinLine(line): def isWinLine(line):
if (line.find("wins the pot")!=-1): return len( [ x for x in WinLines if x in line ] ) > 0
return True
elif (line.find("ties for the high pot")!=-1):
return True
elif (line.find("ties for the high main pot")!=-1):
return True
elif (line.find("ties for the high side pot")!=-1):
return True
elif (line.find("ties for the low pot")!=-1):
return True
elif (line.find("ties for the low main pot")!=-1):
return True
elif (line.find("ties for the low side pot")!=-1):
return True
elif (line.find("wins the low main pot")!=-1):
return True
elif (line.find("wins the low pot")!=-1):
return True
elif (line.find("wins the low side pot")!=-1):
return True
elif (line.find("wins the high main pot")!=-1):
return True
elif (line.find("wins the high pot")!=-1):
return True
elif (line.find("wins the high side pot")!=-1):
return True
elif (line.find("wins the main pot")!=-1):
return True
elif (line.find("collected")!=-1):
return True
else:
return False #not raising error here, any unknown line wouldve been detected in isActionLine already
#end def isWinLine #end def isWinLine
#returns the amount of cash/chips put into the put in the given action line #returns the amount of cash/chips put into the put in the given action line
@ -856,35 +783,31 @@ def parseActionAmount(line, atype, isTourney):
if line.endswith(" and is capped"): if line.endswith(" and is capped"):
line=line[:-14] line=line[:-14]
if atype == "fold" or atype == "check":
if (atype=="fold"): amount = 0
amount=0 elif atype == "unbet":
elif (atype=="check"): pos1 = line.find("$") + 1
amount=0 if pos1 == 0:
elif (atype=="unbet"): pos1 = line.find("(") + 1
#print "ps unbet, line:",line pos2 = line.find(")")
pos1=line.find("$")+1 amount = float2int(line[pos1:pos2])
if pos1==0: elif atype == "bet" and line.find(": raises $")!=-1 and line.find("to $")!=-1:
pos1=line.find("(")+1
pos2=line.find(")")
amount=float2int(line[pos1:pos2])
elif (atype=="bet" and line.find(": raises $")!=-1 and line.find("to $")!=-1):
pos=line.find("to $")+4 pos=line.find("to $")+4
amount=float2int(line[pos:]) amount=float2int(line[pos:])
else: else:
if not isTourney: if not isTourney:
pos=line.rfind("$")+1 pos = line.rfind("$")+1
#print "parseActionAmount, line:", line, "line[pos:]:", line[pos:] #print "parseActionAmount, line:", line, "line[pos:]:", line[pos:]
amount=float2int(line[pos:]) amount = float2int(line[pos:])
else: else:
#print "line:"+line+"EOL" #print "line:"+line+"EOL"
pos=line.rfind(" ")+1 pos = line.rfind(" ")+1
#print "pos:",pos #print "pos:",pos
#print "pos of 20:", line.find("20") #print "pos of 20:", line.find("20")
amount=int(line[pos:]) amount = int(line[pos:])
if atype=="unbet": if atype == "unbet":
amount*=-1 amount *= -1
return amount return amount
#end def parseActionAmount #end def parseActionAmount
@ -892,16 +815,16 @@ def parseActionAmount(line, atype, isTourney):
# action_amounts. For stud this expects numeric streets (3-7), for # action_amounts. For stud this expects numeric streets (3-7), for
# holdem/omaha it expects predeal, preflop, flop, turn or river # holdem/omaha it expects predeal, preflop, flop, turn or river
def parseActionLine(base, isTourney, line, street, playerIDs, names, action_types, allIns, action_amounts, actionNos, actionTypeByNo): def parseActionLine(base, isTourney, line, street, playerIDs, names, action_types, allIns, action_amounts, actionNos, actionTypeByNo):
if (street=="predeal" or street=="preflop"): if street == "predeal" or street == "preflop":
street=0 street = 0
elif (street=="flop"): elif street == "flop":
street=1 street = 1
elif (street=="turn"): elif street == "turn":
street=2 street = 2
elif (street=="river"): elif street == "river":
street=3 street = 3
nextActionNo=0 nextActionNo = 0
for player in xrange(len(actionNos[street])): for player in xrange(len(actionNos[street])):
for count in xrange(len(actionNos[street][player])): for count in xrange(len(actionNos[street][player])):
if actionNos[street][player][count]>=nextActionNo: if actionNos[street][player][count]>=nextActionNo:
@ -922,13 +845,13 @@ def parseActionLine(base, isTourney, line, street, playerIDs, names, action_type
def goesAllInOnThisLine(line): def goesAllInOnThisLine(line):
"""returns whether the player went all-in on this line and removes the all-in text from the line.""" """returns whether the player went all-in on this line and removes the all-in text from the line."""
isAllIn=False isAllIn = False
if (line.endswith(" and is all-in")): if (line.endswith(" and is all-in")):
line=line[:-14] line = line[:-14]
isAllIn=True isAllIn = True
elif (line.endswith(", and is all in")): elif (line.endswith(", and is all in")):
line=line[:-15] line = line[:-15]
isAllIn=True isAllIn = True
return (line, isAllIn) return (line, isAllIn)
#end def goesAllInOnThisLine #end def goesAllInOnThisLine
@ -972,48 +895,48 @@ def parseActionType(line):
#parses the ante out of the given line and checks which player paid it, updates antes accordingly. #parses the ante out of the given line and checks which player paid it, updates antes accordingly.
def parseAnteLine(line, isTourney, names, antes): def parseAnteLine(line, isTourney, names, antes):
for i in xrange(len(names)): for i, name in enumerate(names):
if (line.startswith(names[i].encode("latin-1"))): #found the ante'er if line.startswith(name.encode("latin-1")):
pos=line.rfind("$")+1 pos = line.rfind("$") + 1
if not isTourney: if not isTourney:
antes[i]+=float2int(line[pos:]) antes[i] += float2int(line[pos:])
else: else:
if line.find("all-in")==-1: if "all-in" not in line:
pos=line.rfind(" ")+1 pos = line.rfind(" ") + 1
antes[i]+=int(line[pos:]) antes[i] += int(line[pos:])
else: else:
pos1=line.rfind("ante")+5 pos1 = line.rfind("ante") + 5
pos2=line.find(" ",pos1) pos2 = line.find(" ", pos1)
antes[i]+=int(line[pos1:pos2]) antes[i] += int(line[pos1:pos2])
#print "parseAnteLine line: ", line, "antes[i]", antes[i], "antes", antes #print "parseAnteLine line: ", line, "antes[i]", antes[i], "antes", antes
#end def parseAntes #end def parseAntes
#returns the buyin of a tourney in cents #returns the buyin of a tourney in cents
def parseBuyin(topline): def parseBuyin(topline):
pos1=topline.find("$")+1 pos1 = topline.find("$")+1
pos2=topline.find("+") pos2 = topline.find("+")
return float2int(topline[pos1:pos2]) return float2int(topline[pos1:pos2])
#end def parseBuyin #end def parseBuyin
#parses a card line and changes the passed arrays accordingly #parses a card line and changes the passed arrays accordingly
#todo: reorganise this messy method #todo: reorganise this messy method
def parseCardLine(category, street, line, names, cardValues, cardSuits, boardValues, boardSuits): def parseCardLine(category, street, line, names, cardValues, cardSuits, boardValues, boardSuits):
if (line.startswith("Dealt to ") or line.find(" shows [")!=-1 or line.find("mucked [")!=-1): if line.startswith("Dealt to") or " shows [" in line or "mucked [" in line:
playerNo=recognisePlayerNo(line, names, "card") #anything but unbet will be ok for that string playerNo = recognisePlayerNo(line, names, "card") #anything but unbet will be ok for that string
pos=line.rfind("[")+1 pos = line.rfind("[")+1
if (category=="holdem"): if category == "holdem":
for i in (pos, pos+3): for i in (pos, pos+3):
cardValues[playerNo].append(line[i:i+1]) cardValues[playerNo].append(line[i:i+1])
cardSuits[playerNo].append(line[i+1:i+2]) cardSuits[playerNo].append(line[i+1:i+2])
if (len(cardValues[playerNo])!=2): if len(cardValues[playerNo]) !=2:
if cardValues[playerNo][0]==cardValues[playerNo][2] and cardSuits[playerNo][1]==cardSuits[playerNo][3]: #two tests will do if cardValues[playerNo][0]==cardValues[playerNo][2] and cardSuits[playerNo][1]==cardSuits[playerNo][3]: #two tests will do
cardValues[playerNo]=cardValues[playerNo][0:2] cardValues[playerNo]=cardValues[playerNo][0:2]
cardSuits[playerNo]=cardSuits[playerNo][0:2] cardSuits[playerNo]=cardSuits[playerNo][0:2]
else: else:
print "line:",line,"cardValues[playerNo]:",cardValues[playerNo] print "line:",line,"cardValues[playerNo]:",cardValues[playerNo]
raise FpdbError("read too many/too few holecards in parseCardLine") raise FpdbError("read too many/too few holecards in parseCardLine")
elif (category=="omahahi" or category=="omahahilo"): elif category == "omahahi" or category == "omahahilo":
for i in (pos, pos+3, pos+6, pos+9): for i in (pos, pos+3, pos+6, pos+9):
cardValues[playerNo].append(line[i:i+1]) cardValues[playerNo].append(line[i:i+1])
cardSuits[playerNo].append(line[i+1:i+2]) cardSuits[playerNo].append(line[i+1:i+2])
@ -1024,8 +947,8 @@ def parseCardLine(category, street, line, names, cardValues, cardSuits, boardVal
else: else:
print "line:",line,"cardValues[playerNo]:",cardValues[playerNo] print "line:",line,"cardValues[playerNo]:",cardValues[playerNo]
raise FpdbError("read too many/too few holecards in parseCardLine") raise FpdbError("read too many/too few holecards in parseCardLine")
elif (category=="razz" or category=="studhi" or category=="studhilo"): elif category=="razz" or category=="studhi" or category=="studhilo":
if (line.find("shows")==-1 and line.find("mucked")==-1): if "shows" not in line and "mucked" not in line:
#print "parseCardLine(in stud if), street:", street #print "parseCardLine(in stud if), street:", street
if line[pos+2]=="]": #-> not (hero and 3rd street) if line[pos+2]=="]": #-> not (hero and 3rd street)
cardValues[playerNo][street+2]=line[pos:pos+1] cardValues[playerNo][street+2]=line[pos:pos+1]
@ -1145,12 +1068,8 @@ def parseNames(lines):
return result return result
#end def parseNames #end def parseNames
#returns an array with the positions of the respective players def parsePositions(hand, names):
def parsePositions (hand, names): positions = map(lambda x: -1, names)
#prep array
positions=[]
for i in xrange(len(names)):
positions.append(-1)
#find blinds #find blinds
sb,bb=-1,-1 sb,bb=-1,-1
@ -1162,8 +1081,8 @@ def parsePositions (hand, names):
bb=hand[i] bb=hand[i]
#print "bb:",bb #print "bb:",bb
#identify blinds #identify blinds
#print "parsePositions before recognising sb/bb. names:",names #print "parsePositions before recognising sb/bb. names:",names
sbExists=True sbExists=True
if (sb!=-1): if (sb!=-1):
sb=recognisePlayerNo(sb, names, "bet") sb=recognisePlayerNo(sb, names, "bet")
@ -1276,17 +1195,19 @@ def parseWinLine(line, names, winnings, isTourney):
#returns the category (as per database) string for the given line #returns the category (as per database) string for the given line
def recogniseCategory(line): def recogniseCategory(line):
if (line.find("Razz")!=-1): if "Razz" in line:
return "razz" return "razz"
elif (line.find("Hold'em")!=-1): elif "Hold'em" in line:
return "holdem" return "holdem"
elif (line.find("Omaha")!=-1 and line.find("Hi/Lo")==-1 and line.find("H/L")==-1): elif "Omaha" in line:
if "Hi/Lo" not in line and "H/L" not in line:
return "omahahi" return "omahahi"
elif (line.find("Omaha")!=-1 and (line.find("Hi/Lo")!=-1 or line.find("H/L")!=-1)): else:
return "omahahilo" return "omahahilo"
elif (line.find("Stud")!=-1 and line.find("Hi/Lo")==-1 and line.find("H/L")==-1): elif "Stud" in line:
if "Hi/Lo" not in line and "H/L" not in line:
return "studhi" return "studhi"
elif (line.find("Stud")!=-1 and (line.find("Hi/Lo")!=-1 or line.find("H/L")!=-1)): else:
return "studhilo" return "studhilo"
else: else:
raise FpdbError("failed to recognise category, line:"+line) raise FpdbError("failed to recognise category, line:"+line)
@ -1678,19 +1599,20 @@ sure to also change the following storage method and table_viewer.prepare_data i
firstPfRaiserNo=-1 firstPfRaiserNo=-1
firstPfCallByNo=-1 firstPfCallByNo=-1
firstPfCallerId=-1 firstPfCallerId=-1
for i in xrange(len(actionTypeByNo[0])):
if actionTypeByNo[0][i][1]=="bet": for i, action in enumerate(actionTypeByNo[0]):
firstPfRaiseByNo=i if action[1] == "bet":
firstPfRaiserId=actionTypeByNo[0][i][0] firstPfRaiseByNo = i
for j in xrange(len(player_ids)): firstPfRaiserId = action[0]
if player_ids[j]==firstPfRaiserId: for j, pid in enumerate(player_ids):
firstPfRaiserNo=j if pid == firstPfRaiserId:
firstPfRaiserNo = j
break break
break break
for i in xrange(len(actionTypeByNo[0])): for i, action in enumerate(actionTypeByNo[0]):
if actionTypeByNo[0][i][1]=="call": if action[1] == "call":
firstPfCallByNo=i firstPfCallByNo = i
firstPfCallerId=actionTypeByNo[0][i][0] firstPfCallerId = action[0]
break break
cutoffId=-1 cutoffId=-1
@ -1698,15 +1620,15 @@ sure to also change the following storage method and table_viewer.prepare_data i
sbId=-1 sbId=-1
bbId=-1 bbId=-1
if base=="hold": if base=="hold":
for player in xrange(len(positions)): for player, pos in enumerate(positions):
if positions==1: if pos == 1:
cutoffId=player_ids[player] cutoffId = player_ids[player]
if positions==0: if pos == 0:
buttonId=player_ids[player] buttonId = player_ids[player]
if positions=='S': if pos == 'S':
sbId=player_ids[player] sbId = player_ids[player]
if positions=='B': if pos == 'B':
bbId=player_ids[player] bbId = player_ids[player]
someoneStole=False someoneStole=False
@ -1742,30 +1664,29 @@ sure to also change the following storage method and table_viewer.prepare_data i
#calculate VPIP and PFR #calculate VPIP and PFR
street=0 street=0
heroPfRaiseCount=0 heroPfRaiseCount=0
for count in xrange(len(action_types[street][player])):#finally individual actions for currentAction in action_types[street][player]: # finally individual actions
currentAction=action_types[street][player][count] if currentAction == "bet":
if currentAction=="bet": myStreet0Aggr = True
myStreet0Aggr=True if currentAction == "bet" or currentAction == "call":
if (currentAction=="bet" or currentAction=="call"): myStreet0VPI = True
myStreet0VPI=True
#PF3B4BChance and PF3B4B #PF3B4BChance and PF3B4B
pfFold=-1 pfFold=-1
pfRaise=-1 pfRaise=-1
if firstPfRaiseByNo!=-1: if firstPfRaiseByNo != -1:
for i in xrange(len(actionTypeByNo[0])): for i, actionType in enumerate(actionTypeByNo[0]):
if actionTypeByNo[0][i][0]==player_ids[player]: if actionType[0] == player_ids[player]:
if actionTypeByNo[0][i][1]=="bet" and pfRaise==-1 and i>firstPfRaiseByNo: if actionType[1] == "bet" and pfRaise == -1 and i > firstPfRaiseByNo:
pfRaise=i pfRaise = i
if actionTypeByNo[0][i][1]=="fold" and pfFold==-1: if actionType[1] == "fold" and pfFold == -1:
pfFold=i pfFold = i
if pfFold==-1 or pfFold>firstPfRaiseByNo: if pfFold == -1 or pfFold > firstPfRaiseByNo:
myStreet0_3B4BChance=True myStreet0_3B4BChance = True
if pfRaise>firstPfRaiseByNo: if pfRaise > firstPfRaiseByNo:
myStreet0_3B4BDone=True myStreet0_3B4BDone = True
#steal calculations #steal calculations
if base=="hold": if base == "hold":
if len(player_ids)>=5: #no point otherwise if len(player_ids)>=5: #no point otherwise
if positions[player]==1: if positions[player]==1:
if firstPfRaiserId==player_ids[player]: if firstPfRaiserId==player_ids[player]:
@ -1793,52 +1714,45 @@ sure to also change the following storage method and table_viewer.prepare_data i
#calculate saw* values #calculate saw* values
isAllIn=False isAllIn = False
for i in xrange(len(allIns[0][player])): if any(i for i in allIns[0][player]):
if allIns[0][player][i]: isAllIn = True
isAllIn=True
if (len(action_types[1][player])>0 or isAllIn): if (len(action_types[1][player])>0 or isAllIn):
myStreet1Seen=True myStreet1Seen = True
for i in xrange(len(allIns[1][player])): if any(i for i in allIns[1][player]):
if allIns[1][player][i]: isAllIn = True
isAllIn=True
if (len(action_types[2][player])>0 or isAllIn): if (len(action_types[2][player])>0 or isAllIn):
myStreet2Seen=True myStreet2Seen = True
for i in xrange(len(allIns[2][player])): if any(i for i in allIns[2][player]):
if allIns[2][player][i]: isAllIn = True
isAllIn=True
if (len(action_types[3][player])>0 or isAllIn): if (len(action_types[3][player])>0 or isAllIn):
myStreet3Seen=True myStreet3Seen = True
#print "base:", base #print "base:", base
if base=="hold": if base=="hold":
mySawShowdown=True mySawShowdown = True
for count in xrange(len(action_types[3][player])): if any(actiontype == "fold" for actiontype in action_types[3][player]):
if action_types[3][player][count]=="fold": mySawShowdown = False
mySawShowdown=False
else: else:
#print "in else" #print "in else"
for i in xrange(len(allIns[3][player])): if any(i for i in allIns[3][player]):
if allIns[3][player][i]: isAllIn = True
isAllIn=True
if (len(action_types[4][player])>0 or isAllIn): if (len(action_types[4][player])>0 or isAllIn):
#print "in if" #print "in if"
myStreet4Seen=True myStreet4Seen = True
mySawShowdown=True mySawShowdown = True
for count in xrange(len(action_types[4][player])): if any(actiontype == "fold" for actiontype in action_types[4][player]):
if action_types[4][player][count]=="fold": mySawShowdown = False
mySawShowdown=False
#flop stuff #flop stuff
street=1 street=1
if myStreet1Seen: if myStreet1Seen:
for count in xrange(len(action_types[street][player])): if any(actiontype == "bet" for actiontype in action_types[street][player]):
if action_types[street][player][count]=="bet": myStreet1Aggr = True
myStreet1Aggr=True
for otherPlayer in xrange(len(player_ids)): for otherPlayer in xrange(len(player_ids)):
if player==otherPlayer: if player==otherPlayer:
@ -1854,9 +1768,8 @@ sure to also change the following storage method and table_viewer.prepare_data i
#turn stuff - copy of flop with different vars #turn stuff - copy of flop with different vars
street=2 street=2
if myStreet2Seen: if myStreet2Seen:
for count in xrange(len(action_types[street][player])): if any(actiontype == "bet" for actiontype in action_types[street][player]):
if action_types[street][player][count]=="bet": myStreet2Aggr = True
myStreet2Aggr=True
for otherPlayer in xrange(len(player_ids)): for otherPlayer in xrange(len(player_ids)):
if player==otherPlayer: if player==otherPlayer:
@ -1872,9 +1785,8 @@ sure to also change the following storage method and table_viewer.prepare_data i
#river stuff - copy of flop with different vars #river stuff - copy of flop with different vars
street=3 street=3
if myStreet3Seen: if myStreet3Seen:
for count in xrange(len(action_types[street][player])): if any(actiontype == "bet" for actiontype in action_types[street][player]):
if action_types[street][player][count]=="bet": myStreet3Aggr = True
myStreet3Aggr=True
for otherPlayer in xrange(len(player_ids)): for otherPlayer in xrange(len(player_ids)):
if player==otherPlayer: if player==otherPlayer:
@ -1890,8 +1802,7 @@ sure to also change the following storage method and table_viewer.prepare_data i
#stud river stuff - copy of flop with different vars #stud river stuff - copy of flop with different vars
street=4 street=4
if myStreet4Seen: if myStreet4Seen:
for count in xrange(len(action_types[street][player])): if any(actiontype == "bet" for actiontype in action_types[street][player]):
if action_types[street][player][count]=="bet":
myStreet4Aggr=True myStreet4Aggr=True
for otherPlayer in xrange(len(player_ids)): for otherPlayer in xrange(len(player_ids)):
@ -1905,9 +1816,9 @@ sure to also change the following storage method and table_viewer.prepare_data i
if action_types[street][player][countOtherFold]=="fold": if action_types[street][player][countOtherFold]=="fold":
myFoldToOtherRaisedStreet4=True myFoldToOtherRaisedStreet4=True
if winnings[player]!=0: if winnings[player] != 0:
if myStreet1Seen: if myStreet1Seen:
myWonWhenSeenStreet1=winnings[player]/float(totalWinnings) myWonWhenSeenStreet1 = winnings[player] / float(totalWinnings)
if mySawShowdown: if mySawShowdown:
myWonAtSD=myWonWhenSeenStreet1 myWonAtSD=myWonWhenSeenStreet1

View File

@ -4,7 +4,10 @@ from Hand import *
import py import py
#regression-test-files/stars/badugi/ring-fl-badugi.txt #regression-test-files/stars/badugi/ring-fl-badugi.txt
# s0rrow: start $30.00 end: $22.65 total: ($7.35) # s0rrow: input: $30.00 end: $22.65 total: ($7.35)
#regression-test-files/stars/plo/PLO-6max.txt
# s0rrow: input: $18.35 end: $0 total: ($18.35)
# Notes: last hand #25975302416 s0rrow aifp against 2 players
gametype = {'type':'ring', 'base':'draw', 'category':'badugi', 'limitType':'fl', 'sb':'0.25', 'bb':'0.50','currency':'USD'} gametype = {'type':'ring', 'base':'draw', 'category':'badugi', 'limitType':'fl', 'sb':'0.25', 'bb':'0.50','currency':'USD'}
text = "" text = ""
@ -30,7 +33,10 @@ def testGameInfo():
{'type':'ring', 'base':'hold', 'category':'omahahilo', 'limitType':'fl', 'sb':'2', 'bb':'4','currency':'USD'}), {'type':'ring', 'base':'hold', 'category':'omahahilo', 'limitType':'fl', 'sb':'2', 'bb':'4','currency':'USD'}),
(u"PokerStars Game #25923772706: Badugi Limit ($0.25/$0.50) - 2009/03/13 16:40:58 ET", (u"PokerStars Game #25923772706: Badugi Limit ($0.25/$0.50) - 2009/03/13 16:40:58 ET",
{'type':'ring', 'base':'draw', 'category':'badugi', 'limitType':'fl', 'sb':'0.25', 'bb':'0.50','currency':'USD'}) {'type':'ring', 'base':'draw', 'category':'badugi', 'limitType':'fl', 'sb':'0.25', 'bb':'0.50','currency':'USD'}),
(u"PokerStars Game #25974627364: Omaha Pot Limit ($0.05/$0.10) - 2009/03/15 0:29:00 ET",
{'type':'ring', 'base':'hold', 'category':'omahahi', 'limitType':'pl', 'sb':'0.05', 'bb':'0.10','currency':'USD'})
) )
for (header, info) in pairs: for (header, info) in pairs:
yield checkGameInfo, hhc, header, info yield checkGameInfo, hhc, header, info