Coverage for PokerStarsSummary.py: 0%
347 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-28 16:41 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-09-28 16:41 +0000
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
4#Copyright 2008-2012 Steffen Schaumburg, Carl Gherardi
5#This program is free software: you can redistribute it and/or modify
6#it under the terms of the GNU Affero General Public License as published by
7#the Free Software Foundation, version 3 of the License.
8#
9#This program is distributed in the hope that it will be useful,
10#but WITHOUT ANY WARRANTY; without even the implied warranty of
11#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12#GNU General Public License for more details.
13#
14#You should have received a copy of the GNU Affero General Public License
15#along with this program. If not, see <http://www.gnu.org/licenses/>.
16#In the "official" distribution you can find the license in agpl-3.0.txt.
18"""pokerstars-specific summary parsing code"""
20#import L10n
21#_ = L10n.get_translation()
23from decimal_wrapper import Decimal
24import datetime
26from Exceptions import FpdbParseError
27from HandHistoryConverter import *
28import PokerStarsStructures
29from TourneySummary import *
31class PokerStarsSummary(TourneySummary):
32 hhtype = "summary"
33 limits = { 'No Limit':'nl', 'NO LIMIT':'nl', 'NL':'nl', 'Pot Limit':'pl', 'POT LIMIT':'pl', 'PL':'pl', 'Limit':'fl', 'LIMIT':'fl' , 'Pot Limit Pre-Flop, No Limit Post-Flop': 'pn', 'PNL': 'pn'}
34 games = { # base, category
35 "Hold'em" : ('hold','holdem'),
36 "Hold 'Em" : ('hold','holdem'),
37 "6+ Hold'em" : ('hold','6_holdem'),
38 'Omaha' : ('hold','omahahi'),
39 'Omaha Hi/Lo' : ('hold','omahahilo'),
40 'Omaha H/L' : ('hold','omahahilo'),
41 '5 Card Omaha' : ('hold', '5_omahahi'),
42 '5 Card Omaha Hi/Lo' : ('hold', '5_omaha8'),
43 '5 Card Omaha H/L' : ('hold', '5_omaha8'),
44 '6 Card Omaha' : ('hold', '6_omahahi'),
45 '6 Card Omaha Hi/Lo': ('hold', '6_omaha8'),
46 'Courchevel' : ('hold', 'cour_hi'),
47 'Courchevel Hi/Lo' : ('hold', 'cour_hilo'),
48 'Courchevel H/L' : ('hold', 'cour_hilo'),
49 'Razz' : ('stud','razz'),
50 'RAZZ' : ('stud','razz'),
51 '7 Card Stud' : ('stud','studhi'),
52 '7 Card Stud Hi/Lo' : ('stud','studhilo'),
53 '7 Card Stud H/L' : ('stud','studhilo'),
54 'Badugi' : ('draw','badugi'),
55 'Triple Draw 2-7 Lowball' : ('draw','27_3draw'),
56 'Single Draw 2-7 Lowball' : ('draw','27_1draw'),
57 'Triple Draw 2-7' : ('draw','27_3draw'),
58 'Single Draw 2-7' : ('draw','27_1draw'),
59 '5 Card Draw' : ('draw','fivedraw'),
60 'HORSE' : ('mixed','horse'),
61 'HOSE' : ('mixed','hose'),
62 'Horse' : ('mixed','horse'),
63 'Hose' : ('mixed','hose'),
64 'Triple Stud' : ('mixed','3stud'),
65 '8-Game' : ('mixed','8game'),
66 'Mixed PLH/PLO' : ('mixed','plh_plo'),
67 'Mixed NLH/PLO' : ('mixed','nlh_plo'),
68 'Mixed NLH/NLO' : ('mixed','nlh_nlo'),
69 'Mixed Omaha H/L' : ('mixed','plo_lo'),
70 'Mixed Hold\'em' : ('mixed','mholdem'),
71 'PLH/PLO Mixed' : ('mixed','plh_plo'),
72 'NLH/PLO Mixed' : ('mixed','nlh_plo'),
73 'NLH/NLO Mixed' : ('mixed','nlh_nlo'),
74 'Omaha H/L Mixed' : ('mixed','plo_lo'),
75 'Hold\'em Mixed' : ('mixed','mholdem'),
76 'Mixed Omaha' : ('mixed','momaha'),
77 'Triple Stud' : ('mixed','3stud'),
78 }
80 substitutions = {
81 'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP|SC|INR|CNY", # legal ISO currency codes
82 'LS' : u"\$|\xe2\x82\xac|\u20AC||\£|\u20b9|\¥|Rs\.\s|" # legal currency symbols - Euro(cp1252, utf-8)
83 }
85 re_Identify = re.compile(u'((?P<SITE>PokerStars|Full\sTilt|Run\sIt\sOnce\sPoker)\sTournament\s\#\d+|<title>TOURNEYS:)')
87 re_TourNo = re.compile("\#(?P<TOURNO>[0-9]+),")
88 re_Header = re.compile("History\sRequest\s\-\s")
89 re_emailHeader = re.compile("Delivered\-To\:\s")
91 re_TourneyInfo = re.compile(u"""
92 \#(?P<TOURNO>[0-9]+),\s
93 (?P<DESC1>.+?\sSNG\s)?
94 ((?P<LIMIT>No\sLimit|NO\sLIMIT|Limit|LIMIT|Pot\sLimit|POT\sLIMIT|Pot\sLimit\sPre\-Flop,\sNo\sLimit\sPost\-Flop)\s)?
95 (?P<SPLIT>Split)?\s?
96 (?P<GAME>Hold\'em|6\+\sHold\'em|Hold\s\'Em|Razz|RAZZ|7\sCard\sStud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball|Single\sDraw\s2\-7\sLowball|5\sCard\sDraw|(5|6)\sCard\sOmaha(\sHi/Lo)?|Courchevel(\sHi/Lo)?|HORSE|8\-Game|HOSE|Mixed\sOmaha\sH/L|Mixed\sHold\'em|Mixed\sPLH/PLO|Mixed\sNLH/PLO||Mixed\sOmaha|Triple\sStud)\s+
97 (?P<DESC>[ a-zA-Z]+\s+)?
98 (Buy-In:\s(?P<CURRENCY>[%(LS)s]?)(?P<BUYIN>[,.0-9]+)(\s(?P<CURRENCY1>(FPP|SC)))?(\/[%(LS)s]?(?P<FEE>[,.0-9]+))?(\/[%(LS)s]?(?P<BOUNTY>[,.0-9]+))?(?P<CUR>\s(%(LEGAL_ISO)s))?\s+)?
99 (?P<ENTRIES>[0-9]+)\splayers\s+
100 ([%(LS)s]?(?P<ADDED>[,.\d]+)(\s(%(LEGAL_ISO)s))?\sadded\sto\sthe\sprize\spool\sby\s(PokerStars|Full\sTilt)(\.com)?\s+)?
101 (Total\sPrize\sPool:\s[%(LS)s]?(?P<PRIZEPOOL>[,.0-9]+|Sunday\sMillion\s(ticket|biļete))(\s(%(LEGAL_ISO)s))?\s+)?
102 (?P<SATELLITE>Target\sTournament\s\#(?P<TARGTOURNO>[0-9]+)\s+
103 (Buy-In:\s(?P<TARGCURRENCY>[%(LS)s]?)(?P<TARGBUYIN>[,.0-9]+)(\/[%(LS)s]?(?P<TARGFEE>[,.0-9]+))?(\/[%(LS)s]?(?P<TARGBOUNTY>[,.0-9]+))?(?P<TARGCUR>\s(%(LEGAL_ISO)s))?\s+)?)?
104 ([0-9]+\stickets?\sto\sthe\starget\stournament\s+)?
105 Tournament\sstarted\s+(-\s)?
106 (?P<DATETIME>.*$)
107 """ % substitutions ,re.VERBOSE|re.MULTILINE)
108 #re_TourneyInfo = re.compile(u"""(?P<TOURNO>[0-9]+),\s(?P<DESC1>.+?\sSNG\s)?((?P<LIMIT>No\sLimit|NO\sLIMIT|Limit|LIMIT|Pot\sLimit|POT\sLIMIT|Pot\sLimit\sPre\-Flop,\sNo\sLimit\sPost\-Flop)\s)?(?P<SPLIT>Split)?\s?(?P<GAME>Hold\'em|6\+\sHold\'em|Hold\s\'Em|Razz|RAZZ|7\sCard\sStud|7\sCard\sStud\sHi\/Lo|Omaha|Omaha\sHi\/Lo|Badugi|Triple\sDraw\s2\-7\sLowball|Single\sDraw\s2\-7\sLowball|5\sCard\sDraw|(5|6)\sCard\sOmaha(\sHi\/Lo)?|Courchevel(\sHi\/Lo)?|HORSE|8\-Game|HOSE|Mixed\sOmaha\sH\/L|Mixed\sHold\'em|Mixed\sPLH\/PLO|Mixed\sNLH\/PLO||Mixed\sOmaha|Triple\sStud)\s+Buy-In:\s(?P<CURRENCY>\[%(LS)s\]?)((?P<BUYIN>[,.0-9]+)/\[%(LS)s\]?(?P<FEE>[,.0-9]+)|(?P<BUYIN2>[,.0-9]+))\s+""" % substitutions ,re.VERBOSE|re.MULTILINE)
109 #re_TourneyInfo2 = re.compile(u"""(?P<ENTRIES>[0-9]+)\splayers\s+""" % substitutions ,re.VERBOSE|re.MULTILINE)
110 #re_TourneyInfo3 = re.compile(u"""Total\sPrize\sPool:\s\[%(LS)s\]?(?P<PRIZEPOOL>[,.0-9]+)\s+""" % substitutions ,re.VERBOSE|re.MULTILINE)
111 #re_TourneyInfo4 = re.compile(u"""Tournament\sstarted\s+(-\s)?(?P<DATETIME>.*$)""" % substitutions ,re.VERBOSE|re.MULTILINE)
112 #You made 5 rebuys and 1 addons for a total of USD 3,180.00.
113 re_rebuyAddOn = re.compile("""
114 You\smade\s(?P<REBUYCOUNT>\d+)\srebuys\sand\s(?P<ADDONCOUNT>\d+)\saddons\sfor\sa\stotal\sof\s(%(LEGAL_ISO)s)\s(?P<REBUYADDON>[,.0-9]+)
115 """ % substitutions ,re.VERBOSE|re.MULTILINE)
116 #You collected 5 bounties for a total of USD 875.00.
117 re_KOBounties = re.compile("""
118 You\scollected\s(?P<KOCOUNT>\d+)\sbounties\sfor\sa\stotal\sof\s(%(LEGAL_ISO)s)\s(?P<KOBOUNTY>[,.0-9]+)
119 """ % substitutions ,re.VERBOSE|re.MULTILINE)
121 re_HTMLTourneyInfo = re.compile(r'<td align="right">(?P<DATETIME>.*)</td>' \
122 r'<td align="center">(?P<TOURNO>[0-9]+)</td>' \
123 r'(<td>(?P<TOURNAME>.*)</td>)?' \
124 r'<td align="right">' \
125 r'(?P<LIMIT>[ a-zA-Z\-]+)\s' \
126 r'(?P<SPLIT>Split)?\s?' \
127 r'(?P<GAME>Hold\'em|Razz|RAZZ|7\sCard\sStud|7\sCard\sStud\sH/L|Omaha|Omaha\sH/L|Badugi|Triple\sDraw\s2\-7(\sLowball)?|Single\sDraw\s2\-7(\sLowball)?|5\sCard\sDraw|(5|6)\sCard\sOmaha(\sH/L)?|Courchevel(\sH/L)?|HORSE|Horse|8\-Game|HOSE|Hose|Omaha\sH/L\sMixed|Hold\'em\sMixed|PLH/PLO\sMixed|NLH/PLO\sMixed|Triple\sStud|NLH/NLO\sMixed|Mixed\sNLH/NLO|Mixed\sOmaha\sH/L|Mixed\sHold\'em|Mixed\sPLH/PLO|Mixed\sNLH/PLO)</td>' \
128 r'<td.*?>(?P<CURRENCY>(%(LEGAL_ISO)s)?)( )?</td>' \
129 r'<td.*?>(?P<BUYIN>([,.0-9 ]+|Freeroll))(?P<FPPBUYIN>(\s| )(FPP|SC|StarsCoin))?</td>' \
130 r'<td.*?>(?P<REBUYADDON>[,.0-9 ]+)</td>' \
131 r'<td.*?>(?P<FEE>[,.0-9 ]+)</td>' \
132 r'<td align="?right"?>(?P<RANK>[,.0-9]+)</td>' \
133 r'<td align="right">(?P<ENTRIES>[,.0-9]+)</td>' \
134 r'(<td.*?>[,.0-9]+</td>)?' \
135 r'<td.*?>(?P<WINNINGS>[,.0-9]+)(?P<FPPWINNINGS>\s\+\s[,.0-9]+(\s| )(FPP|SC|StarsCoin))?</td>' \
136 r'<td.*?>(?P<KOS>[,.0-9]+)</td>' \
137 r'<td.*?>((?P<TARGET>[,.0-9]+)|( ))</td>' \
138 r'<td.*?>((?P<WONTICKET>\*\\\/\*)|( ))</td>'
139 % substitutions, re.IGNORECASE)
141 re_XLSTourneyInfo = {}
142 re_XLSTourneyInfo['Date/Time'] = re.compile(r'(?P<DATETIME>.*)')
143 re_XLSTourneyInfo['Tourney'] = re.compile(r'(?P<TOURNO>[0-9]+)')
144 re_XLSTourneyInfo['Name'] = re.compile(r'(?P<TOURNAME>.*)')
145 re_XLSTourneyInfo['Game'] = re.compile(r'(?P<LIMIT>[ a-zA-Z\-]+)\s' \
146 r'(?P<SPLIT>Split)?\s?'
147 r'(?P<GAME>Hold\'em|Razz|RAZZ|7\sCard\sStud|7\sCard\sStud\sH/L|Omaha|Omaha\sH/L|Badugi|Triple\sDraw\s2\-7(\sLowball)?|Single\sDraw\s2\-7(\sLowball)?|5\sCard\sDraw|(5|6)\sCard\sOmaha(\sH/L)?|Courchevel(\sH/L)?|HORSE|Horse|8\-Game|HOSE|Hose|Omaha\sH/L\sMixed|Hold\'em\sMixed|PLH/PLO\sMixed|NLH/PLO\sMixed|Triple\sStud|NLH/NLO\sMixed|Mixed\sNLH/NLO|Mixed\sOmaha\sH/L|Mixed\sHold\'em|Mixed\sPLH/PLO|Mixed\sNLH/PLO)')
148 re_XLSTourneyInfo['Currency'] = re.compile(r'(?P<CURRENCY>(%(LEGAL_ISO)s)?)' % substitutions)
149 re_XLSTourneyInfo['Buy-In'] = re.compile(r'(?P<BUYIN>([,.0-9]+|Freeroll))(?P<FPPBUYIN>\s(FPP|SC|StarsCoin))?')
150 re_XLSTourneyInfo['ReBuys'] = re.compile(r'(?P<REBUYADDON>[,.0-9]+)')
151 re_XLSTourneyInfo['Rake'] = re.compile(r'(?P<FEE>[,.0-9]+)')
152 re_XLSTourneyInfo['Place'] = re.compile(r'(?P<RANK>[,.0-9]+)')
153 re_XLSTourneyInfo['Entries'] = re.compile(r'(?P<ENTRIES>[,.0-9]+)')
154 re_XLSTourneyInfo['Prize'] = re.compile(r'(?P<WINNINGS>[,.0-9]+)(?P<FPPWINNINGS>\s\+\s[,.0-9]+\s(FPP|SC|StarsCoin))?')
155 re_XLSTourneyInfo['Bounty Awarded'] = re.compile(r'(?P<KOS>[,.0-9]+)')
156 re_XLSTourneyInfo['Target ID'] = re.compile(r'(?P<TARGET>[0-9]+)?')
157 re_XLSTourneyInfo['Qualified'] = re.compile(r'(?P<WONTICKET>\*\\\/\*)?')
159 re_PlayerStars = re.compile(u"""(?P<RANK>[,.0-9]+):\s(?P<NAME>.+?)(\s\[(?P<ENTRYID>\d+)\])?\s\(.+?\),(\s)?((?P<CUR>\[%(LS)s]?)(?P<WINNINGS>[,.0-9]+)(\s(?P<CUR1>(FPP|SC)))?)?(?P<STILLPLAYING>still\splaying)?((?P<TICKET>Tournament\sTicket)\s\(WSOP\sStep\s(?P<LEVEL>\d)\))?(?P<QUALIFIED>\s\(qualified\sfor\sthe\starget\stournament\)|Sunday\sMillion\s(ticket|biļete))?(\s+)?""" % substitutions)
160 re_PlayerRIO = re.compile(u"""(?P<RANK>[,.0-9]+):\s(?P<NAME>[^,]+?)(,\s(?P<CUR>\[%(LS)s])(?P<WINNINGS>[,.0-9]+))?(\s+)?$""" % substitutions, re.MULTILINE)
161 re_HTMLPlayer1 = re.compile(r"<h2>All\s+(?P<SNG>(Regular|Sit & Go))\s?Tournaments\splayed\sby\s'(<b>)?(?P<NAME>.+?)':?</h2>", re.IGNORECASE)
162 re_HTMLPlayer2 = re.compile(r"<title>TOURNEYS:\s<(?P<NAME>.+?)></title>", re.IGNORECASE)
163 re_XLSPlayer = re.compile(r'All\s(?P<SNG>(Regular|(Heads\sup\s)?Sit\s&\sGo))\sTournaments\splayed\sby\s\'(?P<NAME>.+?)\'')
165 re_DateTime = re.compile("""(?P<Y>[0-9]{4})\/(?P<M>[0-9]{2})\/(?P<D>[0-9]{2})[\- ]+(?P<H>[0-9]+):(?P<MIN>[0-9]+):(?P<S>[0-9]+)""", re.MULTILINE)
166 re_HTMLDateTime = re.compile("""(?P<M>[0-9]+)\/(?P<D>[0-9]+)\/(?P<Y>[0-9]{4})[\- ]+(?P<H>[0-9]+):(?P<MIN>[0-9]+):(?P<S>[0-9]+) (?P<AMPM>(AM|PM))""", re.MULTILINE)
167 re_HTMLTourneyExtraInfo = re.compile("\[(Deep\s)?((?P<MAX>\d+)-Max,\s?)?((\dx\-)?(?P<SPEED>Turbo|Hyper\-Turbo))?(, )?(?P<REBUYADDON1>\dR\dA)?")
168 re_XLSDateTime = re.compile("^[.0-9]+$")
169 re_Rank = re.compile(u"^You\sfinished\sin\s(?P<RANK>[0-9]+)(st|nd|rd|th)\splace\.", re.MULTILINE)
170 #re_WinningRankOne = re.compile(u"^%(PLYR)s wins the tournament and receives %(CUR)s(?P<AMT>[\.0-9]+) - congratulations!$" % substitutions, re.MULTILINE)
171 #re_WinningRankOther = re.compile(u"^%(PLYR)s finished the tournament in (?P<RANK>[0-9]+)(st|nd|rd|th) place and received %(CUR)s(?P<AMT>[.0-9]+)\.$" % substitutions, re.MULTILINE)
172 #re_RankOther = re.compile(u"^%(PLYR)s finished the tournament in (?P<RANK>[0-9]+)(st|nd|rd|th) place$" % substitutions, re.MULTILINE)
174 codepage = ["utf8", "cp1252"]
176 @staticmethod
177 def getSplitRe(self, head):
178 re_SplitTourneys = re.compile("(?:PokerStars|Full\sTilt|Run\sIt\sOnce\sPoker) Tournament ")
179 re_HTMLSplitTourneys = re.compile("tr id=\"row_\d+")
180 m = re.search("<title>TOURNEYS:", head)
181 if m != None:
182 self.hhtype = "html"
183 return re_HTMLSplitTourneys
184 self.hhtype = "summary"
185 return re_SplitTourneys
187 def parseSummary(self):
188 if self.hhtype == "summary":
189 self.parseSummaryFile()
190 elif self.hhtype == "html":
191 self.parseSummaryHtml()
192 elif self.hhtype == "xls":
193 self.parseSummaryXLS()
194 elif self.hhtype == "hh":
195 self.parseSummaryFromHH()
196 else:
197 raise FpdbParseError(("parseSummary FAIL"))
199 def parseSummaryFromHH(self):
200 raise FpdbParseError(("PokerStarsSummary.parseSummaryHtml: This file format is not yet supported"))
201 # self.entries = Unavailable from HH
202 # self.prizepool = Unavailable from HH
203 # self.startTime = Unreliable from HH (late reg)
204 #obj = getattr(PokerStarsToFpdb, "PokerStars", None)
205 #hhc = obj(self.config, in_path = self.in_path, sitename = None, autostart = False)
207 #self.buyin = int(100*hhc.SnG_Structures[tourneyNameFull]['buyIn'])
208 #self.fee = int(100*hhc.SnG_Structures[tourneyNameFull]['fee'])
210 #self.tourNo =
211 #self.buyin =
212 #self.fee =
213 #self.buyinCurrency =
214 #self.currency =
215 #self.maxseats =
216 #self.isSng =
217 #self.addPlayer(rank, name, winnings, self.currency, rebuyCount, addOnCount, koCount)
219 def parseSummaryXLS(self):
220 info = self.summaryText[0]
221 m = self.re_XLSPlayer.search(info['header'])
222 if m==None:
223 tmp1 = info['header']
224 tmp2 = str(info)[0:200]
225 log.error(("PokerStarsSummary.parseSummaryXLS: '%s' '%s") % (tmp1, tmp2))
226 raise FpdbParseError
227 info.update(m.groupdict())
228 mg = {}
229 for k, j in info.iteritems():
230 if self.re_XLSTourneyInfo.get(k)!=None:
231 m1 = self.re_XLSTourneyInfo[k].search(j)
232 if m1: mg.update(m1.groupdict())
233 elif k=='Game':
234 log.error(("PokerStarsSummary.parseSummaryXLS Game '%s' not found") % j)
235 raise FpdbParseError
236 info.update(mg)
237 self.parseSummaryArchive(info)
239 def parseSummaryHtml(self):
240 info = {}
241 m1 = self.re_HTMLPlayer1.search(self.header)
242 if m1 == None:
243 m1 = self.re_HTMLPlayer2.search(self.header)
244 m2 = self.re_HTMLTourneyInfo.search(self.summaryText)
245 if m1 == None or m2==None:
246 if self.re_HTMLPlayer1.search(self.summaryText) or self.re_HTMLPlayer2.search(self.summaryText):
247 raise FpdbHandPartial
248 tmp1 = self.header[0:200] if m1 == None else 'NA'
249 tmp2 = self.summaryText if m2 == None else 'NA'
250 log.error(("PokerStarsSummary.parseSummaryHtml: '%s' '%s") % (tmp1, tmp2))
251 raise FpdbParseError
252 info.update(m1.groupdict())
253 info.update(m2.groupdict())
254 self.parseSummaryArchive(info)
256 def parseSummaryArchive(self, info):
257 if 'SNG' in info and "Sit & Go" in info['SNG']:
258 self.isSng = True
260 if 'TOURNAME' in info and info['TOURNAME'] != None:
261 self.tourneyName = re.sub("</?(b|font).*?>", "", info['TOURNAME'])
262 m3 = self.re_HTMLTourneyExtraInfo.search(self.tourneyName)
263 if m3 != None:
264 info.update(m3.groupdict())
266 if 'TOURNO' in info:
267 self.tourNo = info['TOURNO']
268 if 'LIMIT' in info and info['LIMIT'] is not None:
269 self.gametype['limitType'] = self.limits[info['LIMIT']]
270 if 'GAME' in info:
271 self.gametype['category'] = self.games[info['GAME']][1]
272 if 'SPLIT' in info and info['SPLIT'] == 'Split':
273 self.isSplit = True
274 if info['BUYIN'] != None:
275 if info['BUYIN']=='Freeroll':
276 self.buyin = 0
277 else:
278 self.buyin = int(100*float(self.clearMoneyString(info['BUYIN'].replace(" ", ""))))
279 if info['FEE'] != None:
280 self.fee = int(100*float(self.clearMoneyString(info['FEE'].replace(" ", ""))))
281 if (('REBUYADDON' in info and float(self.clearMoneyString(info['REBUYADDON'].replace(" ", "")))>0)):
282 self.isRebuy = True
283 self.isAddOn = True
284 rebuyAddOnAmt = int(100*float(self.clearMoneyString(info['REBUYADDON'].replace(" ", ""))))
285 if self.buyin != 0:
286 rebuys = int(rebuyAddOnAmt / self.buyin)
287 if rebuys != 0:
288 self.fee = self.fee / (rebuys + 1)
289 self.rebuyCost = self.buyin + self.fee
290 self.addOnCost = self.buyin + self.fee
291 if ('REBUYADDON1' in info and info['REBUYADDON1'] != None):
292 self.isRebuy = True
293 self.isAddOn = True
294 self.rebuyCost = self.buyin + self.fee
295 self.addOnCost = self.buyin + self.fee
296 if 'ENTRIES' in info:
297 self.entries = int(self.clearMoneyString(info['ENTRIES']))
298 if 'MAX' in info and info['MAX'] != None:
299 self.maxseats = int(info['MAX'])
300 if not self.isSng and 'SPEED' in info and info['SPEED'] != None:
301 if info['SPEED']=='Turbo':
302 self.speed = 'Turbo'
303 elif info['SPEED']=='Hyper-Turbo':
304 self.speed = 'Hyper'
305 if 'TARGET' in info and info['TARGET']!=None:
306 self.isSatellite = True
307 if 'WONTICKET' in info and info['WONTICKET']!=None:
308 self.comment = info['TARGET']
310 if 'DATETIME' in info: m4 = self.re_HTMLDateTime.finditer(info['DATETIME'])
311 datetimestr = None # default used if time not found
312 for a in m4:
313 datetimestr = "%s/%s/%s %s:%s:%s %s" % (a.group('Y'), a.group('M'),a.group('D'),a.group('H'),a.group('MIN'),a.group('S'),a.group('AMPM'))
314 self.endTime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %I:%M:%S %p") # also timezone at end, e.g. " ET"
315 self.endTime = HandHistoryConverter.changeTimezone(self.endTime, "ET", "UTC")
316 if datetimestr==None:
317 if xlrd and self.re_XLSDateTime.match(info['DATETIME']):
318 datetup = xlrd.xldate_as_tuple(float(info['DATETIME']), 0)
319 datetimestr = "%d/%d/%d %d:%d:%d" % (datetup[0],datetup[1],datetup[2],datetup[3],datetup[4],datetup[5])
320 else:
321 datetimestr = "2000/01/01 12:00:00"
322 self.endTime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S") # also timezone at end, e.g. " ET"
323 self.endTime = HandHistoryConverter.changeTimezone(self.endTime, "ET", "UTC")
326 if 'CURRENCY' in info and info['CURRENCY']!=None:
327 self.currency=info['CURRENCY']
328 if info['BUYIN']=='Freeroll':
329 self.buyinCurrency="FREE"
330 self.currency="USD"
331 elif info['FPPBUYIN'] != None:
332 self.buyinCurrency="PSFP"
333 elif self.currency != None:
334 self.buyinCurrency=self.currency
335 else:
336 self.buyinCurrency = "play"
337 self.currency = "play"
339 if self.buyinCurrency not in ('FREE', 'PSFP'):
340 self.prizepool = int(float(self.entries))*self.buyin
342 if self.isSng:
343 self.lookupStructures(self.endTime)
345 if info.get('NAME')!=None and info.get('RANK')!=None:
346 name = info['NAME']
347 rank = int(self.clearMoneyString(info['RANK']))
348 winnings = 0
349 rebuyCount = None
350 addOnCount = None
351 koCount = None
352 entryId = 1
354 if 'WINNINGS' in info and info['WINNINGS'] != None:
355 winnings = int(100*float(self.clearMoneyString(info['WINNINGS'])))
357 if (('REBUYADDON' in info and float(self.clearMoneyString(info['REBUYADDON'].replace(" ", "")))>0)):
358 rebuyAddOnAmt = int(100*float(self.clearMoneyString(info['REBUYADDON'].replace(" ", ""))))
359 rebuyCount = rebuyAddOnAmt/self.buyin
361 # KOs should be exclusively handled in the PokerStars hand history files
362 if 'KOS' in info and info['KOS'] != None and info['KOS'] != '0.00':
363 self.isKO = True
366 re_HTMLEntries = re.compile(r'<td align="center">%s</td>.+?<td align="?right"?>(?P<RANK>[,.0-9]+)</td>' % self.tourNo, re.IGNORECASE)
367 m = re_HTMLEntries.finditer(self.header)
368 entries = []
369 for a in m:
370 entries.append(int(self.clearMoneyString(a.group('RANK'))))
371 entries.sort(reverse=True)
373 if len(entries) > 1:
374 entryId = entries.index(rank) + 1
375 self.isReEntry = True
377 self.addPlayer(rank, name, winnings, self.currency, rebuyCount, addOnCount, koCount, entryId)
379 def parseSummaryFile(self):
380 m = self.re_TourneyInfo.search(self.summaryText)
381 if m == None:
382 if self.re_Header.match(self.summaryText):
383 raise FpdbHandPartial
384 if self.re_emailHeader.match(self.summaryText):
385 raise FpdbHandPartial
386 tmp = self.summaryText[0:200]
387 log.error(("PokerStarsSummary.parseSummaryFile: '%s'") % self.summaryText)
388 raise FpdbParseError
389 #m4 = self.re_TourneyInfo4.search(self.summaryText)
390 #print "DEBUG: m.groupdict(): %s" % m.groupdict()
391 mg = m.groupdict()
392 #mg4 = m4.groupdict()
393 if 'DATETIME' in mg: m1 = self.re_DateTime.finditer(mg['DATETIME'])
394 datetimestr = "2000/01/01 00:00:00" # default used if time not found
395 for a in m1:
396 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'))
398 self.startTime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S") # also timezone at end, e.g. " ET"
399 self.startTime = HandHistoryConverter.changeTimezone(self.startTime, "ET", "UTC")
401 if mg['DESC1'] != None:
402 self.siteName = 'Run It Once Poker'
403 self.siteId = 26
404 re_Player = self.re_PlayerRIO
405 else:
406 re_Player = self.re_PlayerStars
408 if 'TOURNO' in mg: self.tourNo = mg['TOURNO']
409 if 'LIMIT' in mg and mg['LIMIT'] is not None:
410 self.gametype['limitType'] = self.limits[mg['LIMIT']]
411 else:
412 self.gametype['limitType'] = 'fl'
413 if 'GAME' in mg: self.gametype['category'] = self.games[mg['GAME']][1]
414 if 'SPLIT' in mg and mg['SPLIT'] == 'Split':
415 self.isSplit = True
416 if mg['BOUNTY'] != None and mg['FEE'] != None:
417 self.koBounty = int(100*float(self.clearMoneyString(mg['FEE'])))
418 self.isKO = True
419 mg['FEE'] = mg['BOUNTY']
420 if mg['BUYIN'] != None:
421 self.buyin = int(100*float(self.clearMoneyString(mg['BUYIN']))) + self.koBounty
422 if mg['FEE'] != None:
423 self.fee = int(100*float(self.clearMoneyString(mg['FEE'])))
425 m2 = self.re_rebuyAddOn.search(self.summaryText)
426 if m2 and m2.group('REBUYCOUNT') != None:
427 self.isRebuy = True
428 self.isAddOn = True
429 #You made 5 rebuys and 1 addons for a total of USD 3,180.00.
430 rebuyCountHero = int(m2.group('REBUYCOUNT')) + int(m2.group('ADDONCOUNT')) #combine b/c html summary does not split out
431 self.rebuyCost = self.buyin + self.fee
432 self.addOnCost = self.buyin + self.fee
433 else:
434 rebuyCountHero = None
436 if 'PRIZEPOOL' in mg and mg['PRIZEPOOL'] != None:
437 if 'Sunday Million' in mg['PRIZEPOOL']:
438 self.isSatellite = True
439 newBuyinDate = HandHistoryConverter.changeTimezone(datetime.datetime.strptime("2019/01/27 00:00:00", "%Y/%m/%d %H:%M:%S"), "ET", "UTC")
440 if self.startTime > newBuyinDate:
441 targetBuyin, targetCurrency = 10900, "USD"
442 else:
443 targetBuyin, targetCurrency = 21500, "USD"
444 else:
445 self.prizepool = int(float(self.clearMoneyString(mg['PRIZEPOOL'])))
446 if 'ENTRIES' in mg: self.entries = int(mg['ENTRIES'])
447 if 'SATELLITE' in mg and mg['SATELLITE'] != None:
448 self.isSatellite = True
449 targetBuyin, targetCurrency = 0, "USD"
450 if mg['TARGBUYIN'] != None:
451 targetBuyin += int(100*float(self.clearMoneyString(mg['TARGBUYIN'])))
452 if mg['TARGFEE'] != None:
453 targetBuyin += int(100*float(self.clearMoneyString(mg['TARGFEE'])))
454 if mg['TARGBOUNTY'] != None:
455 targetBuyin += int(100*float(self.clearMoneyString(mg['TARGBOUNTY'])))
456 if mg['TARGCUR'] != None:
457 if mg['CUR'] == "$": targetCurrency="USD"
458 elif mg['CUR'] == u"€": targetCurrency="EUR"
459 elif mg['CUR'] == u"£": targetCurrency="GBP"
460 elif mg['CUR'] == u"₹": targetCurrency="INR"
461 elif mg['CUR'] == "Rs. ": targetCurrency = "INR"
462 elif mg['CUR'] == u"¥": targetCurrency="CNY"
463 elif mg['CUR'] == "FPP": targetCurrency="PSFP"
464 elif mg['CUR'] == "SC": targetCurrency="PSFP"
466 if mg['CURRENCY'] == "$": self.buyinCurrency="USD"
467 elif mg['CURRENCY'] == u"€": self.buyinCurrency="EUR"
468 elif mg['CURRENCY'] == u"£": self.buyinCurrency="GBP"
469 elif mg['CURRENCY'] == u"₹": self.buyinCurrency="INR"
470 elif mg['CURRENCY'] == "Rs. ": self.buyinCurrency = "INR"
471 elif mg['CURRENCY'] == u"¥": self.buyinCurrency="CNY"
472 elif mg['CURRENCY1'] == "FPP": self.buyinCurrency="PSFP"
473 elif mg['CURRENCY1'] == "SC": self.buyinCurrency="PSFP"
474 elif not mg['CURRENCY']: self.buyinCurrency="play"
475 if self.buyin == 0: self.buyinCurrency="FREE"
476 self.currency = self.buyinCurrency
478 if 'Zoom' in self.in_path or 'Rush' in self.in_path:
479 self.isFast = True
481 self.lookupStructures(self.startTime)
483 m3 = self.re_Rank.search(self.summaryText)
484 if m3:
485 heroRank = int(m3.group('RANK'))
486 else:
487 heroRank = 0
489 m = re_Player.finditer(self.summaryText)
490 for a in m:
491 mg = a.groupdict()
492 #print "DEBUG: a.groupdict(): %s" % mg
493 name = mg['NAME']
494 rank = int(mg['RANK'])
495 winnings = 0
496 rebuyCount = None
497 addOnCount = None
498 koCount = None
499 entryId = 1
501 if 'WINNINGS' in mg and mg['WINNINGS'] != None:
502 winnings = int(100*float(self.clearMoneyString(mg['WINNINGS'])))
504 if 'CUR' in mg and mg['CUR'] != None:
505 if mg['CUR'] == "$": self.currency="USD"
506 elif mg['CUR'] == u"€": self.currency="EUR"
507 elif mg['CUR'] == u"£": self.currency="GBP"
508 elif mg['CUR'] == u"₹": self.currency="INR"
509 elif mg['CUR'] == "Rs. ": self.currency = "INR"
510 elif mg['CUR'] == u"¥": self.currency="CNY"
511 elif mg['CUR1'] == "FPP": self.currency="PSFP"
512 elif mg['CUR1'] == "SC": self.currency="PSFP"
514 if 'STILLPLAYING' in mg and mg['STILLPLAYING'] != None:
515 #print "stillplaying"
516 rank=None
517 winnings=None
519 if 'TICKET' in mg and mg['TICKET'] != None:
520 #print "Tournament Ticket Level %s" % mg['LEVEL']
521 step_values = {
522 '1' : '750', # Step 1 - $7.50 USD
523 '2' : '2750', # Step 2 - $27.00 USD
524 '3' : '8200', # Step 3 - $82.00 USD
525 '4' : '21500', # Step 4 - $215.00 USD
526 '5' : '70000', # Step 5 - $700.00 USD
527 '6' : '210000', # Step 6 - $2100.00 USD
528 }
529 winnings = int(step_values[mg['LEVEL']])
531 if 'QUALIFIED' in mg and mg['QUALIFIED'] != None and self.isSatellite:
532 winnings = targetBuyin
533 self.currency = targetCurrency
535 if 'ENTRYID' in mg and mg['ENTRYID'] != None:
536 entryId = int(mg['ENTRYID'])
537 self.isReEntry = True
539 if heroRank == rank and entryId == 1:
540 rebuyCount = rebuyCountHero
541 addOnCount = None
542 koCount = None
544 #print "DEBUG: addPlayer(%s, %s, %s, %s, None, None, None)" %(rank, name, winnings, self.currency)
545 #print "DEBUG: self.buyin: %s self.fee %s" %(self.buyin, self.fee)
546 self.addPlayer(rank, name, winnings, self.currency, rebuyCount, addOnCount, koCount, entryId)
548 #print self
550 def lookupStructures(self, date):
551 Structures = PokerStarsStructures.PokerStarsStructures()
552 if self.entries%9==0 and self.entries < 45:
553 entries = 9
554 elif self.entries%6==0 and self.entries < 30:
555 entries = 6
556 elif self.entries > 6 and self.entries < 9:
557 entries = 9
558 else:
559 entries = self.entries
561 speed = Structures.lookupSnG((self.buyin, self.fee, entries), date)
562 if speed is not None:
563 self.speed = speed
564 if entries==10:
565 self.isDoubleOrNothing = True
567#end class PokerStarsSummary