2008-12-16 15:45:58 +01:00
#!/usr/bin/env python
2009-03-10 00:03:17 +01:00
# -*- coding: utf-8 -*-
#
2008-12-16 15:45:58 +01:00
# Copyright 2008, Carl Gherardi
#
# 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
########################################################################
2009-03-04 17:46:01 +01:00
import logging
2008-12-16 15:45:58 +01:00
from HandHistoryConverter import *
2009-03-13 21:00:12 +01:00
# Fulltilt HH Format converter
2008-12-16 15:45:58 +01:00
2009-03-13 21:00:12 +01:00
class Fulltilt ( HandHistoryConverter ) :
2009-02-25 15:35:28 +01:00
2009-08-09 16:19:43 +02:00
sitename = " Fulltilt "
filetype = " text "
2009-08-24 01:40:39 +02:00
codepage = [ " utf-16 " , " cp1252 " ]
2009-08-09 16:19:43 +02:00
siteId = 1 # Needs to match id entry in Sites database
2009-02-25 15:35:28 +01:00
# Static regexes
2009-08-15 19:30:31 +02:00
re_GameInfo = re . compile ( ''' .* \ #(?P<HID>[0-9]+): \ s
( ? : ( ? P < TOURNAMENT > . + ) \s \( ( ? P < TOURNO > \d + ) \) , \s ) ?
2009-07-19 03:33:00 +02:00
. +
- \s ( ? P < CURRENCY > \$ | ) ?
2009-07-17 23:07:53 +02:00
( ? P < SB > [ .0 - 9 ] + ) /
\$ ? ( ? P < BB > [ .0 - 9 ] + ) \s
2009-07-22 14:54:30 +02:00
( Ante \s \$ ? ( ? P < ANTE > [ .0 - 9 ] + ) \s ) ? - \s
2009-10-01 04:49:59 +02:00
\$ ? ( ? P < CAP > [ .0 - 9 ] + \sCap \s ) ?
2009-07-17 23:07:53 +02:00
( ? P < LIMIT > ( No \sLimit | Pot \sLimit | Limit ) ) ? \s
2009-07-22 14:54:30 +02:00
( ? P < GAME > ( Hold \' em|Omaha \ sHi|Omaha \ sH/L|7 \ sCard \ sStud|Stud \ sH/L|Razz|Stud \ sHi))
2009-07-17 23:07:53 +02:00
''' , re.VERBOSE)
2009-03-31 08:44:19 +02:00
re_SplitHands = re . compile ( r " \ n \ n+ " )
re_TailSplitHands = re . compile ( r " ( \ n \ n+) " )
2009-08-09 16:19:43 +02:00
re_HandInfo = re . compile ( r ''' .* \ #(?P<HID>[0-9]+): \ s
2009-07-19 03:33:00 +02:00
( ? : ( ? P < TOURNAMENT > . + ) \s \( ( ? P < TOURNO > \d + ) \) , \s ) ?
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
( Table | Match ) \s
2009-07-22 16:24:29 +02:00
( ? P < PLAY > Play \sChip \s | PC ) ?
2009-07-22 14:54:30 +02:00
( ? P < TABLE > [ - \s \da - zA - Z ] + ) \s
2009-07-17 23:07:53 +02:00
( \( ( ? P < TABLEATTRIBUTES > . + ) \) \s ) ? - \s
2009-07-22 14:54:30 +02:00
\$ ? ( ? P < SB > [ .0 - 9 ] + ) / \$ ? ( ? P < BB > [ .0 - 9 ] + ) \s ( Ante \s \$ ? ( ? P < ANTE > [ .0 - 9 ] + ) \s ) ? - \s
2009-10-01 04:49:59 +02:00
\$ ? ( ? P < CAP > [ .0 - 9 ] + \sCap \s ) ?
2009-07-17 23:07:53 +02:00
( ? P < GAMETYPE > [ a - zA - Z \/ \' \ s]+) \ s- \ s
2009-08-23 21:02:00 +02:00
( ? P < DATETIME > \d + : \d + : \d + \s \w + \s - \s \d + / \d + / \d + ) \s ?
( ? P < PARTIAL > \( partial \) ) ? \n
2009-08-09 16:19:43 +02:00
( ? : . * ? \n ( ? P < CANCELLED > Hand \s \#(?P=HID)\shas\sbeen\scanceled))?
''' , re.VERBOSE|re.DOTALL)
2009-08-26 01:13:34 +02:00
re_TourneyExtraInfo = re . compile ( ''' (((?P<TOURNEY_NAME>[^$]+)?
( ? P < CURRENCY > \$ ) ? ( ? P < BUYIN > [ .0 - 9 ] + ) ? \s * \+ \s * \$ ? ( ? P < FEE > [ .0 - 9 ] + ) ?
( \s ( ? P < SPECIAL > ( KO | Heads \sUp | Matrix \s \dx | Rebuy | Madness ) ) ) ?
( \s ( ? P < SHOOTOUT > Shootout ) ) ?
( \s ( ? P < SNG > Sit \s & \sGo ) ) ?
( \s \( ( ? P < TURBO > Turbo ) \) ) ? ) | ( ? P < UNREADABLE_INFO > . + ) )
''' , re.VERBOSE)
2009-02-26 17:26:50 +01:00
re_Button = re . compile ( ' ^The button is in seat #(?P<BUTTON> \ d+) ' , re . MULTILINE )
2010-01-28 05:16:11 +01:00
re_PlayerInfo = re . compile ( ' Seat (?P<SEAT>[0-9]+): (?P<PNAME>. { 3,15}) \ ( \ $(?P<CASH>[,.0-9]+) \ )$ ' , re . MULTILINE )
re_TourneyPlayerInfo = re . compile ( ' Seat (?P<SEAT>[0-9]+): (?P<PNAME>. { 3,15}) \ ( \ $?(?P<CASH>[,.0-9]+) \ )(, is sitting out)?$ ' , re . MULTILINE )
2009-02-25 15:35:28 +01:00
re_Board = re . compile ( r " \ [(?P<CARDS>.+) \ ] " )
2009-07-22 19:51:48 +02:00
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
#static regex for tourney purpose
re_TourneyInfo = re . compile ( ''' Tournament \ sSummary \ s
( ? P < TOURNAMENT_NAME > [ ^ $ ( ] + ) ? \s *
( ( ? P < CURRENCY > \$ | ) ? ( ? P < BUYIN > [ .0 - 9 ] + ) \s * \+ \s * \$ ? ( ? P < FEE > [ .0 - 9 ] + ) \s ) ?
2009-08-26 01:13:34 +02:00
( ( ? P < SPECIAL > ( KO | Heads \sUp | Matrix \s \dx | Rebuy | Madness ) ) \s ) ?
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
( ( ? P < SHOOTOUT > Shootout ) \s ) ?
( ( ? P < SNG > Sit \s & \sGo ) \s ) ?
( \( ( ? P < TURBO1 > Turbo ) \) \s ) ?
\( ( ? P < TOURNO > \d + ) \) \s
( ( ? P < MATCHNO > Match \s \d ) \s ) ?
( ? P < GAME > ( Hold \' em|Omaha \ sHi|Omaha \ sH/L|7 \ sCard \ sStud|Stud \ sH/L|Razz|Stud \ sHi)) \ s
( \( ( ? P < TURBO2 > Turbo ) \) \s ) ?
( ? P < LIMIT > ( No \sLimit | Pot \sLimit | Limit ) ) ?
''' , re.VERBOSE)
re_TourneyBuyInFee = re . compile ( " Buy-In: (?P<BUYIN_CURRENCY> \ $|)?(?P<BUYIN>[.0-9]+) \ + \ $?(?P<FEE>[.0-9]+) " )
re_TourneyBuyInChips = re . compile ( " Buy-In Chips: (?P<BUYINCHIPS> \ d+) " )
re_TourneyEntries = re . compile ( " (?P<ENTRIES> \ d+) Entries " )
re_TourneyPrizePool = re . compile ( " Total Prize Pool: (?P<PRIZEPOOL_CURRENCY> \ $|)?(?P<PRIZEPOOL>[.,0-9]+) " )
re_TourneyRebuyAmount = re . compile ( " Rebuy: (?P<REBUY_CURRENCY> \ $|)?(?P<REBUY_AMOUNT>[.,0-9]+) " )
re_TourneyAddOnAmount = re . compile ( " Add-On: (?P<ADDON_CURRENCY> \ $|)?(?P<ADDON_AMOUNT>[.,0-9]+) " )
re_TourneyRebuyCount = re . compile ( " performed (?P<REBUY_COUNT> \ d+) Rebuy " )
re_TourneyAddOnCount = re . compile ( " performed (?P<ADDON_COUNT> \ d+) Add-On " )
re_TourneyRebuysTotal = re . compile ( " Total Rebuys: (?P<REBUY_TOTAL> \ d+) " )
re_TourneyAddOnsTotal = re . compile ( " Total Add-Ons: (?P<ADDONS_TOTAL> \ d+) " )
re_TourneyRebuyChips = re . compile ( " Rebuy Chips: (?P<REBUY_CHIPS> \ d+) " )
re_TourneyAddOnChips = re . compile ( " Add-On Chips: (?P<ADDON_CHIPS> \ d+) " )
re_TourneyKOBounty = re . compile ( " Knockout Bounty: (?P<KO_BOUNTY_CURRENCY> \ $|)?(?P<KO_BOUNTY_AMOUNT>[.,0-9]+) " )
re_TourneyCountKO = re . compile ( " received (?P<COUNT_KO> \ d+) Knockout Bounty Award(s)? " )
re_TourneyTimeInfo = re . compile ( " Tournament started: (?P<STARTTIME>.*) \n Tournament ((?P<IN_PROGRESS>is still in progress)?|(finished:(?P<ENDTIME>.*))?)$ " )
re_TourneyPlayersSummary = re . compile ( " ^(?P<RANK>(Still Playing| \ d+))( - |: )(?P<PNAME>[^ \n ,]+)(, )?(?P<WINNING_CURRENCY> \ $|)?(?P<WINNING>[. \ d]+)? " , re . MULTILINE )
re_TourneyHeroFinishingP = re . compile ( " (?P<HERO_NAME>.*) finished in (?P<HERO_FINISHING_POS> \ d+)(st|nd|rd|th) place " )
#TODO: See if we need to deal with play money tourney summaries -- Not right now (they shouldn't pass the re_TourneyInfo)
##Full Tilt Poker Tournament Summary 250 Play Money Sit & Go (102909471) Hold'em No Limit
##Buy-In: 250 Play Chips + 0 Play Chips
##Buy-In Chips: 1500
##6 Entries
##Total Prize Pool: 1,500 Play Chips
2009-07-22 19:51:48 +02:00
# These regexes are for FTP only
2009-07-22 16:24:29 +02:00
re_Mixed = re . compile ( r ' \ s \ - \ s(?P<MIXED>HA|HORSE|HOSE) \ s \ - \ s ' , re . VERBOSE )
2009-07-22 19:51:48 +02:00
re_Max = re . compile ( " (?P<MAX> \ d+)( max)? " , re . MULTILINE )
2009-04-04 16:12:45 +02:00
# NB: if we ever match "Full Tilt Poker" we should also match "FullTiltPoker", which PT Stud erroneously exports.
2009-02-25 15:35:28 +01:00
2009-08-18 21:17:00 +02:00
2009-07-22 16:24:29 +02:00
mixes = { ' HORSE ' : ' horse ' , ' 7-Game ' : ' 7game ' , ' HOSE ' : ' hose ' , ' HA ' : ' ha ' }
2009-08-16 20:01:36 +02:00
2009-03-10 00:03:17 +01:00
def compilePlayerRegexs ( self , hand ) :
players = set ( [ player [ 1 ] for player in hand . players ] )
2009-03-07 10:06:52 +01:00
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 )
self . re_PostSB = re . compile ( r " ^ %s posts the small blind of \ $?(?P<SB>[.0-9]+) " % player_re , re . MULTILINE )
self . re_PostBB = re . compile ( r " ^ %s posts (the big blind of )? \ $?(?P<BB>[.0-9]+) " % player_re , re . MULTILINE )
self . re_Antes = re . compile ( r " ^ %s antes \ $?(?P<ANTE>[.0-9]+) " % player_re , re . MULTILINE )
self . re_BringIn = re . compile ( r " ^ %s brings in for \ $?(?P<BRINGIN>[.0-9]+) " % player_re , re . MULTILINE )
self . re_PostBoth = re . compile ( r " ^ %s posts small \ & big blinds \ [ \ $? (?P<SBBB>[.0-9]+) " % player_re , re . MULTILINE )
2009-03-02 22:48:30 +01:00
self . re_HeroCards = re . compile ( r " ^Dealt to %s (?: \ [(?P<OLDCARDS>.+?) \ ])?( \ [(?P<NEWCARDS>.+?) \ ]) " % player_re , re . MULTILINE )
2009-07-20 20:27:03 +02:00
self . re_Action = re . compile ( r " ^ %s (?P<ATYPE> bets| checks| raises to| completes it to| calls| folds)( \ $?(?P<BET>[., \ d]+))? " % player_re , re . MULTILINE )
2009-03-07 10:06:52 +01:00
self . re_ShowdownAction = re . compile ( r " ^ %s shows \ [(?P<CARDS>.*) \ ] " % player_re , re . MULTILINE )
2009-08-16 20:01:36 +02:00
self . re_CollectPot = re . compile ( r " ^Seat (?P<SEAT>[0-9]+): %s ( \ (button \ ) | \ (small blind \ ) | \ (big blind \ ) )?(collected|showed \ [.* \ ] and won) \ ( \ $?(?P<POT>[., \ d]+) \ )(, mucked| with.*) " % player_re , re . MULTILINE )
2009-03-07 10:06:52 +01:00
self . re_SitsOut = re . compile ( r " ^ %s sits out " % player_re , re . MULTILINE )
2010-01-31 19:37:59 +01:00
self . re_ShownCards = re . compile ( r " ^Seat (?P<SEAT>[0-9]+): %s ( \ (button \ ) | \ (small blind \ ) | \ (big blind \ ) )?(?P<ACT>showed|mucked) \ [(?P<CARDS>.*) \ ].* " % player_re , re . MULTILINE )
2009-02-22 04:42:16 +01:00
2008-12-16 15:45:58 +01:00
def readSupportedGames ( self ) :
2009-02-22 10:07:11 +01:00
return [ [ " ring " , " hold " , " nl " ] ,
2009-02-23 11:24:21 +01:00
[ " ring " , " hold " , " pl " ] ,
2009-03-12 18:21:31 +01:00
[ " ring " , " hold " , " fl " ] ,
2009-10-01 04:49:59 +02:00
[ " ring " , " hold " , " cn " ] ,
2009-07-19 03:33:00 +02:00
2009-03-12 18:18:34 +01:00
[ " ring " , " stud " , " fl " ] ,
2009-07-19 03:33:00 +02:00
[ " tour " , " hold " , " nl " ] ,
[ " tour " , " hold " , " pl " ] ,
[ " tour " , " hold " , " fl " ] ,
[ " tour " , " stud " , " fl " ] ,
2009-02-22 10:07:11 +01:00
]
2008-12-16 15:45:58 +01:00
2009-03-04 16:10:08 +01:00
def determineGameType ( self , handText ) :
2009-02-22 10:07:11 +01:00
# Full Tilt Poker Game #10777181585: Table Deerfly (deep 6) - $0.01/$0.02 - Pot Limit Omaha Hi - 2:24:44 ET - 2009/02/22
# Full Tilt Poker Game #10773265574: Table Butte (6 max) - $0.01/$0.02 - Pot Limit Hold'em - 21:33:46 ET - 2009/02/21
# Full Tilt Poker Game #9403951181: Table CR - tay - $0.05/$0.10 - No Limit Hold'em - 9:40:20 ET - 2008/12/09
2009-03-04 15:29:13 +01:00
# Full Tilt Poker Game #10809877615: Table Danville - $0.50/$1 Ante $0.10 - Limit Razz - 21:47:27 ET - 2009/02/23
2009-03-10 00:03:17 +01:00
info = { ' type ' : ' ring ' }
2009-03-04 16:10:08 +01:00
m = self . re_GameInfo . search ( handText )
2009-03-10 00:03:17 +01:00
if not m :
return None
mg = m . groupdict ( )
# translations from captured groups to our info strings
limits = { ' No Limit ' : ' nl ' , ' Pot Limit ' : ' pl ' , ' Limit ' : ' fl ' }
games = { # base, category
" Hold ' em " : ( ' hold ' , ' holdem ' ) ,
' Omaha Hi ' : ( ' hold ' , ' omahahi ' ) ,
2009-07-17 23:07:53 +02:00
' Omaha H/L ' : ( ' hold ' , ' omahahilo ' ) ,
2009-03-10 00:03:17 +01:00
' Razz ' : ( ' stud ' , ' razz ' ) ,
2009-07-22 14:54:30 +02:00
' Stud Hi ' : ( ' stud ' , ' studhi ' ) ,
' Stud H/L ' : ( ' stud ' , ' studhilo ' )
2009-03-10 00:03:17 +01:00
}
currencies = { u ' € ' : ' EUR ' , ' $ ' : ' USD ' , ' ' : ' T$ ' }
2009-10-01 04:49:59 +02:00
if mg [ ' CAP ' ] :
info [ ' limitType ' ] = ' cn '
else :
info [ ' limitType ' ] = limits [ mg [ ' LIMIT ' ] ]
2009-07-17 23:07:53 +02:00
info [ ' sb ' ] = mg [ ' SB ' ]
info [ ' bb ' ] = mg [ ' BB ' ]
2009-11-03 20:30:52 +01:00
if mg [ ' GAME ' ] is not None :
2009-03-10 00:03:17 +01:00
( info [ ' base ' ] , info [ ' category ' ] ) = games [ mg [ ' GAME ' ] ]
2009-11-03 20:30:52 +01:00
if mg [ ' CURRENCY ' ] is not None :
2009-03-10 00:03:17 +01:00
info [ ' currency ' ] = currencies [ mg [ ' CURRENCY ' ] ]
2009-11-03 20:30:52 +01:00
if mg [ ' TOURNO ' ] is None : info [ ' type ' ] = " ring "
2009-07-19 03:33:00 +02:00
else : info [ ' type ' ] = " tour "
2009-03-10 00:03:17 +01:00
# NB: SB, BB must be interpreted as blinds or bets depending on limit type.
return info
2008-12-16 15:45:58 +01:00
def readHandInfo ( self , hand ) :
2009-08-09 16:19:43 +02:00
m = self . re_HandInfo . search ( hand . handText )
2009-11-03 20:30:52 +01:00
if m is None :
2009-03-18 17:52:18 +01:00
logging . info ( " Didn ' t match re_HandInfo " )
logging . info ( hand . handText )
return None
2008-12-16 15:45:58 +01:00
hand . handid = m . group ( ' HID ' )
hand . tablename = m . group ( ' TABLE ' )
2009-06-09 16:53:09 +02:00
hand . starttime = datetime . datetime . strptime ( m . group ( ' DATETIME ' ) , " % H: % M: % S ET - % Y/ % m/ %d " )
2009-08-09 16:19:43 +02:00
2009-08-23 21:02:00 +02:00
if m . group ( " CANCELLED " ) or m . group ( " PARTIAL " ) :
2009-08-09 16:19:43 +02:00
raise FpdbParseError ( hid = m . group ( ' HID ' ) )
2009-03-21 17:31:36 +01:00
if m . group ( ' TABLEATTRIBUTES ' ) :
2009-07-22 19:51:48 +02:00
m2 = self . re_Max . search ( m . group ( ' TABLEATTRIBUTES ' ) )
if m2 : hand . maxseats = int ( m2 . group ( ' MAX ' ) )
2009-07-19 03:33:00 +02:00
hand . tourNo = m . group ( ' TOURNO ' )
2009-11-03 20:30:52 +01:00
if m . group ( ' PLAY ' ) is not None :
2009-07-22 14:54:30 +02:00
hand . gametype [ ' currency ' ] = ' play '
2009-07-31 02:56:39 +02:00
2009-08-26 01:13:34 +02:00
# Done: if there's a way to figure these out, we should.. otherwise we have to stuff it with unknowns
if m . group ( ' TOURNAMENT ' ) is not None :
n = self . re_TourneyExtraInfo . search ( m . group ( ' TOURNAMENT ' ) )
if n . group ( ' UNREADABLE_INFO ' ) is not None :
hand . tourneyComment = n . group ( ' UNREADABLE_INFO ' )
else :
hand . tourneyComment = n . group ( ' TOURNEY_NAME ' ) # can be None
if ( n . group ( ' CURRENCY ' ) is not None and n . group ( ' BUYIN ' ) is not None and n . group ( ' FEE ' ) is not None ) :
hand . buyin = " %s %s + %s %s " % ( n . group ( ' CURRENCY ' ) , n . group ( ' BUYIN ' ) , n . group ( ' CURRENCY ' ) , n . group ( ' FEE ' ) )
if n . group ( ' TURBO ' ) is not None :
hand . speed = " Turbo "
if n . group ( ' SPECIAL ' ) is not None :
special = n . group ( ' SPECIAL ' )
if special == " Rebuy " :
hand . isRebuy = True
if special == " KO " :
hand . isKO = True
if special == " Head ' s Up " :
hand . isHU = True
if re . search ( " Matrix " , special ) :
hand . isMatrix = True
if special == " Shootout " :
hand . isShootout = True
2009-08-16 20:01:36 +02:00
2009-11-03 20:30:52 +01:00
if hand . buyin is None :
2009-07-31 02:56:39 +02:00
hand . buyin = " $0.00+$0.00 "
2009-11-03 20:30:52 +01:00
if hand . level is None :
2009-07-31 02:56:39 +02:00
hand . level = " 0 "
2009-07-19 03:33:00 +02:00
2008-12-16 15:45:58 +01:00
# These work, but the info is already in the Hand class - should be used for tourneys though.
2009-03-04 15:29:13 +01:00
# m.group('SB')
# m.group('BB')
# m.group('GAMETYPE')
2008-12-16 15:45:58 +01:00
# Stars format (Nov 10 2008): 2008/11/07 12:38:49 CET [2008/11/07 7:38:49 ET]
# or : 2008/11/07 12:38:49 ET
# Not getting it in my HH files yet, so using
# 2008/11/10 3:58:52 ET
#TODO: Do conversion from GMT to ET
#TODO: Need some date functions to convert to different timezones (Date::Manip for perl rocked for this)
2008-12-17 00:23:33 +01:00
#hand.starttime = "%d/%02d/%02d %d:%02d:%02d ET" %(int(m.group('YEAR')), int(m.group('MON')), int(m.group('DAY')),
##int(m.group('HR')), int(m.group('MIN')), int(m.group('SEC')))
2008-12-16 15:45:58 +01:00
def readPlayerStacks ( self , hand ) :
2010-01-28 16:38:52 +01:00
# Split hand text for FTP, as the regex matches the player names incorrectly
# in the summary section
pre , post = hand . handText . split ( ' SUMMARY ' )
2009-08-18 21:17:00 +02:00
if hand . gametype [ ' type ' ] == " ring " :
2010-01-28 16:38:52 +01:00
m = self . re_PlayerInfo . finditer ( pre )
2009-08-18 21:17:00 +02:00
else : #if hand.gametype['type'] == "tour"
2010-01-28 16:38:52 +01:00
m = self . re_TourneyPlayerInfo . finditer ( pre )
2009-08-18 21:17:00 +02:00
2008-12-16 15:45:58 +01:00
for a in m :
2010-01-27 18:44:14 +01:00
hand . addPlayer ( int ( a . group ( ' SEAT ' ) ) , a . group ( ' PNAME ' ) , a . group ( ' CASH ' ) )
2008-12-16 15:45:58 +01:00
def markStreets ( self , hand ) :
# PREFLOP = ** Dealing down cards **
2009-03-10 17:17:54 +01:00
if hand . gametype [ ' base ' ] == ' hold ' :
2009-02-24 17:17:25 +01:00
m = re . search ( r " \ * \ * \ * HOLE CARDS \ * \ * \ *(?P<PREFLOP>.+(?= \ * \ * \ * FLOP \ * \ * \ *)|.+) "
2008-12-16 18:26:58 +01:00
r " ( \ * \ * \ * FLOP \ * \ * \ *(?P<FLOP> \ [ \ S \ S \ S \ S \ S \ S \ ].+(?= \ * \ * \ * TURN \ * \ * \ *)|.+))? "
r " ( \ * \ * \ * TURN \ * \ * \ * \ [ \ S \ S \ S \ S \ S \ S] (?P<TURN> \ [ \ S \ S \ ].+(?= \ * \ * \ * RIVER \ * \ * \ *)|.+))? "
2009-03-04 16:10:08 +01:00
r " ( \ * \ * \ * RIVER \ * \ * \ * \ [ \ S \ S \ S \ S \ S \ S \ S \ S] (?P<RIVER> \ [ \ S \ S \ ].+))? " , hand . handText , re . DOTALL )
2009-03-10 17:17:54 +01:00
elif hand . gametype [ ' base ' ] == " stud " : # or should this be gametype['category'] == 'razz'
2009-02-24 18:05:51 +01:00
m = re . search ( r " (?P<ANTES>.+(?= \ * \ * \ * 3RD STREET \ * \ * \ *)|.+) "
r " ( \ * \ * \ * 3RD STREET \ * \ * \ *(?P<THIRD>.+(?= \ * \ * \ * 4TH STREET \ * \ * \ *)|.+))? "
r " ( \ * \ * \ * 4TH STREET \ * \ * \ *(?P<FOURTH>.+(?= \ * \ * \ * 5TH STREET \ * \ * \ *)|.+))? "
r " ( \ * \ * \ * 5TH STREET \ * \ * \ *(?P<FIFTH>.+(?= \ * \ * \ * 6TH STREET \ * \ * \ *)|.+))? "
r " ( \ * \ * \ * 6TH STREET \ * \ * \ *(?P<SIXTH>.+(?= \ * \ * \ * 7TH STREET \ * \ * \ *)|.+))? "
2009-03-04 16:10:08 +01:00
r " ( \ * \ * \ * 7TH STREET \ * \ * \ *(?P<SEVENTH>.+))? " , hand . handText , re . DOTALL )
2008-12-16 15:45:58 +01:00
hand . addStreets ( m )
2008-12-16 18:26:58 +01:00
def readCommunityCards ( self , hand , street ) : # street has been matched by markStreets, so exists in this hand
if street in ( ' FLOP ' , ' TURN ' , ' RIVER ' ) : # a list of streets which get dealt community cards (i.e. all but PREFLOP)
2008-12-16 22:08:10 +01:00
#print "DEBUG readCommunityCards:", street, hand.streets.group(street)
2009-03-10 17:17:54 +01:00
m = self . re_Board . search ( hand . streets [ street ] )
2008-12-16 18:26:58 +01:00
hand . setCommunityCards ( street , m . group ( ' CARDS ' ) . split ( ' ' ) )
2008-12-16 15:45:58 +01:00
def readBlinds ( self , hand ) :
try :
2009-09-16 08:40:43 +02:00
m = self . re_PostSB . search ( hand . handText )
2008-12-16 15:45:58 +01:00
hand . addBlind ( m . group ( ' PNAME ' ) , ' small blind ' , m . group ( ' SB ' ) )
2009-09-16 08:40:43 +02:00
except : # no small blind
2008-12-16 15:45:58 +01:00
hand . addBlind ( None , None , None )
2009-03-04 16:10:08 +01:00
for a in self . re_PostBB . finditer ( hand . handText ) :
2008-12-16 15:45:58 +01:00
hand . addBlind ( a . group ( ' PNAME ' ) , ' big blind ' , a . group ( ' BB ' ) )
2009-03-04 16:10:08 +01:00
for a in self . re_PostBoth . finditer ( hand . handText ) :
2008-12-16 15:45:58 +01:00
hand . addBlind ( a . group ( ' PNAME ' ) , ' small & big blinds ' , a . group ( ' SBBB ' ) )
2009-02-24 17:17:25 +01:00
def readAntes ( self , hand ) :
2009-03-04 17:46:01 +01:00
logging . debug ( " reading antes " )
2009-03-04 16:10:08 +01:00
m = self . re_Antes . finditer ( hand . handText )
2009-02-25 16:45:46 +01:00
for player in m :
2009-03-04 17:46:01 +01:00
logging . debug ( " hand.addAnte( %s , %s ) " % ( player . group ( ' PNAME ' ) , player . group ( ' ANTE ' ) ) )
2009-07-22 14:54:30 +02:00
# if player.group() !=
2009-02-25 16:45:46 +01:00
hand . addAnte ( player . group ( ' PNAME ' ) , player . group ( ' ANTE ' ) )
2009-02-24 17:17:25 +01:00
def readBringIn ( self , hand ) :
2009-03-04 16:10:08 +01:00
m = self . re_BringIn . search ( hand . handText , re . DOTALL )
2009-03-10 18:25:49 +01:00
if m :
logging . debug ( " Player bringing in: %s for %s " % ( m . group ( ' PNAME ' ) , m . group ( ' BRINGIN ' ) ) )
hand . addBringIn ( m . group ( ' PNAME ' ) , m . group ( ' BRINGIN ' ) )
else :
2009-07-23 01:21:00 +02:00
logging . warning ( " No bringin found, handid = %s " % hand . handid )
2009-02-24 17:17:25 +01:00
def readButton ( self , hand ) :
2009-03-04 16:10:08 +01:00
hand . buttonpos = int ( self . re_Button . search ( hand . handText ) . group ( ' BUTTON ' ) )
2009-02-24 17:17:25 +01:00
2008-12-16 15:45:58 +01:00
def readHeroCards ( self , hand ) :
2009-07-17 23:07:53 +02:00
# streets PREFLOP, PREDRAW, and THIRD are special cases beacause
# we need to grab hero's cards
for street in ( ' PREFLOP ' , ' DEAL ' ) :
if street in hand . streets . keys ( ) :
m = self . re_HeroCards . finditer ( hand . streets [ street ] )
for found in m :
# if m == None:
# hand.involved = False
# else:
hand . hero = found . group ( ' PNAME ' )
newcards = found . group ( ' NEWCARDS ' ) . split ( ' ' )
hand . addHoleCards ( street , hand . hero , closed = newcards , shown = False , mucked = False , dealt = True )
for street , text in hand . streets . iteritems ( ) :
if not text or street in ( ' PREFLOP ' , ' DEAL ' ) : continue # already done these
m = self . re_HeroCards . finditer ( hand . streets [ street ] )
for found in m :
player = found . group ( ' PNAME ' )
2009-11-03 20:30:52 +01:00
if found . group ( ' NEWCARDS ' ) is None :
2009-07-17 23:07:53 +02:00
newcards = [ ]
else :
newcards = found . group ( ' NEWCARDS ' ) . split ( ' ' )
2009-11-03 20:30:52 +01:00
if found . group ( ' OLDCARDS ' ) is None :
2009-07-17 23:07:53 +02:00
oldcards = [ ]
else :
oldcards = found . group ( ' OLDCARDS ' ) . split ( ' ' )
2009-07-22 20:06:05 +02:00
if street == ' THIRD ' and len ( oldcards ) == 2 : # hero in stud game
2009-07-17 23:07:53 +02:00
hand . hero = player
hand . dealt . add ( player ) # need this for stud??
2009-07-22 20:06:05 +02:00
hand . addHoleCards ( street , player , closed = oldcards , open = newcards , shown = False , mucked = False , dealt = False )
2009-07-17 23:07:53 +02:00
else :
hand . addHoleCards ( street , player , open = newcards , closed = oldcards , shown = False , mucked = False , dealt = False )
2009-02-25 11:32:12 +01:00
2008-12-16 15:45:58 +01:00
def readAction ( self , hand , street ) :
2009-03-07 15:35:52 +01:00
m = self . re_Action . finditer ( hand . streets [ street ] )
2008-12-16 15:45:58 +01:00
for action in m :
if action . group ( ' ATYPE ' ) == ' raises to ' :
hand . addRaiseTo ( street , action . group ( ' PNAME ' ) , action . group ( ' BET ' ) )
2009-03-12 02:49:16 +01:00
elif action . group ( ' ATYPE ' ) == ' completes it to ' :
2009-03-11 17:51:58 +01:00
hand . addComplete ( street , action . group ( ' PNAME ' ) , action . group ( ' BET ' ) )
2008-12-16 15:45:58 +01:00
elif action . group ( ' ATYPE ' ) == ' calls ' :
hand . addCall ( street , action . group ( ' PNAME ' ) , action . group ( ' BET ' ) )
elif action . group ( ' ATYPE ' ) == ' bets ' :
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 ' ) )
else :
2009-11-03 20:04:22 +01:00
print " FullTilt: DEBUG: unimplemented readAction: ' %s ' ' %s ' " % ( action . group ( ' PNAME ' ) , action . group ( ' ATYPE ' ) , )
2008-12-16 18:26:58 +01:00
2008-12-16 15:45:58 +01:00
def readShowdownActions ( self , hand ) :
2009-03-04 16:10:08 +01:00
for shows in self . re_ShowdownAction . finditer ( hand . handText ) :
2008-12-16 15:45:58 +01:00
cards = shows . group ( ' CARDS ' )
2009-03-02 16:10:15 +01:00
cards = cards . split ( ' ' )
2008-12-16 15:45:58 +01:00
hand . addShownCards ( cards , shows . group ( ' PNAME ' ) )
def readCollectPot ( self , hand ) :
2009-03-04 16:10:08 +01:00
for m in self . re_CollectPot . finditer ( hand . handText ) :
2009-08-16 20:01:36 +02:00
hand . addCollectPot ( player = m . group ( ' PNAME ' ) , pot = re . sub ( u ' , ' , u ' ' , m . group ( ' POT ' ) ) )
2008-12-16 18:26:58 +01:00
def readShownCards ( self , hand ) :
2009-03-04 16:10:08 +01:00
for m in self . re_ShownCards . finditer ( hand . handText ) :
2008-12-16 15:45:58 +01:00
if m . group ( ' CARDS ' ) is not None :
2010-01-31 19:37:59 +01:00
if m . group ( ' ACT ' ) :
hand . addShownCards ( cards = m . group ( ' CARDS ' ) . split ( ' ' ) , player = m . group ( ' PNAME ' ) , shown = False , mucked = True )
else :
hand . addShownCards ( cards = m . group ( ' CARDS ' ) . split ( ' ' ) , player = m . group ( ' PNAME ' ) , shown = True , mucked = False )
2008-12-16 15:45:58 +01:00
2009-07-20 16:01:51 +02:00
def guessMaxSeats ( self , hand ) :
""" Return a guess at max_seats when not specified in HH. """
mo = self . maxOccSeat ( hand )
if mo == 10 : return 10 #that was easy
if hand . gametype [ ' base ' ] == ' stud ' :
if mo < = 8 : return 8
else : return mo
if hand . gametype [ ' base ' ] == ' draw ' :
if mo < = 6 : return 6
else : return mo
if mo == 2 : return 2
if mo < = 6 : return 6
return 9
2009-07-22 16:24:29 +02:00
def readOther ( self , hand ) :
m = self . re_Mixed . search ( self . in_path )
2009-11-03 20:30:52 +01:00
if m is None :
hand . mixed = None
2009-07-22 16:24:29 +02:00
else :
hand . mixed = self . mixes [ m . groupdict ( ) [ ' MIXED ' ] ]
2008-12-16 15:45:58 +01:00
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
def readSummaryInfo ( self , summaryInfoList ) :
self . status = True
m = re . search ( " Tournament Summary " , summaryInfoList [ 0 ] )
if m :
# info list should be 2 lines : Tourney infos & Finsihing postions with winnings
if ( len ( summaryInfoList ) != 2 ) :
log . info ( " Too many lines ( %d ) in file ' %s ' : ' %s ' " % ( len ( summaryInfoList ) , self . in_path , summaryInfoList ) )
self . status = False
else :
self . tourney = Tourney . Tourney ( sitename = self . sitename , gametype = None , summaryText = summaryInfoList , builtFrom = " HHC " )
2009-09-03 07:51:05 +02:00
self . status = self . getPlayersPositionsAndWinnings ( self . tourney )
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
if self . status == True :
2009-09-03 02:11:38 +02:00
self . status = self . determineTourneyType ( self . tourney )
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
#print self.tourney
else :
log . info ( " Parsing NOK : rejected " )
else :
log . info ( " This is not a summary file : ' %s ' " % ( self . in_path ) )
self . status = False
return self . status
def determineTourneyType ( self , tourney ) :
info = { ' type ' : ' tour ' }
tourneyText = tourney . summaryText [ 0 ]
#print "Examine : '%s'" %(tourneyText)
m = self . re_TourneyInfo . search ( tourneyText )
if not m :
log . info ( " determineTourneyType : Parsing NOK " )
return False
mg = m . groupdict ( )
#print mg
# translations from captured groups to our info strings
limits = { ' No Limit ' : ' nl ' , ' Pot Limit ' : ' pl ' , ' Limit ' : ' fl ' }
games = { # base, category
" Hold ' em " : ( ' hold ' , ' holdem ' ) ,
' Omaha Hi ' : ( ' hold ' , ' omahahi ' ) ,
' Omaha H/L ' : ( ' hold ' , ' omahahilo ' ) ,
' Razz ' : ( ' stud ' , ' razz ' ) ,
' Stud Hi ' : ( ' stud ' , ' studhi ' ) ,
' Stud H/L ' : ( ' stud ' , ' studhilo ' )
}
currencies = { u ' € ' : ' EUR ' , ' $ ' : ' USD ' , ' ' : ' T$ ' }
info [ ' limitType ' ] = limits [ mg [ ' LIMIT ' ] ]
if mg [ ' GAME ' ] is not None :
( info [ ' base ' ] , info [ ' category ' ] ) = games [ mg [ ' GAME ' ] ]
if mg [ ' CURRENCY ' ] is not None :
info [ ' currency ' ] = currencies [ mg [ ' CURRENCY ' ] ]
2009-11-03 20:30:52 +01:00
if mg [ ' TOURNO ' ] is None :
info [ ' type ' ] = " ring "
else :
info [ ' type ' ] = " tour "
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
# NB: SB, BB must be interpreted as blinds or bets depending on limit type.
# Info is now ready to be copied in the tourney object
tourney . gametype = info
# Additional info can be stored in the tourney object
if mg [ ' BUYIN ' ] is not None :
2009-09-01 23:46:46 +02:00
tourney . buyin = 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % mg [ ' BUYIN ' ] ) )
tourney . fee = 0
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
if mg [ ' FEE ' ] is not None :
2009-09-01 23:46:46 +02:00
tourney . fee = 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % mg [ ' FEE ' ] ) )
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
if mg [ ' TOURNAMENT_NAME ' ] is not None :
# Tournament Name can have a trailing space at the end (depending on the tournament description)
tourney . tourneyName = mg [ ' TOURNAMENT_NAME ' ] . rstrip ( )
if mg [ ' SPECIAL ' ] is not None :
special = mg [ ' SPECIAL ' ]
if special == " KO " :
tourney . isKO = True
if special == " Heads Up " :
tourney . isHU = True
tourney . maxseats = 2
if re . search ( " Matrix " , special ) :
tourney . isMatrix = True
if special == " Rebuy " :
tourney . isRebuy = True
2009-08-26 01:13:34 +02:00
if special == " Madness " :
tourney . tourneyComment = " Madness "
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
if mg [ ' SHOOTOUT ' ] is not None :
tourney . isShootout = True
if mg [ ' TURBO1 ' ] is not None or mg [ ' TURBO2 ' ] is not None :
tourney . speed = " Turbo "
if mg [ ' TOURNO ' ] is not None :
tourney . tourNo = mg [ ' TOURNO ' ]
else :
log . info ( " Unable to get a valid Tournament ID -- File rejected " )
return False
if tourney . isMatrix :
if mg [ ' MATCHNO ' ] is not None :
tourney . matrixMatchId = mg [ ' MATCHNO ' ]
else :
tourney . matrixMatchId = 0
# Get BuyIn/Fee
# Try and deal with the different cases that can occur :
# - No buy-in/fee can be on the first line (freerolls, Satellites sometimes ?, ...) but appears in the rest of the description ==> use this one
# - Buy-In/Fee from the first line differs from the rest of the description :
# * OK in matrix tourneys (global buy-in dispatched between the different matches)
# * NOK otherwise ==> issue a warning and store specific data as if were a Matrix Tourney
# - If no buy-in/fee can be found : assume it's a freeroll
m = self . re_TourneyBuyInFee . search ( tourneyText )
if m is not None :
mg = m . groupdict ( )
if tourney . isMatrix :
if mg [ ' BUYIN ' ] is not None :
2009-09-01 23:46:46 +02:00
tourney . subTourneyBuyin = 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % mg [ ' BUYIN ' ] ) )
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
tourney . subTourneyFee = 0
if mg [ ' FEE ' ] is not None :
2009-09-01 23:46:46 +02:00
tourney . subTourneyFee = 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % mg [ ' FEE ' ] ) )
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
else :
if mg [ ' BUYIN ' ] is not None :
if tourney . buyin is None :
2009-09-01 23:46:46 +02:00
tourney . buyin = 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % mg [ ' BUYIN ' ] ) )
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
else :
2009-09-01 23:46:46 +02:00
if 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % mg [ ' BUYIN ' ] ) ) != tourney . buyin :
2010-01-27 07:10:58 +01:00
log . error ( " Conflict between buyins read in topline ( %s ) and in BuyIn field ( %s ) " % ( tourney . buyin , 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % mg [ ' BUYIN ' ] ) ) ) )
2009-09-01 23:46:46 +02:00
tourney . subTourneyBuyin = 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % mg [ ' BUYIN ' ] ) )
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
if mg [ ' FEE ' ] is not None :
if tourney . fee is None :
2009-09-01 23:46:46 +02:00
tourney . fee = 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % mg [ ' FEE ' ] ) )
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
else :
2009-09-01 23:46:46 +02:00
if 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % mg [ ' FEE ' ] ) ) != tourney . fee :
2010-01-27 07:10:58 +01:00
log . error ( " Conflict between fees read in topline ( %s ) and in BuyIn field ( %s ) " % ( tourney . fee , 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % mg [ ' FEE ' ] ) ) ) )
2009-09-01 23:46:46 +02:00
tourney . subTourneyFee = 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % mg [ ' FEE ' ] ) )
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
if tourney . buyin is None :
log . info ( " Unable to affect a buyin to this tournament : assume it ' s a freeroll " )
tourney . buyin = 0
tourney . fee = 0
else :
if tourney . fee is None :
#print "Couldn't initialize fee, even though buyin went OK : assume there are no fees"
tourney . fee = 0
#Get single line infos
dictRegex = { " BUYINCHIPS " : self . re_TourneyBuyInChips ,
" ENTRIES " : self . re_TourneyEntries ,
" PRIZEPOOL " : self . re_TourneyPrizePool ,
" REBUY_AMOUNT " : self . re_TourneyRebuyAmount ,
" ADDON_AMOUNT " : self . re_TourneyAddOnAmount ,
" REBUY_TOTAL " : self . re_TourneyRebuysTotal ,
" ADDONS_TOTAL " : self . re_TourneyAddOnsTotal ,
" REBUY_CHIPS " : self . re_TourneyRebuyChips ,
" ADDON_CHIPS " : self . re_TourneyAddOnChips ,
" STARTTIME " : self . re_TourneyTimeInfo ,
" KO_BOUNTY_AMOUNT " : self . re_TourneyKOBounty ,
}
dictHolders = { " BUYINCHIPS " : " buyInChips " ,
" ENTRIES " : " entries " ,
" PRIZEPOOL " : " prizepool " ,
" REBUY_AMOUNT " : " rebuyAmount " ,
" ADDON_AMOUNT " : " addOnAmount " ,
" REBUY_TOTAL " : " totalRebuys " ,
" ADDONS_TOTAL " : " totalAddOns " ,
" REBUY_CHIPS " : " rebuyChips " ,
" ADDON_CHIPS " : " addOnChips " ,
" STARTTIME " : " starttime " ,
2009-09-03 02:11:38 +02:00
" KO_BOUNTY_AMOUNT " : " koBounty "
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
}
mg = { } # After the loop, mg will contain all the matching groups, including the ones that have not been used, like ENDTIME and IN-PROGRESS
for data in dictRegex :
m = dictRegex . get ( data ) . search ( tourneyText )
if m is not None :
mg . update ( m . groupdict ( ) )
setattr ( tourney , dictHolders [ data ] , mg [ data ] )
if mg [ ' IN_PROGRESS ' ] is not None or mg [ ' ENDTIME ' ] is not None :
# Assign endtime to tourney (if None, that's ok, it's because the tourney wans't over over when the summary file was produced)
tourney . endtime = mg [ ' ENDTIME ' ]
2009-09-03 02:11:38 +02:00
# Deal with hero specific information
if tourney . hero is not None :
m = self . re_TourneyRebuyCount . search ( tourneyText )
if m is not None :
mg = m . groupdict ( )
if mg [ ' REBUY_COUNT ' ] is not None :
tourney . countRebuys . update ( { tourney . hero : Decimal ( mg [ ' REBUY_COUNT ' ] ) } )
m = self . re_TourneyAddOnCount . search ( tourneyText )
if m is not None :
mg = m . groupdict ( )
if mg [ ' ADDON_COUNT ' ] is not None :
tourney . countAddOns . update ( { tourney . hero : Decimal ( mg [ ' ADDON_COUNT ' ] ) } )
m = self . re_TourneyCountKO . search ( tourneyText )
if m is not None :
mg = m . groupdict ( )
if mg [ ' COUNT_KO ' ] is not None :
tourney . countKO . update ( { tourney . hero : Decimal ( mg [ ' COUNT_KO ' ] ) } )
2009-09-01 23:46:46 +02:00
# Deal with money amounts
tourney . koBounty = 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % tourney . koBounty ) )
tourney . prizepool = 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % tourney . prizepool ) )
tourney . rebuyAmount = 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % tourney . rebuyAmount ) )
tourney . addOnAmount = 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % tourney . addOnAmount ) )
2009-09-03 02:11:38 +02:00
# Calculate payin amounts and update winnings -- not possible to take into account nb of rebuys, addons or Knockouts for other players than hero on FTP
for p in tourney . players :
tourney . payinAmounts [ p ] = tourney . buyin + tourney . fee + ( tourney . rebuyAmount * tourney . countRebuys [ p ] ) + ( tourney . addOnAmount * tourney . countAddOns [ p ] )
#print " player %s : payinAmount = %d" %( p, tourney.payinAmounts[p])
if tourney . isKO :
#tourney.incrementPlayerWinnings(tourney.players[p], Decimal(tourney.koBounty)*Decimal(tourney.countKO[p]))
tourney . winnings [ p ] + = Decimal ( tourney . koBounty ) * Decimal ( tourney . countKO [ p ] )
#print "player %s : winnings %d" % (p, tourney.winnings[p])
2009-09-01 23:46:46 +02:00
#print mg
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
return True
def getPlayersPositionsAndWinnings ( self , tourney ) :
playersText = tourney . summaryText [ 1 ]
#print "Examine : '%s'" %(playersText)
m = self . re_TourneyPlayersSummary . finditer ( playersText )
for a in m :
if a . group ( ' PNAME ' ) is not None and a . group ( ' RANK ' ) is not None :
if a . group ( ' RANK ' ) == " Still Playing " :
rank = - 1
else :
rank = Decimal ( a . group ( ' RANK ' ) )
if a . group ( ' WINNING ' ) is not None :
2009-09-01 23:46:46 +02:00
winnings = 100 * Decimal ( re . sub ( u ' , ' , u ' ' , " %s " % a . group ( ' WINNING ' ) ) )
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
else :
winnings = " 0 "
2009-09-03 02:11:38 +02:00
tourney . addPlayer ( rank , a . group ( ' PNAME ' ) , winnings , 0 , 0 , 0 , 0 )
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
else :
2009-11-03 20:04:22 +01:00
print " FullTilt: Player finishing stats unreadable : %s " % a
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
2009-09-03 02:11:38 +02:00
# Find Hero
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
n = self . re_TourneyHeroFinishingP . search ( playersText )
if n is not None :
heroName = n . group ( ' HERO_NAME ' )
tourney . hero = heroName
# Is this really useful ?
2009-09-16 08:28:28 +02:00
if heroName not in tourney . finishPositions :
2009-11-03 20:04:22 +01:00
print " FullTilt: " , heroName , " not found in tourney.finishPositions ... "
2009-09-16 08:28:28 +02:00
elif ( tourney . finishPositions [ heroName ] != Decimal ( n . group ( ' HERO_FINISHING_POS ' ) ) ) :
2009-11-03 20:04:22 +01:00
print " FullTilt: Bad parsing : finish position incoherent : %s / %s " % ( tourney . finishPositions [ heroName ] , n . group ( ' HERO_FINISHING_POS ' ) )
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00
return True
2008-12-16 15:45:58 +01:00
if __name__ == " __main__ " :
2009-03-02 22:48:30 +01:00
parser = OptionParser ( )
parser . add_option ( " -i " , " --input " , dest = " ipath " , help = " parse input hand history " , default = " regression-test-files/fulltilt/razz/FT20090223 Danville - $0.50-$1 Ante $0.10 - Limit Razz.txt " )
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 )
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 ( )
2009-03-13 21:00:12 +01:00
e = Fulltilt ( in_path = options . ipath , out_path = options . opath , follow = options . follow )
First attempt to parsing summary files from FTP
modified: FulltiltToFpdb.py
* Modified re_HandInfo regex to take into account Matrix Tournament Hands Histories
* Add Regex for Tourney Summaries files parsing
* New methods : readSummaryInfo, determineTourneyType, getPlayersPositionsAndWinnings
modified: HandHistoryConverter.py
* Add a Tourney object in the attributes to allow storing the summary info retrieved and the ability to hand it over after parsing
* Add a new attribut parsedObjectType (string : "HH" or "Summary")
* In follow = False mode : read the first line to swicth between HH & Summary parsing
* TO DO : Deal with parsing summary files in follow = True mode
* New methods added : isSummary, getParsedObjectType (to be called in fpdb_import), readSummaryInfo : abstract (to be implemented in each specific HHC), getTourney (returns the new attribute)
new file: Tourney.py
* New object
* Lots of attributes regarding the tourney info (buy-in, fee, entries, speed, Rebuy/add-on info, starting chips, KnockOut info, isHeadsUp, isShootout, isMatrix, ...
* List of players with finishing positions (when available) and winnings (when available)
* Methods :
** addPlayer(self, rank, name, winnings)
** incrementPlayerWinnings(self, name, additionnalWinnings): used for KO tourneys when KO occured (for Hero only)
** calculatePayinAmount : unused yet, should be necessary for DB storage
** some Hand methods copied that are still to be done including : assemble and insert
** TO DO : write the insert method for the object to be stored in DB. This will have to deal with the fact that the DB write can occur both before (Bulk Import) or after the HH file info has been stored (tourney might or might not already exist)
modified: fpdb_import.py
* import_file_dict modified :
** after the construction of the hhc, it now calls the new getParsedObjectType method of HHC in order to know what has been parsed by the HHC
** If it's a hand history file (actual expected behaviour) : do as before
** If it's a summary file, gets the tourney object that has been built from the hhc and calls the insert method on it (similar to NEWIMPORT=True for HH)
2009-08-22 00:09:34 +02:00