Coverage for PokerStarsSummary.py: 0%

347 statements  

« 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 -*- 

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 

23from decimal_wrapper import Decimal 

24import datetime 

25 

26from Exceptions import FpdbParseError 

27from HandHistoryConverter import * 

28import PokerStarsStructures 

29from TourneySummary import * 

30 

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 } 

79 

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 } 

84 

85 re_Identify = re.compile(u'((?P<SITE>PokerStars|Full\sTilt|Run\sIt\sOnce\sPoker)\sTournament\s\#\d+|<title>TOURNEYS:)') 

86 

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

90 

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) 

120 

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)?)(&nbsp;)?</td>' \ 

129 r'<td.*?>(?P<BUYIN>([,.0-9 ]+|Freeroll))(?P<FPPBUYIN>(\s|&nbsp;)(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|&nbsp;)(FPP|SC|StarsCoin))?</td>' \ 

136 r'<td.*?>(?P<KOS>[,.0-9]+)</td>' \ 

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

138 r'<td.*?>((?P<WONTICKET>\*\\\/\*)|(&nbsp;))</td>' 

139 % substitutions, re.IGNORECASE) 

140 

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>\*\\\/\*)?') 

158 

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&lt;(?P<NAME>.+?)&gt;</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>.+?)\'') 

164 

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) 

173 

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

175 

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 

186 

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

198 

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) 

206 

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

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

209 

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) 

218 

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) 

238 

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) 

255 

256 def parseSummaryArchive(self, info): 

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

258 self.isSng = True 

259 

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()) 

265 

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'] 

309 

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

324 

325 

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" 

338 

339 if self.buyinCurrency not in ('FREE', 'PSFP'): 

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

341 

342 if self.isSng: 

343 self.lookupStructures(self.endTime) 

344 

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 

353 

354 if 'WINNINGS' in info and info['WINNINGS'] != None: 

355 winnings = int(100*float(self.clearMoneyString(info['WINNINGS']))) 

356 

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 

360 

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 

364 

365 

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) 

372 

373 if len(entries) > 1: 

374 entryId = entries.index(rank) + 1 

375 self.isReEntry = True 

376 

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

378 

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')) 

397 

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

400 

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 

407 

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']))) 

424 

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 

435 

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" 

465 

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 

477 

478 if 'Zoom' in self.in_path or 'Rush' in self.in_path: 

479 self.isFast = True 

480 

481 self.lookupStructures(self.startTime) 

482 

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

484 if m3: 

485 heroRank = int(m3.group('RANK')) 

486 else: 

487 heroRank = 0 

488 

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 

500 

501 if 'WINNINGS' in mg and mg['WINNINGS'] != None: 

502 winnings = int(100*float(self.clearMoneyString(mg['WINNINGS']))) 

503 

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" 

513 

514 if 'STILLPLAYING' in mg and mg['STILLPLAYING'] != None: 

515 #print "stillplaying" 

516 rank=None 

517 winnings=None 

518 

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']]) 

530 

531 if 'QUALIFIED' in mg and mg['QUALIFIED'] != None and self.isSatellite: 

532 winnings = targetBuyin 

533 self.currency = targetCurrency 

534 

535 if 'ENTRYID' in mg and mg['ENTRYID'] != None: 

536 entryId = int(mg['ENTRYID']) 

537 self.isReEntry = True 

538 

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

540 rebuyCount = rebuyCountHero 

541 addOnCount = None 

542 koCount = None 

543 

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) 

547 

548 #print self 

549 

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 

560 

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 

566 

567#end class PokerStarsSummary