Skip to content

Commit

Permalink
Updated Merge parser to accept new format. Tablename now only in file…
Browse files Browse the repository at this point in the history
…name. Included cash game regression
  • Loading branch information
ChazDazzle committed Aug 14, 2014
1 parent 8b26d95 commit 138ad0d
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 35 deletions.
7 changes: 7 additions & 0 deletions pyfpdb/HandHistoryConverter.py
Expand Up @@ -24,6 +24,7 @@
from optparse import OptionParser
import os
import os.path
import ntpath
import xml.dom.minidom
import codecs
from decimal_wrapper import Decimal
Expand Down Expand Up @@ -82,6 +83,7 @@ def __init__( self, config, in_path = '-', out_path = '-', index=0
self.ftpArchive = ftpArchive

self.in_path = in_path
self.base_name = self.getBasename()
self.out_path = out_path
self.kodec = None

Expand Down Expand Up @@ -519,6 +521,11 @@ def isSummary(self, topline):

def getParsedObjectType(self):
return self.parsedObjectType

def getBasename(self):
head, tail = ntpath.split(self.in_path)
base = tail or ntpath.basename(head)
return base.split('.')[0]

#returns a status (True/False) indicating wether the parsing could be done correctly or not
def readSummaryInfo(self, summaryInfoList): abstract
Expand Down
73 changes: 38 additions & 35 deletions pyfpdb/MergeToFpdb.py
Expand Up @@ -115,35 +115,35 @@ class Merge(HandHistoryConverter):
re_Identify = re.compile(u'<game\sid=\"[0-9]+\-[0-9]+\"\sstarttime')
re_SplitHands = re.compile(r'</game>\n+(?=<)')
re_TailSplitHands = re.compile(r'(</game>)')
re_GameInfo = re.compile(r'<description type="(?P<GAME>Holdem|Omaha|Omaha|Omaha\sH/L8|2\-7\sLowball|A\-5\sLowball|Badugi|5\-Draw\sw/Joker|5\-Draw|7\-Stud|7\-Stud\sH/L8|5\-Stud|Razz|HORSE|RASH|HA|HO|SHOE|HOSE|HAR)(?P<TYPE>\sTournament)?" stakes="(?P<LIMIT>[a-zA-Z ]+)(\s\(?\$?(?P<SB>[.0-9]+)?/?\$?(?P<BB>[.0-9]+)?(?P<blah>.*)\)?)?"(\sversion="\d+")?/>', re.MULTILINE)
re_GameInfo = re.compile(r'<description type="(?P<GAME>Holdem|Omaha|Omaha|Omaha\sH/L8|2\-7\sLowball|A\-5\sLowball|Badugi|5\-Draw\sw/Joker|5\-Draw|7\-Stud|7\-Stud\sH/L8|5\-Stud|Razz|HORSE|RASH|HA|HO|SHOE|HOSE|HAR)(?P<TYPE>\sTournament)?" stakes="(?P<LIMIT>[a-zA-Z ]+)(\s\(?\$?(?P<SB>[.0-9]+)?/?\$?(?P<BB>[.0-9]+)?(?P<blah>.*)\)?)?"(\sversion="\d+")?\s?/>', re.MULTILINE)
# <game id="46154255-645" starttime="20111230232051" numholecards="2" gametype="1" seats="9" realmoney="false" data="20111230|Play Money (46154255)|46154255|46154255-645|false">
# <game id="46165919-1" starttime="20111230161824" numholecards="2" gametype="23" seats="10" realmoney="true" data="20111230|Fun Step 1|46165833-1|46165919-1|true">
# <game id="46289039-1" starttime="20120101200100" numholecards="2" gametype="23" seats="9" realmoney="true" data="20120101|$200 Freeroll - NL Holdem - 20%3A00|46245544-1|46289039-1|true">
re_HandInfo = re.compile(r'<game id="(?P<HID1>[0-9]+)-(?P<HID2>[0-9]+)" starttime="(?P<DATETIME>.+?)" numholecards="[0-9]+" gametype="[0-9]+" (multigametype="(?P<MULTIGAMETYPE>\d+)" )?(seats="(?P<SEATS>[0-9]+)" )?realmoney="(?P<REALMONEY>(true|false))" data="[0-9]+[|:](?P<TABLENAME>[^|:]+)[|:](?P<TDATA>[^|:]+)[|:]?.*>', re.MULTILINE)
re_Button = re.compile(r'<players dealer="(?P<BUTTON>[0-9]+)">')
re_PlayerInfo = re.compile(r'<player seat="(?P<SEAT>[0-9]+)" nickname="(?P<PNAME>.+)" balance="\$(?P<CASH>[.0-9]+)" dealtin="(?P<DEALTIN>(true|false))" />', re.MULTILINE)
re_HandInfo = re.compile(r'<game id="(?P<HID1>[0-9]+)-(?P<HID2>[0-9]+)" starttime="(?P<DATETIME>.+?)" numholecards="[0-9]+" gametype="[0-9]+" (multigametype="(?P<MULTIGAMETYPE>\d+)" )?(seats="(?P<SEATS>[0-9]+)" )?realmoney="(?P<REALMONEY>(true|false))" (data="[0-9]+[|:](?P<TABLENAME>[^|:]+)[|:](?P<TDATA>[^|:]+)[|:]?)?.*>', re.MULTILINE)
re_Button = re.compile(r'<players dealer="(?P<BUTTON>[0-9]+)"\s?>')
re_PlayerInfo = re.compile(r'<player seat="(?P<SEAT>[0-9]+)" nickname="(?P<PNAME>.+)" balance="\$?(?P<CASH>[.0-9]+)" dealtin="(?P<DEALTIN>(true|false))" />', re.MULTILINE)
re_Board = re.compile(r'<cards type="COMMUNITY" cards="(?P<CARDS>[^"]+)"', re.MULTILINE)
re_Buyin = re.compile(r'\$(?P<BUYIN>[.,0-9]+)\s(?P<TYPE>Freeroll|Satellite|Guaranteed)?', re.MULTILINE)
re_secondGame = re.compile(r'\$?(?P<SB>[.0-9]+)?/?\$?(?P<BB>[.0-9]+)', re.MULTILINE)

# The following are also static regexes: there is no need to call
# compilePlayerRegexes (which does nothing), since players are identified
# not by name but by seat number
re_PostSB = re.compile(r'<event sequence="[0-9]+" type="SMALL_BLIND" (?P<TIMESTAMP>timestamp="[0-9]+" )?player="(?P<PSEAT>[0-9])" amount="(?P<SB>[.0-9]+)"/>', re.MULTILINE)
re_PostBB = re.compile(r'<event sequence="[0-9]+" type="(BIG_BLIND|INITIAL_BLIND)" (?P<TIMESTAMP>timestamp="[0-9]+" )?player="(?P<PSEAT>[0-9])" amount="(?P<BB>[.0-9]+)"/>', re.MULTILINE)
re_PostBoth = re.compile(r'<event sequence="[0-9]+" type="RETURN_BLIND" (?P<TIMESTAMP>timestamp="[0-9]+" )?player="(?P<PSEAT>[0-9])" amount="(?P<SBBB>[.0-9]+)"/>', re.MULTILINE)
re_Antes = re.compile(r'<event sequence="[0-9]+" type="ANTE" (?P<TIMESTAMP>timestamp="\d+" )?player="(?P<PSEAT>[0-9])" amount="(?P<ANTE>[.0-9]+)"/>', re.MULTILINE)
re_BringIn = re.compile(r'<event sequence="[0-9]+" type="BRING_IN" (?P<TIMESTAMP>timestamp="\d+" )?player="(?P<PSEAT>[0-9])" amount="(?P<BRINGIN>[.0-9]+)"/>', re.MULTILINE)
re_PostSB = re.compile(r'<event sequence="[0-9]+" type="SMALL_BLIND" (?P<TIMESTAMP>timestamp="[0-9]+" )?player="(?P<PSEAT>[0-9])" amount="(?P<SB>[.0-9]+)"\s?/>', re.MULTILINE)
re_PostBB = re.compile(r'<event sequence="[0-9]+" type="(BIG_BLIND|INITIAL_BLIND)" (?P<TIMESTAMP>timestamp="[0-9]+" )?player="(?P<PSEAT>[0-9])" amount="(?P<BB>[.0-9]+)"\s?/>', re.MULTILINE)
re_PostBoth = re.compile(r'<event sequence="[0-9]+" type="RETURN_BLIND" (?P<TIMESTAMP>timestamp="[0-9]+" )?player="(?P<PSEAT>[0-9])" amount="(?P<SBBB>[.0-9]+)"\s?/>', re.MULTILINE)
re_Antes = re.compile(r'<event sequence="[0-9]+" type="ANTE" (?P<TIMESTAMP>timestamp="\d+" )?player="(?P<PSEAT>[0-9])" amount="(?P<ANTE>[.0-9]+)"\s?/>', re.MULTILINE)
re_BringIn = re.compile(r'<event sequence="[0-9]+" type="BRING_IN" (?P<TIMESTAMP>timestamp="\d+" )?player="(?P<PSEAT>[0-9])" amount="(?P<BRINGIN>[.0-9]+)"\s?/>', re.MULTILINE)
re_HeroCards = re.compile(r'<cards type="(HOLE|DRAW_DRAWN_CARDS)" cards="(?P<CARDS>.+)" player="(?P<PSEAT>[0-9])"', re.MULTILINE)
re_Action = re.compile(r'<event sequence="[0-9]+" type="(?P<ATYPE>FOLD|CHECK|CALL|BET|RAISE|ALL_IN|SIT_OUT|DRAW|COMPLETE)"( timestamp="(?P<TIMESTAMP>[0-9]+)")? player="(?P<PSEAT>[0-9])"( amount="(?P<BET>[.0-9]+)")?( text="(?P<TXT>.+)")?/>', re.MULTILINE)
re_AllActions = re.compile(r'<event sequence="[0-9]+" type="(?P<ATYPE>FOLD|CHECK|CALL|BET|RAISE|ALL_IN|SIT_OUT|DRAW|COMPLETE|BIG_BLIND|INITIAL_BLIND|SMALL_BLIND|RETURN_BLIND|BRING_IN|ANTE)"( timestamp="(?P<TIMESTAMP>[0-9]+)")? player="(?P<PSEAT>[0-9])"( amount="(?P<BET>[.0-9]+)")?( text="(?P<TXT>.+)")?/>', re.MULTILINE)
re_Action = re.compile(r'<event sequence="[0-9]+" type="(?P<ATYPE>FOLD|CHECK|CALL|BET|RAISE|ALL_IN|SIT_OUT|DRAW|COMPLETE)"( timestamp="(?P<TIMESTAMP>[0-9]+)")? player="(?P<PSEAT>[0-9])"( amount="(?P<BET>[.0-9]+)")?( text="(?P<TXT>.+)")?\s?/>', re.MULTILINE)
re_AllActions = re.compile(r'<event sequence="[0-9]+" type="(?P<ATYPE>FOLD|CHECK|CALL|BET|RAISE|ALL_IN|SIT_OUT|DRAW|COMPLETE|BIG_BLIND|INITIAL_BLIND|SMALL_BLIND|RETURN_BLIND|BRING_IN|ANTE)"( timestamp="(?P<TIMESTAMP>[0-9]+)")? player="(?P<PSEAT>[0-9])"( amount="(?P<BET>[.0-9]+)")?( text="(?P<TXT>.+)")?\s?/>', re.MULTILINE)
re_CollectPot = re.compile(r'<winner amount="(?P<POT>[.0-9]+)" uncalled="(?P<UNCALLED>false|true)" potnumber="[0-9]+" player="(?P<PSEAT>[0-9])"', re.MULTILINE)
re_SitsOut = re.compile(r'<event sequence="[0-9]+" type="SIT_OUT" player="(?P<PSEAT>[0-9])"/>', re.MULTILINE)
re_ShownCards = re.compile(r'<cards type="(?P<SHOWED>SHOWN|MUCKED)" cards="(?P<CARDS>.+)" player="(?P<PSEAT>[0-9])"/>', re.MULTILINE)
re_Connection = re.compile(r'<event sequence="[0-9]+" type="(?P<TYPE>RECONNECTED|DISCONNECTED)" timestamp="[0-9]+" player="[0-9]"/>', re.MULTILINE)
re_Cancelled = re.compile(r'<event sequence="\d+" type="GAME_CANCELLED" timestamp="\d+"/>', re.MULTILINE)
re_LeaveTable = re.compile(r'<event sequence="\d+" type="LEAVE" timestamp="\d+" player="\d"/>', re.MULTILINE)
re_PlayerOut = re.compile(r'<event sequence="\d+" type="(PLAYER_OUT|LEAVE)" timestamp="\d+" player="(?P<PSEAT>[0-9])"/>', re.MULTILINE)
re_SitsOut = re.compile(r'<event sequence="[0-9]+" type="SIT_OUT" player="(?P<PSEAT>[0-9])"\s?/>', re.MULTILINE)
re_ShownCards = re.compile(r'<cards type="(?P<SHOWED>SHOWN|MUCKED)" cards="(?P<CARDS>.+)" player="(?P<PSEAT>[0-9])"\s?/>', re.MULTILINE)
re_Connection = re.compile(r'<event sequence="[0-9]+" type="(?P<TYPE>RECONNECTED|DISCONNECTED)" timestamp="[0-9]+" player="[0-9]"\s?/>', re.MULTILINE)
re_Cancelled = re.compile(r'<event sequence="\d+" type="GAME_CANCELLED" timestamp="\d+"\s?/>', re.MULTILINE)
re_LeaveTable = re.compile(r'<event sequence="\d+" type="LEAVE" timestamp="\d+" player="\d"\s?/>', re.MULTILINE)
re_PlayerOut = re.compile(r'<event sequence="\d+" type="(PLAYER_OUT|LEAVE)" timestamp="\d+" player="(?P<PSEAT>[0-9])"\s?/>', re.MULTILINE)
re_EndOfHand = re.compile(r'<round id="END_OF_GAME"', re.MULTILINE)
re_DateTime = re.compile(r'(?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]+)', re.MULTILINE)
re_PlayMoney = re.compile(r'realmoney="false"')
Expand Down Expand Up @@ -314,8 +314,11 @@ def readHandInfo(self, hand):
hand.maxseats = int(m.group('SEATS'))
else:
#log.debug("HID %s-%s, Table %s" % (m.group('HID1'), m.group('HID2'), m.group('TABLENAME')))
hand.tablename = m.group('TABLENAME')
hand.maxseats = None
if m.group('TABLENAME')!=None:
hand.tablename = m.group('TABLENAME')
else:
hand.tablename = self.base_name
if m.group('SEATS')!=None:
hand.maxseats = int(m.group('SEATS'))
# Check that the hand is complete up to the awarding of the pot; if
Expand Down Expand Up @@ -370,28 +373,28 @@ def readPlayerStacks(self, hand):

def markStreets(self, hand):
if hand.gametype['base'] == 'hold':
m = re.search(r'<round id="PREFLOP" sequence="[0-9]+">(?P<PREFLOP>.+(?=<round id="POSTFLOP")|.+)'
r'(<round id="POSTFLOP" sequence="[0-9]+">(?P<FLOP>.+(?=<round id="POSTTURN")|.+))?'
r'(<round id="POSTTURN" sequence="[0-9]+">(?P<TURN>.+(?=<round id="POSTRIVER")|.+))?'
r'(<round id="POSTRIVER" sequence="[0-9]+">(?P<RIVER>.+))?', hand.handText, re.DOTALL)
m = re.search(r'<round id="PREFLOP" sequence="[0-9]+"\s?>(?P<PREFLOP>.+(?=<round id="POSTFLOP")|.+)'
r'(<round id="POSTFLOP" sequence="[0-9]+"\s?>(?P<FLOP>.+(?=<round id="POSTTURN")|.+))?'
r'(<round id="POSTTURN" sequence="[0-9]+"\s?>(?P<TURN>.+(?=<round id="POSTRIVER")|.+))?'
r'(<round id="POSTRIVER" sequence="[0-9]+"\s?>(?P<RIVER>.+))?', hand.handText, re.DOTALL)
elif hand.gametype['base'] == 'draw':
if hand.gametype['category'] in ('27_3draw','badugi','a5_3draw'):
m = re.search(r'(?P<PREDEAL>.+(?=<round id="PRE_FIRST_DRAW" sequence="[0-9]+">)|.+)'
r'(<round id="PRE_FIRST_DRAW" sequence="[0-9]+">(?P<DEAL>.+(?=<round id="FIRST_DRAW" sequence="[0-9]+">)|.+))?'
r'(<round id="FIRST_DRAW" sequence="[0-9]+">(?P<DRAWONE>.+(?=<round id="SECOND_DRAW" sequence="[0-9]+">)|.+))?'
r'(<round id="SECOND_DRAW" sequence="[0-9]+">(?P<DRAWTWO>.+(?=<round id="THIRD_DRAW" sequence="[0-9]+">)|.+))?'
r'(<round id="THIRD_DRAW" sequence="[0-9]+">(?P<DRAWTHREE>.+))?', hand.handText,re.DOTALL)
r'(<round id="PRE_FIRST_DRAW" sequence="[0-9]+"\s?>(?P<DEAL>.+(?=<round id="FIRST_DRAW" sequence="[0-9]+">)|.+))?'
r'(<round id="FIRST_DRAW" sequence="[0-9]+"\s?>(?P<DRAWONE>.+(?=<round id="SECOND_DRAW" sequence="[0-9]+">)|.+))?'
r'(<round id="SECOND_DRAW" sequence="[0-9]+"\s?>(?P<DRAWTWO>.+(?=<round id="THIRD_DRAW" sequence="[0-9]+">)|.+))?'
r'(<round id="THIRD_DRAW" sequence="[0-9]+"\s?>(?P<DRAWTHREE>.+))?', hand.handText,re.DOTALL)
else:
m = re.search(r'(?P<PREDEAL>.+(?=<round id="PRE_FIRST_DRAW" sequence="[0-9]+">)|.+)'
r'(<round id="PRE_FIRST_DRAW" sequence="[0-9]+">(?P<DEAL>.+(?=<round id="FIRST_DRAW" sequence="[0-9]+">)|.+))?'
r'(<round id="FIRST_DRAW" sequence="[0-9]+">(?P<DRAWONE>.+(?=<round id="SECOND_DRAW" sequence="[0-9]+">)|.+))?', hand.handText,re.DOTALL)
m = re.search(r'(?P<PREDEAL>.+(?=<round id="PRE_FIRST_DRAW" sequence="[0-9]+"\s?>)|.+)'
r'(<round id="PRE_FIRST_DRAW" sequence="[0-9]+"\s?>(?P<DEAL>.+(?=<round id="FIRST_DRAW" sequence="[0-9]+">)|.+))?'
r'(<round id="FIRST_DRAW" sequence="[0-9]+"\s?>(?P<DRAWONE>.+(?=<round id="SECOND_DRAW" sequence="[0-9]+">)|.+))?', hand.handText,re.DOTALL)
elif hand.gametype['base'] == 'stud':
m = re.search(r'(?P<ANTES>.+(?=<round id="BRING_IN" sequence="[0-9]+">)|.+)'
r'(<round id="BRING_IN" sequence="[0-9]+">(?P<THIRD>.+(?=<round id="FOURTH_STREET" sequence="[0-9]+">)|.+))?'
r'(<round id="FOURTH_STREET" sequence="[0-9]+">(?P<FOURTH>.+(?=<round id="FIFTH_STREET" sequence="[0-9]+">)|.+))?'
r'(<round id="FIFTH_STREET" sequence="[0-9]+">(?P<FIFTH>.+(?=<round id="SIXTH_STREET" sequence="[0-9]+">)|.+))?'
r'(<round id="SIXTH_STREET" sequence="[0-9]+">(?P<SIXTH>.+(?=<round id="SEVENTH_STREET" sequence="[0-9]+">)|.+))?'
r'(<round id="SEVENTH_STREET" sequence="[0-9]+">(?P<SEVENTH>.+))?', hand.handText,re.DOTALL)
m = re.search(r'(?P<ANTES>.+(?=<round id="BRING_IN" sequence="[0-9]+"\s?>)|.+)'
r'(<round id="BRING_IN" sequence="[0-9]+"\s?>(?P<THIRD>.+(?=<round id="FOURTH_STREET" sequence="[0-9]+">)|.+))?'
r'(<round id="FOURTH_STREET" sequence="[0-9]+"\s?>(?P<FOURTH>.+(?=<round id="FIFTH_STREET" sequence="[0-9]+">)|.+))?'
r'(<round id="FIFTH_STREET" sequence="[0-9]+"\s?>(?P<FIFTH>.+(?=<round id="SIXTH_STREET" sequence="[0-9]+">)|.+))?'
r'(<round id="SIXTH_STREET" sequence="[0-9]+"\s?>(?P<SIXTH>.+(?=<round id="SEVENTH_STREET" sequence="[0-9]+">)|.+))?'
r'(<round id="SEVENTH_STREET" sequence="[0-9]+"\s?>(?P<SEVENTH>.+))?', hand.handText,re.DOTALL)
if m == None:
self.determineErrorType(hand, "markStreets")
hand.addStreets(m)
Expand Down
@@ -0,0 +1,48 @@
<description type="Holdem" stakes="No Limit ($0.02/$0.04)" version="2" />
<game id="78024719-264" starttime="20140722193309" numholecards="2" gametype="2" seats="6" realmoney="true" >
<players dealer="3" >
<player seat="0" nickname="Player0" balance="4.00" dealtin="false" />
<player seat="1" nickname="Hero" balance="2.00" dealtin="true" />
<player seat="2" nickname="Player1" balance="4.96" dealtin="true" />
<player seat="3" nickname="Player2" balance="1.40" dealtin="true" />
<player seat="4" nickname="Player3" balance="2.21" dealtin="true" />
<player seat="5" nickname="Player4" balance="4.01" dealtin="true" />
</players>
<round id="BLINDS" sequence="1" >
<event sequence="1" type="SMALL_BLIND" player="4" amount="0.02" />
<event sequence="2" type="BIG_BLIND" player="5" amount="0.04" />
</round>
<round id="PREFLOP" sequence="2" >
<event sequence="3" type="FOLD" player="1" />
<event sequence="4" type="FOLD" player="2" />
<event sequence="5" type="RAISE" player="3" amount="0.14" />
<event sequence="6" type="CALL" player="4" amount="0.12" />
<event sequence="7" type="FOLD" player="5" />
<cards type="HOLE" cards="3d,4h" player="1" hand="Four High" />
</round>
<round id="POSTFLOP" sequence="3" >
<event sequence="8" type="CHECK" player="4" />
<event sequence="9" type="CHECK" player="3" />
<cards type="COMMUNITY" cards="Td,8h,Ac" player="-1" hand="Ace High" />
</round>
<round id="POSTTURN" sequence="4" >
<event sequence="10" type="BET" player="4" amount="0.16" />
<event sequence="11" type="CALL" player="3" amount="0.16" />
<cards type="COMMUNITY" cards="Td,8h,Ac,2d" player="-1" hand="Ace High" />
</round>
<round id="POSTRIVER" sequence="5" >
<event sequence="12" type="BET" player="4" amount="0.16" />
<event sequence="13" type="CALL" player="3" amount="0.16" />
<cards type="COMMUNITY" cards="Td,8h,Ac,2d,6c" player="-1" hand="Ace High" />
</round>
<round id="SHOWDOWN" sequence="6" >
<event sequence="14" type="SHOW" player="4" />
<event sequence="15" type="MUCK" player="3" />
<cards type="SHOWN" cards="Qc,Qd" player="4" />
<cards type="MUCKED" cards="Tc,Jd" player="3" />
</round>
<round id="END_OF_GAME" sequence="7" >
<winner amount="0.91" uncalled="false" potnumber="1" player="4" pottype="n" hand="Pair of Queens" />
</round>
</game>

0 comments on commit 138ad0d

Please sign in to comment.