Merge branch 'master' into siteneutral

Conflicts:

	pyfpdb/HUD_config.xml.example
	pyfpdb/fpdb_save_to_db.py
	pyfpdb/fpdb_simple.py
This commit is contained in:
Worros
2009-04-10 00:38:27 +08:00
96 changed files with 680 additions and 2549 deletions
+14 -8
View File
@@ -33,6 +33,9 @@ import xml.dom.minidom
from xml.dom.minidom import Node
def fix_tf(x, default = True):
# The xml parser doesn't translate "True" to True. Therefore, we never get
# True or False from the parser only "True" or "False". So translate the
# string to the python boolean representation.
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":
@@ -80,11 +83,11 @@ class Site:
self.hudbgcolor = node.getAttribute("bgcolor")
self.hudfgcolor = node.getAttribute("fgcolor")
self.converter = node.getAttribute("converter")
self.enabled = node.getAttribute("enabled")
self.aux_window = node.getAttribute("aux_window")
self.font = node.getAttribute("font")
self.font_size = node.getAttribute("font_size")
self.use_frames = node.getAttribute("use_frames")
self.enabled = fix_tf(node.getAttribute("enabled"), default = True)
self.layout = {}
for layout_node in node.getElementsByTagName('layout'):
@@ -222,7 +225,7 @@ class Import:
self.callFpdbHud = node.getAttribute("callFpdbHud")
self.hhArchiveBase = node.getAttribute("hhArchiveBase")
self.saveActions = fix_tf(node.getAttribute("saveActions"), True)
self.fastStoreHudCache = fix_tf(node.getAttribute("fastStoreHudCache"), True)
self.fastStoreHudCache = fix_tf(node.getAttribute("fastStoreHudCache"), False)
def __str__(self):
return " interval = %s\n callFpdbHud = %s\n hhArchiveBase = %s\n saveActions = %s\n fastStoreHudCache = %s\n" \
@@ -547,7 +550,7 @@ class Config:
return paths
def get_frames(self, site = "PokerStars"):
return self.supported_sites[site].use_frames == "True"
return self.supported_sites[site].use_frames == True
def get_default_colors(self, site = "PokerStars"):
colors = {}
@@ -598,14 +601,17 @@ class Config:
( 0, 280), (121, 280), ( 46, 30) )
return locations
def get_supported_sites(self):
def get_supported_sites(self, all = False):
"""Returns the list of supported sites."""
return self.supported_sites.keys()
the_sites = []
for site in self.supported_sites.keys():
params = self.get_site_parameters(site)
if all or params['enabled']:
the_sites.append(site)
return the_sites
def get_site_parameters(self, site):
"""Returns a dict of the site parameters for the specified site"""
if not self.supported_sites.has_key(site):
return None
parms = {}
parms["converter"] = self.supported_sites[site].converter
parms["decoder"] = self.supported_sites[site].decoder
@@ -617,10 +623,10 @@ class Config:
parms["table_finder"] = self.supported_sites[site].table_finder
parms["HH_path"] = self.supported_sites[site].HH_path
parms["site_name"] = self.supported_sites[site].site_name
parms["enabled"] = self.supported_sites[site].enabled
parms["aux_window"] = self.supported_sites[site].aux_window
parms["font"] = self.supported_sites[site].font
parms["font_size"] = self.supported_sites[site].font_size
parms["enabled"] = self.supported_sites[site].enabled
return parms
def set_site_parameters(self, site_name, converter = None, decoder = None,
+1 -1
View File
@@ -27,7 +27,7 @@ from HandHistoryConverter import *
class Everleaf(HandHistoryConverter):
# Static regexes
re_SplitHands = re.compile(r"\n\n+")
re_SplitHands = re.compile(r"(\n\n\n+)")
re_GameInfo = re.compile(ur"^(Blinds )?(?P<CURRENCY>\$| €|)(?P<SB>[.0-9]+)/(?:\$| €)?(?P<BB>[.0-9]+) (?P<LIMIT>NL|PL|) ?(?P<GAME>(Hold\'em|Omaha|7 Card Stud))", re.MULTILINE)
#re.compile(ur"^(Blinds )?(?P<CURRENCY>\$| €|)(?P<SB>[.0-9]+)/(?:\$| €)?(?P<BB>[.0-9]+) (?P<LIMIT>NL|PL|) (?P<GAME>(Hold\'em|Omaha|7 Card Stud))", re.MULTILINE)
re_HandInfo = re.compile(ur".*#(?P<HID>[0-9]+)\n.*\n(Blinds )?(?:\$| €|)(?P<SB>[.0-9]+)/(?:\$| €|)(?P<BB>[.0-9]+) (?P<GAMETYPE>.*) - (?P<DATETIME>\d\d\d\d/\d\d/\d\d - \d\d:\d\d:\d\d)\nTable (?P<TABLE>.+$)", re.MULTILINE)
+1 -1
View File
@@ -28,7 +28,7 @@ class Fulltilt(HandHistoryConverter):
# Static regexes
re_GameInfo = re.compile('- (?P<CURRENCY>\$|)?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) (Ante \$(?P<ANTE>[.0-9]+) )?- (?P<LIMIT>(No Limit|Pot Limit|Limit))? (?P<GAME>(Hold\'em|Omaha Hi|Razz))')
re_SplitHands = re.compile(r"\n\n+")
re_SplitHands = re.compile(r"(\n\n+)")
re_HandInfo = re.compile('.*#(?P<HID>[0-9]+): Table (?P<TABLE>[- a-zA-Z]+) (\((?P<TABLEATTRIBUTES>.+)\) )?- \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) (Ante \$(?P<ANTE>[.0-9]+) )?- (?P<GAMETYPE>[a-zA-Z\' ]+) - (?P<DATETIME>.*)')
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>.*) \(\$(?P<CASH>[.0-9]+)\)\n')
+4 -3
View File
@@ -202,13 +202,14 @@ class GuiAutoImport (threading.Thread):
filter.show()
def addSites(self, vbox):
for site in self.config.supported_sites.keys():
the_sites = self.config.get_supported_sites()
for site in the_sites:
pathHBox = gtk.HBox(False, 0)
vbox.pack_start(pathHBox, False, True, 0)
pathHBox.show()
paths = self.config.get_default_paths(site)
params = self.config.get_site_parameters(site)
paths = self.config.get_default_paths(site)
self.createSiteLine(pathHBox, site, False, paths['hud-defaultPath'], params['converter'], params['enabled'])
self.input_settings[site] = [paths['hud-defaultPath']] + [params['converter']]
+2 -4
View File
@@ -206,9 +206,7 @@ class GuiBulkImport():
self.lab_drop.set_sensitive(False)
def main(argv=None):
"""main can also be called in the python interpreter, by supplying the command line as the argument.
>>>import GuiBulkImport
>>>GuiBulkImport.main(['-f'.'~/data/hands'])"""
"""main can also be called in the python interpreter, by supplying the command line as the argument."""
if argv is None:
argv = sys.argv[1:]
@@ -242,7 +240,7 @@ def main(argv=None):
settings.update(config.get_default_paths())
if not options.gui:
print """-q is deprecated. Just use "-f filename" instead"""
print '-q is deprecated. Just use "-f filename" instead'
# This is because -q on its own causes an error, so -f is necessary and sufficient for cmd line use
if not options.filename:
i = GuiBulkImport(db, settings, config)
+99 -20
View File
@@ -1,8 +1,24 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<FreePokerToolsConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FreePokerToolsConfig.xsd">
<import callFpdbHud = "True" interval = "10" fastStoreHudCache="False" hhArchiveBase="~/.fpdb/HandHistories/" saveActions="True"></import>
<supported_sites>
<site enabled="True" site_name="PokerStars" table_finder="PokerStars.exe" screen_name="DO NOT NEED THIS YET" site_path="~/.wine/drive_c/Program Files/PokerStars/" HH_path="~/.wine/drive_c/Program Files/PokerStars/HandHistory/abc/" decoder="pokerstars_decode_table">
<site enabled="True"
site_name="PokerStars"
table_finder="PokerStars.exe"
screen_name="YOUR SCREEN NAME HERE"
site_path="C:/Program Files/PokerStars/"
HH_path="C:/Program Files/PokerStars/HandHistory/YOUR SCREEN NAME HERE/"
decoder="pokerstars_decode_table"
bgcolor="#000000"
fgcolor="#FFFFFF"
hudopacity="1.0"
font="Sans"
font_size="8"
supported_games="holdem,razz,omahahi,omahahilo,studhi,studhilo">
<layout max="8" width="792" height="546" fav_seat="0">
<location seat="1" x="684" y="61"> </location>
<location seat="2" x="689" y="239"> </location>
@@ -49,7 +65,20 @@
<location seat="2" x="10" y="288"> </location>
</layout>
</site>
<site enabled="True" site_name="Full Tilt" table_finder="FullTiltPoker.exe" screen_name="DO NOT NEED THIS YET" site_path="~/.wine/drive_c/Program Files/Full Tilt Poker/" HH_path="~/.wine/drive_c/Program Files/Full Tilt Poker/HandHistory/abc/" decoder="fulltilt_decode_table">
<site enabled="True"
site_name="Full Tilt Poker"
table_finder="FullTiltPoker"
screen_name="YOUR SCREEN NAME HERE"
site_path="C:/Program Files/Full Tilt Poker/"
HH_path="C:/Program Files/Full Tilt Poker/HandHistory/YOUR SCREEN NAME HERE/"
decoder="fulltilt_decode_table"
bgcolor="#000000"
fgcolor="#FFFFFF"
hudopacity="1.0"
font="Sans"
font_size="8"
supported_games="holdem,razz,omahahi,omahahilo,studhi,studhilo">
<layout fav_seat="0" height="547" max="8" width="794">
<location seat="1" x="640" y="64"> </location>
<location seat="2" x="650" y="230"> </location>
@@ -84,7 +113,15 @@
<location seat="9" x="70" y="53"> </location>
</layout>
</site>
<site enabled="False" site_name="Everleaf" table_finder="Everleaf.exe" screen_name="DO NOT NEED THIS YET" site_path="" HH_path="" decoder="everleaf_decode_table">
<site enabled="False"
site_name="Everleaf"
table_finder="Everleaf.exe"
screen_name="YOUR SCREEN NAME HERE"
site_path=""
HH_path=""
decoder="everleaf_decode_table"
supported_games="holdem">
<layout fav_seat="0" height="547" max="8" width="794">
<location seat="1" x="640" y="64"> </location>
<location seat="2" x="650" y="230"> </location>
@@ -120,8 +157,10 @@
</layout>
</site>
</supported_sites>
<supported_games>
<game cols="3" db="fpdb" game_name="holdem" rows="2">
<game cols="3" db="fpdb" game_name="holdem" rows="2" aux="mucked">
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat>
@@ -129,7 +168,8 @@
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
</game>
<game cols="3" db="fpdb" game_name="razz" rows="2">
<game cols="3" db="fpdb" game_name="razz" rows="2" aux="stud_mucked">
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat>
@@ -137,7 +177,8 @@
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
</game>
<game cols="3" db="fpdb" game_name="omahahi" rows="2">
<game cols="3" db="fpdb" game_name="omahahi" rows="2" aux="mucked">
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat>
@@ -145,7 +186,8 @@
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
</game>
<game cols="3" db="fpdb" game_name="omahahilo" rows="2">
<game cols="3" db="fpdb" game_name="omahahilo" rows="2" aux="mucked">
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat>
@@ -153,7 +195,8 @@
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
</game>
<game cols="3" db="fpdb" game_name="studhi" rows="2">
<game cols="3" db="fpdb" game_name="studhi" rows="2" aux="stud_mucked">
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat>
@@ -161,7 +204,8 @@
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
</game>
<game cols="3" db="fpdb" game_name="studhilo" rows="2">
<game cols="3" db="fpdb" game_name="studhilo" rows="2" aux="stud_mucked">
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat>
@@ -170,6 +214,7 @@
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
</game>
</supported_games>
<popup_windows>
<pu pu_name="default">
<pu_stat pu_stat_name="n"> </pu_stat>
@@ -196,20 +241,54 @@
<pu_stat pu_stat_name="ffreq_4"> </pu_stat>
</pu>
</popup_windows>
<import callFpdbHud = "True" interval = "10" ></import>
<tv combinedStealFold = "True" combined2B3B = "True" combinedPostflop = "True"></tv>
<hhcs>
<hhc site="PokerStars" converter="PokerStarsToFpdb"></hhc>
<hhc site="Full Tilt Poker" converter="FulltiltToFpdb"></hhc>
<hhc site="Everleaf" converter="EverleafToFpdb"></hhc>
</hhcs>
<aux_windows>
<aw card_ht="42" card_wd="30" class="Stud_mucked" cols="11" deck="Cards01.png" module="Mucked" name="stud_mucked" rows="8"> </aw>
<aw class="Hello" module="Hello" name="Hello"> </aw>
<aw class="Hello_Menu" module="Hello" name="Hello_menu"> </aw>
<aw class="Hello_plus" module="Hello" name="Hello_plus"> </aw>
<aw card_ht="42" card_wd="30" class="Flop_Mucked" deck="Cards01.png" module="Mucked" name="mucked" opacity="0.7" timeout="5">
<layout height="546" max="6" width="792">
<location seat="1" x="555" y="169"> </location>
<location seat="2" x="572" y="276"> </location>
<location seat="3" x="363" y="348"> </location>
<location seat="4" x="150" y="273"> </location>
<location seat="5" x="150" y="169"> </location>
<location seat="6" x="363" y="113"> </location>
<location common="1" x="323" y="232"> </location>
</layout>
<layout height="546" max="9" width="792">
<location seat="1" x="486" y="113"> </location>
<location seat="2" x="555" y="169"> </location>
<location seat="3" x="572" y="276"> </location>
<location seat="4" x="522" y="345"> </location>
<location seat="5" x="363" y="348"> </location>
<location seat="6" x="217" y="341"> </location>
<location seat="7" x="150" y="273"> </location>
<location seat="8" x="150" y="169"> </location>
<location seat="9" x="230" y="115"> </location>
<location common="1" x="323" y="232"> </location>
</layout>
<layout height="546" max="10" width="792">
<location seat="1" x="486" y="113"> </location>
<location seat="2" x="499" y="138"> </location>
<location seat="3" x="522" y="212"> </location>
<location seat="4" x="501" y="281"> </location>
<location seat="5" x="402" y="323"> </location>
<location seat="6" x="243" y="311"> </location>
<location seat="7" x="203" y="262"> </location>
<location seat="8" x="170" y="185"> </location>
<location seat="9" x="183" y="128"> </location>
<location seat="10" x="213" y="86"> </location>
<location common="1" x="317" y="237"> </location>
</layout>
</aw>
</aux_windows>
<supported_databases>
<database db_name="fpdb" db_server="mysql" db_ip="localhost" db_user="fpdb" db_pass="YOUR MYSQL PASSWORD" db_type="fpdb"> </database>
<database db_name="fpdb" db_server="mysql" db_ip="localhost" db_user="fpdb" db_pass="YOUR MYSQL PASSWORD" db_type="fpdb"></database>
</supported_databases>
<mucked_windows>
<mw mw_name="stud1" format="stud" rows="8" cols="11" deck="Cards01.png" card_wd="30" card_ht="42"> </mw>
</mucked_windows>
</FreePokerToolsConfig>
+19 -16
View File
@@ -51,6 +51,8 @@ import Database
import Tables
import Hud
aggregate_stats = {"ring": False, "tour": False} # config file!
class HUD_main(object):
"""A main() object to own both the read_stdin thread and the gui."""
# This class mainly provides state for controlling the multiple HUDs.
@@ -85,7 +87,7 @@ class HUD_main(object):
del(self.hud_dict[table])
self.main_window.resize(1,1)
def create_HUD(self, new_hand_id, table, table_name, max, poker_game, is_tournament, stat_dict, cards):
def create_HUD(self, new_hand_id, table, table_name, max, poker_game, stat_dict, cards):
def idle_func():
@@ -108,9 +110,9 @@ class HUD_main(object):
gtk.gdk.threads_leave()
self.hud_dict[table_name] = Hud.Hud(self, table, max, poker_game, self.config, self.db_connection)
self.hud_dict[table_name].table_name = table_name
self.hud_dict[table_name].stat_dict = stat_dict
self.hud_dict[table_name].cards = cards
[aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[table_name].aux_windows]
gobject.idle_add(idle_func)
@@ -149,8 +151,8 @@ class HUD_main(object):
# get basic info about the new hand from the db
# if there is a db error, complain, skip hand, and proceed
try:
(table_name, max, poker_game) = self.db_connection.get_table_name(new_hand_id)
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id)
(table_name, max, poker_game, type) = self.db_connection.get_table_name(new_hand_id)
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, aggregate = aggregate_stats[type])
cards = self.db_connection.get_cards(new_hand_id)
comm_cards = self.db_connection.get_common_cards(new_hand_id)
if comm_cards != {}: # stud!
@@ -160,15 +162,17 @@ class HUD_main(object):
sys.stderr.write("Database error %s in hand %d. Skipping.\n" % (err, int(new_hand_id)))
continue
# find out if this hand is from a tournament
mat_obj = tourny_finder.search(table_name)
if mat_obj:
is_tournament = True
(tour_number, tab_number) = mat_obj.group(1, 2)
temp_key = tour_number
if type == "tour": # hand is from a tournament
mat_obj = tourny_finder.search(table_name)
if mat_obj:
(tour_number, tab_number) = mat_obj.group(1, 2)
temp_key = tour_number
else: # tourney, but can't get number and table
print "could not find tournamtne: skipping "
sys.stderr.write("Could not find tournament %d in hand %d. Skipping.\n" % (int(tour_number), int(new_hand_id)))
continue
else:
is_tournament = False
(tour_number, tab_number) = (0, 0)
temp_key = table_name
# Update an existing HUD
@@ -180,18 +184,17 @@ class HUD_main(object):
# Or create a new HUD
else:
if is_tournament:
if type == "tour":
tablewindow = Tables.discover_tournament_table(self.config, tour_number, tab_number)
else:
tablewindow = Tables.discover_table_by_name(self.config, table_name)
if tablewindow == None:
# If no client window is found on the screen, complain and continue
if is_tournament:
if type == "tour":
table_name = "%s %s" % (tour_number, tab_number)
sys.stderr.write("table name "+table_name+" not found, skipping.\n")
else:
self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, is_tournament, stat_dict, cards)
self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, stat_dict, cards)
if __name__== "__main__":
sys.stderr.write("HUD_main starting\n")
+2 -2
View File
@@ -458,7 +458,7 @@ Card ranks will be uppercased
def writeHand(self, fh=sys.__stdout__):
# PokerStars format.
print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, time.strftime('%Y/%m/%d - %H:%M:%S ET', self.starttime)))
print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, time.strftime('%Y/%m/%d - %H:%M:%S ET', self.starttime)))
print >>fh, _("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
players_who_act_preflop = set(([x[0] for x in self.actions['PREFLOP']]+[x[0] for x in self.actions['BLINDSANTES']]))
@@ -820,7 +820,7 @@ Add a complete on [street] by [player] to [amountTo]
def writeHand(self, fh=sys.__stdout__):
# PokerStars format.
print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, time.strftime('%Y/%m/%d - %H:%M:%S (ET)', self.starttime)))
print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, time.strftime('%Y/%m/%d - %H:%M:%S (ET)', self.starttime)))
print >>fh, _("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
players_who_post_antes = set([x[0] for x in self.actions['ANTES']])
+7 -4
View File
@@ -72,7 +72,8 @@ import gettext
gettext.install('myapplication')
class HandHistoryConverter():
READ_CHUNK_SIZE = 1000 # bytes to read at a time from file
READ_CHUNK_SIZE = 10000 # bytes to read at a time from file (in tail mode)
def __init__(self, in_path = '-', out_path = '-', sitename = None, follow=False):
logging.info("HandHistory init called")
@@ -154,7 +155,7 @@ Tail the in_path file and yield handTexts separated by re_SplitHands"""
time.sleep(interval)
fd.seek(where)
else:
print "%s changed inode numbers from %d to %d" % (self.in_path, fd_results[1], st_results[1])
logging.debug("%s changed inode numbers from %d to %d" % (self.in_path, fd_results[1], st_results[1]))
fd = codecs.open(self.in_path, 'r', self.codepage)
fd.seek(where)
else:
@@ -162,6 +163,7 @@ Tail the in_path file and yield handTexts separated by re_SplitHands"""
data = data + newdata
result = self.re_SplitHands.split(data)
result = iter(result)
data = ''
# --x data (- is bit of splitter, x is paragraph) yield,...,keep
# [,--,x] result of re.split (with group around splitter)
# ,x our output: yield nothing, keep x
@@ -181,9 +183,10 @@ Tail the in_path file and yield handTexts separated by re_SplitHands"""
# We want to yield all paragraphs followed by a splitter, i.e. all even indices except the last.
for para in result:
try:
splitter = result.next()
result.next()
splitter = True
except StopIteration:
splitter = None
splitter = False
if splitter: # para is followed by a splitter
if para: yield para # para not ''
else:
+11 -6
View File
@@ -125,7 +125,7 @@ class Hud:
self.menu = gtk.Menu()
self.item1 = gtk.MenuItem('Kill this HUD')
self.menu.append(self.item1)
self.item1.connect("activate", self.parent.kill_hud, self.table.name)
self.item1.connect("activate", self.parent.kill_hud, self.table_name)
self.item1.show()
self.item2 = gtk.MenuItem('Save Layout')
@@ -176,7 +176,7 @@ class Hud:
loc = self.config.get_locations(self.table.site, self.max)
# TODO: is stat_windows getting converted somewhere from a list to a dict, for no good reason?
for i, w in enumerate(self.stat_windows.itervalues()):
(x, y) = loc[adj[i]]
(x, y) = loc[adj[i+1]]
w.relocate(x, y)
return True
@@ -197,16 +197,21 @@ class Hud:
s.window.destroy()
self.stat_windows = {}
# also kill any aux windows
(aux.destroy() for aux in self.aux_windows)
for aux in self.aux_windows:
aux.destroy()
self.aux_windows = []
def reposition_windows(self, *args):
if self.stat_windows != {} and len(self.stat_windows) > 0:
(x.window.move(x.x, x.y) for x in self.stat_windows.itervalues() if type(x) != int)
for w in self.stat_windows.itervalues():
if type(w) == int:
# print "in reposition, w =", w
continue
# print "in reposition, w =", w, w.x, w.y
w.window.move(w.x, w.y)
return True
def debug_stat_windows(self, *args):
print self.table, "\n", self.main_window.window.get_transient_for()
# print self.table, "\n", self.main_window.window.get_transient_for()
for w in self.stat_windows:
print self.stat_windows[w].window.window.get_transient_for()
+1 -1
View File
@@ -451,7 +451,7 @@ class Flop_Mucked(Aux_Window):
def save_layout(self, *args):
"""Save new layout back to the aux element in the config file."""
new_locs = {}
print "adj =", self.adj
# print "adj =", self.adj
for (i, pos) in self.positions.iteritems():
if i != 'common':
new_locs[self.adj[int(i)]] = (pos[0] - self.hud.table.x, pos[1] - self.hud.table.y)
+1 -1
View File
@@ -27,7 +27,7 @@ class PokerStars(HandHistoryConverter):
# Static regexes
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_Button = re.compile('Seat #(?P<BUTTON>\d+) is the button', re.MULTILINE)
re_PlayerInfo = re.compile('^Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\$?(?P<CASH>[.0-9]+) in chips\)', re.MULTILINE)
+1 -1
View File
@@ -331,7 +331,7 @@ class Sql:
"""
self.query['get_table_name'] = """
select tableName, maxSeats, category
select tableName, maxSeats, category, type
from Hands,Gametypes
where Hands.id = %s
and Gametypes.id = Hands.gametypeId
+2 -2
View File
@@ -135,7 +135,7 @@ def discover_posix(c):
if re.search(params['table_finder'], listing):
if 'Lobby' in listing: continue
if 'Instant Hand History' in listing: continue
if '\"Full Tilt Poker\"' in listing: continue
# if '\"Full Tilt Poker\"' in listing: continue
if 'History for table:' in listing: continue
if 'has no name' in listing: continue
info = decode_xwininfo(c, listing)
@@ -387,7 +387,7 @@ def discover_mac_by_name(c, tablename):
if __name__=="__main__":
c = Configuration.Config()
print discover_table_by_name(c, "Ringe")
print discover_table_by_name(c, "Torino")
# print discover_tournament_table(c, "118942908", "3")
tables = discover(c)
+329
View File
@@ -0,0 +1,329 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2008, Carl Gherardi
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
########################################################################
import sys
from HandHistoryConverter import *
class UltimateBet(HandHistoryConverter):
# Static regexes
re_GameInfo = re.compile("Stage #(?P<HID>[0-9]+):\s+\(?(?P<GAME>Hold\'em|Razz|Seven Card|Omaha|Omaha Hi/Lo|Badugi) (?P<LIMIT>No Limit|Normal|Pot Limit),? \(?(?P<CURRENCY>\$|)?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+)\) - (?P<DATETIME>.*$)", re.MULTILINE)
re_SplitHands = re.compile('(\n\n\n+)')
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_PlayerInfo = re.compile('^Seat (?P<SEAT>[0-9]+) - (?P<PNAME>.*) \(\$?(?P<CASH>[.0-9]+) in chips\)', re.MULTILINE)
re_Board = re.compile(r"\[(?P<CARDS>.+)\]")
# self.re_setHandInfoRegex('.*#(?P<HID>[0-9]+): Table (?P<TABLE>[ a-zA-Z]+) - \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) - (?P<GAMETYPE>.*) - (?P<HR>[0-9]+):(?P<MIN>[0-9]+) ET - (?P<YEAR>[0-9]+)/(?P<MON>[0-9]+)/(?P<DAY>[0-9]+)Table (?P<TABLE>[ a-zA-Z]+)\nSeat (?P<BUTTON>[0-9]+)')
def __init__(self, in_path = '-', out_path = '-', follow = False, autostart=True):
"""\
in_path (default '-' = sys.stdin)
out_path (default '-' = sys.stdout)
follow : whether to tail -f the input"""
HandHistoryConverter.__init__(self, in_path, out_path, sitename="UltimateBet", follow=follow)
logging.info("Initialising UltimateBetconverter class")
self.filetype = "text"
self.codepage = "cp1252"
if autostart:
self.start()
def compilePlayerRegexs(self, hand):
players = set([player[1] for player in hand.players])
if not players <= self.compiledPlayers: # x <= y means 'x is subset of y'
# we need to recompile the player regexs.
self.compiledPlayers = players
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
logging.debug("player_re: " + player_re)
self.re_PostSB = re.compile(r"^%s: posts small blind \$?(?P<SB>[.0-9]+)" % player_re, re.MULTILINE)
self.re_PostBB = re.compile(r"^%s: posts big blind \$?(?P<BB>[.0-9]+)" % player_re, re.MULTILINE)
self.re_Antes = re.compile(r"^%s - Ante \$?(?P<ANTE>[.0-9]+)" % player_re, re.MULTILINE)
self.re_BringIn = re.compile(r"^%s - Bring-In \$?(?P<BRINGIN>[.0-9]+)" % player_re, re.MULTILINE)
self.re_PostBoth = re.compile(r"^%s: posts small \& big blinds \[\$? (?P<SBBB>[.0-9]+)" % player_re, re.MULTILINE)
self.re_HeroCards = re.compile(r"^Dealt to %s - Pocket (\[(?P<OLDCARDS>.+?)\])?( \[(?P<NEWCARDS>.+?)\])" % player_re, re.MULTILINE)
self.re_Action = re.compile(r"^%s -(?P<ATYPE> Bets| Checks| raises| Calls| Folds)( \$(?P<BET>[.\d]+))?( to \$(?P<BETTO>[.\d]+))?( (?P<NODISCARDED>\d) cards?( \[(?P<DISCARDED>.+?)\])?)?" % player_re, re.MULTILINE)
self.re_ShowdownAction = re.compile(r"^%s - Shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
self.re_CollectPot = re.compile(r"Seat (?P<SEAT>[0-9]+): %s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \(\$(?P<POT>[.\d]+)\)(, mucked| with.*|)" % player_re, re.MULTILINE)
self.re_sitsOut = re.compile("^%s sits out" % player_re, re.MULTILINE)
self.re_ShownCards = re.compile("^Seat (?P<SEAT>[0-9]+): %s \(.*\) showed \[(?P<CARDS>.*)\].*" % player_re, re.MULTILINE)
def readSupportedGames(self):
return [ ["ring", "stud", "fl"]
]
def determineGameType(self, handText):
info = {'type':'ring'}
m = self.re_GameInfo.search(handText)
if not m:
return None
mg = m.groupdict()
# translations from captured groups to our info strings
limits = { 'No Limit':'nl', 'Pot Limit':'pl', 'Limit':'fl' }
games = { # base, category
"Hold'em" : ('hold','holdem'),
'Omaha' : ('hold','omahahi'),
'Omaha Hi/Lo' : ('hold','omahahilo'),
'Razz' : ('stud','razz'),
'7 Card Stud' : ('stud','studhi'),
'Badugi' : ('draw','badugi')
}
currencies = { u'':'EUR', '$':'USD', '':'T$' }
if 'LIMIT' in mg:
info['limitType'] = limits[mg['LIMIT']]
if 'GAME' in mg:
(info['base'], info['category']) = games[mg['GAME']]
if 'SB' in mg:
info['sb'] = mg['SB']
if 'BB' in mg:
info['bb'] = mg['BB']
if 'CURRENCY' in mg:
info['currency'] = currencies[mg['CURRENCY']]
# NB: SB, BB must be interpreted as blinds or bets depending on limit type.
return info
def readHandInfo(self, hand):
info = {}
m = self.re_HandInfo.search(hand.handText,re.DOTALL)
if m:
info.update(m.groupdict())
# TODO: Be less lazy and parse maxseats from the HandInfo regex
if m.group('TABLEATTRIBUTES'):
m2 = re.search("\s*(\d+)-max", m.group('TABLEATTRIBUTES'))
hand.maxseats = int(m2.group(1))
m = self.re_GameInfo.search(hand.handText)
if m: info.update(m.groupdict())
m = self.re_Button.search(hand.handText)
if m: info.update(m.groupdict())
# TODO : I rather like the idea of just having this dict as hand.info
logging.debug("readHandInfo: %s" % info)
for key in info:
if key == 'DATETIME':
#2008/11/12 10:00:48 CET [2008/11/12 4:00:48 ET]
#2008/08/17 - 01:14:43 (ET)
#2008/09/07 06:23:14 ET
m2 = re.search("(?P<Y>[0-9]{4})\/(?P<M>[0-9]{2})\/(?P<D>[0-9]{2})[\- ]+(?P<H>[0-9]+):(?P<MIN>[0-9]+):(?P<S>[0-9]+)", info[key])
datetime = "%s/%s/%s %s:%s:%s" % (m2.group('Y'), m2.group('M'),m2.group('D'),m2.group('H'),m2.group('MIN'),m2.group('S'))
hand.starttime = time.strptime(datetime, "%Y/%m/%d %H:%M:%S")
if key == 'HID':
hand.handid = info[key]
if key == 'TABLE':
hand.tablename = info[key]
if key == 'BUTTON':
hand.buttonpos = info[key]
def readButton(self, hand):
m = self.re_Button.search(hand.handText)
if m:
hand.buttonpos = int(m.group('BUTTON'))
else:
logging.info('readButton: not found')
def readPlayerStacks(self, hand):
logging.debug("readPlayerStacks")
m = self.re_PlayerInfo.finditer(hand.handText)
players = []
for a in m:
hand.addPlayer(int(a.group('SEAT')), a.group('PNAME'), a.group('CASH'))
def markStreets(self, hand):
# PREFLOP = ** Dealing down cards **
# This re fails if, say, river is missing; then we don't get the ** that starts the river.
if hand.gametype['base'] in ("hold"):
m = re.search(r"\*\*\* HOLE CARDS \*\*\*(?P<PREFLOP>.+(?=\*\*\* FLOP \*\*\*)|.+)"
r"(\*\*\* FLOP \*\*\*(?P<FLOP> \[\S\S \S\S \S\S\].+(?=\*\*\* TURN \*\*\*)|.+))?"
r"(\*\*\* TURN \*\*\* \[\S\S \S\S \S\S] (?P<TURN>\[\S\S\].+(?=\*\*\* RIVER \*\*\*)|.+))?"
r"(\*\*\* RIVER \*\*\* \[\S\S \S\S \S\S \S\S] (?P<RIVER>\[\S\S\].+))?", hand.handText,re.DOTALL)
elif hand.gametype['base'] in ("stud"):
m = re.search(r"(?P<ANTES>.+(?=\*\*\* 3rd STREET \*\*\*)|.+)"
r"(\*\*\* 3rd STREET \*\*\*(?P<THIRD>.+(?=\*\*\* 4th STREET \*\*\*)|.+))?"
r"(\*\*\* 4th STREET \*\*\*(?P<FOURTH>.+(?=\*\*\* 5th STREET \*\*\*)|.+))?"
r"(\*\*\* 5th STREET \*\*\*(?P<FIFTH>.+(?=\*\*\* 6th STREET \*\*\*)|.+))?"
r"(\*\*\* 6th STREET \*\*\*(?P<SIXTH>.+(?=\*\*\* RIVER \*\*\*)|.+))?"
r"(\*\*\* RIVER \*\*\*(?P<SEVENTH>.+))?", hand.handText,re.DOTALL)
elif hand.gametype['base'] in ("draw"):
m = re.search(r"(?P<PREDEAL>.+(?=\*\*\* DEALING HANDS \*\*\*)|.+)"
r"(\*\*\* DEALING HANDS \*\*\*(?P<DEAL>.+(?=\*\*\* FIRST DRAW \*\*\*)|.+))?"
r"(\*\*\* FIRST DRAW \*\*\*(?P<DRAWONE>.+(?=\*\*\* SECOND DRAW \*\*\*)|.+))?"
r"(\*\*\* SECOND DRAW \*\*\*(?P<DRAWTWO>.+(?=\*\*\* THIRD DRAW \*\*\*)|.+))?"
r"(\*\*\* THIRD DRAW \*\*\*(?P<DRAWTHREE>.+))?", hand.handText,re.DOTALL)
hand.addStreets(m)
def readCommunityCards(self, hand, street): # street has been matched by markStreets, so exists in this hand
if street in ('FLOP','TURN','RIVER'): # a list of streets which get dealt community cards (i.e. all but PREFLOP)
#print "DEBUG readCommunityCards:", street, hand.streets.group(street)
m = self.re_Board.search(hand.streets[street])
hand.setCommunityCards(street, m.group('CARDS').split(' '))
def readAntes(self, hand):
logging.debug("reading antes")
m = self.re_Antes.finditer(hand.handText)
for player in m:
#~ logging.debug("hand.addAnte(%s,%s)" %(player.group('PNAME'), player.group('ANTE')))
hand.addAnte(player.group('PNAME'), player.group('ANTE'))
def readBringIn(self, hand):
m = self.re_BringIn.search(hand.handText,re.DOTALL)
if m:
#~ logging.debug("readBringIn: %s for %s" %(m.group('PNAME'), m.group('BRINGIN')))
hand.addBringIn(m.group('PNAME'), m.group('BRINGIN'))
def readBlinds(self, hand):
try:
m = self.re_PostSB.search(hand.handText)
hand.addBlind(m.group('PNAME'), 'small blind', m.group('SB'))
except: # no small blind
hand.addBlind(None, None, None)
for a in self.re_PostBB.finditer(hand.handText):
hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB'))
for a in self.re_PostBoth.finditer(hand.handText):
hand.addBlind(a.group('PNAME'), 'small & big blinds', a.group('SBBB'))
def readHeroCards(self, hand):
m = self.re_HeroCards.search(hand.handText)
if(m == None):
#Not involved in hand
hand.involved = False
else:
hand.hero = m.group('PNAME')
# "2c, qh" -> set(["2c","qc"])
# Also works with Omaha hands.
cards = m.group('NEWCARDS')
cards = set(cards.split(' '))
hand.addHoleCards(cards, m.group('PNAME'))
def readDrawCards(self, hand, street):
logging.debug("readDrawCards")
m = self.re_HeroCards.finditer(hand.streets[street])
if m == None:
hand.involved = False
else:
for player in m:
hand.hero = player.group('PNAME') # Only really need to do this once
newcards = player.group('NEWCARDS')
oldcards = player.group('OLDCARDS')
if newcards == None:
newcards = set()
else:
newcards = set(newcards.split(' '))
if oldcards == None:
oldcards = set()
else:
oldcards = set(oldcards.split(' '))
hand.addDrawHoleCards(newcards, oldcards, player.group('PNAME'), street)
def readStudPlayerCards(self, hand, street):
# See comments of reference implementation in FullTiltToFpdb.py
logging.debug("readStudPlayerCards")
m = self.re_HeroCards.finditer(hand.streets[street])
for player in m:
#~ logging.debug(player.groupdict())
(pname, oldcards, newcards) = (player.group('PNAME'), player.group('OLDCARDS'), player.group('NEWCARDS'))
if oldcards:
oldcards = [c.strip() for c in oldcards.split(' ')]
if newcards:
newcards = [c.strip() for c in newcards.split(' ')]
if street=='ANTES':
return
elif street=='THIRD':
# we'll have observed hero holecards in CARDS and thirdstreet open cards in 'NEWCARDS'
# hero: [xx][o]
# others: [o]
hand.addPlayerCards(player = player.group('PNAME'), street = street, closed = oldcards, open = newcards)
elif street in ('FOURTH', 'FIFTH', 'SIXTH'):
# 4th:
# hero: [xxo] [o]
# others: [o] [o]
# 5th:
# hero: [xxoo] [o]
# others: [oo] [o]
# 6th:
# hero: [xxooo] [o]
# others: [ooo] [o]
hand.addPlayerCards(player = player.group('PNAME'), street = street, open = newcards)
# we may additionally want to check the earlier streets tally with what we have but lets trust it for now.
elif street=='SEVENTH' and newcards:
# hero: [xxoooo] [x]
# others: not reported.
hand.addPlayerCards(player = player.group('PNAME'), street = street, closed = newcards)
def readAction(self, hand, street):
m = self.re_Action.finditer(hand.streets[street])
for action in m:
if action.group('ATYPE') == ' Raises':
hand.addRaiseBy( street, action.group('PNAME'), action.group('BET') )
elif action.group('ATYPE') == ' Calls':
hand.addCall( street, action.group('PNAME'), action.group('BET') )
elif action.group('ATYPE') == ' Bets':
hand.addBet( street, action.group('PNAME'), action.group('BET') )
elif action.group('ATYPE') == ' Folds':
hand.addFold( street, action.group('PNAME'))
elif action.group('ATYPE') == ' Checks':
hand.addCheck( street, action.group('PNAME'))
#elif action.group('ATYPE') == ' discards':
# hand.addDiscard(street, action.group('PNAME'), action.group('NODISCARDED'), action.group('DISCARDED'))
#elif action.group('ATYPE') == ' stands pat':
# hand.addStandsPat( street, action.group('PNAME'))
else:
print "DEBUG: unimplemented readAction: '%s' '%s'" %(action.group('PNAME'),action.group('ATYPE'),)
def readShowdownActions(self, hand):
for shows in self.re_ShowdownAction.finditer(hand.handText):
cards = shows.group('CARDS')
cards = set(cards.split(' '))
hand.addShownCards(cards, shows.group('PNAME'))
def readCollectPot(self,hand):
for m in self.re_CollectPot.finditer(hand.handText):
hand.addCollectPot(player=m.group('PNAME'),pot=m.group('POT'))
def readShownCards(self,hand):
for m in self.re_ShownCards.finditer(hand.handText):
if m.group('CARDS') is not None:
cards = m.group('CARDS')
cards = set(cards.split(' '))
hand.addShownCards(cards=cards, player=m.group('PNAME'))
if __name__ == "__main__":
parser = OptionParser()
parser.add_option("-i", "--input", dest="ipath", help="parse input hand history", default="regression-test-files/pokerstars/HH20090226 Natalie V - $0.10-$0.20 - HORSE.txt")
parser.add_option("-o", "--output", dest="opath", help="output translation to", default="-")
parser.add_option("-f", "--follow", dest="follow", help="follow (tail -f) the input", action="store_true", default=False)
parser.add_option("-q", "--quiet",
action="store_const", const=logging.CRITICAL, dest="verbosity", default=logging.INFO)
parser.add_option("-v", "--verbose",
action="store_const", const=logging.INFO, dest="verbosity")
parser.add_option("--vv",
action="store_const", const=logging.DEBUG, dest="verbosity")
(options, args) = parser.parse_args()
LOG_FILENAME = './logging.out'
logging.basicConfig(filename=LOG_FILENAME,level=options.verbosity)
e = UltimateBet(in_path = options.ipath, out_path = options.opath, follow = options.follow)
+1 -1
View File
@@ -47,7 +47,7 @@ import GuiGraphViewer
import FpdbSQLQueries
import Configuration
VERSION = "0.10"
VERSION = "0.11"
class fpdb:
def tab_clicked(self, widget, tab_name):
+11 -11
View File
@@ -26,7 +26,7 @@ MYSQL_INNODB = 2
PGSQL = 3
SQLITE = 4
fastStoreHudCache = True # set this to True to test the new storeHudCache routine
fastStoreHudCache = False # set this to True to test the new storeHudCache routine
saveActions = True # set this to False to avoid storing action data
# Pros: speeds up imports
@@ -41,8 +41,8 @@ def ring_stud(config, backend, db, cursor, base, category, site_hand_no, gametyp
import_options = config.get_import_parameters()
saveActions = False if import_options['saveActions'] == 'False' else True
fastStoreHudCache = True if import_options['fastStoreHudCache'] == 'True' else False
saveActions = False if import_options['saveActions'] == False else True
fastStoreHudCache = True if import_options['fastStoreHudCache'] == True else False
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
@@ -69,11 +69,11 @@ def ring_holdem_omaha(config, backend, db, cursor, base, category, site_hand_no,
"""stores a holdem/omaha hand into the database"""
import_options = config.get_import_parameters()
saveActions = False if import_options['saveActions'] == 'False' else True
fastStoreHudCache = False if import_options['fastStoreHudCache'] == 'False' else True
saveActions = False if import_options['saveActions'] == False else True
fastStoreHudCache = True if import_options['fastStoreHudCache'] == True else False
# print "DEBUG: saveActions = '%s' fastStoreHudCache = '%s'"%(saveActions, fastStoreHudCache)
# print "DEBUG: import_options = ", import_options
# print "DEBUG: saveActions = '%s' fastStoreHudCache = '%s'"%(saveActions, fastStoreHudCache)
# print "DEBUG: import_options = ", import_options
t0 = time()
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
@@ -113,8 +113,8 @@ def tourney_holdem_omaha(config, backend, db, cursor, base, category, siteTourne
"""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
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.fill_board_cards(board_values, board_suits)
@@ -150,8 +150,8 @@ def tourney_stud(config, backend, db, cursor, base, category, siteTourneyNo, buy
#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
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)
+40 -26
View File
@@ -163,9 +163,9 @@ def prepareBulkImport(fdb):
# DON'T FORGET TO RECREATE THEM!!
#print "dropping pg fk", fk['fktab'], fk['fkcol']
try:
#print "alter table %s drop constraint %s_%s_fkey" % (fk['fktab'], fk['fktab'], fk['fkcol'])
#print "alter table %s drop constraint %s_%s_fkey" % (fk['fktab'], fk['fktab'], fk['fkcol'])
fdb.cursor.execute("alter table %s drop constraint %s_%s_fkey" % (fk['fktab'], fk['fktab'], fk['fkcol']))
print "dropped pg fk pg fk %s_%s_fkey" % (fk['fktab'], fk['fkcol'])
print "dropped pg fk pg fk %s_%s_fkey" % (fk['fktab'], fk['fkcol'])
except:
print "! failed drop pg fk %s_%s_fkey" % (fk['fktab'], fk['fkcol'])
else:
@@ -465,21 +465,12 @@ def convert3B4B(category, limit_type, actionTypes, actionAmounts):
for k in xrange(len(actionTypes[i][j])):
if (actionTypes[i][j][k]=="bet"):
bets.append((i,j,k))
if (len(bets)==2):
#print "len(bets) 2 or higher, need to correct it. bets:",bets,"len:",len(bets)
amount2=actionAmounts[bets[1][0]][bets[1][1]][bets[1][2]]
amount1=actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]]
actionAmounts[bets[1][0]][bets[1][1]][bets[1][2]]=amount2-amount1
elif (len(bets)>2):
fail=True
#todo: run correction for below
if (limit_type=="nl" or limit_type == "pl"):
fail=False
if fail:
print "len(bets)>2 in convert3B4B, i didnt think this is possible. i:",i,"j:",j,"k:",k
print "actionTypes:",actionTypes
raise FpdbError ("too many bets in convert3B4B")
if (len(bets)>=2):
#print "len(bets) 2 or higher, need to correct it. bets:",bets,"len:",len(bets)
for betNo in reversed(xrange (1,len(bets))):
amount2=actionAmounts[bets[betNo][0]][bets[betNo][1]][bets[betNo][2]]
amount1=actionAmounts[bets[betNo-1][0]][bets[betNo-1][1]][bets[betNo-1][2]]
actionAmounts[bets[betNo][0]][bets[betNo][1]][bets[betNo][2]]=amount2-amount1
#print "actionAmounts postConvert",actionAmounts
#end def convert3B4B(actionTypes, actionAmounts)
@@ -649,7 +640,7 @@ def filterCrap(hand, isTourney):
hand[i] = False
elif hand[i].find(" is low with [")!=-1:
hand[i] = False
elif (hand[i].endswith(" mucks")):
elif hand[i].endswith(" mucks"):
hand[i] = False
elif hand[i].endswith(": mucks hand"):
hand[i] = False
@@ -853,11 +844,19 @@ def goesAllInOnThisLine(line):
#end def goesAllInOnThisLine
#returns the action type code (see table design) of the given action line
ActionTypes = { 'calls':"call", 'brings in for':"blind", 'completes it to':"bet", ' posts $':"blind",
' posts a dead ' : "blind", ' posts the small blind of $':"blind", ': posts big blind ':"blind",
' posts the big blind of $':"blind", ': posts small & big blinds $':"blind",
': posts small blind $':"blind",
' bets' : "bet", ' raises' : "bet"
ActionTypes = { 'brings in for' :"blind",
' posts $' :"blind",
' posts a dead ' :"blind",
' posts the small blind of $' :"blind",
': posts big blind ' :"blind",
': posts small blind ' :"blind",
' posts the big blind of $' :"blind",
': posts small & big blinds $' :"blind",
': posts small blind $' :"blind",
'calls' :"call",
'completes it to' :"bet",
' bets' :"bet",
' raises' :"bet"
}
def parseActionType(line):
if (line.startswith("Uncalled bet")):
@@ -1310,18 +1309,33 @@ def recogniseTourneyTypeId(cursor, siteId, buyin, fee, knockout, rebuyOrAddon):
# { playername: id } instead of depending on it's relation to the positions list
# then this can be reduced in complexity a bit
#def recognisePlayerIDs(cursor, names, site_id):
# result = []
# for i in xrange(len(names)):
# cursor.execute ("SELECT id FROM Players WHERE name=%s", (names[i],))
# tmp=cursor.fetchall()
# if (len(tmp)==0): #new player
# cursor.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)", (names[i], site_id))
# #print "Number of players rows inserted: %d" % cursor.rowcount
# cursor.execute ("SELECT id FROM Players WHERE name=%s", (names[i],))
# tmp=cursor.fetchall()
# #print "recognisePlayerIDs, names[i]:",names[i],"tmp:",tmp
# result.append(tmp[0][0])
# return result
def recognisePlayerIDs(cursor, names, site_id):
cursor.execute("SELECT name,id FROM Players WHERE name='%s'" % "' OR name='".join(names)) # get all playerids by the names passed in
q = "SELECT name,id FROM Players WHERE name=%s" % " OR name=".join(["%s" for n in names])
cursor.execute(q, names) # get all playerids by the names passed in
ids = dict(cursor.fetchall()) # convert to dict
if len(ids) != len(names):
notfound = [n for n in names if n not in ids] # make list of names not in database
if notfound: # insert them into database
cursor.executemany("INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")", (notfound))
cursor.execute("SELECT name,id FROM Players WHERE name='%s'" % "' OR name='".join(notfound)) # get their new ids
q2 = "SELECT name,id FROM Players WHERE name=%s" % " OR name=".join(["%s" for n in notfound])
cursor.execute(q2, notfound) # get their new ids
tmp = dict(cursor.fetchall())
for n in tmp: # put them all into the same dict
ids[n] = tmp[n]
# return them in the SAME ORDER that they came in in the names argument, rather than the order they came out of the DB
return [ids[n] for n in names]
#end def recognisePlayerIDs
+35
View File
@@ -44,3 +44,38 @@ def testGameInfo():
for (header, info) in pairs:
yield checkGameInfo, hhc, header, info
def testHandInfo():
text = u""""PokerStars Game #20461877044: Hold'em No Limit ($1/$2) - 2008/09/16 18:58:01 ET"""
hhc = PokerStarsToFpdb.PokerStars(autostart=False)
h = HoldemOmahaHand(None, "PokerStars", gametype, text, builtFrom = "Test")
hhc.readHandInfo(h)
assert h.handid == '20461877044'
assert h.sitename == 'PokerStars'
assert h.starttime == (2008, 9, 16, 18, 58, 1, 1, 260, -1)
text = u"""PokerStars Game #18707234955: Razz Limit ($0.50/$1.00) - 2008/07/09 - 21:41:43 (ET)
Table 'Lepus II' 8-max"""
hhc = PokerStarsToFpdb.PokerStars(autostart=False)
h = HoldemOmahaHand(None, "PokerStars", gametype, text, builtFrom = "Test")
hhc.readHandInfo(h)
assert h.handid == '18707234955'
assert h.sitename == 'PokerStars'
assert h.maxseats == 8
assert h.tablename == 'Lepus II'
assert h.starttime == (2008,7 , 9, 21, 41, 43, 2, 191, -1)
text = u"""PokerStars Game #22073591924: Hold'em No Limit ($0.50/$1.00) - 2008/11/16 1:22:21 CET [2008/11/15 19:22:21 ET]
Table 'Caia II' 6-max Seat #2 is the button"""
hhc = PokerStarsToFpdb.PokerStars(autostart=False)
h = HoldemOmahaHand(None, "PokerStars", gametype, text, builtFrom = "Test")
hhc.readHandInfo(h)
assert h.handid == '22073591924'
assert h.sitename == 'PokerStars'
assert h.maxseats == 6
assert h.tablename == 'Caia II'
assert h.buttonpos == '2' # TODO: should this be an int?
assert h.starttime == (2008,11 , 15, 19, 22, 21, 5, 320, -1)