Merge branch 'master' of git://git.assembla.com/fpdb-eric

This commit is contained in:
Eratosthenes 2010-02-01 10:47:49 -05:00
commit 2a9c00953a
3 changed files with 39 additions and 31 deletions

View File

@ -38,8 +38,9 @@ class Everleaf(HandHistoryConverter):
#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) 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)
re_Button = re.compile(ur"^Seat (?P<BUTTON>\d+) is the button", re.MULTILINE) re_Button = re.compile(ur"^Seat (?P<BUTTON>\d+) is the button", re.MULTILINE)
re_PlayerInfo = re.compile(ur"^Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\s+((?:\$| €|) (?P<CASH>[.0-9]+) (USD|EUR|)|new player|All-in) \)", re.MULTILINE) re_PlayerInfo = re.compile(ur"^Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\s+((?:\$| €|) (?P<CASH>[.0-9]+) (USD|EURO|Chips)|new player|All-in) \)", re.MULTILINE)
re_Board = re.compile(ur"\[ (?P<CARDS>.+) \]") re_Board = re.compile(ur"\[ (?P<CARDS>.+) \]")
re_TourneyInfoFromFilename = re.compile(ur".*TID_(?P<TOURNO>[0-9]+)-(?P<TABLE>[0-9]+)\.txt")
def compilePlayerRegexs(self, hand): def compilePlayerRegexs(self, hand):
@ -55,10 +56,10 @@ class Everleaf(HandHistoryConverter):
self.re_Antes = re.compile(ur"^%s: posts ante \[(?:\$| €|) (?P<ANTE>[.0-9]+)" % player_re, re.MULTILINE) self.re_Antes = re.compile(ur"^%s: posts ante \[(?:\$| €|) (?P<ANTE>[.0-9]+)" % player_re, re.MULTILINE)
self.re_BringIn = re.compile(ur"^%s posts bring-in (?:\$| €|)(?P<BRINGIN>[.0-9]+)\." % player_re, re.MULTILINE) self.re_BringIn = re.compile(ur"^%s posts bring-in (?:\$| €|)(?P<BRINGIN>[.0-9]+)\." % player_re, re.MULTILINE)
self.re_HeroCards = re.compile(ur"^Dealt to %s \[ (?P<CARDS>.*) \]" % player_re, re.MULTILINE) self.re_HeroCards = re.compile(ur"^Dealt to %s \[ (?P<CARDS>.*) \]" % player_re, re.MULTILINE)
self.re_Action = re.compile(ur"^%s(?P<ATYPE>: bets| checks| raises| calls| folds)(\s\[(?:\$| €|) (?P<BET>[.\d]+) (USD|EUR|)\])?" % player_re, re.MULTILINE) self.re_Action = re.compile(ur"^%s(?P<ATYPE>: bets| checks| raises| calls| folds)(\s\[(?:\$| €|) (?P<BET>[.,\d]+) (USD|EURO|Chips)\])?" % player_re, re.MULTILINE)
#self.re_Action = re.compile(ur"^%s(?P<ATYPE>: bets| checks| raises| calls| folds| complete to)(\s\[?(?:\$| €|) ?(?P<BET>\d+\.?\d*)\.?\s?(USD|EUR|)\]?)?" % player_re, re.MULTILINE) #self.re_Action = re.compile(ur"^%s(?P<ATYPE>: bets| checks| raises| calls| folds| complete to)(\s\[?(?:\$| €|) ?(?P<BET>\d+\.?\d*)\.?\s?(USD|EUR|)\]?)?" % player_re, re.MULTILINE)
self.re_ShowdownAction = re.compile(ur"^%s shows \[ (?P<CARDS>.*) \]" % player_re, re.MULTILINE) self.re_ShowdownAction = re.compile(ur"^%s shows \[ (?P<CARDS>.*) \]" % player_re, re.MULTILINE)
self.re_CollectPot = re.compile(ur"^%s wins (?:\$| €|) (?P<POT>[.\d]+) (USD|EUR|chips)(.*?\[ (?P<CARDS>.*?) \])?" % player_re, re.MULTILINE) self.re_CollectPot = re.compile(ur"^%s wins (?:\$| €|) (?P<POT>[.\d]+) (USD|EURO|chips)(.*?\[ (?P<CARDS>.*?) \])?" % player_re, re.MULTILINE)
self.re_SitsOut = re.compile(ur"^%s sits out" % player_re, re.MULTILINE) self.re_SitsOut = re.compile(ur"^%s sits out" % player_re, re.MULTILINE)
def readSupportedGames(self): def readSupportedGames(self):
@ -66,7 +67,9 @@ class Everleaf(HandHistoryConverter):
["ring", "hold", "pl"], ["ring", "hold", "pl"],
["ring", "hold", "fl"], ["ring", "hold", "fl"],
["ring", "studhi", "fl"], ["ring", "studhi", "fl"],
["ring", "omahahi", "pl"] ["ring", "omahahi", "pl"],
["ring", "omahahilo", "pl"],
["tour", "hold", "nl"]
] ]
def determineGameType(self, handText): def determineGameType(self, handText):
@ -138,6 +141,12 @@ or None if we fail to get the info """
hand.tablename = m.group('TABLE') hand.tablename = m.group('TABLE')
hand.maxseats = 6 # assume 6-max unless we have proof it's a larger/smaller game, since everleaf doesn't give seat max info hand.maxseats = 6 # assume 6-max unless we have proof it's a larger/smaller game, since everleaf doesn't give seat max info
t = self.re_TourneyInfoFromFilename.search(self.in_path)
if t:
tourno = t.group('TOURNO')
hand.tourNo = tourno
hand.tablename = t.group('TABLE')
# Believe Everleaf time is GMT/UTC, no transation necessary # Believe Everleaf time is GMT/UTC, no transation necessary
# Stars format (Nov 10 2008): 2008/11/07 12:38:49 CET [2008/11/07 7:38:49 ET] # Stars format (Nov 10 2008): 2008/11/07 12:38:49 CET [2008/11/07 7:38:49 ET]
# or : 2008/11/07 12:38:49 ET # or : 2008/11/07 12:38:49 ET
@ -287,7 +296,9 @@ or None if we fail to get the info """
@staticmethod @staticmethod
def getTableTitleRe(type, table_name=None, tournament = None, table_number=None): def getTableTitleRe(type, table_name=None, tournament = None, table_number=None):
return "^%s -" % (table_name) if tournament:
return "%s - Tournament ID: %s -" % (table_number, tournament)
return "%s -" % (table_name)

View File

@ -270,7 +270,7 @@ class HUD_main(object):
cards['common'] = comm_cards['common'] cards['common'] = comm_cards['common']
table_kwargs = dict(table_name = table_name, tournament = tour_number, table_number = tab_number) table_kwargs = dict(table_name = table_name, tournament = tour_number, table_number = tab_number)
search_string = getTableTitleRe(self.config, site, type, **table_kwargs) search_string = getTableTitleRe(self.config, site_name, type, **table_kwargs)
tablewindow = Tables.Table(search_string, **table_kwargs) tablewindow = Tables.Table(search_string, **table_kwargs)
if tablewindow is None: if tablewindow is None:

View File

@ -67,7 +67,7 @@ follow : whether to tail -f the input"""
self.config = config self.config = config
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) )
self.index = index self.index = index
self.starsArchive = starsArchive self.starsArchive = starsArchive
@ -80,7 +80,7 @@ follow : whether to tail -f the input"""
# Tourney object used to store TourneyInfo when called to deal with a Summary file # Tourney object used to store TourneyInfo when called to deal with a Summary file
self.tourney = None self.tourney = None
if in_path == '-': if in_path == '-':
self.in_fh = sys.stdin self.in_fh = sys.stdin
@ -109,7 +109,7 @@ follow : whether to tail -f the input"""
self.follow = follow self.follow = follow
self.compiledPlayers = set() self.compiledPlayers = set()
self.maxseats = 10 self.maxseats = 10
self.status = True self.status = True
self.parsedObjectType = "HH" #default behaviour : parsing HH files, can be "Summary" if the parsing encounters a Summary File self.parsedObjectType = "HH" #default behaviour : parsing HH files, can be "Summary" if the parsing encounters a Summary File
@ -124,7 +124,7 @@ HandHistoryConverter: '%(sitename)s'
in_path '%(in_path)s' in_path '%(in_path)s'
out_path '%(out_path)s' out_path '%(out_path)s'
follow '%(follow)s' follow '%(follow)s'
""" % locals() """ % locals()
def start(self): def start(self):
"""Process a hand at a time from the input specified by in_path. """Process a hand at a time from the input specified by in_path.
@ -144,7 +144,7 @@ Otherwise, finish at EOF.
self.numHands = 0 self.numHands = 0
self.numErrors = 0 self.numErrors = 0
if self.follow: if self.follow:
#TODO: See how summary files can be handled on the fly (here they should be rejected as before) #TODO: See how summary files can be handled on the fly (here they should be rejected as before)
log.info("Tailing '%s'" % self.in_path) log.info("Tailing '%s'" % self.in_path)
for handText in self.tailHands(): for handText in self.tailHands():
try: try:
@ -179,7 +179,7 @@ Otherwise, finish at EOF.
endtime = time.time() endtime = time.time()
if summaryParsingStatus : if summaryParsingStatus :
log.info("Summary file '%s' correctly parsed (took %.3f seconds)" % (self.in_path, endtime - starttime)) log.info("Summary file '%s' correctly parsed (took %.3f seconds)" % (self.in_path, endtime - starttime))
else : else :
log.warning("Error converting summary file '%s' (took %.3f seconds)" % (self.in_path, endtime - starttime)) log.warning("Error converting summary file '%s' (took %.3f seconds)" % (self.in_path, endtime - starttime))
except IOError, ioe: except IOError, ioe:
@ -233,7 +233,7 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
# x-- [x,--,] x,-- # x-- [x,--,] x,--
# x--x [x,--,x] x,x # x--x [x,--,x] x,x
# x--x-- [x,--,x,--,] x,x,-- # x--x-- [x,--,x,--,] x,x,--
# The length is always odd. # The length is always odd.
# 'odd' indices are always splitters. # 'odd' indices are always splitters.
# 'even' indices are always paragraphs or '' # 'even' indices are always paragraphs or ''
@ -267,13 +267,13 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
log.info("Read no hands.") log.info("Read no hands.")
return [] return []
return re.split(self.re_SplitHands, self.obs) return re.split(self.re_SplitHands, self.obs)
def processHand(self, handText): def processHand(self, handText):
gametype = self.determineGameType(handText) gametype = self.determineGameType(handText)
log.debug("gametype %s" % gametype) log.debug("gametype %s" % gametype)
hand = None hand = None
l = None l = None
if gametype is None: if gametype is None:
gametype = "unmatched" gametype = "unmatched"
# TODO: not ideal, just trying to not error. # TODO: not ideal, just trying to not error.
# TODO: Need to count failed hands. # TODO: Need to count failed hands.
@ -307,7 +307,7 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
# This function should return a list of lists looking like: # This function should return a list of lists looking like:
# return [["ring", "hold", "nl"], ["tour", "hold", "nl"]] # return [["ring", "hold", "nl"], ["tour", "hold", "nl"]]
# Showing all supported games limits and types # Showing all supported games limits and types
def readSupportedGames(self): abstract def readSupportedGames(self): abstract
# should return a list # should return a list
@ -342,17 +342,17 @@ or None if we fail to get the info """
# Needs to return a list of lists in the format # Needs to return a list of lists in the format
# [['seat#', 'player1name', 'stacksize'] ['seat#', 'player2name', 'stacksize'] [...]] # [['seat#', 'player1name', 'stacksize'] ['seat#', 'player2name', 'stacksize'] [...]]
def readPlayerStacks(self, hand): abstract def readPlayerStacks(self, hand): abstract
def compilePlayerRegexs(self): abstract def compilePlayerRegexs(self): abstract
"""Compile dynamic regexes -- these explicitly match known player names and must be updated if a new player joins""" """Compile dynamic regexes -- these explicitly match known player names and must be updated if a new player joins"""
# Needs to return a MatchObject with group names identifying the streets into the Hand object # Needs to return a MatchObject with group names identifying the streets into the Hand object
# so groups are called by street names 'PREFLOP', 'FLOP', 'STREET2' etc # so groups are called by street names 'PREFLOP', 'FLOP', 'STREET2' etc
# blinds are done seperately # blinds are done seperately
def markStreets(self, hand): abstract def markStreets(self, hand): abstract
#Needs to return a list in the format #Needs to return a list in the format
# ['player1name', 'player2name', ...] where player1name is the sb and player2name is bb, # ['player1name', 'player2name', ...] where player1name is the sb and player2name is bb,
# addtional players are assumed to post a bb oop # addtional players are assumed to post a bb oop
def readBlinds(self, hand): abstract def readBlinds(self, hand): abstract
def readAntes(self, hand): abstract def readAntes(self, hand): abstract
@ -365,16 +365,16 @@ or None if we fail to get the info """
def readShownCards(self, hand): abstract def readShownCards(self, hand): abstract
# Some sites do odd stuff that doesn't fall in to the normal HH parsing. # Some sites do odd stuff that doesn't fall in to the normal HH parsing.
# e.g., FTP doesn't put mixed game info in the HH, but puts in in the # e.g., FTP doesn't put mixed game info in the HH, but puts in in the
# file name. Use readOther() to clean up those messes. # file name. Use readOther() to clean up those messes.
def readOther(self, hand): pass def readOther(self, hand): pass
# Some sites don't report the rake. This will be called at the end of the hand after the pot total has been calculated # Some sites don't report the rake. This will be called at the end of the hand after the pot total has been calculated
# an inheriting class can calculate it for the specific site if need be. # an inheriting class can calculate it for the specific site if need be.
def getRake(self, hand): def getRake(self, hand):
hand.rake = hand.totalpot - hand.totalcollected # * Decimal('0.05') # probably not quite right hand.rake = hand.totalpot - hand.totalcollected # * Decimal('0.05') # probably not quite right
def sanityCheck(self): def sanityCheck(self):
"""Check we aren't going to do some stupid things""" """Check we aren't going to do some stupid things"""
#TODO: the hhbase stuff needs to be in fpdb_import #TODO: the hhbase stuff needs to be in fpdb_import
@ -399,7 +399,7 @@ or None if we fail to get the info """
# Make sure input and output files are different or we'll overwrite the source file # Make sure input and output files are different or we'll overwrite the source file
if True: # basically.. I don't know if True: # basically.. I don't know
sane = True sane = True
if self.in_path != '-' and self.out_path == self.in_path: if self.in_path != '-' and self.out_path == self.in_path:
print "HH Sanity Check: output and input files are the same, check config" print "HH Sanity Check: output and input files are the same, check config"
sane = False sane = False
@ -432,7 +432,7 @@ or None if we fail to get the info """
def readFile(self): def readFile(self):
"""Open in_path according to self.codepage. Exceptions caught further up""" """Open in_path according to self.codepage. Exceptions caught further up"""
if self.filetype == "text": if self.filetype == "text":
if self.in_path == '-': if self.in_path == '-':
# read from stdin # read from stdin
@ -467,7 +467,7 @@ or None if we fail to get the info """
if hand.gametype['base'] == 'stud': if hand.gametype['base'] == 'stud':
if mo <= 8: return 8 if mo <= 8: return 8
else: return mo else: return mo
if hand.gametype['base'] == 'draw': if hand.gametype['base'] == 'draw':
if mo <= 6: return 6 if mo <= 6: return 6
@ -503,9 +503,9 @@ or None if we fail to get the info """
def getParsedObjectType(self): def getParsedObjectType(self):
return self.parsedObjectType return self.parsedObjectType
#returns a status (True/False) indicating wether the parsing could be done correctly or not #returns a status (True/False) indicating wether the parsing could be done correctly or not
def readSummaryInfo(self, summaryInfoList): abstract def readSummaryInfo(self, summaryInfoList): abstract
def getTourney(self): def getTourney(self):
return self.tourney return self.tourney
@ -528,6 +528,3 @@ 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])