2010-07-08 20:01:03 +02:00
#!/usr/bin/env python
2009-08-06 03:07:16 +02:00
# -*- coding: utf-8 -*-
#
2010-07-04 03:05:16 +02:00
# Copyright 2008-2010, Carl Gherardi
2009-08-06 03:07:16 +02:00
#
# 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
########################################################################
2010-09-22 17:51:56 +02:00
import L10n
_ = L10n . get_translation ( )
2009-08-06 03:07:16 +02:00
# TODO: I have no idea if AP has multi-currency options, i just copied the regex out of Everleaf converter for the currency symbols.. weeeeee - Eric
import sys
import logging
from HandHistoryConverter import *
# Class for converting Absolute HH format.
class Absolute ( HandHistoryConverter ) :
2009-08-12 12:34:17 +02:00
# Class Variables
sitename = " Absolute "
filetype = " text "
codepage = " cp1252 "
siteid = 8
2009-08-31 10:18:00 +02:00
HORSEHand = False
2009-08-06 03:07:16 +02:00
# Static regexes
re_SplitHands = re . compile ( r " \ n \ n \ n+ " )
re_TailSplitHands = re . compile ( r " ( \ n \ n \ n+) " )
#Stage #1571362962: Holdem No Limit $0.02 - 2009-08-05 15:24:06 (ET)
#Table: TORONTO AVE (Real Money) Seat #6 is the dealer
#Seat 6 - FETS63 ($0.75 in chips)
#Board [10s 5d Kh Qh 8c]
2010-09-03 05:49:41 +02:00
re_GameInfo = re . compile ( ur """ ^Stage #(C?[0-9]+): \ s+
( ? P < GAME > Holdem | Seven \sCard \sHi \/ L | HORSE )
( ? : \s \( 1 \son \s1 \) | ) ? \s + ?
( ? P < LIMIT > No Limit | Pot \sLimit | Normal | ) ? \s ?
( ? P < CURRENCY > \$ | \s € | )
( ? P < SB > [ .0 - 9 ] + ) / ? ( ? : \$ | \s € | ) ( ? P < BB > [ .0 - 9 ] + ) ?
""" , re.MULTILINE|re.VERBOSE)
2009-08-31 10:18:00 +02:00
re_HorseGameInfo = re . compile ( ur " ^Game Type: (?P<LIMIT>Limit) (?P<GAME>Holdem) " , re . MULTILINE )
2009-08-27 09:29:44 +02:00
# TODO: can set max seats via (1 on 1) to a known 2 ..
2010-07-31 12:38:24 +02:00
re_HandInfo = re . compile ( ur " ^Stage #C?(?P<HID>[0-9]+): .*(?P<DATETIME> \ d \ d \ d \ d- \ d \ d- \ d \ d \ d \ d: \ d \ d: \ d \ d).* \n (Table: (?P<TABLE>.*) \ (Real Money \ ))? " , re . MULTILINE )
2009-08-31 10:18:00 +02:00
re_TableFromFilename = re . compile ( ur " .*IHH([0-9]+) (?P<TABLE>.*) - " ) # on HORSE STUD games, the table name isn't in the hand info!
2009-08-06 03:07:16 +02:00
re_Button = re . compile ( ur " Seat #(?P<BUTTON>[0-9]) is the ?[dead]* dealer$ " , re . MULTILINE ) # TODO: that's not the right way to match for "dead" dealer is it?
re_PlayerInfo = re . compile ( ur " ^Seat (?P<SEAT>[0-9]) - (?P<PNAME>.*) \ ((?: \ $| €|)(?P<CASH>[0-9]*[.0-9]+) in chips \ ) " , re . MULTILINE )
re_Board = re . compile ( ur " \ [(?P<CARDS>[^ \ ]]*) \ ]? *$ " , re . MULTILINE )
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 )
#(?P<CURRENCY>\$| €|)(?P<BB>[0-9]*[.0-9]+)
self . re_PostSB = re . compile ( ur " ^ %s - Posts small blind (?: \ $| €|)(?P<SB>[0-9]*[.0-9]+) " % player_re , re . MULTILINE )
self . re_PostBB = re . compile ( ur " ^ %s - Posts big blind (?: \ $| €|)(?P<BB>[0-9]*[.0-9]+) " % player_re , re . MULTILINE )
# TODO: Absolute posting when coming in new: %s - Posts $0.02 .. should that be a new Post line? where do we need to add support for that? *confused*
self . re_PostBoth = re . compile ( ur " ^ %s - Posts dead (?: \ $| €|)(?P<SBBB>[0-9]*[.0-9]+) " % player_re , re . MULTILINE )
self . re_Action = re . compile ( ur " ^ %s - (?P<ATYPE>Bets |Raises |All-In |All-In \ (Raise \ ) |Calls |Folds|Checks)? \ $?(?P<BET>[0-9]*[.0-9]+)? " % player_re , re . MULTILINE )
2009-08-06 13:23:57 +02:00
# print "^%s - (?P<ATYPE>Bets |Raises |All-In |All-In\(Raise\) |Calls |Folds|Checks)?\$?(?P<BET>[0-9]*[.0-9]+)?" % player_re
2009-08-06 03:07:16 +02:00
self . re_ShowdownAction = re . compile ( ur " ^ %s - Shows \ [(?P<CARDS>.*) \ ] " % player_re , re . MULTILINE )
2009-08-27 09:29:44 +02:00
self . re_CollectPot = re . compile ( ur " ^Seat [0-9]: %s (?: \ (dealer \ )|)(?: \ (big blind \ )| \ (small blind \ )|) (?:won|collected) Total \ ((?: \ $| €|)(?P<POT>[0-9]*[.0-9]+) \ ) " % player_re , re . MULTILINE )
2009-08-06 03:07:16 +02:00
#self.re_PostSB = re.compile(ur"^%s: posts small blind \[(?:\$| €|) (?P<SB>[.0-9]+)" % player_re, re.MULTILINE)
#self.re_PostBB = re.compile(ur"^%s: posts big blind \[(?:\$| €|) (?P<BB>[.0-9]+)" % player_re, re.MULTILINE)
#self.re_PostBoth = re.compile(ur"^%s: posts both blinds \[(?:\$| €|) (?P<SBBB>[.0-9]+)" % player_re, re.MULTILINE)
2009-08-21 12:57:04 +02:00
self . re_Antes = re . compile ( ur " ^ %s - Ante \ [(?: \ $| €|)(?P<ANTE>[.0-9]+) " % player_re , re . MULTILINE )
2009-08-06 03:07:16 +02:00
#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_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| 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_CollectPot = re.compile(ur"^%s wins (?:\$| €|) (?P<POT>[.\d]+) (USD|EUR|chips)(.*?\[ (?P<CARDS>.*?) \])?" % player_re, re.MULTILINE)
#self.re_SitsOut = re.compile(ur"^%s sits out" % player_re, re.MULTILINE)
def readSupportedGames ( self ) :
return [ [ " ring " , " hold " , " nl " ] ,
[ " ring " , " hold " , " pl " ] ,
[ " ring " , " hold " , " fl " ] ,
[ " ring " , " studhi " , " fl " ] ,
[ " ring " , " omahahi " , " pl " ]
]
def determineGameType ( self , handText ) :
""" return dict with keys/values:
2010-07-31 12:38:24 +02:00
' type ' in ( ' ring ' , ' tour ' )
' limitType ' in ( ' nl ' , ' cn ' , ' pl ' , ' cp ' , ' fl ' )
' base ' in ( ' hold ' , ' stud ' , ' draw ' )
' category ' in ( ' holdem ' , ' omahahi ' , omahahilo ' , ' razz ' , ' studhi ' , ' studhilo ' , ' fivedraw ' , ' 27_1 draw ' , ' 27_3 draw ' , ' badugi ' )
' hilo ' in ( ' h ' , ' l ' , ' s ' )
' smallBlind ' int ?
' bigBlind ' int ?
' smallBet '
' bigBet '
' currency ' in ( ' USD ' , ' EUR ' , ' T$ ' , < countrycode > )
or None if we fail to get the info """
2009-08-06 03:07:16 +02:00
info = { ' type ' : ' ring ' }
m = self . re_GameInfo . search ( handText )
if not m :
2010-09-03 05:49:41 +02:00
tmp = handText [ 0 : 100 ]
log . error ( _ ( " determineGameType: Unable to recognise gametype from: ' %s ' " ) % tmp )
log . error ( _ ( " determineGameType: Raising FpdbParseError " ) )
raise FpdbParseError ( _ ( " Unable to recognise gametype from: ' %s ' " ) % tmp )
2009-08-06 03:07:16 +02:00
mg = m . groupdict ( )
# translations from captured groups to our info strings
2009-08-31 10:18:00 +02:00
limits = { ' No Limit ' : ' nl ' , ' Pot Limit ' : ' pl ' , ' Normal ' : ' fl ' , ' Limit ' : ' fl ' }
2009-08-06 03:07:16 +02:00
games = { # base, category
2010-09-03 05:49:41 +02:00
" Holdem " : ( ' hold ' , ' holdem ' ) ,
2009-08-06 03:07:16 +02:00
' Omaha ' : ( ' hold ' , ' omahahi ' ) ,
' Razz ' : ( ' stud ' , ' razz ' ) ,
2010-09-03 05:49:41 +02:00
' Seven Card Hi/L ' : ( ' stud ' , ' studhilo ' ) ,
2009-08-06 03:07:16 +02:00
' 7 Card Stud ' : ( ' stud ' , ' studhi ' )
}
currencies = { u ' € ' : ' EUR ' , ' $ ' : ' USD ' , ' ' : ' T$ ' }
2009-08-31 10:18:00 +02:00
if ' GAME ' in mg and mg [ ' GAME ' ] == " HORSE " : # if we're a HORSE game, the game type is on the next line
self . HORSEHand = True
m = self . re_HorseGameInfo . search ( handText )
if not m :
return None # it's a HORSE game and we don't understand the game type
temp = m . groupdict ( )
#print "AP HORSE processing"
if ' GAME ' not in temp or ' LIMIT ' not in temp :
return None # sort of understood it but not really
#print "temp=", temp
mg [ ' GAME ' ] = temp [ ' GAME ' ]
mg [ ' LIMIT ' ] = temp [ ' LIMIT ' ]
2009-08-06 03:07:16 +02:00
if ' GAME ' in mg :
( info [ ' base ' ] , info [ ' category ' ] ) = games [ mg [ ' GAME ' ] ]
2009-08-31 10:18:00 +02:00
if ' LIMIT ' in mg :
info [ ' limitType ' ] = limits [ mg [ ' LIMIT ' ] ]
2009-08-06 03:07:16 +02:00
if ' SB ' in mg :
info [ ' sb ' ] = mg [ ' SB ' ]
else :
2009-08-27 09:29:44 +02:00
info [ ' sb ' ] = str ( float ( mg [ ' BB ' ] ) * 0.5 ) # TODO: Apparently AP doesn't provide small blind info!? must search to see if it's posted, I guess
2009-08-27 11:28:59 +02:00
if ' BB ' in mg :
2009-08-06 03:07:16 +02:00
info [ ' bb ' ] = mg [ ' BB ' ]
if ' CURRENCY ' in mg :
info [ ' currency ' ] = currencies [ mg [ ' CURRENCY ' ] ]
if info [ ' currency ' ] == ' T$ ' :
info [ ' type ' ] = ' tour '
# NB: SB, BB must be interpreted as blinds or bets depending on limit type.
2009-08-27 11:28:59 +02:00
if info [ ' bb ' ] is None :
info [ ' bb ' ] = mg [ ' SB ' ]
info [ ' sb ' ] = str ( float ( mg [ ' SB ' ] ) * 0.5 ) # TODO: AP does provide Small BET for Limit .. I think? at least 1-on-1 limit they do.. sigh
#print info;
2009-08-06 03:07:16 +02:00
return info
def readHandInfo ( self , hand ) :
m = self . re_HandInfo . search ( hand . handText )
if ( m == None ) :
2010-08-29 21:31:34 +02:00
logging . info ( _ ( " Didn ' t match re_HandInfo " ) )
2009-08-06 03:07:16 +02:00
logging . info ( hand . handText )
return None
logging . debug ( " HID %s , Table %s " % ( m . group ( ' HID ' ) , m . group ( ' TABLE ' ) ) )
hand . handid = m . group ( ' HID ' )
2009-08-31 10:18:00 +02:00
if m . group ( ' TABLE ' ) :
hand . tablename = m . group ( ' TABLE ' )
else :
t = self . re_TableFromFilename . search ( self . in_path )
hand . tablename = t . group ( ' TABLE ' )
2009-08-06 03:07:16 +02:00
hand . maxseats = 6 # assume 6-max unless we have proof it's a larger/smaller game, since absolute doesn't give seat max info
2009-08-31 10:18:00 +02:00
# TODO: (1-on-1) does have that info in the game type line
if self . HORSEHand :
hand . maxseats = 8
2010-07-08 17:30:02 +02:00
hand . startTime = datetime . datetime . strptime ( m . group ( ' DATETIME ' ) , " % Y- % m- %d % H: % M: % S " )
2009-08-06 03:07:16 +02:00
return
def readPlayerStacks ( self , hand ) :
m = self . re_PlayerInfo . finditer ( hand . handText )
for a in m :
seatnum = int ( a . group ( ' SEAT ' ) )
hand . addPlayer ( seatnum , a . group ( ' PNAME ' ) , a . group ( ' CASH ' ) )
if seatnum > 6 :
hand . maxseats = 10 # absolute does 2/4/6/8/10 games
# TODO: implement lookup list by table-name to determine maxes, then fall back to 6 default/10 here, if there's no entry in the list?
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.
#m = re.search('(\*\* Dealing down cards \*\*\n)(?P<PREFLOP>.*?\n\*\*)?( Dealing Flop \*\* \[ (?P<FLOP1>\S\S), (?P<FLOP2>\S\S), (?P<FLOP3>\S\S) \])?(?P<FLOP>.*?\*\*)?( Dealing Turn \*\* \[ (?P<TURN1>\S\S) \])?(?P<TURN>.*?\*\*)?( Dealing River \*\* \[ (?P<RIVER1>\S\S) \])?(?P<RIVER>.*)', hand.handText,re.DOTALL)
if hand . gametype [ ' base ' ] == ' hold ' :
m = re . search ( r " \ * \ * \ * POCKET CARDS \ * \ * \ *(?P<PREFLOP>.+(?= \ * \ * \ * FLOP \ * \ * \ *)|.+) "
2009-08-06 05:30:21 +02:00
r " ( \ * \ * \ * FLOP \ * \ * \ *(?P<FLOP>.+(?= \ * \ * \ * TURN \ * \ * \ *)|.+))? "
r " ( \ * \ * \ * TURN \ * \ * \ *(?P<TURN>.+(?= \ * \ * \ * RIVER \ * \ * \ *)|.+))? "
r " ( \ * \ * \ * RIVER \ * \ * \ *(?P<RIVER>.+))? " , hand . handText , re . DOTALL )
2009-08-06 03:07:16 +02:00
elif hand . gametype [ ' base ' ] == ' stud ' : # TODO: Not implemented yet
m = re . search ( r " (?P<ANTES>.+(?= \ * \ * Dealing down cards \ * \ *)|.+) "
r " ( \ * \ * Dealing down cards \ * \ *(?P<THIRD>.+(?= \ * \ * \ * \ * dealing 4th street \ * \ * \ * \ *)|.+))? "
r " ( \ * \ * \ * \ * dealing 4th street \ * \ * \ * \ *(?P<FOURTH>.+(?= \ * \ * \ * \ * dealing 5th street \ * \ * \ * \ *)|.+))? "
r " ( \ * \ * \ * \ * dealing 5th street \ * \ * \ * \ *(?P<FIFTH>.+(?= \ * \ * \ * \ * dealing 6th street \ * \ * \ * \ *)|.+))? "
r " ( \ * \ * \ * \ * dealing 6th street \ * \ * \ * \ *(?P<SIXTH>.+(?= \ * \ * \ * \ * dealing river \ * \ * \ * \ *)|.+))? "
r " ( \ * \ * \ * \ * dealing river \ * \ * \ * \ *(?P<SEVENTH>.+))? " , hand . handText , re . DOTALL )
hand . addStreets ( m )
def readCommunityCards ( self , hand , street ) : # street has been matched by markStreets, so exists in this hand
# If this has been called, street is a street which gets dealt community cards by type hand
# but it might be worth checking somehow.
# if street in ('FLOP','TURN','RIVER'): # a list of streets which get dealt community cards (i.e. all but PREFLOP)
logging . debug ( " readCommunityCards ( %s ) " % street )
m = self . re_Board . search ( hand . streets [ street ] )
cards = m . group ( ' CARDS ' )
2009-08-06 03:35:01 +02:00
cards = [ validCard ( card ) for card in cards . split ( ' ' ) ]
2009-08-06 03:07:16 +02:00
hand . setCommunityCards ( street = s treet , cards = cards )
def readAntes ( self , hand ) :
2010-08-29 21:31:34 +02:00
logging . debug ( _ ( " reading antes " ) )
2009-08-06 03:07:16 +02:00
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 :
2010-08-29 21:31:34 +02:00
logging . debug ( _ ( " Player bringing in: %s for %s " % ( m . group ( ' PNAME ' ) , m . group ( ' BRINGIN ' ) ) ) )
2009-08-06 03:07:16 +02:00
hand . addBringIn ( m . group ( ' PNAME ' ) , m . group ( ' BRINGIN ' ) )
else :
2010-08-29 21:31:34 +02:00
logging . warning ( _ ( " No bringin found. " ) )
2009-08-06 03:07:16 +02:00
def readBlinds ( self , hand ) :
m = self . re_PostSB . search ( hand . handText )
if m is not None :
hand . addBlind ( m . group ( ' PNAME ' ) , ' small blind ' , m . group ( ' SB ' ) )
else :
2010-08-29 21:31:34 +02:00
logging . debug ( _ ( " No small blind " ) )
2009-08-06 03:07:16 +02:00
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 ' ) , ' both ' , a . group ( ' SBBB ' ) )
def readButton ( self , hand ) :
hand . buttonpos = int ( self . re_Button . search ( hand . handText ) . group ( ' BUTTON ' ) )
def readHeroCards ( self , hand ) :
m = self . re_HeroCards . search ( hand . handText )
if m :
hand . hero = m . group ( ' PNAME ' )
# "2c, qh" -> ["2c","qc"]
# Also works with Omaha hands.
cards = m . group ( ' CARDS ' )
2009-08-06 03:35:01 +02:00
cards = [ validCard ( card ) for card in cards . split ( ' ' ) ]
2009-08-06 03:07:16 +02:00
# hand.addHoleCards(cards, m.group('PNAME'))
hand . addHoleCards ( ' PREFLOP ' , hand . hero , closed = cards , shown = False , mucked = False , dealt = True )
else :
#Not involved in hand
hand . involved = False
2009-08-06 03:35:01 +02:00
2009-08-06 03:07:16 +02:00
def readStudPlayerCards ( self , hand , street ) :
# lol. see Plymouth.txt
2010-08-29 21:31:34 +02:00
logging . warning ( _ ( " Absolute readStudPlayerCards is only a stub. " ) )
2009-08-06 03:07:16 +02:00
#~ if street in ('THIRD', 'FOURTH', 'FIFTH', 'SIXTH'):
#~ hand.addPlayerCards(player = player.group('PNAME'), street = street, closed = [], open = [])
def readAction ( self , hand , street ) :
logging . debug ( " readAction ( %s ) " % street )
m = self . re_Action . finditer ( hand . streets [ street ] )
for action in m :
logging . debug ( " %s %s " % ( action . group ( ' ATYPE ' ) , action . groupdict ( ) ) )
if action . group ( ' ATYPE ' ) == ' Raises ' or action . group ( ' ATYPE ' ) == ' All-In(Raise) ' :
hand . addCallandRaise ( 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 ' or action . group ( ' ATYPE ' ) == ' All-In ' :
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 ' ) == ' complete to ' : # TODO: not supported yet ?
hand . addComplete ( street , action . group ( ' PNAME ' ) , action . group ( ' BET ' ) )
else :
2010-08-29 21:31:34 +02:00
logging . debug ( _ ( " Unimplemented readAction: %s %s " % ( action . group ( ' PNAME ' ) , action . group ( ' ATYPE ' ) , ) ) )
2009-08-06 03:07:16 +02:00
def readShowdownActions ( self , hand ) :
""" Reads lines where holecards are reported in a showdown """
logging . debug ( " readShowdownActions " )
for shows in self . re_ShowdownAction . finditer ( hand . handText ) :
cards = shows . group ( ' CARDS ' )
2009-08-06 03:35:01 +02:00
cards = [ validCard ( card ) for card in cards . split ( ' ' ) ]
2009-08-06 03:07:16 +02:00
logging . debug ( " readShowdownActions %s %s " % ( cards , shows . group ( ' PNAME ' ) ) )
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 ) :
""" Reads lines where hole & board cards are mixed to form a hand (summary lines) """
for m in self . re_CollectPot . finditer ( hand . handText ) :
try :
if m . group ( ' CARDS ' ) is not None :
cards = m . group ( ' CARDS ' )
2009-08-06 03:35:01 +02:00
cards = [ validCard ( card ) for card in cards . split ( ' ' ) ]
2009-08-06 03:07:16 +02:00
player = m . group ( ' PNAME ' )
logging . debug ( " readShownCards %s cards= %s " % ( player , cards ) )
# hand.addShownCards(cards=None, player=m.group('PNAME'), holeandboard=cards)
hand . addShownCards ( cards = cards , player = m . group ( ' PNAME ' ) )
except IndexError :
pass # there's no "PLAYER - Mucks" at AP that I can see
2009-08-06 03:35:01 +02:00
def validCard ( card ) :
card = card . strip ( )
if card == ' 10s ' : card = ' Ts '
if card == ' 10h ' : card = ' Th '
if card == ' 10d ' : card = ' Td '
if card == ' 10c ' : card = ' Tc '
return card
2009-08-06 03:07:16 +02:00
if __name__ == " __main__ " :
2010-07-31 12:38:24 +02:00
import Configuration
config = Configuration . Config ( None )
2009-08-06 03:07:16 +02:00
parser = OptionParser ( )
2010-08-29 21:31:34 +02:00
parser . add_option ( " -i " , " --input " , dest = " ipath " , help = _ ( " parse input hand history " ) , default = " - " )
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 )
2009-08-06 03:07:16 +02:00
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 )
2010-07-31 12:38:24 +02:00
e = Absolute ( config , in_path = options . ipath , out_path = options . opath , follow = options . follow , autostart = True )
2009-08-06 03:07:16 +02:00