Use debian 2.7 only
[fpbd-bostik.git] / pyfpdb / WinamaxToFpdb.py
blobeb6f210ba24c3c5855b93b7b9069b1d3e74cc390
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
4 # Copyright 2008-2011, Carl Gherardi
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ########################################################################
21 import L10n
22 _ = L10n.get_translation()
24 import sys
25 import exceptions
27 from HandHistoryConverter import *
28 from decimal_wrapper import Decimal
30 # Winamax HH Format
32 class Winamax(HandHistoryConverter):
33 def Trace(f):
34 def my_f(*args, **kwds):
35 print ( "entering " + f.__name__)
36 result= f(*args, **kwds)
37 print ( "exiting " + f.__name__)
38 return result
39 my_f.__name = f.__name__
40 my_f.__doc__ = f.__doc__
41 return my_f
43 filter = "Winamax"
44 siteName = "Winamax"
45 filetype = "text"
46 codepage = ("utf8", "cp1252")
47 siteId = 14 # Needs to match id entry in Sites database
49 mixes = { } # Legal mixed games
50 sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": u"\xe2\x82\xac|\u20ac", "GBP": "\xa3"} # ADD Euro, Sterling, etc HERE
51 substitutions = {
52 'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes
53 'LS' : u"\$|\xe2\x82\xac|\u20ac|" # legal currency symbols - Euro(cp1252, utf-8)
56 limits = { 'no limit':'nl', 'pot limit' : 'pl','LIMIT':'fl'}
58 games = { # base, category
59 "Holdem" : ('hold','holdem'),
60 'Omaha' : ('hold','omahahi'),
61 # It appears French law prevents any other games from being spread.
64 # Static regexes
65 # ***** End of hand R5-75443872-57 *****
66 re_SplitHands = re.compile(r'\n\n')
70 # Winamax Poker - CashGame - HandId: #279823-223-1285031451 - Holdem no limit (0.02€/0.05€) - 2010/09/21 03:10:51 UTC
71 # Table: 'Charenton-le-Pont' 9-max (real money) Seat #5 is the button
72 re_HandInfo = re.compile(u"""
73 \s*Winamax\sPoker\s-\s
74 (?P<RING>CashGame)?
75 (?P<TOUR>Tournament\s
76 (?P<TOURNAME>.+)?\s
77 buyIn:\s(?P<BUYIN>(?P<BIAMT>[%(LS)s\d\,]+)?\s\+?\s(?P<BIRAKE>[%(LS)s\d\,]+)?\+?(?P<BOUNTY>[%(LS)s\d\.]+)?\s?(?P<TOUR_ISO>%(LEGAL_ISO)s)?|Freeroll|Gratuit|Ticket\suniquement|Free)?\s
78 (level:\s(?P<LEVEL>\d+))?
79 .*)?
80 \s-\sHandId:\s\#(?P<HID1>\d+)-(?P<HID2>\d+)-(?P<HID3>\d+).*\s # REB says: HID3 is the correct hand number
81 (?P<GAME>Holdem|Omaha)\s
82 (?P<LIMIT>no\slimit|pot\slimit)\s
84 (((%(LS)s)?(?P<ANTE>[.0-9]+)(%(LS)s)?)/)?
85 ((%(LS)s)?(?P<SB>[.0-9]+)(%(LS)s)?)/
86 ((%(LS)s)?(?P<BB>[.0-9]+)(%(LS)s)?)
87 \)\s-\s
88 (?P<DATETIME>.*)
89 Table:\s\'(?P<TABLE>[^(]+)
90 (.(?P<TOURNO>\d+).\#(?P<TABLENO>\d+))?.*
92 \s(?P<MAXPLAYER>\d+)\-max
93 """ % substitutions, re.MULTILINE|re.DOTALL|re.VERBOSE)
95 re_TailSplitHands = re.compile(r'\n\s*\n')
96 re_Button = re.compile(r'Seat\s#(?P<BUTTON>\d+)\sis\sthe\sbutton')
97 re_Board = re.compile(r"\[(?P<CARDS>.+)\]")
98 re_Total = re.compile(r"Total pot (?P<TOTAL>[\.\d]+).*(No rake|Rake (?P<RAKE>[\.\d]+))" % substitutions)
100 # 2010/09/21 03:10:51 UTC
101 re_DateTime = re.compile("""
102 (?P<Y>[0-9]{4})/
103 (?P<M>[0-9]+)/
104 (?P<D>[0-9]+)\s
105 (?P<H>[0-9]+):(?P<MIN>[0-9]+):(?P<S>[0-9]+)\s
107 """, re.MULTILINE|re.VERBOSE)
109 # Seat 1: some_player (5€)
110 # Seat 2: some_other_player21 (6.33€)
112 re_PlayerInfo = re.compile(u'Seat\s(?P<SEAT>[0-9]+):\s(?P<PNAME>.*)\s\((%(LS)s)?(?P<CASH>[.0-9]+)(%(LS)s)?\)' % substitutions)
114 def compilePlayerRegexs(self, hand):
115 players = set([player[1] for player in hand.players])
116 if not players <= self.compiledPlayers: # x <= y means 'x is subset of y'
117 # we need to recompile the player regexs.
118 # TODO: should probably rename re_HeroCards and corresponding method,
119 # since they are used to find all cards on lines starting with "Dealt to:"
120 # They still identify the hero.
121 self.compiledPlayers = players
122 #ANTES/BLINDS
123 #helander2222 posts blind ($0.25), lopllopl posts blind ($0.50).
124 player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
125 subst = {'PLYR': player_re, 'CUR': self.sym[hand.gametype['currency']]}
126 self.re_PostSB = re.compile('%(PLYR)s posts small blind (%(CUR)s)?(?P<SB>[\.0-9]+)(%(CUR)s)?' % subst, re.MULTILINE)
127 self.re_PostBB = re.compile('%(PLYR)s posts big blind (%(CUR)s)?(?P<BB>[\.0-9]+)(%(CUR)s)?' % subst, re.MULTILINE)
128 self.re_DenySB = re.compile('(?P<PNAME>.*) deny SB' % subst, re.MULTILINE)
129 self.re_Antes = re.compile(r"^%(PLYR)s posts ante (%(CUR)s)?(?P<ANTE>[\.0-9]+)(%(CUR)s)?" % subst, re.MULTILINE)
130 self.re_BringIn = re.compile(r"^%(PLYR)s brings[- ]in( low|) for (%(CUR)s)?(?P<BRINGIN>[\.0-9]+(%(CUR)s)?)" % subst, re.MULTILINE)
131 self.re_PostBoth = re.compile('(?P<PNAME>.*): posts small \& big blind \( (%(CUR)s)?(?P<SBBB>[\.0-9]+)(%(CUR)s)?\)' % subst)
132 self.re_PostDead = re.compile('(?P<PNAME>.*) posts dead blind \((%(CUR)s)?(?P<DEAD>[\.0-9]+)(%(CUR)s)?\)' % subst, re.MULTILINE)
133 self.re_HeroCards = re.compile('Dealt\sto\s%(PLYR)s\s\[(?P<CARDS>.*)\]' % subst)
135 self.re_Action = re.compile('(, )?(?P<PNAME>.*?)(?P<ATYPE> bets| checks| raises| calls| folds)( (%(CUR)s)?(?P<BET>[\d\.]+)(%(CUR)s)?)?( and is all-in)?' % subst)
136 self.re_ShowdownAction = re.compile('(?P<PNAME>[^\(\)\n]*) (\((small blind|big blind|button)\) )?shows \[(?P<CARDS>.+)\]')
138 self.re_CollectPot = re.compile('\s*(?P<PNAME>.*)\scollected\s(%(CUR)s)?(?P<POT>[\.\d]+)(%(CUR)s)?.*' % subst)
139 self.re_ShownCards = re.compile("^Seat (?P<SEAT>[0-9]+): %(PLYR)s showed \[(?P<CARDS>.*)\].*" % subst, re.MULTILINE)
140 self.re_sitsOut = re.compile('(?P<PNAME>.*) sits out')
142 def readSupportedGames(self):
143 return [
144 ["ring", "hold", "fl"],
145 ["ring", "hold", "nl"],
146 ["ring", "hold", "pl"],
147 ["tour", "hold", "fl"],
148 ["tour", "hold", "nl"],
149 ["tour", "hold", "pl"],
152 def determineGameType(self, handText):
153 # Inspect the handText and return the gametype dict
154 # gametype dict is: {'limitType': xxx, 'base': xxx, 'category': xxx}
155 info = {}
157 m = self.re_HandInfo.search(handText)
158 if not m:
159 tmp = handText[0:200]
160 log.error(_("WinamaxToFpdb.determineGameType: '%s'") % tmp)
161 raise FpdbParseError
163 mg = m.groupdict()
165 if mg.get('TOUR'):
166 info['type'] = 'tour'
167 elif mg.get('RING'):
168 info['type'] = 'ring'
170 info['currency'] = 'EUR'
172 if 'LIMIT' in mg:
173 if mg['LIMIT'] in self.limits:
174 info['limitType'] = self.limits[mg['LIMIT']]
175 else:
176 tmp = handText[0:100]
177 log.error(_("WinamaxToFpdb.determineGameType: Limit not found in %s.") % tmp)
178 raise FpdbParseError
179 if 'GAME' in mg:
180 (info['base'], info['category']) = self.games[mg['GAME']]
181 if 'SB' in mg:
182 info['sb'] = mg['SB']
183 if 'BB' in mg:
184 info['bb'] = mg['BB']
186 return info
188 def readHandInfo(self, hand):
189 info = {}
190 m = self.re_HandInfo.search(hand.handText)
191 if m is None:
192 tmp = hand.handText[0:200]
193 log.error(_("WinamaxToFpdb.readHandInfo: '%s'") % tmp)
194 raise FpdbParseError
196 info.update(m.groupdict())
197 #log.debug("readHandInfo: %s" % info)
198 for key in info:
199 if key == 'DATETIME':
200 a = self.re_DateTime.search(info[key])
201 if a:
202 datetimestr = "%s/%s/%s %s:%s:%s" % (a.group('Y'),a.group('M'), a.group('D'), a.group('H'),a.group('MIN'),a.group('S'))
203 else:
204 datetimestr = "2010/Jan/01 01:01:01"
205 log.error("readHandInfo: " + _("DATETIME not matched: '%s'") % info[key])
206 #print "DEBUG: readHandInfo: DATETIME not matched: '%s'" % info[key]
207 hand.startTime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S")
208 hand.startTime = HandHistoryConverter.changeTimezone(hand.startTime, "CET", "UTC")
209 if key == 'HID1':
210 # Need to remove non-alphanumerics for MySQL
211 # hand.handid = "1%.9d%s%s"%(int(info['HID2']),info['HID1'],info['HID3'])
212 hand.handid = "%s%s%s"%(int(info['HID1']),info['HID2'],info['HID3'])
213 if len (hand.handid) > 19:
214 hand.handid = "%s%s" % (int(info['HID2']), int(info['HID3']))
216 # if key == 'HID3':
217 # hand.handid = int(info['HID3']) # correct hand no (REB)
218 if key == 'TOURNO':
219 hand.tourNo = info[key]
220 if key == 'TABLE':
221 hand.tablename = info[key]
222 if hand.gametype['type'] == 'tour':
223 hand.tablename = info['TABLENO']
224 # TODO: long-term solution for table naming on Winamax.
225 if hand.tablename.endswith(u'No Limit Hold\'em'):
226 hand.tablename = hand.tablename[:-len(u'No Limit Hold\'em')] + u'NLHE'
227 if key == 'MAXPLAYER' and info[key] != None:
228 hand.maxseats = int(info[key])
230 if key == 'BUYIN':
231 if hand.tourNo!=None:
232 #print "DEBUG: info['BUYIN']: %s" % info['BUYIN']
233 #print "DEBUG: info['BIAMT']: %s" % info['BIAMT']
234 #print "DEBUG: info['BIRAKE']: %s" % info['BIRAKE']
235 #print "DEBUG: info['BOUNTY']: %s" % info['BOUNTY']
236 for k in ['BIAMT','BIRAKE']:
237 if k in info.keys() and info[k]:
238 info[k] = info[k].replace(',','.')
240 if info[key] == 'Gratuit' or info[key] == 'Freeroll' or info[key] == 'Ticket uniquement':
241 hand.buyin = 0
242 hand.fee = 0
243 hand.buyinCurrency = "FREE"
244 else:
245 if info[key].find("$")!=-1:
246 hand.buyinCurrency="USD"
247 elif info[key].find(u"€")!=-1:
248 hand.buyinCurrency="EUR"
249 elif info[key].find("FPP")!=-1:
250 hand.buyinCurrency="WIFP"
251 elif info[key].find("Free")!=-1:
252 hand.buyinCurrency="WIFP"
253 else:
254 #FIXME: handle other currencies (are there other currencies?)
255 log.error(_("WinamaxToFpdb.readHandInfo: Failed to detect currency.") + " Hand ID: %s: '%s'" % (hand.handid, info[key]))
256 raise FpdbParseError
258 if info['BIAMT'] is not None:
259 info['BIAMT'] = info['BIAMT'].strip(u'$€FPP')
260 else:
261 info['BIAMT'] = 0
263 if hand.buyinCurrency!="WIFP":
264 if info['BOUNTY'] != None:
265 # There is a bounty, Which means we need to switch BOUNTY and BIRAKE values
266 tmp = info['BOUNTY']
267 info['BOUNTY'] = info['BIRAKE']
268 info['BIRAKE'] = tmp
269 info['BOUNTY'] = info['BOUNTY'].strip(u'$€') # Strip here where it isn't 'None'
270 hand.koBounty = int(100*Decimal(info['BOUNTY']))
271 hand.isKO = True
272 else:
273 hand.isKO = False
275 info['BIRAKE'] = info['BIRAKE'].strip(u'$€')
277 # TODO: Is this correct? Old code tried to
278 # conditionally multiply by 100, but we
279 # want hand.buyin in 100ths of
280 # dollars/euros (so hand.buyin = 90 for $0.90 BI).
281 hand.buyin = int(100 * Decimal(info['BIAMT']))
282 hand.fee = int(100 * Decimal(info['BIRAKE']))
283 else:
284 hand.buyin = int(Decimal(info['BIAMT']))
285 hand.fee = 0
287 if key == 'LEVEL':
288 hand.level = info[key]
290 m = self.re_Button.search(hand.handText)
291 hand.buttonpos = m.groupdict().get('BUTTON', None)
293 hand.mixed = None
295 def readPlayerStacks(self, hand):
296 #log.debug("readplayerstacks re: '%s'" % self.re_PlayerInfo)
297 m = self.re_PlayerInfo.finditer(hand.handText)
298 for a in m:
299 hand.addPlayer(int(a.group('SEAT')), a.group('PNAME'), a.group('CASH'))
302 def markStreets(self, hand):
303 m = re.search(r"\*\*\* ANTE\/BLINDS \*\*\*(?P<PREFLOP>.+(?=\*\*\* FLOP \*\*\*)|.+)"
304 r"(\*\*\* FLOP \*\*\*(?P<FLOP> \[\S\S \S\S \S\S\].+(?=\*\*\* TURN \*\*\*)|.+))?"
305 r"(\*\*\* TURN \*\*\* \[\S\S \S\S \S\S](?P<TURN>\[\S\S\].+(?=\*\*\* RIVER \*\*\*)|.+))?"
306 r"(\*\*\* RIVER \*\*\* \[\S\S \S\S \S\S \S\S](?P<RIVER>\[\S\S\].+))?", hand.handText,re.DOTALL)
308 try:
309 hand.addStreets(m)
310 # print "adding street", m.group(0)
311 # print "---"
312 except:
313 log.info(_("Failed to add streets. handtext=%s"))
315 #Needs to return a list in the format
316 # ['player1name', 'player2name', ...] where player1name is the sb and player2name is bb,
317 # addtional players are assumed to post a bb oop
319 def readButton(self, hand):
320 m = self.re_Button.search(hand.handText)
321 if m:
322 hand.buttonpos = int(m.group('BUTTON'))
323 #log.debug(_('readButton: button on pos %d') % hand.buttonpos)
324 else:
325 log.info('readButton: ' + _('not found'))
327 # def readCommunityCards(self, hand, street):
328 # #print hand.streets.group(street)
329 # if street in ('FLOP','TURN','RIVER'): # a list of streets which get dealt community cards (i.e. all but PREFLOP)
330 # m = self.re_Board.search(hand.streets.group(street))
331 # hand.setCommunityCards(street, m.group('CARDS').split(','))
333 def readCommunityCards(self, hand, street): # street has been matched by markStreets, so exists in this hand
334 if street in ('FLOP','TURN','RIVER'): # a list of streets which get dealt community cards (i.e. all but PREFLOP)
335 #print "DEBUG readCommunityCards:", street, hand.streets.group(street)
336 m = self.re_Board.search(hand.streets[street])
337 hand.setCommunityCards(street, m.group('CARDS').split(' '))
339 def readBlinds(self, hand):
340 if not self.re_DenySB.search(hand.handText):
341 try:
342 m = self.re_PostSB.search(hand.handText)
343 hand.addBlind(m.group('PNAME'), 'small blind', m.group('SB'))
344 except exceptions.AttributeError: # no small blind
345 log.warning( _("No small blinds found.")+str(sys.exc_info()) )
346 #hand.addBlind(None, None, None)
347 for a in self.re_PostBB.finditer(hand.handText):
348 hand.addBlind(a.group('PNAME'), 'big blind', a.group('BB'))
349 for a in self.re_PostDead.finditer(hand.handText):
350 #print "DEBUG: Found dead blind: addBlind(%s, 'secondsb', %s)" %(a.group('PNAME'), a.group('DEAD'))
351 hand.addBlind(a.group('PNAME'), 'secondsb', a.group('DEAD'))
352 for a in self.re_PostBoth.finditer(hand.handText):
353 hand.addBlind(a.group('PNAME'), 'small & big blinds', a.group('SBBB'))
355 def readAntes(self, hand):
356 log.debug(_("reading antes"))
357 m = self.re_Antes.finditer(hand.handText)
358 for player in m:
359 #~ logging.debug("hand.addAnte(%s,%s)" %(player.group('PNAME'), player.group('ANTE')))
360 hand.addAnte(player.group('PNAME'), player.group('ANTE'))
362 def readBringIn(self, hand):
363 m = self.re_BringIn.search(hand.handText,re.DOTALL)
364 if m:
365 #~ logging.debug("readBringIn: %s for %s" %(m.group('PNAME'), m.group('BRINGIN')))
366 hand.addBringIn(m.group('PNAME'), m.group('BRINGIN'))
368 def readHeroCards(self, hand):
369 # streets PREFLOP, PREDRAW, and THIRD are special cases beacause
370 # we need to grab hero's cards
371 for street in ('PREFLOP', 'DEAL', 'BLINDSANTES'):
372 if street in hand.streets.keys():
373 m = self.re_HeroCards.finditer(hand.streets[street])
374 if m == []:
375 log.debug(_("No hole cards found for %s") % street)
376 for found in m:
377 hand.hero = found.group('PNAME')
378 newcards = found.group('CARDS').split(' ')
379 # print "DEBUG: addHoleCards(%s, %s, %s)" %(street, hand.hero, newcards)
380 hand.addHoleCards(street, hand.hero, closed=newcards, shown=False, mucked=False, dealt=True)
381 log.debug(_("Hero cards %s: %s") % (hand.hero, newcards))
383 def readAction(self, hand, street):
384 m = self.re_Action.finditer(hand.streets[street])
385 for action in m:
386 #acts = action.groupdict()
387 #print "DEBUG: acts: %s" % acts
388 if action.group('ATYPE') == ' folds':
389 hand.addFold( street, action.group('PNAME'))
390 elif action.group('ATYPE') == ' checks':
391 hand.addCheck( street, action.group('PNAME'))
392 elif action.group('ATYPE') == ' calls':
393 hand.addCall( street, action.group('PNAME'), action.group('BET') )
394 elif action.group('ATYPE') == ' raises':
395 hand.addRaiseBy( street, action.group('PNAME'), action.group('BET') )
396 elif action.group('ATYPE') == ' bets':
397 hand.addBet( street, action.group('PNAME'), action.group('BET') )
398 elif action.group('ATYPE') == ' discards':
399 hand.addDiscard(street, action.group('PNAME'), action.group('BET'), action.group('DISCARDED'))
400 elif action.group('ATYPE') == ' stands pat':
401 hand.addStandsPat( street, action.group('PNAME'))
402 else:
403 log.fatal(_("DEBUG:") + _("Unimplemented %s: '%s' '%s'") % ("readAction", action.group('PNAME'), action.group('ATYPE')))
404 # print "Processed %s"%acts
405 # print "committed=",hand.pot.committed
407 def readShowdownActions(self, hand):
408 for shows in self.re_ShowdownAction.finditer(hand.handText):
409 #log.debug(_("add show actions %s") % shows)
410 cards = shows.group('CARDS')
411 cards = cards.split(' ')
412 # print "DEBUG: addShownCards(%s, %s)" %(cards, shows.group('PNAME'))
413 hand.addShownCards(cards, shows.group('PNAME'))
415 def readCollectPot(self,hand):
416 # Winamax has unfortunately thinks that a sidepot is created
417 # when there is uncalled money in the pot - something that can
418 # only happen when a player is all-in
420 # Becuase of this, we need to do the same calculations as class Pot()
421 # and determine if the amount returned is the same as the amount collected
422 # if so then the collected line is invalid
424 total = sum(hand.pot.committed.values()) + sum(hand.pot.common.values())
426 # Return any uncalled bet.
427 committed = sorted([ (v,k) for (k,v) in hand.pot.committed.items()])
428 #print "DEBUG: committed: %s" % committed
429 returned = {}
430 lastbet = committed[-1][0] - committed[-2][0]
431 if lastbet > 0: # uncalled
432 returnto = committed[-1][1]
433 #print "DEBUG: returning %f to %s" % (lastbet, returnto)
434 total -= lastbet
435 returned[returnto] = lastbet
437 collectees = []
439 tp = self.re_Total.search(hand.handText)
440 rake = tp.group('RAKE')
441 if rake == None:
442 rake = 0
443 for m in self.re_CollectPot.finditer(hand.handText):
444 collectees.append([m.group('PNAME'), m.group('POT')])
446 #print "DEBUG: Total pot: %s" % tp.groupdict()
447 #print "DEBUG: According to pot: %s" % total
448 #print "DEBUG: Rake: %s" % rake
450 if len(collectees) == 1:
451 plyr, p = collectees[0]
452 # p may be wrong, use calculated total - rake
453 p = total - Decimal(rake)
454 #print "DEBUG: len1: addCollectPot(%s,%s)" %(plyr, p)
455 hand.addCollectPot(player=plyr,pot=p)
456 else:
457 for plyr, p in collectees:
458 if plyr in returned.keys():
459 p = Decimal(p) - returned[plyr]
460 if p > 0:
461 #print "DEBUG: addCollectPot(%s,%s)" %(plyr, p)
462 hand.addCollectPot(player=plyr,pot=p)
464 def readShownCards(self,hand):
465 for m in self.re_ShownCards.finditer(hand.handText):
466 log.debug(_("Read shown cards: %s") % m.group(0))
467 cards = m.group('CARDS')
468 cards = cards.split(' ') # needs to be a list, not a set--stud needs the order
469 (shown, mucked) = (False, False)
470 if m.group('CARDS') is not None:
471 shown = True
472 hand.addShownCards(cards=cards, player=m.group('PNAME'), shown=shown, mucked=mucked)
474 @staticmethod
475 def getTableTitleRe(type, table_name=None, tournament = None, table_number=None):
477 SnG's
478 No Limit Hold'em(17027463)#0 - 20-40 NL Holdem - Buy-in: 1€
479 No Limit Hold'em(17055704)#0 - 300-600 (ante 75) NL Holdem - Buy-in: 0,50€
480 No Limit Hold'em(17056243)#2 - 400-800 (ante 40) NL Holdem - Buy-in: 0,50€
481 Deglingos !(17060078)#0 - 30-60 NL Holdem - Buy-in: 0,50€
482 Deglingos Qualif. 2€(17060167)#0 - 20-40 NL Holdem - Buy-in: 0,50€
483 Double Shootout(17059623)#1 - 15-30 NL Holdem - Buy-in: 0,50€
484 Double Shootout(17060527)#1 - 40-80 NL Holdem - Buy-in: 0,50€
485 No Limit Hold'em(17056975)#0 - 300-600 (ante 75) NL Holdem - Buy-in: 0,50€
486 No Limit Hold'em(17056975)#0 - 300-600 (ante 75) NL Holdem - Buy-in: 0,50€
487 No Limit Hold'em(17059475)#2 - 15-30 NL Holdem - Buy-in: 1€
488 No Limit Hold'em(17059934)#0 - 15-30 NL Holdem - Buy-in: 0,50€
489 No Limit Hold'em(17059934)#0 - 20-40 NL Holdem - Buy-in: 0,50€
490 Pot Limit Omaha(17059108)#0 - 60-120 PL Omaha - Buy-in: 0,50€
491 Qualificatif 2€(17057954)#0 - 80-160 NL Holdem - Buy-in: 0,50€
492 Qualificatif 5€(17057018)#0 - 300-600 (ante 30) NL Holdem - Buy-in: 1€
493 Quitte ou Double(17057267)#0 - 150-300 PL Omaha - Buy-in: 0,50€
494 Quitte ou Double(17058093)#0 - 100-200 (ante 10) NL Holdem - Buy-in: 0,50€
495 Starting Block Winamax Poker Tour(17059192)#0 - 30-60 NL Holdem - Buy-in: 0€
496 MTT's
497 1€ et un autre...(16362149)#016 - 60-120 (ante 10) NL Holdem - Buy-in: 1€
498 2€ et l'apéro...(16362145)#000 - 5k-10k (ante 1k) NL Holdem - Buy-in: 2€
499 Deepstack Hold'em(16362363)#013 - 200-400 (ante 30) NL Holdem - Buy-in: 5€
500 Deglingos MAIN EVENT(16362466)#002 - 10-20 NL Holdem - Buy-in: 2€
501 Hold'em(16362170)#013 - 30-60 NL Holdem - Buy-in: 2€
502 MAIN EVENT(16362311)#008 - 300-600 (ante 60) NL Holdem - Buy-in: 150€
503 MiniRoll 0.25€(16362117)#045 - 1,25k-2,50k (ante 250) NL Holdem - Buy-in: 0,25€
504 MiniRoll 0.50€(16362116)#018 - 20k-40k (ante 4k) NL Holdem - Buy-in: 0,50€
505 MiniRoll 0.50€(16362118)#007 - 75-150 (ante 15) NL Holdem - Buy-in: 0,50€
506 Qualificatif 5€(16362201)#010 - 10-20 NL Holdem - Buy-in: 0,50€
507 Tremplin Caen 2(15290669)#026 - 2,50k-5k (ante 500) NL Holdem - Buy-in: 0€
508 Freeroll 250€(16362273)#035 - 2,50k-5k (ante 500) NL Holdem - Buy-in: 0€
510 log.info("Winamax.getTableTitleRe: table_name='%s' tournament='%s' table_number='%s'" % (table_name, tournament, table_number))
511 regex = "%s /" % (table_name)
512 if tournament:
513 regex = "\(%s\)#(%s|%03d)" % (tournament, table_number,int(table_number))
514 log.info("Winamax.getTableTitleRe: returns: '%s'" % (regex))
515 return regex