Coverage for PokerStarsSummary.py: 0%

383 statements  

« prev     ^ index     » next       coverage.py v7.6.4, created at 2024-11-07 02:19 +0000

1#!/usr/bin/env python 

2# -*- coding: utf-8 -*- 

3 

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. 

17 

18"""pokerstars-specific summary parsing code""" 

19 

20# import L10n 

21# _ = L10n.get_translation() 

22 

23import datetime 

24import re 

25from HandHistoryConverter import HandHistoryConverter, FpdbParseError, FpdbHandPartial 

26import PokerStarsStructures 

27from TourneySummary import TourneySummary 

28 

29import logging 

30 

31try: 

32 import xlrd 

33except ImportError: 

34 xlrd = None 

35 

36# PPokerstatars HH Format 

37log = logging.getLogger("parser") 

38 

39 

40class PokerStarsSummary(TourneySummary): 

41 hhtype = "summary" 

42 limits = { 

43 "No Limit": "nl", 

44 "NO LIMIT": "nl", 

45 "NL": "nl", 

46 "Pot Limit": "pl", 

47 "POT LIMIT": "pl", 

48 "PL": "pl", 

49 "Limit": "fl", 

50 "LIMIT": "fl", 

51 "Pot Limit Pre-Flop, No Limit Post-Flop": "pn", 

52 "PNL": "pn", 

53 } 

54 games = { # base, category 

55 "Hold'em": ("hold", "holdem"), 

56 "Hold 'Em": ("hold", "holdem"), 

57 "6+ Hold'em": ("hold", "6_holdem"), 

58 "Omaha": ("hold", "omahahi"), 

59 "Omaha Hi/Lo": ("hold", "omahahilo"), 

60 "Omaha H/L": ("hold", "omahahilo"), 

61 "5 Card Omaha": ("hold", "5_omahahi"), 

62 "5 Card Omaha Hi/Lo": ("hold", "5_omaha8"), 

63 "5 Card Omaha H/L": ("hold", "5_omaha8"), 

64 "6 Card Omaha": ("hold", "6_omahahi"), 

65 "6 Card Omaha Hi/Lo": ("hold", "6_omaha8"), 

66 "Courchevel": ("hold", "cour_hi"), 

67 "Courchevel Hi/Lo": ("hold", "cour_hilo"), 

68 "Courchevel H/L": ("hold", "cour_hilo"), 

69 "Razz": ("stud", "razz"), 

70 "RAZZ": ("stud", "razz"), 

71 "7 Card Stud": ("stud", "studhi"), 

72 "7 Card Stud Hi/Lo": ("stud", "studhilo"), 

73 "7 Card Stud H/L": ("stud", "studhilo"), 

74 "Badugi": ("draw", "badugi"), 

75 "Triple Draw 2-7 Lowball": ("draw", "27_3draw"), 

76 "Single Draw 2-7 Lowball": ("draw", "27_1draw"), 

77 "Triple Draw 2-7": ("draw", "27_3draw"), 

78 "Single Draw 2-7": ("draw", "27_1draw"), 

79 "5 Card Draw": ("draw", "fivedraw"), 

80 "HORSE": ("mixed", "horse"), 

81 "HOSE": ("mixed", "hose"), 

82 "Horse": ("mixed", "horse"), 

83 "Hose": ("mixed", "hose"), 

84 "Triple Stud": ("mixed", "3stud"), 

85 "8-Game": ("mixed", "8game"), 

86 "Mixed PLH/PLO": ("mixed", "plh_plo"), 

87 "Mixed NLH/PLO": ("mixed", "nlh_plo"), 

88 "Mixed NLH/NLO": ("mixed", "nlh_nlo"), 

89 "Mixed Omaha H/L": ("mixed", "plo_lo"), 

90 "Mixed Hold'em": ("mixed", "mholdem"), 

91 "PLH/PLO Mixed": ("mixed", "plh_plo"), 

92 "NLH/PLO Mixed": ("mixed", "nlh_plo"), 

93 "NLH/NLO Mixed": ("mixed", "nlh_nlo"), 

94 "Omaha H/L Mixed": ("mixed", "plo_lo"), 

95 "Hold'em Mixed": ("mixed", "mholdem"), 

96 "Mixed Omaha": ("mixed", "momaha"), 

97 } 

98 

99 substitutions = { 

100 "LEGAL_ISO": "USD|EUR|GBP|CAD|FPP|SC|INR|CNY", # legal ISO currency codes 

101 "LS": "\$|\xe2\x82\xac|\u20ac||\£|\u20b9|\¥|Rs\.\s|", # legal currency symbols - Euro(cp1252, utf-8) 

102 } 

103 

104 re_Identify = re.compile( 

105 "((?P<SITE>PokerStars|Full\sTilt|Run\sIt\sOnce\sPoker)\sTournament\s\#\d+|<title>TOURNEYS:)" 

106 ) 

107 

108 re_TourNo = re.compile("\#(?P<TOURNO>[0-9]+),") 

109 re_Header = re.compile("History\sRequest\s\-\s") 

110 re_emailHeader = re.compile("Delivered\-To\:\s") 

111 

112 re_TourneyInfo = re.compile( 

113 """ 

114 \#(?P<TOURNO>[0-9]+),\s 

115 (?P<DESC1>.+?\sSNG\s)? 

116 ((?P<LIMIT>No\sLimit|NO\sLIMIT|Limit|LIMIT|Pot\sLimit|POT\sLIMIT|Pot\sLimit\sPre\-Flop,\sNo\sLimit\sPost\-Flop)\s)? 

117 (?P<SPLIT>Split)?\s? 

118 (?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+ 

119 (?P<DESC>[ a-zA-Z]+\s+)? 

120 (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+)? 

121 (?P<ENTRIES>[0-9]+)\splayers\s+ 

122 ([%(LS)s]?(?P<ADDED>[,.\d]+)(\s(%(LEGAL_ISO)s))?\sadded\sto\sthe\sprize\spool\sby\s(PokerStars|Full\sTilt)(\.com)?\s+)? 

123 (Total\sPrize\sPool:\s[%(LS)s]?(?P<PRIZEPOOL>[,.0-9]+|Sunday\sMillion\s(ticket|biļete))(\s(%(LEGAL_ISO)s))?\s+)? 

124 (?P<SATELLITE>Target\sTournament\s\#(?P<TARGTOURNO>[0-9]+)\s+ 

125 (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+)?)? 

126 ([0-9]+\stickets?\sto\sthe\starget\stournament\s+)? 

127 Tournament\sstarted\s+(-\s)? 

128 (?P<DATETIME>.*$) 

129 """ 

130 % substitutions, 

131 re.VERBOSE | re.MULTILINE, 

132 ) 

133 # 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) 

134 # re_TourneyInfo2 = re.compile(u"""(?P<ENTRIES>[0-9]+)\splayers\s+""" % substitutions ,re.VERBOSE|re.MULTILINE) 

135 # re_TourneyInfo3 = re.compile(u"""Total\sPrize\sPool:\s\[%(LS)s\]?(?P<PRIZEPOOL>[,.0-9]+)\s+""" % substitutions ,re.VERBOSE|re.MULTILINE) 

136 # re_TourneyInfo4 = re.compile(u"""Tournament\sstarted\s+(-\s)?(?P<DATETIME>.*$)""" % substitutions ,re.VERBOSE|re.MULTILINE) 

137 # You made 5 rebuys and 1 addons for a total of USD 3,180.00. 

138 re_rebuyAddOn = re.compile( 

139 """ 

140 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]+) 

141 """ 

142 % substitutions, 

143 re.VERBOSE | re.MULTILINE, 

144 ) 

145 # You collected 5 bounties for a total of USD 875.00. 

146 re_KOBounties = re.compile( 

147 """ 

148 You\scollected\s(?P<KOCOUNT>\d+)\sbounties\sfor\sa\stotal\sof\s(%(LEGAL_ISO)s)\s(?P<KOBOUNTY>[,.0-9]+) 

149 """ 

150 % substitutions, 

151 re.VERBOSE | re.MULTILINE, 

152 ) 

153 

154 re_HTMLTourneyInfo = re.compile( 

155 r'<td align="right">(?P<DATETIME>.*)</td>' 

156 r'<td align="center">(?P<TOURNO>[0-9]+)</td>' 

157 r"(<td>(?P<TOURNAME>.*)</td>)?" 

158 r'<td align="right">' 

159 r"(?P<LIMIT>[ a-zA-Z\-]+)\s" 

160 r"(?P<SPLIT>Split)?\s?" 

161 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>" 

162 r"<td.*?>(?P<CURRENCY>(%(LEGAL_ISO)s)?)(&nbsp;)?</td>" 

163 r"<td.*?>(?P<BUYIN>([,.0-9 ]+|Freeroll))(?P<FPPBUYIN>(\s|&nbsp;)(FPP|SC|StarsCoin))?</td>" 

164 r"<td.*?>(?P<REBUYADDON>[,.0-9 ]+)</td>" 

165 r"<td.*?>(?P<FEE>[,.0-9 ]+)</td>" 

166 r'<td align="?right"?>(?P<RANK>[,.0-9]+)</td>' 

167 r'<td align="right">(?P<ENTRIES>[,.0-9]+)</td>' 

168 r"(<td.*?>[,.0-9]+</td>)?" 

169 r"<td.*?>(?P<WINNINGS>[,.0-9]+)(?P<FPPWINNINGS>\s\+\s[,.0-9]+(\s|&nbsp;)(FPP|SC|StarsCoin))?</td>" 

170 r"<td.*?>(?P<KOS>[,.0-9]+)</td>" 

171 r"<td.*?>((?P<TARGET>[,.0-9]+)|(&nbsp;))</td>" 

172 r"<td.*?>((?P<WONTICKET>\*\\\/\*)|(&nbsp;))</td>" % substitutions, 

173 re.IGNORECASE, 

174 ) 

175 

176 re_XLSTourneyInfo = {} 

177 re_XLSTourneyInfo["Date/Time"] = re.compile(r"(?P<DATETIME>.*)") 

178 re_XLSTourneyInfo["Tourney"] = re.compile(r"(?P<TOURNO>[0-9]+)") 

179 re_XLSTourneyInfo["Name"] = re.compile(r"(?P<TOURNAME>.*)") 

180 re_XLSTourneyInfo["Game"] = re.compile( 

181 r"(?P<LIMIT>[ a-zA-Z\-]+)\s" 

182 r"(?P<SPLIT>Split)?\s?" 

183 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)" 

184 ) 

185 re_XLSTourneyInfo["Currency"] = re.compile(r"(?P<CURRENCY>(%(LEGAL_ISO)s)?)" % substitutions) 

186 re_XLSTourneyInfo["Buy-In"] = re.compile(r"(?P<BUYIN>([,.0-9]+|Freeroll))(?P<FPPBUYIN>\s(FPP|SC|StarsCoin))?") 

187 re_XLSTourneyInfo["ReBuys"] = re.compile(r"(?P<REBUYADDON>[,.0-9]+)") 

188 re_XLSTourneyInfo["Rake"] = re.compile(r"(?P<FEE>[,.0-9]+)") 

189 re_XLSTourneyInfo["Place"] = re.compile(r"(?P<RANK>[,.0-9]+)") 

190 re_XLSTourneyInfo["Entries"] = re.compile(r"(?P<ENTRIES>[,.0-9]+)") 

191 re_XLSTourneyInfo["Prize"] = re.compile( 

192 r"(?P<WINNINGS>[,.0-9]+)(?P<FPPWINNINGS>\s\+\s[,.0-9]+\s(FPP|SC|StarsCoin))?" 

193 ) 

194 re_XLSTourneyInfo["Bounty Awarded"] = re.compile(r"(?P<KOS>[,.0-9]+)") 

195 re_XLSTourneyInfo["Target ID"] = re.compile(r"(?P<TARGET>[0-9]+)?") 

196 re_XLSTourneyInfo["Qualified"] = re.compile(r"(?P<WONTICKET>\*\\\/\*)?") 

197 

198 re_PlayerStars = re.compile( 

199 """(?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+)?""" 

200 % substitutions 

201 ) 

202 re_PlayerRIO = re.compile( 

203 """(?P<RANK>[,.0-9]+):\s(?P<NAME>[^,]+?)(,\s(?P<CUR>\[%(LS)s])(?P<WINNINGS>[,.0-9]+))?(\s+)?$""" 

204 % substitutions, 

205 re.MULTILINE, 

206 ) 

207 re_HTMLPlayer1 = re.compile( 

208 r"<h2>All\s+(?P<SNG>(Regular|Sit & Go))\s?Tournaments\splayed\sby\s'(<b>)?(?P<NAME>.+?)':?</h2>", re.IGNORECASE 

209 ) 

210 re_HTMLPlayer2 = re.compile(r"<title>TOURNEYS:\s&lt;(?P<NAME>.+?)&gt;</title>", re.IGNORECASE) 

211 re_XLSPlayer = re.compile( 

212 r"All\s(?P<SNG>(Regular|(Heads\sup\s)?Sit\s&\sGo))\sTournaments\splayed\sby\s\'(?P<NAME>.+?)\'" 

213 ) 

214 

215 re_DateTime = re.compile( 

216 """(?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]+)""", 

217 re.MULTILINE, 

218 ) 

219 re_HTMLDateTime = re.compile( 

220 """(?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))""", 

221 re.MULTILINE, 

222 ) 

223 re_HTMLTourneyExtraInfo = re.compile( 

224 "\[(Deep\s)?((?P<MAX>\d+)-Max,\s?)?((\dx\-)?(?P<SPEED>Turbo|Hyper\-Turbo))?(, )?(?P<REBUYADDON1>\dR\dA)?" 

225 ) 

226 re_XLSDateTime = re.compile("^[.0-9]+$") 

227 re_Rank = re.compile("^You\sfinished\sin\s(?P<RANK>[0-9]+)(st|nd|rd|th)\splace\.", re.MULTILINE) 

228 # re_WinningRankOne = re.compile(u"^%(PLYR)s wins the tournament and receives %(CUR)s(?P<AMT>[\.0-9]+) - congratulations!$" % substitutions, re.MULTILINE) 

229 # 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) 

230 # re_RankOther = re.compile(u"^%(PLYR)s finished the tournament in (?P<RANK>[0-9]+)(st|nd|rd|th) place$" % substitutions, re.MULTILINE) 

231 

232 codepage = ["utf8", "cp1252"] 

233 

234 @staticmethod 

235 def getSplitRe(self, head): 

236 re_SplitTourneys = re.compile("(?:PokerStars|Full\sTilt|Run\sIt\sOnce\sPoker) Tournament ") 

237 re_HTMLSplitTourneys = re.compile('tr id="row_\d+') 

238 m = re.search("<title>TOURNEYS:", head) 

239 if m is not None: 

240 self.hhtype = "html" 

241 return re_HTMLSplitTourneys 

242 self.hhtype = "summary" 

243 return re_SplitTourneys 

244 

245 def parseSummary(self): 

246 if self.hhtype == "summary": 

247 self.parseSummaryFile() 

248 elif self.hhtype == "html": 

249 self.parseSummaryHtml() 

250 elif self.hhtype == "xls": 

251 self.parseSummaryXLS() 

252 elif self.hhtype == "hh": 

253 self.parseSummaryFromHH() 

254 else: 

255 raise FpdbParseError(("parseSummary FAIL")) 

256 

257 def parseSummaryFromHH(self): 

258 raise FpdbParseError(("PokerStarsSummary.parseSummaryHtml: This file format is not yet supported")) 

259 # self.entries = Unavailable from HH 

260 # self.prizepool = Unavailable from HH 

261 # self.startTime = Unreliable from HH (late reg) 

262 # obj = getattr(PokerStarsToFpdb, "PokerStars", None) 

263 # hhc = obj(self.config, in_path = self.in_path, sitename = None, autostart = False) 

264 

265 # self.buyin = int(100*hhc.SnG_Structures[tourneyNameFull]['buyIn']) 

266 # self.fee = int(100*hhc.SnG_Structures[tourneyNameFull]['fee']) 

267 

268 # self.tourNo = 

269 # self.buyin = 

270 # self.fee = 

271 # self.buyinCurrency = 

272 # self.currency = 

273 # self.maxseats = 

274 # self.isSng = 

275 # self.addPlayer(rank, name, winnings, self.currency, rebuyCount, addOnCount, koCount) 

276 

277 def parseSummaryXLS(self): 

278 info = self.summaryText[0] 

279 m = self.re_XLSPlayer.search(info["header"]) 

280 if m is None: 

281 tmp1 = info["header"] 

282 tmp2 = str(info)[0:200] 

283 log.error(("PokerStarsSummary.parseSummaryXLS: '%s' '%s") % (tmp1, tmp2)) 

284 raise FpdbParseError 

285 info.update(m.groupdict()) 

286 mg = {} 

287 for k, j in info.iteritems(): 

288 if self.re_XLSTourneyInfo.get(k) is not None: 

289 m1 = self.re_XLSTourneyInfo[k].search(j) 

290 if m1: 

291 mg.update(m1.groupdict()) 

292 elif k == "Game": 

293 log.error(("PokerStarsSummary.parseSummaryXLS Game '%s' not found") % j) 

294 raise FpdbParseError 

295 info.update(mg) 

296 self.parseSummaryArchive(info) 

297 

298 def parseSummaryHtml(self): 

299 info = {} 

300 m1 = self.re_HTMLPlayer1.search(self.header) 

301 if m1 is None: 

302 m1 = self.re_HTMLPlayer2.search(self.header) 

303 m2 = self.re_HTMLTourneyInfo.search(self.summaryText) 

304 if m1 is None or m2 is None: 

305 if self.re_HTMLPlayer1.search(self.summaryText) or self.re_HTMLPlayer2.search(self.summaryText): 

306 raise FpdbHandPartial 

307 tmp1 = self.header[0:200] if m1 is None else "NA" 

308 tmp2 = self.summaryText if m2 is None else "NA" 

309 log.error(("PokerStarsSummary.parseSummaryHtml: '%s' '%s") % (tmp1, tmp2)) 

310 raise FpdbParseError 

311 info.update(m1.groupdict()) 

312 info.update(m2.groupdict()) 

313 self.parseSummaryArchive(info) 

314 

315 def parseSummaryArchive(self, info): 

316 if "SNG" in info and "Sit & Go" in info["SNG"]: 

317 self.isSng = True 

318 

319 if "TOURNAME" in info and info["TOURNAME"] is not None: 

320 self.tourneyName = re.sub("</?(b|font).*?>", "", info["TOURNAME"]) 

321 m3 = self.re_HTMLTourneyExtraInfo.search(self.tourneyName) 

322 if m3 is not None: 

323 info.update(m3.groupdict()) 

324 

325 if "TOURNO" in info: 

326 self.tourNo = info["TOURNO"] 

327 if "LIMIT" in info and info["LIMIT"] is not None: 

328 self.gametype["limitType"] = self.limits[info["LIMIT"]] 

329 if "GAME" in info: 

330 self.gametype["category"] = self.games[info["GAME"]][1] 

331 if "SPLIT" in info and info["SPLIT"] == "Split": 

332 self.isSplit = True 

333 if info["BUYIN"] is not None: 

334 if info["BUYIN"] == "Freeroll": 

335 self.buyin = 0 

336 else: 

337 self.buyin = int(100 * float(self.clearMoneyString(info["BUYIN"].replace(" ", "")))) 

338 if info["FEE"] is not None: 

339 self.fee = int(100 * float(self.clearMoneyString(info["FEE"].replace(" ", "")))) 

340 if "REBUYADDON" in info and float(self.clearMoneyString(info["REBUYADDON"].replace(" ", ""))) > 0: 

341 self.isRebuy = True 

342 self.isAddOn = True 

343 rebuyAddOnAmt = int(100 * float(self.clearMoneyString(info["REBUYADDON"].replace(" ", "")))) 

344 if self.buyin != 0: 

345 rebuys = int(rebuyAddOnAmt / self.buyin) 

346 if rebuys != 0: 

347 self.fee = self.fee / (rebuys + 1) 

348 self.rebuyCost = self.buyin + self.fee 

349 self.addOnCost = self.buyin + self.fee 

350 if "REBUYADDON1" in info and info["REBUYADDON1"] is not None: 

351 self.isRebuy = True 

352 self.isAddOn = True 

353 self.rebuyCost = self.buyin + self.fee 

354 self.addOnCost = self.buyin + self.fee 

355 if "ENTRIES" in info: 

356 self.entries = int(self.clearMoneyString(info["ENTRIES"])) 

357 if "MAX" in info and info["MAX"] is not None: 

358 self.maxseats = int(info["MAX"]) 

359 if not self.isSng and "SPEED" in info and info["SPEED"] is not None: 

360 if info["SPEED"] == "Turbo": 

361 self.speed = "Turbo" 

362 elif info["SPEED"] == "Hyper-Turbo": 

363 self.speed = "Hyper" 

364 if "TARGET" in info and info["TARGET"] is not None: 

365 self.isSatellite = True 

366 if "WONTICKET" in info and info["WONTICKET"] is not None: 

367 self.comment = info["TARGET"] 

368 

369 if "DATETIME" in info: 

370 m4 = self.re_HTMLDateTime.finditer(info["DATETIME"]) 

371 datetimestr = None # default used if time not found 

372 for a in m4: 

373 datetimestr = "%s/%s/%s %s:%s:%s %s" % ( 

374 a.group("Y"), 

375 a.group("M"), 

376 a.group("D"), 

377 a.group("H"), 

378 a.group("MIN"), 

379 a.group("S"), 

380 a.group("AMPM"), 

381 ) 

382 self.endTime = datetime.datetime.strptime( 

383 datetimestr, "%Y/%m/%d %I:%M:%S %p" 

384 ) # also timezone at end, e.g. " ET" 

385 self.endTime = HandHistoryConverter.changeTimezone(self.endTime, "ET", "UTC") 

386 if datetimestr is None: 

387 if xlrd and self.re_XLSDateTime.match(info["DATETIME"]): 

388 datetup = xlrd.xldate_as_tuple(float(info["DATETIME"]), 0) 

389 datetimestr = "%d/%d/%d %d:%d:%d" % ( 

390 datetup[0], 

391 datetup[1], 

392 datetup[2], 

393 datetup[3], 

394 datetup[4], 

395 datetup[5], 

396 ) 

397 else: 

398 datetimestr = "2000/01/01 12:00:00" 

399 self.endTime = datetime.datetime.strptime( 

400 datetimestr, "%Y/%m/%d %H:%M:%S" 

401 ) # also timezone at end, e.g. " ET" 

402 self.endTime = HandHistoryConverter.changeTimezone(self.endTime, "ET", "UTC") 

403 

404 if "CURRENCY" in info and info["CURRENCY"] is not None: 

405 self.currency = info["CURRENCY"] 

406 if info["BUYIN"] == "Freeroll": 

407 self.buyinCurrency = "FREE" 

408 self.currency = "USD" 

409 elif info["FPPBUYIN"] is not None: 

410 self.buyinCurrency = "PSFP" 

411 elif self.currency is not None: 

412 self.buyinCurrency = self.currency 

413 else: 

414 self.buyinCurrency = "play" 

415 self.currency = "play" 

416 

417 if self.buyinCurrency not in ("FREE", "PSFP"): 

418 self.prizepool = int(float(self.entries)) * self.buyin 

419 

420 if self.isSng: 

421 self.lookupStructures(self.endTime) 

422 

423 if info.get("NAME") is not None and info.get("RANK") is not None: 

424 name = info["NAME"] 

425 rank = int(self.clearMoneyString(info["RANK"])) 

426 winnings = 0 

427 rebuyCount = None 

428 addOnCount = None 

429 koCount = None 

430 entryId = 1 

431 

432 if "WINNINGS" in info and info["WINNINGS"] is not None: 

433 winnings = int(100 * float(self.clearMoneyString(info["WINNINGS"]))) 

434 

435 if "REBUYADDON" in info and float(self.clearMoneyString(info["REBUYADDON"].replace(" ", ""))) > 0: 

436 rebuyAddOnAmt = int(100 * float(self.clearMoneyString(info["REBUYADDON"].replace(" ", "")))) 

437 rebuyCount = rebuyAddOnAmt / self.buyin 

438 

439 # KOs should be exclusively handled in the PokerStars hand history files 

440 if "KOS" in info and info["KOS"] is not None and info["KOS"] != "0.00": 

441 self.isKO = True 

442 

443 re_HTMLEntries = re.compile( 

444 r'<td align="center">%s</td>.+?<td align="?right"?>(?P<RANK>[,.0-9]+)</td>' % self.tourNo, re.IGNORECASE 

445 ) 

446 m = re_HTMLEntries.finditer(self.header) 

447 entries = [] 

448 for a in m: 

449 entries.append(int(self.clearMoneyString(a.group("RANK")))) 

450 entries.sort(reverse=True) 

451 

452 if len(entries) > 1: 

453 entryId = entries.index(rank) + 1 

454 self.isReEntry = True 

455 

456 self.addPlayer(rank, name, winnings, self.currency, rebuyCount, addOnCount, koCount, entryId) 

457 

458 def parseSummaryFile(self): 

459 m = self.re_TourneyInfo.search(self.summaryText) 

460 if m is None: 

461 if self.re_Header.match(self.summaryText): 

462 raise FpdbHandPartial 

463 if self.re_emailHeader.match(self.summaryText): 

464 raise FpdbHandPartial 

465 # tmp = self.summaryText[0:200] 

466 log.error(("PokerStarsSummary.parseSummaryFile: '%s'") % self.summaryText) 

467 raise FpdbParseError 

468 # m4 = self.re_TourneyInfo4.search(self.summaryText) 

469 # print "DEBUG: m.groupdict(): %s" % m.groupdict() 

470 mg = m.groupdict() 

471 # mg4 = m4.groupdict() 

472 if "DATETIME" in mg: 

473 m1 = self.re_DateTime.finditer(mg["DATETIME"]) 

474 datetimestr = "2000/01/01 00:00:00" # default used if time not found 

475 for a in m1: 

476 datetimestr = "%s/%s/%s %s:%s:%s" % ( 

477 a.group("Y"), 

478 a.group("M"), 

479 a.group("D"), 

480 a.group("H"), 

481 a.group("MIN"), 

482 a.group("S"), 

483 ) 

484 

485 self.startTime = datetime.datetime.strptime( 

486 datetimestr, "%Y/%m/%d %H:%M:%S" 

487 ) # also timezone at end, e.g. " ET" 

488 self.startTime = HandHistoryConverter.changeTimezone(self.startTime, "ET", "UTC") 

489 

490 if mg["DESC1"] is not None: 

491 self.siteName = "Run It Once Poker" 

492 self.siteId = 26 

493 re_Player = self.re_PlayerRIO 

494 else: 

495 re_Player = self.re_PlayerStars 

496 

497 if "TOURNO" in mg: 

498 self.tourNo = mg["TOURNO"] 

499 if "LIMIT" in mg and mg["LIMIT"] is not None: 

500 self.gametype["limitType"] = self.limits[mg["LIMIT"]] 

501 else: 

502 self.gametype["limitType"] = "fl" 

503 if "GAME" in mg: 

504 self.gametype["category"] = self.games[mg["GAME"]][1] 

505 if "SPLIT" in mg and mg["SPLIT"] == "Split": 

506 self.isSplit = True 

507 if mg["BOUNTY"] is not None and mg["FEE"] is not None: 

508 self.koBounty = int(100 * float(self.clearMoneyString(mg["FEE"]))) 

509 self.isKO = True 

510 mg["FEE"] = mg["BOUNTY"] 

511 if mg["BUYIN"] is not None: 

512 self.buyin = int(100 * float(self.clearMoneyString(mg["BUYIN"]))) + self.koBounty 

513 if mg["FEE"] is not None: 

514 self.fee = int(100 * float(self.clearMoneyString(mg["FEE"]))) 

515 

516 m2 = self.re_rebuyAddOn.search(self.summaryText) 

517 if m2 and m2.group("REBUYCOUNT") is not None: 

518 self.isRebuy = True 

519 self.isAddOn = True 

520 # You made 5 rebuys and 1 addons for a total of USD 3,180.00. 

521 rebuyCountHero = int(m2.group("REBUYCOUNT")) + int( 

522 m2.group("ADDONCOUNT") 

523 ) # combine b/c html summary does not split out 

524 self.rebuyCost = self.buyin + self.fee 

525 self.addOnCost = self.buyin + self.fee 

526 else: 

527 rebuyCountHero = None 

528 

529 if "PRIZEPOOL" in mg and mg["PRIZEPOOL"] is not None: 

530 if "Sunday Million" in mg["PRIZEPOOL"]: 

531 self.isSatellite = True 

532 newBuyinDate = HandHistoryConverter.changeTimezone( 

533 datetime.datetime.strptime("2019/01/27 00:00:00", "%Y/%m/%d %H:%M:%S"), "ET", "UTC" 

534 ) 

535 if self.startTime > newBuyinDate: 

536 targetBuyin, targetCurrency = 10900, "USD" 

537 else: 

538 targetBuyin, targetCurrency = 21500, "USD" 

539 else: 

540 self.prizepool = int(float(self.clearMoneyString(mg["PRIZEPOOL"]))) 

541 if "ENTRIES" in mg: 

542 self.entries = int(mg["ENTRIES"]) 

543 if "SATELLITE" in mg and mg["SATELLITE"] is not None: 

544 self.isSatellite = True 

545 targetBuyin, targetCurrency = 0, "USD" 

546 if mg["TARGBUYIN"] is not None: 

547 targetBuyin += int(100 * float(self.clearMoneyString(mg["TARGBUYIN"]))) 

548 if mg["TARGFEE"] is not None: 

549 targetBuyin += int(100 * float(self.clearMoneyString(mg["TARGFEE"]))) 

550 if mg["TARGBOUNTY"] is not None: 

551 targetBuyin += int(100 * float(self.clearMoneyString(mg["TARGBOUNTY"]))) 

552 if mg["TARGCUR"] is not None: 

553 if mg["CUR"] == "$": 

554 targetCurrency = "USD" 

555 elif mg["CUR"] == "€": 

556 targetCurrency = "EUR" 

557 elif mg["CUR"] == "£": 

558 targetCurrency = "GBP" 

559 elif mg["CUR"] == "₹": 

560 targetCurrency = "INR" 

561 elif mg["CUR"] == "Rs. ": 

562 targetCurrency = "INR" 

563 elif mg["CUR"] == "¥": 

564 targetCurrency = "CNY" 

565 elif mg["CUR"] == "FPP": 

566 targetCurrency = "PSFP" 

567 elif mg["CUR"] == "SC": 

568 targetCurrency = "PSFP" 

569 

570 if mg["CURRENCY"] == "$": 

571 self.buyinCurrency = "USD" 

572 elif mg["CURRENCY"] == "€": 

573 self.buyinCurrency = "EUR" 

574 elif mg["CURRENCY"] == "£": 

575 self.buyinCurrency = "GBP" 

576 elif mg["CURRENCY"] == "₹": 

577 self.buyinCurrency = "INR" 

578 elif mg["CURRENCY"] == "Rs. ": 

579 self.buyinCurrency = "INR" 

580 elif mg["CURRENCY"] == "¥": 

581 self.buyinCurrency = "CNY" 

582 elif mg["CURRENCY1"] == "FPP": 

583 self.buyinCurrency = "PSFP" 

584 elif mg["CURRENCY1"] == "SC": 

585 self.buyinCurrency = "PSFP" 

586 elif not mg["CURRENCY"]: 

587 self.buyinCurrency = "play" 

588 if self.buyin == 0: 

589 self.buyinCurrency = "FREE" 

590 self.currency = self.buyinCurrency 

591 

592 if "Zoom" in self.in_path or "Rush" in self.in_path: 

593 self.isFast = True 

594 

595 self.lookupStructures(self.startTime) 

596 

597 m3 = self.re_Rank.search(self.summaryText) 

598 if m3: 

599 heroRank = int(m3.group("RANK")) 

600 else: 

601 heroRank = 0 

602 

603 m = re_Player.finditer(self.summaryText) 

604 for a in m: 

605 mg = a.groupdict() 

606 # print "DEBUG: a.groupdict(): %s" % mg 

607 name = mg["NAME"] 

608 rank = int(mg["RANK"]) 

609 winnings = 0 

610 rebuyCount = None 

611 addOnCount = None 

612 koCount = None 

613 entryId = 1 

614 

615 if "WINNINGS" in mg and mg["WINNINGS"] is not None: 

616 winnings = int(100 * float(self.clearMoneyString(mg["WINNINGS"]))) 

617 

618 if "CUR" in mg and mg["CUR"] is not None: 

619 if mg["CUR"] == "$": 

620 self.currency = "USD" 

621 elif mg["CUR"] == "€": 

622 self.currency = "EUR" 

623 elif mg["CUR"] == "£": 

624 self.currency = "GBP" 

625 elif mg["CUR"] == "₹": 

626 self.currency = "INR" 

627 elif mg["CUR"] == "Rs. ": 

628 self.currency = "INR" 

629 elif mg["CUR"] == "¥": 

630 self.currency = "CNY" 

631 elif mg["CUR1"] == "FPP": 

632 self.currency = "PSFP" 

633 elif mg["CUR1"] == "SC": 

634 self.currency = "PSFP" 

635 

636 if "STILLPLAYING" in mg and mg["STILLPLAYING"] is not None: 

637 # print "stillplaying" 

638 rank = None 

639 winnings = None 

640 

641 if "TICKET" in mg and mg["TICKET"] is not None: 

642 # print "Tournament Ticket Level %s" % mg['LEVEL'] 

643 step_values = { 

644 "1": "750", # Step 1 - $7.50 USD 

645 "2": "2750", # Step 2 - $27.00 USD 

646 "3": "8200", # Step 3 - $82.00 USD 

647 "4": "21500", # Step 4 - $215.00 USD 

648 "5": "70000", # Step 5 - $700.00 USD 

649 "6": "210000", # Step 6 - $2100.00 USD 

650 } 

651 winnings = int(step_values[mg["LEVEL"]]) 

652 

653 if "QUALIFIED" in mg and mg["QUALIFIED"] is not None and self.isSatellite: 

654 winnings = targetBuyin 

655 self.currency = targetCurrency 

656 

657 if "ENTRYID" in mg and mg["ENTRYID"] is not None: 

658 entryId = int(mg["ENTRYID"]) 

659 self.isReEntry = True 

660 

661 if heroRank == rank and entryId == 1: 

662 rebuyCount = rebuyCountHero 

663 addOnCount = None 

664 koCount = None 

665 

666 # print "DEBUG: addPlayer(%s, %s, %s, %s, None, None, None)" %(rank, name, winnings, self.currency) 

667 # print "DEBUG: self.buyin: %s self.fee %s" %(self.buyin, self.fee) 

668 self.addPlayer(rank, name, winnings, self.currency, rebuyCount, addOnCount, koCount, entryId) 

669 

670 # print self 

671 

672 def lookupStructures(self, date): 

673 Structures = PokerStarsStructures.PokerStarsStructures() 

674 if self.entries % 9 == 0 and self.entries < 45: 

675 entries = 9 

676 elif self.entries % 6 == 0 and self.entries < 30: 

677 entries = 6 

678 elif self.entries > 6 and self.entries < 9: 

679 entries = 9 

680 else: 

681 entries = self.entries 

682 

683 speed = Structures.lookupSnG((self.buyin, self.fee, entries), date) 

684 if speed is not None: 

685 self.speed = speed 

686 if entries == 10: 

687 self.isDoubleOrNothing = True 

688 

689 

690# end class PokerStarsSummary