def parseSummary(self): if self.hhtype == "summary": self.parseSummaryFile() elif self.hhtype == "html": self.parseSummaryHtml() elif self.hhtype == "hh": self.parseSummaryFromHH() else: raise FpdbParseError(_("parseSummary FAIL"))
def parseSummary(self): if self.hhtype == "summary": self.parseSummaryFile() elif self.hhtype == "html": if self.header == self.summaryText: raise FpdbHandPartial self.parseSummaryHtml() elif self.hhtype == "hh": self.parseSummaryFromHH() else: raise FpdbParseError(_("parseSummary FAIL"))
def readAction(self, hand, street): m = self.re_Action.finditer(hand.streets[street]) for action in m: acts = action.groupdict() playerName = action.group('PNAME') amount = clearMoneyString( action.group('BET')) if action.group('BET') else None actionType = action.group('ATYPE') if actionType == 'is all-In': # party's allin can mean either raise or bet or call Bp = hand.lastBet[street] if Bp == 0: actionType = 'bets' elif Bp < Decimal(amount): actionType = 'raises' else: actionType = 'calls' if actionType == 'raises': if street == 'PREFLOP' and \ playerName in [item[0] for item in hand.actions['BLINDSANTES'] if item[2]!='ante']: # preflop raise from blind hand.addCallandRaise(street, playerName, amount) else: hand.addCallandRaise(street, playerName, amount) elif actionType == 'calls': hand.addCall(street, playerName, amount) elif actionType == 'bets': hand.addBet(street, playerName, amount) elif actionType == 'folds': hand.addFold(street, playerName) elif actionType == 'checks': hand.addCheck(street, playerName) else: raise FpdbParseError( _("Unimplemented readAction: '%s' '%s'") % ( playerName, actionType, ), hid=hand.hid, )
def parseSummary(self): m = self.re_TourneyInfo.search(self.summaryText) if m == None: tmp = self.summaryText[0:200] log.error("parseSummary: " + _("Unable to recognise Tourney Info: '%s'") % tmp) log.error("parseSummary: " + _("Raising FpdbParseError")) raise FpdbParseError(_("Unable to recognise Tourney Info: '%s'") % tmp) print "DEBUG: m.groupdict(): %s" % m.groupdict() mg = m.groupdict() self.tourNo = '' self.gametype['limitType'] = '' self.gametype['category'] = '' self.buyin = 0 self.fee = 0 self.prizepool = 0 self.entries = 0 #self.startTime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S") self.currency = "USD"
def processHand(self, handText): gametype = self.determineGameType(handText) log.debug("gametype %s" % gametype) hand = None l = None if gametype is None: gametype = "unmatched" # TODO: not ideal, just trying to not error. Throw ParseException? self.numErrors += 1 else: # See if gametype is supported. if 'mix' not in gametype: gametype['mix'] = 'none' type = gametype['type'] base = gametype['base'] limit = gametype['limitType'] l = [type] + [base] + [limit] if l in self.readSupportedGames(): if gametype['base'] == 'hold': log.debug( "hand = Hand.HoldemOmahaHand(self, self.sitename, gametype, handtext)" ) hand = Hand.HoldemOmahaHand(self.config, self, self.sitename, gametype, handText) elif gametype['base'] == 'stud': hand = Hand.StudHand(self.config, self, self.sitename, gametype, handText) elif gametype['base'] == 'draw': hand = Hand.DrawHand(self.config, self, self.sitename, gametype, handText) else: log.error(_("Unsupported game type: %s") % gametype) raise FpdbParseError(_("Unsupported game type: %s") % gametype) if hand: #hand.writeHand(self.out_fh) return hand else: log.error(_("Unsupported game type: %s") % gametype)
def parseSummaryHtml(self): raise FpdbParseError( _("PokerStarsSummary.parseSummaryHtml: This file format is not yet supported" ))
def parseSummary(self): m = self.re_TourneyInfo.search(self.summaryText) if m == None: tmp = self.summaryText[0:200] log.error("parseSummary: " + _("Unable to recognise Tourney Info: '%s'") % tmp) log.error("parseSummary: " + _("Raising FpdbParseError")) raise FpdbParseError( _("Unable to recognise Tourney Info: '%s'") % tmp) #print "DEBUG: m.groupdict(): %s" % m.groupdict() mg = m.groupdict() if 'TOURNO' in mg: self.tourNo = mg['TOURNO'] if 'LIMIT' in mg: self.gametype['limitType'] = self.limits[mg['LIMIT']] if 'GAME' in mg: self.gametype['category'] = self.games[mg['GAME']][1] if mg['BUYIN'] != None: self.buyin = int(100 * Decimal(mg['BUYIN'])) if mg['FEE'] != None: self.fee = int(100 * Decimal(mg['FEE'])) if 'PRIZEPOOL' in mg: self.prizepool = mg['PRIZEPOOL'] if 'ENTRIES' in mg: self.entries = mg['ENTRIES'] datetimestr = "%s/%s/%s %s:%s:%s" % (mg['Y'], mg['M'], mg['D'], mg['H'], mg['MIN'], mg['S']) self.startTime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S") if 'TZ' in mg: self.startTime = HandHistoryConverter.changeTimezone( self.startTime, mg['TZ'], "UTC") m = self.re_Currency.search(self.summaryText) if m == None: log.error("parseSummary: " + _("Unable to locate currency")) log.error("parseSummary: " + _("Raising FpdbParseError")) raise FpdbParseError(_("Unable to locate currency")) #print "DEBUG: m.groupdict(): %s" % m.groupdict() mg = m.groupdict() if mg['CURRENCY'] == "$": self.currency = "USD" elif mg['CURRENCY'] == u"€": self.currency = "EUR" elif mg['CURRENCY'] == "FPP": self.currency = "PSFP" m = self.re_Player.finditer(self.summaryText) for a in m: mg = a.groupdict() #print "DEBUG: a.groupdict(): %s" % mg name = mg['NAME'] rank = mg['RANK'] winnings = 0 if 'WINNINGS' in mg and mg['WINNINGS'] != None: winnings = int(100 * Decimal(mg['WINNINGS'])) if 'STILLPLAYING' in mg and mg['STILLPLAYING'] != None: #print "stillplaying" rank = None winnings = None if 'TICKET' and mg['TICKET'] != None: #print "Tournament Ticket Level %s" % mg['LEVEL'] step_values = { '1': '750', # Step 1 - $7.50 USD '2': '2750', # Step 2 - $27.00 USD '3': '8200', # Step 3 - $82.00 USD '4': '21500', # Step 4 - $215.00 USD '5': '70000', # Step 5 - $700.00 USD '6': '210000', # Step 6 - $2100.00 USD } winnings = step_values[mg['LEVEL']] #TODO: currency, ko/addon/rebuy count -> need examples! #print "DEBUG: addPlayer(%s, %s, %s, %s, None, None, None)" %(rank, name, winnings, self.currency) #print "DEBUG: self.buyin: %s self.fee %s" %(self.buyin, self.fee) self.addPlayer(rank, name, winnings, self.currency, None, None, None)
def parseSummary(self): lines = self.summaryText.splitlines() self.tourNo = self.re_TourNo.findall(lines[0])[0][ 1:-1] #ignore game and limit type as thats not recorded result = self.re_GameInfo.search(lines[0]) result = result.groupdict() self.gametype['limitType'] = self.limits[result['LIMIT']] self.gametype['category'] = self.games[result['GAME']][1] if lines[1].find( "$" ) != -1: #TODO: move this into a method and call that from PokerStarsToFpdb.py:269 if hand.buyinCurrency=="USD" etc. self.currency = "USD" elif lines[1].find(u"€") != -1: self.currency = "EUR" elif lines[1].find("FPP") != -1: self.currency = "PSFP" else: raise FpdbParseError( _("didn't recognise buyin currency in:") + lines[1]) if self.currency == "USD" or self.currency == "EUR": result = self.re_BuyInFee.search(lines[1]) result = result.groupdict() self.buyin = int(100 * Decimal(result['BUYIN'])) self.fee = int(100 * Decimal(result['FEE'])) elif self.currency == "PSFP": result = self.re_FPP.search(lines[1]) result = result.groupdict() self.buyin = int(Decimal(result['FPP'])) self.fee = 0 currentLine = 2 self.entries = self.re_Entries.findall(lines[currentLine])[0] currentLine += 1 #note that I chose to make the code keep state (the current line number) #as that means it'll fail rather than silently skip potentially valuable information #print "after entries lines[currentLine]", lines[currentLine] result = self.re_Added.search(lines[currentLine]) if result: result = result.groupdict() self.added = 100 * int(Decimal(result['DOLLAR'])) + int( Decimal(result['CENT'])) self.addedCurrency = result['CURRENCY'] currentLine += 1 else: self.added = 0 self.addedCurrency = "NA" #print "after added/entries lines[currentLine]", lines[currentLine] result = self.re_Prizepool.findall(lines[currentLine]) if result: self.prizepool = result[0] self.prizepool = self.prizepool[1:-3] + self.prizepool[-2:] currentLine += 1 #print "after prizepool lines[currentLine]", lines[currentLine] useET = False result = self.re_DateTime.search(lines[currentLine]) if not result: print _("in not result starttime") useET = True result = self.re_DateTimeET.search(lines[currentLine]) result = result.groupdict() datetimestr = "%s/%s/%s %s:%s:%s" % (result['Y'], result['M'], result['D'], result['H'], result['MIN'], result['S']) self.startTime = datetime.datetime.strptime( datetimestr, "%Y/%m/%d %H:%M:%S") # also timezone at end, e.g. " ET" self.startTime = HandHistoryConverter.changeTimezone( self.startTime, "ET", "UTC") currentLine += 1 if useET: result = self.re_DateTimeET.search(lines[currentLine]) else: result = self.re_DateTime.search(lines[currentLine]) if result: result = result.groupdict() datetimestr = "%s/%s/%s %s:%s:%s" % (result['Y'], result['M'], result['D'], result['H'], result['MIN'], result['S']) self.endTime = datetime.datetime.strptime( datetimestr, "%Y/%m/%d %H:%M:%S") # also timezone at end, e.g. " ET" self.endTime = HandHistoryConverter.changeTimezone( self.endTime, "ET", "UTC") currentLine += 1 if lines[currentLine].find("Tournament is still in progress") != -1: currentLine += 1 for i in range(currentLine, len(lines) - 2): #lines with rank and winnings info if lines[i].find(":") == -1: break result = self.re_Player.search(lines[i]) result = result.groupdict() rank = result['RANK'] name = result['NAME'] winnings = result['WINNINGS'] if winnings: winnings = int(100 * Decimal(winnings)) else: winnings = 0 if result['STILLPLAYING']: #print "stillplaying" rank = None winnings = None self.addPlayer( rank, name, winnings, self.currency, None, None, None) #TODO: currency, ko/addon/rebuy count -> need examples!
def parseSummary(self): m = self.re_TourneyInfo.search(self.summaryText[:2000]) if m == None: tmp = self.summaryText[0:200] log.error("parseSummary: " + _("Unable to recognise Tourney Info: '%s'") % tmp) log.error("parseSummary: " + _("Raising FpdbParseError")) raise FpdbParseError( _("Unable to recognise Tourney Info: '%s'") % tmp) #print "DEBUG: m.groupdict(): %s" % m.groupdict() mg = m.groupdict() if 'TOURNO' in mg: self.tourNo = mg['TOURNO'] if 'LIMIT' in mg: self.gametype['limitType'] = self.limits[mg['LIMIT']] if 'GAME' in mg: self.gametype['category'] = self.games[mg['GAME']][1] if mg['BUYIN'] != None: self.buyin = int(100 * Decimal(mg['BUYIN'])) if mg['FEE'] != None: self.fee = int(100 * Decimal(mg['FEE'])) if 'PRIZEPOOL' in mg: self.prizepool = mg['PRIZEPOOL'] if 'ENTRIES' in mg: self.entries = mg['ENTRIES'] datetimestr = "%s/%s/%s %s:%s:%s" % (mg['Y'], mg['M'], mg['D'], mg['H'], mg['MIN'], mg['S']) self.startTime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S") if 'TZ' in mg: self.startTime = HandHistoryConverter.changeTimezone( self.startTime, mg['TZ'], "UTC") m = self.re_Currency.search(self.summaryText) if m == None: log.error("parseSummary: " + _("Unable to locate currency")) log.error("parseSummary: " + _("Raising FpdbParseError")) raise FpdbParseError(_("Unable to locate currency")) #print "DEBUG: m.groupdict(): %s" % m.groupdict() mg = m.groupdict() if mg['CURRENCY'] == "$": self.currency = "USD" elif mg['CURRENCY'] == u"€": self.currency = "EUR" elif mg['CURRENCY'] == "FPP": self.currency = "PSFP" m = self.re_Player.finditer(self.summaryText) playercount = 0 for a in m: mg = a.groupdict() #print "DEBUG: a.groupdict(): %s" % mg name = mg['NAME'] rank = mg['RANK'] winnings = 0 if 'WINNINGS' in mg and mg['WINNINGS'] != None: winnings = int(100 * Decimal(mg['WINNINGS'])) self.addPlayer(rank, name, winnings, self.currency, None, None, None) playercount += 1 # Some files dont contain the normals lines, and only contain the line # <PLAYER> finished in XXXXrd place if playercount == 0: m = self.re_Finished.finditer(self.summaryText) for a in m: winnings = 0 name = a.group('NAME') rank = a.group('RANK') self.addPlayer(rank, name, winnings, self.currency, None, None, None)
def readHandInfo(self, hand): info = {} try: info.update(self.re_Hid.search(hand.handText).groupdict()) except: raise FpdbParseError(_("Cannot read HID for current hand")) try: info.update( self.re_HandInfo.search(hand.handText, re.DOTALL).groupdict()) except: raise FpdbParseError(_("Cannot read Handinfo for current hand"), hid=info['HID']) try: info.update(self._getGameType(hand.handText).groupdict()) except: raise FpdbParseError(_("Cannot read GameType for current hand"), hid=info['HID']) m = self.re_CountedSeats.search(hand.handText) if m: info.update(m.groupdict()) # FIXME: it's dirty hack # party doesnt subtract uncalled money from commited money # so hand.totalPot calculation has to be redefined from Hand import Pot, HoldemOmahaHand def getNewTotalPot(origTotalPot): def totalPot(self): if self.totalpot is None: self.pot.end() self.totalpot = self.pot.total for i, v in enumerate(self.collected): if v[0] in self.pot.returned: self.collected[i][1] = Decimal( v[1]) - self.pot.returned[v[0]] self.collectees[v[0]] -= self.pot.returned[v[0]] self.pot.returned[v[0]] = 0 return origTotalPot() return totalPot instancemethod = type(hand.totalPot) hand.totalPot = instancemethod(getNewTotalPot(hand.totalPot), hand, HoldemOmahaHand) log.debug("readHandInfo: %s" % info) for key in info: if key == 'DATETIME': #Saturday, July 25, 07:53:52 EDT 2009 #Thursday, July 30, 21:40:41 MSKS 2009 #Sunday, October 25, 13:39:07 MSK 2009 m2 = re.search( "\w+, (?P<M>\w+) (?P<D>\d+), (?P<H>\d+):(?P<MIN>\d+):(?P<S>\d+) (?P<TZ>[A-Z]+) (?P<Y>\d+)", info[key]) # we cant use '%B' due to locale problems months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] month = months.index(m2.group('M')) + 1 datetimestr = "%s/%s/%s %s:%s:%s" % ( m2.group('Y'), month, m2.group('D'), m2.group('H'), m2.group('MIN'), m2.group('S')) hand.startTime = datetime.datetime.strptime( datetimestr, "%Y/%m/%d %H:%M:%S") # FIXME: some timezone correction required #tzShift = defaultdict(lambda:0, {'EDT': -5, 'EST': -6, 'MSKS': 3}) #hand.starttime -= datetime.timedelta(hours=tzShift[m2.group('TZ')]) if key == 'HID': hand.handid = info[key] if key == 'TABLE': hand.tablename = info[key] if key == 'MTTTABLE': if info[key] != None: hand.tablename = info[key] hand.tourNo = info['TABLE'] if key == 'BUTTON': hand.buttonpos = info[key] if key == 'TOURNO': hand.tourNo = info[key] if key == 'TABLE_ID_WRAPPER': if info[key] == '#': # FIXME: there is no such property in Hand class self.isSNG = True if key == 'BUYIN': # FIXME: it's dirty hack T_T # code below assumes that tournament rake is equal to zero if info[key] == None: hand.buyin = '$0+$0' else: cur = info[key][0] if info[key][ 0] not in '0123456789' else '' hand.buyin = info[key] + '+%s0' % cur if key == 'LEVEL': hand.level = info[key] if key == 'PLAY' and info['PLAY'] != 'Real': # if realy party doesn's save play money hh hand.gametype['currency'] = 'play' if key == 'MAX' and info[key] is not None: hand.maxseats = int(info[key])
class PartyPoker(HandHistoryConverter): sitename = "PartyPoker" codepage = "utf8" siteId = 9 filetype = "text" sym = {'USD': "\$", 'EUR': u"\u20ac", 'T$': ""} currencies = { "\$": "USD", "$": "USD", u"\xe2\x82\xac": "EUR", u"\u20ac": "EUR", '': "T$" } substitutions = { 'LEGAL_ISO': "USD|EUR", # legal ISO currency codes 'LS': u"\$|\u20ac|\xe2\x82\xac|", # Currency symbols - Euro(cp1252, utf-8) 'NUM': u".,\d", } # Static regexes # $5 USD NL Texas Hold'em - Saturday, July 25, 07:53:52 EDT 2009 # NL Texas Hold'em $1 USD Buy-in Trny:45685440 Level:8 Blinds-Antes(600/1 200 -50) - Sunday, May 17, 11:25:07 MSKS 2009 re_GameInfoRing = re.compile( u""" (?P<CURRENCY>[%(LS)s])\s*(?P<RINGLIMIT>[.,0-9]+)([.,0-9/$]+)?\s*(?:%(LEGAL_ISO)s)?\s* (?P<LIMIT>(NL|PL|))\s* (?P<GAME>(Texas\ Hold\'em|Omaha|7\ Card\ Stud\ Hi-Lo)) \s*\-\s* (?P<DATETIME>.+) """ % substitutions, re.VERBOSE | re.UNICODE) re_GameInfoTrny = re.compile( """ (?P<LIMIT>(NL|PL|))\s* (?P<GAME>(Texas\ Hold\'em|Omaha))\s+ (?:(?P<BUYIN>\$?[.,0-9]+)\s*(?P<BUYIN_CURRENCY>%(LEGAL_ISO)s)?\s*Buy-in\s+)? Trny:\s?(?P<TOURNO>\d+)\s+ Level:\s*(?P<LEVEL>\d+)\s+ ((Blinds|Stakes)(?:-Antes)?)\( (?P<SB>[.,0-9 ]+)\s* /(?P<BB>[.,0-9 ]+) (?:\s*-\s*(?P<ANTE>[.,0-9 ]+)\$?)? \) \s*\-\s* (?P<DATETIME>.+) """ % substitutions, re.VERBOSE | re.UNICODE) re_Hid = re.compile("Game \#(?P<HID>\d+) starts.") re_PlayerInfo = re.compile( u""" Seat\s(?P<SEAT>\d+):\s (?P<PNAME>.*)\s \(\s*[%(LS)s]?(?P<CASH>[%(NUM)s]+)\s*(?:%(LEGAL_ISO)s|)\s*\) """ % substitutions, re.VERBOSE | re.UNICODE) re_HandInfo = re.compile( """ ^Table\s+(?P<TTYPE>[$a-zA-Z0-9 ]+)?\s+ (?: \#|\(|)(?P<TABLE>\d+)\)?\s+ (?:[a-zA-Z0-9 ]+\s+\#(?P<MTTTABLE>\d+).+)? (\(No\sDP\)\s)? \((?P<PLAY>Real|Play)\s+Money\)\s+ # FIXME: check if play money is correct Seat\s+(?P<BUTTON>\d+)\sis\sthe\sbutton \s+Total\s+number\s+of\s+players\s+\:\s+(?P<PLYRS>\d+)/?(?P<MAX>\d+)? """, re.VERBOSE | re.MULTILINE | re.DOTALL) re_CountedSeats = re.compile( "^Total\s+number\s+of\s+players\s*:\s*(?P<COUNTED_SEATS>\d+)", re.MULTILINE) re_SplitHands = re.compile('\x00+') re_TailSplitHands = re.compile('(\x00+)') lineSplitter = '\n' re_Button = re.compile('Seat (?P<BUTTON>\d+) is the button', re.MULTILINE) re_Board = re.compile(r"\[(?P<CARDS>.+)\]") re_NoSmallBlind = re.compile( '^There is no Small Blind in this hand as the Big Blind ' 'of the previous hand left the table', re.MULTILINE) re_20BBmin = re.compile(r"Table 20BB Min") def allHandsAsList(self): list = HandHistoryConverter.allHandsAsList(self) if list is None: return [] return filter(lambda text: len(text.strip()), list) def guessMaxSeats(self, hand): """Return a guess at max_seats when not specified in HH.""" mo = self.maxOccSeat(hand) if mo == 10: return mo if mo == 2: return 2 if mo <= 6: return 6 # there are 9-max tables for cash and 10-max for tournaments return 9 if hand.gametype['type'] == 'ring' else 10 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' self.compiledPlayers = players player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")" subst = { 'PLYR': player_re, 'CUR_SYM': self.sym[hand.gametype['currency']], 'CUR': hand.gametype['currency'] if hand.gametype['currency'] != 'T$' else '' } self.re_PostSB = re.compile( r"^%(PLYR)s posts small blind \[%(CUR_SYM)s(?P<SB>[.,0-9]+) ?%(CUR)s\]\." % subst, re.MULTILINE) self.re_PostBB = re.compile( u"%(PLYR)s posts big blind \[%(CUR_SYM)s(?P<BB>[.,0-9]+) ?%(CUR)s\]\." % subst, re.MULTILINE) self.re_PostDead = re.compile( r"^%(PLYR)s posts big blind + dead \[(?P<BBNDEAD>[.,0-9]+) ?%(CUR_SYM)s\]\." % subst, re.MULTILINE) self.re_Antes = re.compile( r"^%(PLYR)s posts ante \[%(CUR_SYM)s(?P<ANTE>[.,0-9]+) ?%(CUR)s\]" % subst, re.MULTILINE) self.re_HeroCards = re.compile( r"^Dealt to %(PLYR)s \[\s*(?P<NEWCARDS>.+)\s*\]" % subst, re.MULTILINE) self.re_Action = re.compile( u""" ^%(PLYR)s\s+(?P<ATYPE>bets|checks|raises|calls|folds|is\sall-In) (?:\s+\[%(CUR_SYM)s(?P<BET>[.,\d]+)\s*%(CUR)s\])? """ % subst, re.MULTILINE | re.VERBOSE) self.re_ShownCards = re.compile( r"^%s (?P<SHOWED>(?:doesn\'t )?shows?) " % player_re + r"\[ *(?P<CARDS>.+) *\](?P<COMBINATION>.+)\.", re.MULTILINE) self.re_CollectPot = re.compile( r"""^%(PLYR)s \s+ wins \s+ %(CUR_SYM)s(?P<POT>[.,\d]+)\s*%(CUR)s""" % subst, re.MULTILINE | re.VERBOSE) def readSupportedGames(self): return [ ["ring", "hold", "nl"], ["ring", "hold", "pl"], ["ring", "hold", "fl"], ["tour", "hold", "nl"], ["tour", "hold", "pl"], ["tour", "hold", "fl"], ] def _getGameType(self, handText): if not hasattr(self, '_gameType'): self._gameType = None if self._gameType is None: # let's determine whether hand is trny # and whether 5-th line contains head line headLine = handText.split(self.lineSplitter)[4] for headLineContainer in headLine, handText: for regexp in self.re_GameInfoTrny, self.re_GameInfoRing: m = regexp.search(headLineContainer) if m is not None: self._gameType = m return self._gameType return self._gameType def determineGameType(self, handText): """inspect the handText and return the gametype dict gametype dict is: {'limitType': xxx, 'base': xxx, 'category': xxx}""" info = {} m = self._getGameType(handText) m_20BBmin = self.re_20BBmin.search(handText) if m is None: tmp = handText[0:100] log.error(_("Unable to recognise gametype from: '%s'") % tmp) log.error("determineGameType: " + _("Raising FpdbParseError")) raise FpdbParseError( _("Unable to recognise gametype from: '%s'") % tmp) mg = m.groupdict() # translations from captured groups to fpdb info strings limits = {'NL': 'nl', 'PL': 'pl', '': 'fl'} games = { # base, category "Texas Hold'em" : ('hold','holdem'), 'Omaha' : ('hold','omahahi'), "7 Card Stud Hi-Lo" : ('stud','studhi'), } for expectedField in ['LIMIT', 'GAME']: if mg[expectedField] is None: raise FpdbParseError( _("Cannot fetch field '%s'") % expectedField) try: info['limitType'] = limits[mg['LIMIT'].strip()] except: raise FpdbParseError(_("Unknown limit '%s'") % mg['LIMIT']) try: (info['base'], info['category']) = games[mg['GAME']] except: raise FpdbParseError(_("Unknown game type '%s'") % mg['GAME']) if 'TOURNO' in mg: info['type'] = 'tour' else: info['type'] = 'ring' if info['type'] == 'ring': if m_20BBmin is None: bb = float(mg['RINGLIMIT']) / 100.0 else: bb = float(mg['RINGLIMIT']) / 40.0 if bb == 0.25: sb = 0.10 else: sb = bb / 2.0 info['bb'] = "%.2f" % (bb) info['sb'] = "%.2f" % (sb) info['currency'] = self.currencies[mg['CURRENCY']] else: info['sb'] = self.clearMoneyString(mg['SB']) info['bb'] = self.clearMoneyString(mg['BB']) info['currency'] = 'T$' return info def readHandInfo(self, hand): info = {} try: info.update(self.re_Hid.search(hand.handText).groupdict()) except AttributeError, e: raise FpdbParseError(_("Cannot read HID for current hand: %s") % e) try: info.update( self.re_HandInfo.search(hand.handText, re.DOTALL).groupdict()) except: raise FpdbParseError(_("Cannot read Handinfo for current hand"), hid=info['HID']) try: info.update(self._getGameType(hand.handText).groupdict()) except: raise FpdbParseError(_("Cannot read GameType for current hand"), hid=info['HID']) m = self.re_CountedSeats.search(hand.handText) if m: info.update(m.groupdict()) # FIXME: it's dirty hack # party doesnt subtract uncalled money from commited money # so hand.totalPot calculation has to be redefined from Hand import Pot, HoldemOmahaHand def getNewTotalPot(origTotalPot): def totalPot(self): if self.totalpot is None: self.pot.end() self.totalpot = self.pot.total for i, v in enumerate(self.collected): if v[0] in self.pot.returned: self.collected[i][1] = Decimal( v[1]) - self.pot.returned[v[0]] self.collectees[v[0]] -= self.pot.returned[v[0]] self.pot.returned[v[0]] = 0 return origTotalPot() return totalPot instancemethod = type(hand.totalPot) hand.totalPot = instancemethod(getNewTotalPot(hand.totalPot), hand, HoldemOmahaHand) log.debug("readHandInfo: %s" % info) for key in info: if key == 'DATETIME': #Saturday, July 25, 07:53:52 EDT 2009 #Thursday, July 30, 21:40:41 MSKS 2009 #Sunday, October 25, 13:39:07 MSK 2009 m2 = re.search( r"\w+,\s+(?P<M>\w+)\s+(?P<D>\d+),\s+(?P<H>\d+):(?P<MIN>\d+):(?P<S>\d+)\s+(?P<TZ>[A-Z]+)\s+(?P<Y>\d+)", info[key], re.UNICODE) months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] if m2.group('M') not in months: raise FpdbParseError("Only english hh is supported", hid=info["HID"]) month = months.index(m2.group('M')) + 1 datetimestr = "%s/%s/%s %s:%s:%s" % ( m2.group('Y'), month, m2.group('D'), m2.group('H'), m2.group('MIN'), m2.group('S')) hand.startTime = datetime.datetime.strptime( datetimestr, "%Y/%m/%d %H:%M:%S") # FIXME: some timezone correction required #tzShift = defaultdict(lambda:0, {'EDT': -5, 'EST': -6, 'MSKS': 3}) #hand.starttime -= datetime.timedelta(hours=tzShift[m2.group('TZ')]) if key == 'HID': hand.handid = info[key] if key == 'TABLE': hand.tablename = info[key] if key == 'MTTTABLE': if info[key] != None: hand.tablename = info[key] hand.tourNo = info['TABLE'] if key == 'BUTTON': hand.buttonpos = info[key] if key == 'TOURNO': hand.tourNo = info[key] if key == 'TABLE_ID_WRAPPER': if info[key] == '#': # FIXME: there is no such property in Hand class self.isSNG = True if key == 'BUYIN': if info[key] == None: # Freeroll tourney hand.buyin = 0 hand.fee = 0 hand.buyinCurrency = "FREE" hand.isKO = False elif hand.tourNo != None: hand.buyin = 0 hand.fee = 0 hand.buyinCurrency = "FREE" hand.isKO = False if info[key].find("$") != -1: hand.buyinCurrency = "USD" elif info[key].find(u"€") != -1: hand.buyinCurrency = "EUR" else: raise FpdbParseError( _("Failed to detect currency.") + " " + _("Hand ID: %s: '%s'") % (hand.handid, info[key])) info[key] = info[key].strip(u'$€') hand.buyin = int(100 * Decimal(info[key])) if key == 'LEVEL': hand.level = info[key] if key == 'PLAY' and info['PLAY'] != 'Real': # if realy party doesn's save play money hh hand.gametype['currency'] = 'play' if key == 'MAX' and info[key] is not None: hand.maxseats = int(info[key])
def readHandInfo(self, hand): info = {} try: info.update(self.re_Hid.search(hand.handText).groupdict()) except AttributeError, e: raise FpdbParseError(_("Cannot read HID for current hand: %s") % e)
def determineGameType(self, handText): """inspect the handText and return the gametype dict gametype dict is: {'limitType': xxx, 'base': xxx, 'category': xxx}""" info = {} m = self._getGameType(handText) m_20BBmin = self.re_20BBmin.search(handText) if m is None: tmp = handText[0:100] log.error(_("Unable to recognise gametype from: '%s'") % tmp) log.error("determineGameType: " + _("Raising FpdbParseError")) raise FpdbParseError( _("Unable to recognise gametype from: '%s'") % tmp) mg = m.groupdict() # translations from captured groups to fpdb info strings limits = {'NL': 'nl', 'PL': 'pl', '': 'fl'} games = { # base, category "Texas Hold'em" : ('hold','holdem'), 'Omaha' : ('hold','omahahi'), "7 Card Stud Hi-Lo" : ('stud','studhi'), } for expectedField in ['LIMIT', 'GAME']: if mg[expectedField] is None: raise FpdbParseError( _("Cannot fetch field '%s'") % expectedField) try: info['limitType'] = limits[mg['LIMIT'].strip()] except: raise FpdbParseError(_("Unknown limit '%s'") % mg['LIMIT']) try: (info['base'], info['category']) = games[mg['GAME']] except: raise FpdbParseError(_("Unknown game type '%s'") % mg['GAME']) if 'TOURNO' in mg: info['type'] = 'tour' else: info['type'] = 'ring' if info['type'] == 'ring': if m_20BBmin is None: bb = float(mg['RINGLIMIT']) / 100.0 else: bb = float(mg['RINGLIMIT']) / 40.0 if bb == 0.25: sb = 0.10 else: sb = bb / 2.0 info['bb'] = "%.2f" % (bb) info['sb'] = "%.2f" % (sb) info['currency'] = self.currencies[mg['CURRENCY']] else: info['sb'] = self.clearMoneyString(mg['SB']) info['bb'] = self.clearMoneyString(mg['BB']) info['currency'] = 'T$' return info