Merge branch 'master' of git://git.assembla.com/fpdboz
This commit is contained in:
commit
2856b90828
|
@ -1,5 +1,5 @@
|
||||||
README.txt
|
README.txt
|
||||||
updated 26 March 2009, REB
|
updated 22 February 2010, REB
|
||||||
|
|
||||||
fpdb - Free Poker Database
|
fpdb - Free Poker Database
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ fpdb supports:
|
||||||
Omaha (incl Hi/low)
|
Omaha (incl Hi/low)
|
||||||
7 Card Stud (incl Hi/low)
|
7 Card Stud (incl Hi/low)
|
||||||
Razz
|
Razz
|
||||||
Draw support is under development
|
Triple Draw and Badugi
|
||||||
Mixed Games -- HUD under development
|
Mixed Games -- HUD under development
|
||||||
|
|
||||||
Operating Systems:
|
Operating Systems:
|
||||||
|
@ -38,23 +38,38 @@ fpdb supports:
|
||||||
Mac OS/X -- no support for HUD
|
Mac OS/X -- no support for HUD
|
||||||
|
|
||||||
Databases:
|
Databases:
|
||||||
|
SQLite configured by default
|
||||||
MySQL
|
MySQL
|
||||||
PostgreSQL
|
PostgreSQL
|
||||||
SQLite under development
|
|
||||||
|
|
||||||
Downloads:
|
Downloads:
|
||||||
Releases: http://sourceforge.net/project/showfiles.php?group_id=226872
|
Releases: http://sourceforge.net/project/showfiles.php?group_id=226872
|
||||||
Development code via git: http://www.assembla.com/spaces/free_poker_tools/trac_git_tool
|
Development code via git: http://www.assembla.com/spaces/free_poker_tools/trac_git_tool
|
||||||
|
|
||||||
Developers:
|
Developers:
|
||||||
At least 7 people have contributed code or patches. Others are welcome.
|
At least 10 people have contributed code or patches. Others are welcome.
|
||||||
|
|
||||||
|
Source Code:
|
||||||
|
If you received fpdb as the Windows compressed exe, then you did not
|
||||||
|
receive souce code for fpdb or the included libraries. If you wish, you can
|
||||||
|
obtain the source code here:
|
||||||
|
|
||||||
|
fpdb: see Downloads, above.
|
||||||
|
python: http://python.org/
|
||||||
|
gtk: http://www.gtk.org/download.html
|
||||||
|
pygtk: http://www.pygtk.org/downloads.html
|
||||||
|
psycopg2: http://initd.org/pub/software/psycopg/
|
||||||
|
mysqldb: http://sourceforge.net/projects/mysql-python/files/
|
||||||
|
sqlalchemy: http://www.sqlalchemy.org/download.html
|
||||||
|
numpy: http://www.scipy.org/Download
|
||||||
|
matplotlib: http://sourceforge.net/projects/matplotlib/files/
|
||||||
|
|
||||||
License
|
License
|
||||||
=======
|
=======
|
||||||
Trademarks of third parties have been used under Fair Use or similar laws.
|
Trademarks of third parties have been used under Fair Use or similar laws.
|
||||||
|
|
||||||
Copyright 2008 Steffen Jobbagy-Felso
|
Copyright 2008 Steffen Jobbagy-Felso
|
||||||
Copyright 2009 Ray E. Barker
|
Copyright 2009,2010 Ray E. Barker
|
||||||
Permission is granted to copy, distribute and/or modify this
|
Permission is granted to copy, distribute and/or modify this
|
||||||
document under the terms of the GNU Free Documentation License,
|
document under the terms of the GNU Free Documentation License,
|
||||||
Version 1.2 as published by the Free Software Foundation; with
|
Version 1.2 as published by the Free Software Foundation; with
|
||||||
|
|
|
@ -414,6 +414,7 @@ class Import:
|
||||||
self.hhArchiveBase = node.getAttribute("hhArchiveBase")
|
self.hhArchiveBase = node.getAttribute("hhArchiveBase")
|
||||||
self.saveActions = string_to_bool(node.getAttribute("saveActions"), default=True)
|
self.saveActions = string_to_bool(node.getAttribute("saveActions"), default=True)
|
||||||
self.fastStoreHudCache = string_to_bool(node.getAttribute("fastStoreHudCache"), default=False)
|
self.fastStoreHudCache = string_to_bool(node.getAttribute("fastStoreHudCache"), default=False)
|
||||||
|
self.saveStarsHH = string_to_bool(node.getAttribute("saveStarsHH"), default=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return " interval = %s\n callFpdbHud = %s\n hhArchiveBase = %s\n saveActions = %s\n fastStoreHudCache = %s\n" \
|
return " interval = %s\n callFpdbHud = %s\n hhArchiveBase = %s\n saveActions = %s\n fastStoreHudCache = %s\n" \
|
||||||
|
@ -469,7 +470,8 @@ class Config:
|
||||||
|
|
||||||
self.file = file
|
self.file = file
|
||||||
self.dir_self = get_exec_path()
|
self.dir_self = get_exec_path()
|
||||||
self.dir_config = os.path.dirname(self.file)
|
# self.dir_config = os.path.dirname(self.file)
|
||||||
|
self.dir_config = get_default_config_path()
|
||||||
self.dir_log = os.path.join(self.dir_config, 'log')
|
self.dir_log = os.path.join(self.dir_config, 'log')
|
||||||
self.dir_database = os.path.join(self.dir_config, 'database')
|
self.dir_database = os.path.join(self.dir_config, 'database')
|
||||||
self.log_file = os.path.join(self.dir_log, 'fpdb-log.txt')
|
self.log_file = os.path.join(self.dir_log, 'fpdb-log.txt')
|
||||||
|
@ -822,8 +824,12 @@ class Config:
|
||||||
try: imp['saveActions'] = self.imp.saveActions
|
try: imp['saveActions'] = self.imp.saveActions
|
||||||
except: imp['saveActions'] = True
|
except: imp['saveActions'] = True
|
||||||
|
|
||||||
|
try: imp['saveStarsHH'] = self.imp.saveStarsHH
|
||||||
|
except: imp['saveStarsHH'] = False
|
||||||
|
|
||||||
try: imp['fastStoreHudCache'] = self.imp.fastStoreHudCache
|
try: imp['fastStoreHudCache'] = self.imp.fastStoreHudCache
|
||||||
except: imp['fastStoreHudCache'] = True
|
except: imp['fastStoreHudCache'] = True
|
||||||
|
|
||||||
return imp
|
return imp
|
||||||
|
|
||||||
def get_default_paths(self, site = None):
|
def get_default_paths(self, site = None):
|
||||||
|
|
|
@ -917,7 +917,6 @@ class Database:
|
||||||
print "warning: constraint %s_%s_fkey not dropped: %s, continuing ..." \
|
print "warning: constraint %s_%s_fkey not dropped: %s, continuing ..." \
|
||||||
% (fk['fktab'],fk['fkcol'], str(sys.exc_value).rstrip('\n'))
|
% (fk['fktab'],fk['fkcol'], str(sys.exc_value).rstrip('\n'))
|
||||||
else:
|
else:
|
||||||
print "Only MySQL and Postgres supported so far"
|
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
for idx in self.indexes[self.backend]:
|
for idx in self.indexes[self.backend]:
|
||||||
|
@ -952,7 +951,6 @@ class Database:
|
||||||
print "warning: index %s_%s_idx not dropped %s, continuing ..." \
|
print "warning: index %s_%s_idx not dropped %s, continuing ..." \
|
||||||
% (idx['tab'],idx['col'], str(sys.exc_value).rstrip('\n'))
|
% (idx['tab'],idx['col'], str(sys.exc_value).rstrip('\n'))
|
||||||
else:
|
else:
|
||||||
print "Error: Only MySQL and Postgres supported so far"
|
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
if self.backend == self.PGSQL:
|
if self.backend == self.PGSQL:
|
||||||
|
@ -1007,7 +1005,6 @@ class Database:
|
||||||
except:
|
except:
|
||||||
print " create fk failed: " + str(sys.exc_info())
|
print " create fk failed: " + str(sys.exc_info())
|
||||||
else:
|
else:
|
||||||
print "Only MySQL and Postgres supported so far"
|
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
for idx in self.indexes[self.backend]:
|
for idx in self.indexes[self.backend]:
|
||||||
|
@ -1029,7 +1026,6 @@ class Database:
|
||||||
except:
|
except:
|
||||||
print " create index failed: " + str(sys.exc_info())
|
print " create index failed: " + str(sys.exc_info())
|
||||||
else:
|
else:
|
||||||
print "Only MySQL and Postgres supported so far"
|
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
if self.backend == self.PGSQL:
|
if self.backend == self.PGSQL:
|
||||||
|
|
|
@ -162,7 +162,7 @@ class DerivedStats():
|
||||||
self.handsplayers[player]['wonAtSD'] = 1.0
|
self.handsplayers[player]['wonAtSD'] = 1.0
|
||||||
|
|
||||||
for player in hand.pot.committed:
|
for player in hand.pot.committed:
|
||||||
self.handsplayers[player]['totalProfit'] = int(self.handsplayers[player]['winnings'] - (100*hand.pot.committed[player]))
|
self.handsplayers[player]['totalProfit'] = int(self.handsplayers[player]['winnings'] - (100*hand.pot.committed[player])- (100*hand.pot.common[player]))
|
||||||
|
|
||||||
self.calcCBets(hand)
|
self.calcCBets(hand)
|
||||||
|
|
||||||
|
@ -345,9 +345,9 @@ class DerivedStats():
|
||||||
for action in hand.actions[hand.actionStreets[1]]:
|
for action in hand.actions[hand.actionStreets[1]]:
|
||||||
# FIXME: fill other(3|4)BStreet0 - i have no idea what does it mean
|
# FIXME: fill other(3|4)BStreet0 - i have no idea what does it mean
|
||||||
pname, aggr = action[0], action[1] in ('raises', 'bets')
|
pname, aggr = action[0], action[1] in ('raises', 'bets')
|
||||||
self.handsplayers[pname]['street0_3BChance'] = bet_level == 2
|
self.handsplayers[pname]['street0_3BChance'] = self.handsplayers[pname]['street0_3BChance'] or bet_level == 2
|
||||||
self.handsplayers[pname]['street0_4BChance'] = bet_level == 3
|
self.handsplayers[pname]['street0_4BChance'] = bet_level == 3
|
||||||
self.handsplayers[pname]['street0_3BDone'] = aggr and (self.handsplayers[pname]['street0_3BChance'])
|
self.handsplayers[pname]['street0_3BDone'] = self.handsplayers[pname]['street0_3BDone'] or (aggr and self.handsplayers[pname]['street0_3BChance'])
|
||||||
self.handsplayers[pname]['street0_4BDone'] = aggr and (self.handsplayers[pname]['street0_4BChance'])
|
self.handsplayers[pname]['street0_4BDone'] = aggr and (self.handsplayers[pname]['street0_4BChance'])
|
||||||
if aggr:
|
if aggr:
|
||||||
bet_level += 1
|
bet_level += 1
|
||||||
|
|
|
@ -65,8 +65,8 @@ class Fulltilt(HandHistoryConverter):
|
||||||
(\s\((?P<TURBO>Turbo)\))?)|(?P<UNREADABLE_INFO>.+))
|
(\s\((?P<TURBO>Turbo)\))?)|(?P<UNREADABLE_INFO>.+))
|
||||||
''', re.VERBOSE)
|
''', re.VERBOSE)
|
||||||
re_Button = re.compile('^The button is in seat #(?P<BUTTON>\d+)', re.MULTILINE)
|
re_Button = re.compile('^The button is in seat #(?P<BUTTON>\d+)', re.MULTILINE)
|
||||||
re_PlayerInfo = re.compile('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.{3,15}) \(\$(?P<CASH>[,.0-9]+)\)$', re.MULTILINE)
|
re_PlayerInfo = re.compile('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.{2,15}) \(\$(?P<CASH>[,.0-9]+)\)$', re.MULTILINE)
|
||||||
re_TourneyPlayerInfo = re.compile('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.{3,15}) \(\$?(?P<CASH>[,.0-9]+)\)(, is sitting out)?$', re.MULTILINE)
|
re_TourneyPlayerInfo = re.compile('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.{2,15}) \(\$?(?P<CASH>[,.0-9]+)\)(, is sitting out)?$', re.MULTILINE)
|
||||||
re_Board = re.compile(r"\[(?P<CARDS>.+)\]")
|
re_Board = re.compile(r"\[(?P<CARDS>.+)\]")
|
||||||
|
|
||||||
#static regex for tourney purpose
|
#static regex for tourney purpose
|
||||||
|
@ -128,6 +128,7 @@ class Fulltilt(HandHistoryConverter):
|
||||||
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
|
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
|
||||||
logging.debug("player_re: " + player_re)
|
logging.debug("player_re: " + player_re)
|
||||||
self.re_PostSB = re.compile(r"^%s posts the small blind of \$?(?P<SB>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_PostSB = re.compile(r"^%s posts the small blind of \$?(?P<SB>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
|
self.re_PostDead = re.compile(r"^%s posts a dead small blind of \$?(?P<SB>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.re_PostBB = re.compile(r"^%s posts (the big blind of )?\$?(?P<BB>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_PostBB = re.compile(r"^%s posts (the big blind of )?\$?(?P<BB>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.re_Antes = re.compile(r"^%s antes \$?(?P<ANTE>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_Antes = re.compile(r"^%s antes \$?(?P<ANTE>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.re_BringIn = re.compile(r"^%s brings in for \$?(?P<BRINGIN>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_BringIn = re.compile(r"^%s brings in for \$?(?P<BRINGIN>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
|
@ -298,6 +299,8 @@ class Fulltilt(HandHistoryConverter):
|
||||||
hand.addBlind(m.group('PNAME'), 'small blind', m.group('SB'))
|
hand.addBlind(m.group('PNAME'), 'small blind', m.group('SB'))
|
||||||
except: # no small blind
|
except: # no small blind
|
||||||
hand.addBlind(None, None, None)
|
hand.addBlind(None, None, None)
|
||||||
|
for a in self.re_PostDead.finditer(hand.handText):
|
||||||
|
hand.addBlind(a.group('PNAME'), 'secondsb', a.group('SB'))
|
||||||
for a in self.re_PostBB.finditer(hand.handText):
|
for a in self.re_PostBB.finditer(hand.handText):
|
||||||
hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB'))
|
hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB'))
|
||||||
for a in self.re_PostBoth.finditer(hand.handText):
|
for a in self.re_PostBoth.finditer(hand.handText):
|
||||||
|
|
|
@ -81,7 +81,7 @@ class GuiPlayerStats (threading.Thread):
|
||||||
self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display)
|
self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display)
|
||||||
self.filters.registerButton1Name("_Filters")
|
self.filters.registerButton1Name("_Filters")
|
||||||
self.filters.registerButton1Callback(self.showDetailFilter)
|
self.filters.registerButton1Callback(self.showDetailFilter)
|
||||||
self.filters.registerButton2Name("_Refresh Stats")
|
self.filters.registerButton2Name("_Refresh")
|
||||||
self.filters.registerButton2Callback(self.refreshStats)
|
self.filters.registerButton2Callback(self.refreshStats)
|
||||||
|
|
||||||
# ToDo: store in config
|
# ToDo: store in config
|
||||||
|
@ -92,7 +92,7 @@ class GuiPlayerStats (threading.Thread):
|
||||||
, ["hand", False, "Hand", 0.0, "%s", "str"] # true not allowed for this line
|
, ["hand", False, "Hand", 0.0, "%s", "str"] # true not allowed for this line
|
||||||
, ["plposition", False, "Posn", 1.0, "%s", "str"] # true not allowed for this line (set in code)
|
, ["plposition", False, "Posn", 1.0, "%s", "str"] # true not allowed for this line (set in code)
|
||||||
, ["pname", False, "Name", 0.0, "%s", "str"] # true not allowed for this line (set in code)
|
, ["pname", False, "Name", 0.0, "%s", "str"] # true not allowed for this line (set in code)
|
||||||
, ["n", True, "Hds", 1.0, "%d", "str"]
|
, ["n", True, "Hds", 1.0, "%1.0f", "str"]
|
||||||
, ["avgseats", False, "Seats", 1.0, "%3.1f", "str"]
|
, ["avgseats", False, "Seats", 1.0, "%3.1f", "str"]
|
||||||
, ["vpip", True, "VPIP", 1.0, "%3.1f", "str"]
|
, ["vpip", True, "VPIP", 1.0, "%3.1f", "str"]
|
||||||
, ["pfr", True, "PFR", 1.0, "%3.1f", "str"]
|
, ["pfr", True, "PFR", 1.0, "%3.1f", "str"]
|
||||||
|
@ -482,6 +482,22 @@ class GuiPlayerStats (threading.Thread):
|
||||||
gametest = "and gt.category IS NULL"
|
gametest = "and gt.category IS NULL"
|
||||||
query = query.replace("<game_test>", gametest)
|
query = query.replace("<game_test>", gametest)
|
||||||
|
|
||||||
|
sitetest = ""
|
||||||
|
q = []
|
||||||
|
for m in self.filters.display.items():
|
||||||
|
if m[0] == 'Sites' and m[1]:
|
||||||
|
for n in sitenos:
|
||||||
|
q.append(n)
|
||||||
|
if len(q) > 0:
|
||||||
|
sitetest = str(tuple(q))
|
||||||
|
sitetest = sitetest.replace("L", "")
|
||||||
|
sitetest = sitetest.replace(",)",")")
|
||||||
|
sitetest = sitetest.replace("u'","'")
|
||||||
|
sitetest = "and gt.siteId in %s" % sitetest
|
||||||
|
else:
|
||||||
|
sitetest = "and gt.siteId IS NULL"
|
||||||
|
query = query.replace("<site_test>", sitetest)
|
||||||
|
|
||||||
if seats:
|
if seats:
|
||||||
query = query.replace('<seats_test>', 'between ' + str(seats['from']) + ' and ' + str(seats['to']))
|
query = query.replace('<seats_test>', 'between ' + str(seats['from']) + ' and ' + str(seats['to']))
|
||||||
if 'show' in seats and seats['show']:
|
if 'show' in seats and seats['show']:
|
||||||
|
@ -539,7 +555,7 @@ class GuiPlayerStats (threading.Thread):
|
||||||
query = query.replace("<orderbyhgameTypeId>", "")
|
query = query.replace("<orderbyhgameTypeId>", "")
|
||||||
groupLevels = "show" not in str(limits)
|
groupLevels = "show" not in str(limits)
|
||||||
if groupLevels:
|
if groupLevels:
|
||||||
query = query.replace("<hgameTypeId>", "p.name")
|
query = query.replace("<hgameTypeId>", "-1")
|
||||||
else:
|
else:
|
||||||
query = query.replace("<hgameTypeId>", "h.gameTypeId")
|
query = query.replace("<hgameTypeId>", "h.gameTypeId")
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ import Hud
|
||||||
|
|
||||||
|
|
||||||
# get config and set up logger
|
# get config and set up logger
|
||||||
c = Configuration.Config(file=options.config)
|
c = Configuration.Config(file=options.config, dbname=options.dbname)
|
||||||
log = Configuration.get_logger("logging.conf", "hud", log_dir=c.dir_log, log_file='HUD-log.txt')
|
log = Configuration.get_logger("logging.conf", "hud", log_dir=c.dir_log, log_file='HUD-log.txt')
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,14 +78,14 @@ class HUD_main(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not options.errorsToConsole:
|
if not options.errorsToConsole:
|
||||||
fileName = os.path.join(self.config.dir_log, 'HUD-errors.txt')
|
fileName = os.path.join(self.config.dir_log, 'HUD-errors.txt')
|
||||||
print "Note: error output is being diverted to:\n"+fileName \
|
print "Note: error output is being diverted to:\n"+fileName \
|
||||||
+ "\nAny major error will be reported there _only_.\n"
|
+ "\nAny major error will be reported there _only_.\n"
|
||||||
log.info("Note: error output is being diverted to:"+fileName)
|
log.info("Note: error output is being diverted to:"+fileName)
|
||||||
log.info("Any major error will be reported there _only_.")
|
log.info("Any major error will be reported there _only_.")
|
||||||
errorFile = open(fileName, 'w', 0)
|
errorFile = open(fileName, 'w', 0)
|
||||||
sys.stderr = errorFile
|
sys.stderr = errorFile
|
||||||
sys.stderr.write("HUD_main: starting ...\n")
|
sys.stderr.write("HUD_main: starting ...\n")
|
||||||
|
|
||||||
self.hud_dict = {}
|
self.hud_dict = {}
|
||||||
self.hud_params = self.config.get_hud_ui_parameters()
|
self.hud_params = self.config.get_hud_ui_parameters()
|
||||||
|
@ -237,7 +237,7 @@ class HUD_main(object):
|
||||||
try:
|
try:
|
||||||
(table_name, max, poker_game, type, site_id, site_name, num_seats, tour_number, tab_number) = \
|
(table_name, max, poker_game, type, site_id, site_name, num_seats, tour_number, tab_number) = \
|
||||||
self.db_connection.get_table_info(new_hand_id)
|
self.db_connection.get_table_info(new_hand_id)
|
||||||
except Exception, err:
|
except Exception:
|
||||||
log.error("db error: skipping %s" % new_hand_id)
|
log.error("db error: skipping %s" % new_hand_id)
|
||||||
continue
|
continue
|
||||||
t1 = time.time()
|
t1 = time.time()
|
||||||
|
|
|
@ -323,7 +323,9 @@ For sites (currently only Carbon Poker) which record "all in" as a special actio
|
||||||
self.stacks[player] -= Decimal(ante)
|
self.stacks[player] -= Decimal(ante)
|
||||||
act = (player, 'posts', "ante", ante, self.stacks[player]==0)
|
act = (player, 'posts', "ante", ante, self.stacks[player]==0)
|
||||||
self.actions['BLINDSANTES'].append(act)
|
self.actions['BLINDSANTES'].append(act)
|
||||||
self.pot.addMoney(player, Decimal(ante))
|
# self.pot.addMoney(player, Decimal(ante))
|
||||||
|
self.pot.addCommonMoney(player, Decimal(ante))
|
||||||
|
#I think the antes should be common money, don't have enough hand history to check
|
||||||
|
|
||||||
def addBlind(self, player, blindtype, amount):
|
def addBlind(self, player, blindtype, amount):
|
||||||
# if player is None, it's a missing small blind.
|
# if player is None, it's a missing small blind.
|
||||||
|
@ -342,14 +344,16 @@ For sites (currently only Carbon Poker) which record "all in" as a special actio
|
||||||
self.actions['BLINDSANTES'].append(act)
|
self.actions['BLINDSANTES'].append(act)
|
||||||
|
|
||||||
if blindtype == 'both':
|
if blindtype == 'both':
|
||||||
|
# work with the real ammount. limit games are listed as $1, $2, where
|
||||||
|
# the SB 0.50 and the BB is $1, after the turn the minimum bet amount is $2....
|
||||||
amount = self.bb
|
amount = self.bb
|
||||||
self.bets['BLINDSANTES'][player].append(Decimal(self.sb))
|
self.bets['BLINDSANTES'][player].append(Decimal(self.sb))
|
||||||
self.pot.addCommonMoney(Decimal(self.sb))
|
self.pot.addCommonMoney(player, Decimal(self.sb))
|
||||||
|
|
||||||
if blindtype == 'secondsb':
|
if blindtype == 'secondsb':
|
||||||
amount = Decimal(0)
|
amount = Decimal(0)
|
||||||
self.bets['BLINDSANTES'][player].append(Decimal(self.sb))
|
self.bets['BLINDSANTES'][player].append(Decimal(self.sb))
|
||||||
self.pot.addCommonMoney(Decimal(self.sb))
|
self.pot.addCommonMoney(player, Decimal(self.sb))
|
||||||
|
|
||||||
self.bets['PREFLOP'][player].append(Decimal(amount))
|
self.bets['PREFLOP'][player].append(Decimal(amount))
|
||||||
self.pot.addMoney(player, Decimal(amount))
|
self.pot.addMoney(player, Decimal(amount))
|
||||||
|
@ -513,9 +517,6 @@ Card ranks will be uppercased
|
||||||
for entry in self.collected:
|
for entry in self.collected:
|
||||||
self.totalcollected += Decimal(entry[1])
|
self.totalcollected += Decimal(entry[1])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def getGameTypeAsString(self):
|
def getGameTypeAsString(self):
|
||||||
"""\
|
"""\
|
||||||
Map the tuple self.gametype onto the pokerstars string describing it
|
Map the tuple self.gametype onto the pokerstars string describing it
|
||||||
|
@ -994,11 +995,12 @@ class DrawHand(Hand):
|
||||||
self.lastBet['DEAL'] = Decimal(amount)
|
self.lastBet['DEAL'] = Decimal(amount)
|
||||||
elif blindtype == 'both':
|
elif blindtype == 'both':
|
||||||
# extra small blind is 'dead'
|
# extra small blind is 'dead'
|
||||||
self.lastBet['DEAL'] = Decimal(self.bb)
|
amount = Decimal(amount)/3
|
||||||
|
amount += amount
|
||||||
|
self.lastBet['DEAL'] = Decimal(amount)
|
||||||
self.posted = self.posted + [[player,blindtype]]
|
self.posted = self.posted + [[player,blindtype]]
|
||||||
#print "DEBUG: self.posted: %s" %(self.posted)
|
#print "DEBUG: self.posted: %s" %(self.posted)
|
||||||
|
|
||||||
|
|
||||||
def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False):
|
def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False):
|
||||||
if player == self.hero: # we have hero's cards just update shown/mucked
|
if player == self.hero: # we have hero's cards just update shown/mucked
|
||||||
if shown: self.shown.add(player)
|
if shown: self.shown.add(player)
|
||||||
|
@ -1413,7 +1415,7 @@ class Pot(object):
|
||||||
self.contenders = set()
|
self.contenders = set()
|
||||||
self.committed = {}
|
self.committed = {}
|
||||||
self.streettotals = {}
|
self.streettotals = {}
|
||||||
self.common = Decimal(0)
|
self.common = {}
|
||||||
self.total = None
|
self.total = None
|
||||||
self.returned = {}
|
self.returned = {}
|
||||||
self.sym = u'$' # this is the default currency symbol
|
self.sym = u'$' # this is the default currency symbol
|
||||||
|
@ -1423,13 +1425,14 @@ class Pot(object):
|
||||||
|
|
||||||
def addPlayer(self,player):
|
def addPlayer(self,player):
|
||||||
self.committed[player] = Decimal(0)
|
self.committed[player] = Decimal(0)
|
||||||
|
self.common[player] = Decimal(0)
|
||||||
|
|
||||||
def addFold(self, player):
|
def addFold(self, player):
|
||||||
# addFold must be called when a player folds
|
# addFold must be called when a player folds
|
||||||
self.contenders.discard(player)
|
self.contenders.discard(player)
|
||||||
|
|
||||||
def addCommonMoney(self, amount):
|
def addCommonMoney(self, player, amount):
|
||||||
self.common += amount
|
self.common[player] += amount
|
||||||
|
|
||||||
def addMoney(self, player, amount):
|
def addMoney(self, player, amount):
|
||||||
# addMoney must be called for any actions that put money in the pot, in the order they occur
|
# addMoney must be called for any actions that put money in the pot, in the order they occur
|
||||||
|
@ -1437,7 +1440,7 @@ class Pot(object):
|
||||||
self.committed[player] += amount
|
self.committed[player] += amount
|
||||||
|
|
||||||
def markTotal(self, street):
|
def markTotal(self, street):
|
||||||
self.streettotals[street] = sum(self.committed.values()) + self.common
|
self.streettotals[street] = sum(self.committed.values()) + sum(self.common.values())
|
||||||
|
|
||||||
def getTotalAtStreet(self, street):
|
def getTotalAtStreet(self, street):
|
||||||
if street in self.streettotals:
|
if street in self.streettotals:
|
||||||
|
@ -1445,11 +1448,11 @@ class Pot(object):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def end(self):
|
def end(self):
|
||||||
self.total = sum(self.committed.values()) + self.common
|
self.total = sum(self.committed.values()) + sum(self.common.values())
|
||||||
|
|
||||||
# Return any uncalled bet.
|
# Return any uncalled bet.
|
||||||
committed = sorted([ (v,k) for (k,v) in self.committed.items()])
|
committed = sorted([ (v,k) for (k,v) in self.committed.items()])
|
||||||
print "DEBUG: committed: %s" % committed
|
#print "DEBUG: committed: %s" % committed
|
||||||
#ERROR below. lastbet is correct in most cases, but wrong when
|
#ERROR below. lastbet is correct in most cases, but wrong when
|
||||||
# additional money is committed to the pot in cash games
|
# additional money is committed to the pot in cash games
|
||||||
# due to an additional sb being posted. (Speculate that
|
# due to an additional sb being posted. (Speculate that
|
||||||
|
|
|
@ -69,6 +69,7 @@ out_path (default '-' = sys.stdout)
|
||||||
follow : whether to tail -f the input"""
|
follow : whether to tail -f the input"""
|
||||||
|
|
||||||
self.config = config
|
self.config = config
|
||||||
|
self.import_parameters = self.config.get_import_parameters()
|
||||||
#log = Configuration.get_logger("logging.conf", "parser", log_dir=self.config.dir_log)
|
#log = Configuration.get_logger("logging.conf", "parser", log_dir=self.config.dir_log)
|
||||||
log.info("HandHistory init - %s subclass, in_path '%s'; out_path '%s'" % (self.sitename, in_path, out_path) )
|
log.info("HandHistory init - %s subclass, in_path '%s'; out_path '%s'" % (self.sitename, in_path, out_path) )
|
||||||
|
|
||||||
|
@ -87,12 +88,8 @@ follow : whether to tail -f the input"""
|
||||||
|
|
||||||
if in_path == '-':
|
if in_path == '-':
|
||||||
self.in_fh = sys.stdin
|
self.in_fh = sys.stdin
|
||||||
|
self.out_fh = get_out_fh(out_path, self.import_parameters)
|
||||||
|
|
||||||
if out_path == '-':
|
|
||||||
self.out_fh = sys.stdout
|
|
||||||
else:
|
|
||||||
# TODO: out_path should be sanity checked.
|
|
||||||
self.out_fh = sys.stdout
|
|
||||||
self.follow = follow
|
self.follow = follow
|
||||||
self.compiledPlayers = set()
|
self.compiledPlayers = set()
|
||||||
self.maxseats = 10
|
self.maxseats = 10
|
||||||
|
@ -446,8 +443,8 @@ or None if we fail to get the info """
|
||||||
def guessMaxSeats(self, hand):
|
def guessMaxSeats(self, hand):
|
||||||
"""Return a guess at maxseats when not specified in HH."""
|
"""Return a guess at maxseats when not specified in HH."""
|
||||||
# if some other code prior to this has already set it, return it
|
# if some other code prior to this has already set it, return it
|
||||||
if maxseats > 1 and maxseats < 11:
|
if self.maxseats > 1 and self.maxseats < 11:
|
||||||
return maxseats
|
return self.maxseats
|
||||||
mo = self.maxOccSeat(hand)
|
mo = self.maxOccSeat(hand)
|
||||||
|
|
||||||
if mo == 10: return 10 #that was easy
|
if mo == 10: return 10 #that was easy
|
||||||
|
@ -515,3 +512,23 @@ def getSiteHhc(config, sitename):
|
||||||
hhcName = config.supported_sites[sitename].converter
|
hhcName = config.supported_sites[sitename].converter
|
||||||
hhcModule = __import__(hhcName)
|
hhcModule = __import__(hhcName)
|
||||||
return getattr(hhcModule, hhcName[:-6])
|
return getattr(hhcModule, hhcName[:-6])
|
||||||
|
|
||||||
|
def get_out_fh(out_path, parameters):
|
||||||
|
if out_path == '-':
|
||||||
|
return(sys.stdout)
|
||||||
|
elif parameters['saveStarsHH']:
|
||||||
|
out_dir = os.path.dirname(out_path)
|
||||||
|
if not os.path.isdir(out_dir) and out_dir != '':
|
||||||
|
try:
|
||||||
|
os.makedirs(out_dir)
|
||||||
|
except: # we get a WindowsError here in Windows.. pretty sure something else for Linux :D
|
||||||
|
log.error("Unable to create output directory %s for HHC!" % out_dir)
|
||||||
|
print "*** ERROR: UNABLE TO CREATE OUTPUT DIRECTORY", out_dir
|
||||||
|
else:
|
||||||
|
log.info("Created directory '%s'" % out_dir)
|
||||||
|
try:
|
||||||
|
return(codecs.open(out_path, 'w', 'utf8'))
|
||||||
|
except:
|
||||||
|
log.error("out_path %s couldn't be opened" % (out_path))
|
||||||
|
else:
|
||||||
|
return(sys.stdout)
|
||||||
|
|
|
@ -27,7 +27,7 @@ def fpdb_options():
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="If passed error output will go to the console rather than .")
|
help="If passed error output will go to the console rather than .")
|
||||||
parser.add_option("-d", "--databaseName",
|
parser.add_option("-d", "--databaseName",
|
||||||
dest="dbname", default="fpdb",
|
dest="dbname",
|
||||||
help="Overrides the default database name")
|
help="Overrides the default database name")
|
||||||
parser.add_option("-c", "--configFile",
|
parser.add_option("-c", "--configFile",
|
||||||
dest="config", default=None,
|
dest="config", default=None,
|
||||||
|
|
|
@ -465,8 +465,9 @@ class PartyPoker(HandHistoryConverter):
|
||||||
def getTableTitleRe(type, table_name=None, tournament = None, table_number=None):
|
def getTableTitleRe(type, table_name=None, tournament = None, table_number=None):
|
||||||
"Returns string to search in windows titles"
|
"Returns string to search in windows titles"
|
||||||
if type=="tour":
|
if type=="tour":
|
||||||
print 'party', 'getTableTitleRe', "%s.+Table\s#%s" % (table_name, table_number)
|
TableName = table_name.split(" ")
|
||||||
return "%s.+Table\s#%s" % (table_name, table_number)
|
print 'party', 'getTableTitleRe', "%s.+Table\s#%s" % (TableName[0], table_number)
|
||||||
|
return "%s.+Table\s#%s" % (TableName[0], table_number)
|
||||||
else:
|
else:
|
||||||
print 'party', 'getTableTitleRe', table_number
|
print 'party', 'getTableTitleRe', table_number
|
||||||
return table_name
|
return table_name
|
||||||
|
|
30
pyfpdb/PokerStarsToFpdb.py
Executable file → Normal file
30
pyfpdb/PokerStarsToFpdb.py
Executable file → Normal file
|
@ -140,6 +140,14 @@ class PokerStars(HandHistoryConverter):
|
||||||
|
|
||||||
mg = m.groupdict()
|
mg = m.groupdict()
|
||||||
# translations from captured groups to fpdb info strings
|
# translations from captured groups to fpdb info strings
|
||||||
|
Lim_Blinds = { '0.04': ('0.01', '0.02'), '0.10': ('0.02', '0.05'), '0.20': ('0.05', '0.10'),
|
||||||
|
'0.50': ('0.10', '0.25'), '1.00': ('0.25', '0.50'), '2.00': ('0.50', '1.00'),
|
||||||
|
'4.00': ('1.00', '2.00'), '6.00': ('1.00', '3.00'), '10.00': ('2.00', '5.00'),
|
||||||
|
'20.00': ('5.00', '10.00'), '30.00': ('10.00', '15.00'), '60.00': ('15.00', '30.00'),
|
||||||
|
'100.00': ('25.00', '50.00'),'200.00': ('50.00', '100.00'),'400.00': ('100.00', '200.00'),
|
||||||
|
'1000.00': ('250.00', '500.00')}
|
||||||
|
|
||||||
|
|
||||||
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'),
|
||||||
|
@ -173,6 +181,10 @@ class PokerStars(HandHistoryConverter):
|
||||||
else:
|
else:
|
||||||
info['type'] = 'tour'
|
info['type'] = 'tour'
|
||||||
|
|
||||||
|
if info['limitType'] == 'fl' and info['bb'] != None and info['type'] == 'ring':
|
||||||
|
info['sb'] = Lim_Blinds[mg['BB']][0]
|
||||||
|
info['bb'] = Lim_Blinds[mg['BB']][1]
|
||||||
|
|
||||||
# NB: SB, BB must be interpreted as blinds or bets depending on limit type.
|
# NB: SB, BB must be interpreted as blinds or bets depending on limit type.
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
@ -287,16 +299,14 @@ class PokerStars(HandHistoryConverter):
|
||||||
hand.addBringIn(m.group('PNAME'), m.group('BRINGIN'))
|
hand.addBringIn(m.group('PNAME'), m.group('BRINGIN'))
|
||||||
|
|
||||||
def readBlinds(self, hand):
|
def readBlinds(self, hand):
|
||||||
try:
|
liveBlind = True
|
||||||
count = 0
|
for a in self.re_PostSB.finditer(hand.handText):
|
||||||
for a in self.re_PostSB.finditer(hand.handText):
|
if liveBlind:
|
||||||
if count == 0:
|
hand.addBlind(a.group('PNAME'), 'small blind', a.group('SB'))
|
||||||
hand.addBlind(a.group('PNAME'), 'small blind', a.group('SB'))
|
liveBlind = False
|
||||||
count = 1
|
else:
|
||||||
else:
|
# Post dead blinds as ante
|
||||||
hand.addBlind(a.group('PNAME'), 'secondsb', a.group('SB'))
|
hand.addBlind(a.group('PNAME'), 'secondsb', a.group('SB'))
|
||||||
except: # no small blind
|
|
||||||
hand.addBlind(None, None, None)
|
|
||||||
for a in self.re_PostBB.finditer(hand.handText):
|
for a in self.re_PostBB.finditer(hand.handText):
|
||||||
hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB'))
|
hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB'))
|
||||||
for a in self.re_PostBoth.finditer(hand.handText):
|
for a in self.re_PostBoth.finditer(hand.handText):
|
||||||
|
|
|
@ -1916,6 +1916,7 @@ class Sql:
|
||||||
inner join Players p on (p.Id = hp.playerId)
|
inner join Players p on (p.Id = hp.playerId)
|
||||||
where hp.playerId in <player_test>
|
where hp.playerId in <player_test>
|
||||||
<game_test>
|
<game_test>
|
||||||
|
<site_test>
|
||||||
/*and hp.tourneysPlayersId IS NULL*/
|
/*and hp.tourneysPlayersId IS NULL*/
|
||||||
and h.seats <seats_test>
|
and h.seats <seats_test>
|
||||||
<flagtest>
|
<flagtest>
|
||||||
|
@ -2000,6 +2001,7 @@ class Sql:
|
||||||
inner join Players p on (p.Id = hp.playerId)
|
inner join Players p on (p.Id = hp.playerId)
|
||||||
where hp.playerId in <player_test>
|
where hp.playerId in <player_test>
|
||||||
<game_test>
|
<game_test>
|
||||||
|
<site_test>
|
||||||
/*and hp.tourneysPlayersId IS NULL*/
|
/*and hp.tourneysPlayersId IS NULL*/
|
||||||
and h.seats <seats_test>
|
and h.seats <seats_test>
|
||||||
<flagtest>
|
<flagtest>
|
||||||
|
@ -2086,6 +2088,7 @@ class Sql:
|
||||||
inner join Players p on (p.Id = hp.playerId)
|
inner join Players p on (p.Id = hp.playerId)
|
||||||
where hp.playerId in <player_test>
|
where hp.playerId in <player_test>
|
||||||
<game_test>
|
<game_test>
|
||||||
|
<site_test>
|
||||||
/*and hp.tourneysPlayersId IS NULL*/
|
/*and hp.tourneysPlayersId IS NULL*/
|
||||||
and h.seats <seats_test>
|
and h.seats <seats_test>
|
||||||
<flagtest>
|
<flagtest>
|
||||||
|
|
|
@ -89,7 +89,6 @@ class Table(Table_Window):
|
||||||
# break
|
# break
|
||||||
|
|
||||||
if window_number is None:
|
if window_number is None:
|
||||||
print "Window %s not found. Skipping." % search_string
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# my_geo = self.window.get_geometry()
|
# my_geo = self.window.get_geometry()
|
||||||
|
|
|
@ -1025,23 +1025,24 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def validate_config(self):
|
def validate_config(self):
|
||||||
hhbase = self.config.get_import_parameters().get("hhArchiveBase")
|
if self.config.get_import_parameters().get('saveStarsHH'):
|
||||||
hhbase = os.path.expanduser(hhbase)
|
hhbase = self.config.get_import_parameters().get("hhArchiveBase")
|
||||||
#hhdir = os.path.join(hhbase,site)
|
hhbase = os.path.expanduser(hhbase)
|
||||||
hhdir = hhbase
|
#hhdir = os.path.join(hhbase,site)
|
||||||
if not os.path.isdir(hhdir):
|
hhdir = hhbase
|
||||||
diapath = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING, buttons=(gtk.BUTTONS_YES_NO), message_format="Setup hh dir")
|
if not os.path.isdir(hhdir):
|
||||||
diastring = "WARNING: Unable to find output hh directory %s\n\n Press YES to create this directory, or NO to select a new one." % hhdir
|
diapath = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING, buttons=(gtk.BUTTONS_YES_NO), message_format="Setup hh dir")
|
||||||
diapath.format_secondary_text(diastring)
|
diastring = "WARNING: Unable to find output hh directory %s\n\n Press YES to create this directory, or NO to select a new one." % hhdir
|
||||||
response = diapath.run()
|
diapath.format_secondary_text(diastring)
|
||||||
diapath.destroy()
|
response = diapath.run()
|
||||||
if response == gtk.RESPONSE_YES:
|
diapath.destroy()
|
||||||
try:
|
if response == gtk.RESPONSE_YES:
|
||||||
os.makedirs(hhdir)
|
try:
|
||||||
except:
|
os.makedirs(hhdir)
|
||||||
self.warning_box("WARNING: Unable to create hand output directory. Importing is not likely to work until this is fixed.")
|
except:
|
||||||
elif response == gtk.RESPONSE_NO:
|
self.warning_box("WARNING: Unable to create hand output directory. Importing is not likely to work until this is fixed.")
|
||||||
self.select_hhArchiveBase()
|
elif response == gtk.RESPONSE_NO:
|
||||||
|
self.select_hhArchiveBase()
|
||||||
|
|
||||||
def select_hhArchiveBase(self, widget=None):
|
def select_hhArchiveBase(self, widget=None):
|
||||||
fc = gtk.FileChooserDialog(title="Select HH Output Directory", parent=None, action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_OPEN,gtk.RESPONSE_OK), backend=None)
|
fc = gtk.FileChooserDialog(title="Select HH Output Directory", parent=None, action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_OPEN,gtk.RESPONSE_OK), backend=None)
|
||||||
|
|
0
run_fpdb.py
Executable file → Normal file
0
run_fpdb.py
Executable file → Normal file
Loading…
Reference in New Issue
Block a user