Explicit matching of player names
About the only place where we are guaranteed to get all the players' names correctly is in the seating plan in the hand header. We extract the names and build a regex that matches only the names. We only do this if the current regex is out of date, to avoid recompiling them too often. I also did away with self.rexx because it seemed unnecessary and was difficult to work with.
This commit is contained in:
parent
81c92f9599
commit
483e177346
|
@ -70,20 +70,24 @@ class Everleaf(HandHistoryConverter):
|
||||||
HandHistoryConverter.__init__(self, config, file, sitename="Everleaf") # Call super class init.
|
HandHistoryConverter.__init__(self, config, file, sitename="Everleaf") # Call super class init.
|
||||||
self.sitename = "Everleaf"
|
self.sitename = "Everleaf"
|
||||||
self.setFileType("text", "cp1252")
|
self.setFileType("text", "cp1252")
|
||||||
self.rexx.setGameInfoRegex('.*Blinds \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+)')
|
|
||||||
self.rexx.setSplitHandRegex('\n\n+')
|
self.re_GameInfo = re.compile(r".*Blinds \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+)")
|
||||||
self.rexx.setHandInfoRegex('.*#(?P<HID>[0-9]+)\n.*\nBlinds \$?(?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>[ a-zA-Z]+)\nSeat (?P<BUTTON>[0-9]+)')
|
self.re_SplitHands = re.compile(r"\n\n+")
|
||||||
self.rexx.setPlayerInfoRegex('Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\s+(\$ (?P<CASH>[.0-9]+) USD|new player|All-in) \)')
|
self.re_HandInfo = re.compile(r".*#(?P<HID>[0-9]+)\n.*\nBlinds \$?(?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>[ a-zA-Z]+)\nSeat (?P<BUTTON>[0-9]+)")
|
||||||
self.rexx.setPostSbRegex('.*\n(?P<PNAME>.*): posts small blind \[\$? (?P<SB>[.0-9]+)')
|
self.re_PlayerInfo = re.compile(r"^Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\s+(\$ (?P<CASH>[.0-9]+) USD|new player|All-in) \)", re.MULTILINE)
|
||||||
self.rexx.setPostBbRegex('.*\n(?P<PNAME>.*): posts big blind \[\$? (?P<BB>[.0-9]+)')
|
self.re_Board = re.compile(r"\[ (?P<CARDS>.+) \]")
|
||||||
self.rexx.setPostBothRegex('.*\n(?P<PNAME>.*): posts small \& big blinds \[\$? (?P<SBBB>[.0-9]+)')
|
|
||||||
self.rexx.setHeroCardsRegex('.*\nDealt\sto\s(?P<PNAME>.*)\s\[ (?P<CARDS>.*) \]')
|
def compile_player_regexs(self):
|
||||||
self.rexx.setActionStepRegex('.*\n(?P<PNAME>[^: ]*)(?P<ATYPE>: bets| checks| raises| calls| folds)(\s\[\$ (?P<BET>[.\d]+) (USD|EUR)\])?')
|
player_re = "(?P<PNAME>" + "|".join(map(re.escape, self.players)) + ")"
|
||||||
self.rexx.setShowdownActionRegex('.*\n(?P<PNAME>.*) shows \[ (?P<CARDS>.*) \]')
|
print "DEBUG player_re: " + player_re
|
||||||
self.rexx.setCollectPotRegex('.*\n(?P<PNAME>.*) wins \$ (?P<POT>[.\d]+) (USD|EUR)(.*?\[ (?P<CARDS>.*?) \])?')
|
self.re_PostSB = re.compile(r"^%s: posts small blind \[\$? (?P<SB>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
#self.rexx.setCollectPotRegex('.*\n(?P<PNAME>.*) wins \$ (?P<POT>[.\d]+) USD(.*\[ (?P<CARDS>) \S\S, \S\S, \S\S, \S\S, \S\S \])?')
|
self.re_PostBB = re.compile(r"^%s: posts big blind \[\$? (?P<BB>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.rexx.sits_out_re = re.compile('(?P<PNAME>.*) sits out')
|
self.re_PostBoth = re.compile(r"^%s: posts small \& big blinds \[\$? (?P<SBBB>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.rexx.compileRegexes()
|
self.re_HeroCards = re.compile(r"^Dealt to %s \[ (?P<CARDS>.*) \]" % player_re, re.MULTILINE)
|
||||||
|
self.re_Action = re.compile(r"^%s(?P<ATYPE>: bets| checks| raises| calls| folds)(\s\[\$ (?P<BET>[.\d]+) (USD|EUR)\])?" % player_re, re.MULTILINE)
|
||||||
|
self.re_ShowdownAction = re.compile(r"^%s shows \[ (?P<CARDS>.*) \]" % player_re, re.MULTILINE)
|
||||||
|
self.re_CollectPot = re.compile(r"^%s wins \$ (?P<POT>[.\d]+) (USD|EUR)(.*?\[ (?P<CARDS>.*?) \])?" % player_re, re.MULTILINE)
|
||||||
|
self.re_SitsOut = re.compile(r"^%s sits out" % player_re, re.MULTILINE)
|
||||||
|
|
||||||
def readSupportedGames(self):
|
def readSupportedGames(self):
|
||||||
return [["ring", "hold", "nl"]]
|
return [["ring", "hold", "nl"]]
|
||||||
|
@ -91,15 +95,13 @@ class Everleaf(HandHistoryConverter):
|
||||||
def determineGameType(self):
|
def determineGameType(self):
|
||||||
# Cheating with this regex, only support nlhe at the moment
|
# Cheating with this regex, only support nlhe at the moment
|
||||||
gametype = ["ring", "hold", "nl"]
|
gametype = ["ring", "hold", "nl"]
|
||||||
|
m = self.re_GameInfo.search(self.obs)
|
||||||
m = self.rexx.game_info_re.search(self.obs)
|
|
||||||
gametype = gametype + [m.group('SB')]
|
gametype = gametype + [m.group('SB')]
|
||||||
gametype = gametype + [m.group('BB')]
|
gametype = gametype + [m.group('BB')]
|
||||||
|
|
||||||
return gametype
|
return gametype
|
||||||
|
|
||||||
def readHandInfo(self, hand):
|
def readHandInfo(self, hand):
|
||||||
m = self.rexx.hand_info_re.search(hand.string)
|
m = self.re_HandInfo.search(hand.string)
|
||||||
hand.handid = m.group('HID')
|
hand.handid = m.group('HID')
|
||||||
hand.tablename = m.group('TABLE')
|
hand.tablename = m.group('TABLE')
|
||||||
# These work, but the info is already in the Hand class - should be used for tourneys though.
|
# These work, but the info is already in the Hand class - should be used for tourneys though.
|
||||||
|
@ -118,11 +120,12 @@ class Everleaf(HandHistoryConverter):
|
||||||
hand.buttonpos = int(m.group('BUTTON'))
|
hand.buttonpos = int(m.group('BUTTON'))
|
||||||
|
|
||||||
def readPlayerStacks(self, hand):
|
def readPlayerStacks(self, hand):
|
||||||
m = self.rexx.player_info_re.finditer(hand.string)
|
m = self.re_PlayerInfo.finditer(hand.string)
|
||||||
players = []
|
|
||||||
for a in m:
|
for a in m:
|
||||||
hand.addPlayer(int(a.group('SEAT')), a.group('PNAME'), a.group('CASH'))
|
hand.addPlayer(int(a.group('SEAT')), a.group('PNAME'), a.group('CASH'))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def markStreets(self, hand):
|
def markStreets(self, hand):
|
||||||
# PREFLOP = ** Dealing down cards **
|
# PREFLOP = ** Dealing down cards **
|
||||||
# This re fails if, say, river is missing; then we don't get the ** that starts the river.
|
# This re fails if, say, river is missing; then we don't get the ** that starts the river.
|
||||||
|
@ -137,25 +140,26 @@ class Everleaf(HandHistoryConverter):
|
||||||
|
|
||||||
|
|
||||||
def readCommunityCards(self, hand, street): # street has been matched by markStreets, so exists in this hand
|
def readCommunityCards(self, hand, street): # street has been matched by markStreets, so exists in this hand
|
||||||
self.rexx.board_re = re.compile(r"\[ (?P<CARDS>.+) \]")
|
print "DEBUG " + street + ":"
|
||||||
print hand.streets.group(street)
|
print hand.streets.group(street) + "\n"
|
||||||
if street in ('FLOP','TURN','RIVER'): # a list of streets which get dealt community cards (i.e. all but PREFLOP)
|
if street in ('FLOP','TURN','RIVER'): # a list of streets which get dealt community cards (i.e. all but PREFLOP)
|
||||||
m = self.rexx.board_re.search(hand.streets.group(street))
|
m = self.re_Board.search(hand.streets.group(street))
|
||||||
hand.setCommunityCards(street, m.group('CARDS').split(', '))
|
hand.setCommunityCards(street, m.group('CARDS').split(', '))
|
||||||
|
|
||||||
def readBlinds(self, hand):
|
def readBlinds(self, hand):
|
||||||
try:
|
try:
|
||||||
m = self.rexx.small_blind_re.search(hand.string)
|
m = self.re_PostSB.search(hand.string)
|
||||||
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 Exception, e: # no small blind
|
||||||
|
print e
|
||||||
hand.addBlind(None, None, None)
|
hand.addBlind(None, None, None)
|
||||||
for a in self.rexx.big_blind_re.finditer(hand.string):
|
for a in self.re_PostBB.finditer(hand.string):
|
||||||
hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB'))
|
hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB'))
|
||||||
for a in self.rexx.both_blinds_re.finditer(hand.string):
|
for a in self.re_PostBoth.finditer(hand.string):
|
||||||
hand.addBlind(a.group('PNAME'), 'small & big blinds', a.group('SBBB'))
|
hand.addBlind(a.group('PNAME'), 'small & big blinds', a.group('SBBB'))
|
||||||
|
|
||||||
def readHeroCards(self, hand):
|
def readHeroCards(self, hand):
|
||||||
m = self.rexx.hero_cards_re.search(hand.string)
|
m = self.re_HeroCards.search(hand.string)
|
||||||
if(m == None):
|
if(m == None):
|
||||||
#Not involved in hand
|
#Not involved in hand
|
||||||
hand.involved = False
|
hand.involved = False
|
||||||
|
@ -168,7 +172,7 @@ class Everleaf(HandHistoryConverter):
|
||||||
hand.addHoleCards(cards, m.group('PNAME'))
|
hand.addHoleCards(cards, m.group('PNAME'))
|
||||||
|
|
||||||
def readAction(self, hand, street):
|
def readAction(self, hand, street):
|
||||||
m = self.rexx.action_re.finditer(hand.streets.group(street))
|
m = self.re_Action.finditer(hand.streets.group(street))
|
||||||
for action in m:
|
for action in m:
|
||||||
if action.group('ATYPE') == ' raises':
|
if action.group('ATYPE') == ' raises':
|
||||||
hand.addCallandRaise( street, action.group('PNAME'), action.group('BET') )
|
hand.addCallandRaise( street, action.group('PNAME'), action.group('BET') )
|
||||||
|
@ -185,17 +189,17 @@ class Everleaf(HandHistoryConverter):
|
||||||
|
|
||||||
|
|
||||||
def readShowdownActions(self, hand):
|
def readShowdownActions(self, hand):
|
||||||
for shows in self.rexx.showdown_action_re.finditer(hand.string):
|
for shows in self.re_ShowdownAction.finditer(hand.string):
|
||||||
cards = shows.group('CARDS')
|
cards = shows.group('CARDS')
|
||||||
cards = set(cards.split(', '))
|
cards = set(cards.split(', '))
|
||||||
hand.addShownCards(cards, shows.group('PNAME'))
|
hand.addShownCards(cards, shows.group('PNAME'))
|
||||||
|
|
||||||
def readCollectPot(self,hand):
|
def readCollectPot(self,hand):
|
||||||
for m in self.rexx.collect_pot_re.finditer(hand.string):
|
for m in self.re_CollectPot.finditer(hand.string):
|
||||||
hand.addCollectPot(player=m.group('PNAME'),pot=m.group('POT'))
|
hand.addCollectPot(player=m.group('PNAME'),pot=m.group('POT'))
|
||||||
|
|
||||||
def readShownCards(self,hand):
|
def readShownCards(self,hand):
|
||||||
for m in self.rexx.collect_pot_re.finditer(hand.string):
|
for m in self.re_CollectPot.finditer(hand.string):
|
||||||
if m.group('CARDS') is not None:
|
if m.group('CARDS') is not None:
|
||||||
cards = m.group('CARDS')
|
cards = m.group('CARDS')
|
||||||
cards = set(cards.split(', '))
|
cards = set(cards.split(', '))
|
||||||
|
|
|
@ -145,7 +145,7 @@ class GuiAutoImport (threading.Thread):
|
||||||
|
|
||||||
# Add directories to importer object.
|
# Add directories to importer object.
|
||||||
for site in self.input_settings:
|
for site in self.input_settings:
|
||||||
self.importer.addImportDirectory(self.input_settings[site][0], True, site, self.input_settings[site][1])
|
self.importer.addImportDirectory(self.input_settings[site][0], monitor=True, site, self.input_settings[site][1])
|
||||||
print "Adding import directories - Site: " + site + " dir: "+ str(self.input_settings[site][0])
|
print "Adding import directories - Site: " + site + " dir: "+ str(self.input_settings[site][0])
|
||||||
self.do_import()
|
self.do_import()
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,9 @@ class HandHistoryConverter:
|
||||||
self.hhdir = os.path.join(self.hhbase,sitename)
|
self.hhdir = os.path.join(self.hhbase,sitename)
|
||||||
self.gametype = []
|
self.gametype = []
|
||||||
self.ofile = os.path.join(self.hhdir, os.path.basename(file))
|
self.ofile = os.path.join(self.hhdir, os.path.basename(file))
|
||||||
|
print self.ofile
|
||||||
self.rexx = FpdbRegex.FpdbRegex()
|
self.rexx = FpdbRegex.FpdbRegex()
|
||||||
|
self.players = set()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
tmp = "HandHistoryConverter: '%s'\n" % (self.sitename)
|
tmp = "HandHistoryConverter: '%s'\n" % (self.sitename)
|
||||||
|
@ -116,10 +118,21 @@ class HandHistoryConverter:
|
||||||
self.gametype = self.determineGameType()
|
self.gametype = self.determineGameType()
|
||||||
self.hands = self.splitFileIntoHands()
|
self.hands = self.splitFileIntoHands()
|
||||||
for hand in self.hands:
|
for hand in self.hands:
|
||||||
print "\nInput:\n"+hand.string
|
print "\nInput:\n"+hand.string+"\n"
|
||||||
self.readHandInfo(hand)
|
self.readHandInfo(hand)
|
||||||
|
|
||||||
self.readPlayerStacks(hand)
|
self.readPlayerStacks(hand)
|
||||||
print "DEBUG stacks:", hand.stacks
|
print "DEBUG stacks:", hand.stacks
|
||||||
|
# at this point we know the player names, they are in hand.players
|
||||||
|
playersThisHand = set([player[1] for player in hand.players])
|
||||||
|
if playersThisHand <= self.players: # x <= y means 'x is subset of y'
|
||||||
|
# we're ok; the regex should already cover them all.
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# we need to recompile the player regexs.
|
||||||
|
self.players = playersThisHand
|
||||||
|
self.compile_player_regexs()
|
||||||
|
|
||||||
self.markStreets(hand)
|
self.markStreets(hand)
|
||||||
self.readBlinds(hand)
|
self.readBlinds(hand)
|
||||||
self.readHeroCards(hand) # want to generalise to draw games
|
self.readHeroCards(hand) # want to generalise to draw games
|
||||||
|
@ -178,7 +191,11 @@ class HandHistoryConverter:
|
||||||
# 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
|
||||||
|
|
||||||
|
# Given
|
||||||
|
#
|
||||||
|
def compile_player_regexs(self): abstract
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -228,7 +245,7 @@ class HandHistoryConverter:
|
||||||
def splitFileIntoHands(self):
|
def splitFileIntoHands(self):
|
||||||
hands = []
|
hands = []
|
||||||
self.obs.strip()
|
self.obs.strip()
|
||||||
list = self.rexx.split_hand_re.split(self.obs)
|
list = self.re_SplitHands.split(self.obs)
|
||||||
list.pop() #Last entry is empty
|
list.pop() #Last entry is empty
|
||||||
for l in list:
|
for l in list:
|
||||||
# print "'" + l + "'"
|
# print "'" + l + "'"
|
||||||
|
@ -250,22 +267,6 @@ class HandHistoryConverter:
|
||||||
traceback.print_exc(file=sys.stderr)
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
#takes a poker float (including , for thousand seperator and converts it to an int
|
|
||||||
def float2int (self, string):
|
|
||||||
pos=string.find(",")
|
|
||||||
if (pos!=-1): #remove , the thousand seperator
|
|
||||||
string=string[0:pos]+string[pos+1:]
|
|
||||||
|
|
||||||
pos=string.find(".")
|
|
||||||
if (pos!=-1): #remove decimal point
|
|
||||||
string=string[0:pos]+string[pos+1:]
|
|
||||||
|
|
||||||
result = int(string)
|
|
||||||
if pos==-1: #no decimal point - was in full dollars - need to multiply with 100
|
|
||||||
result*=100
|
|
||||||
return result
|
|
||||||
#end def float2int
|
|
||||||
|
|
||||||
def getStatus(self):
|
def getStatus(self):
|
||||||
#TODO: Return a status of true if file processed ok
|
#TODO: Return a status of true if file processed ok
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -218,6 +218,10 @@ class Importer:
|
||||||
conv.processFile()
|
conv.processFile()
|
||||||
if(conv.getStatus()):
|
if(conv.getStatus()):
|
||||||
(stored, duplicates, partial, errors, ttime) = self.import_fpdb_file(conv.getProcessedFile(), site)
|
(stored, duplicates, partial, errors, ttime) = self.import_fpdb_file(conv.getProcessedFile(), site)
|
||||||
|
else:
|
||||||
|
# conversion didn't work
|
||||||
|
# TODO: appropriate response?
|
||||||
|
return (0, 0, 0, 1, 0)
|
||||||
|
|
||||||
#This will barf if conv.getStatus != True
|
#This will barf if conv.getStatus != True
|
||||||
return (stored, duplicates, partial, errors, ttime)
|
return (stored, duplicates, partial, errors, ttime)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user