Coverage for WinamaxSummary.py: 0%

195 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-09-27 18:50 +0000

1#!/usr/bin/env python 

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

3 

4#Copyright 2008-2011 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 

19#import L10n 

20#_ = L10n.get_translation() 

21 

22from decimal_wrapper import Decimal 

23import datetime 

24from bs4 import BeautifulSoup 

25 

26from Exceptions import FpdbParseError 

27from HandHistoryConverter import * 

28import PokerStarsToFpdb 

29from TourneySummary import * 

30 

31 

32class WinamaxSummary(TourneySummary): 

33 

34 limits = { 'No Limit':'nl', 'Pot Limit':'pl', 'Limit':'fl', 'LIMIT':'fl' } 

35 games = { # base, category 

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

37 'Omaha' : ('hold','omahahi'), 

38 "5 Card Omaha": ('hold','5_omahahi'), 

39 "Omaha 5": ('hold','5_omahahi'), 

40 "5 Card Omaha Hi/Lo": ('hold','5_omahahi'), #incorrect in file 

41 "Omaha Hi/Lo": ('hold','omahahilo'), 

42 "7-Card Stud": ('stud','studhi'), 

43 "7-Card Stud Hi/Lo": ('stud','studhilo'), 

44 "Razz": ('stud','razz'), 

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

46 } 

47 

48 substitutions = { 

49 'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes 

50 'LS' : u"\$|€|" # legal currency symbols 

51 } 

52 

53 re_Identify = re.compile(u"Winamax\sPoker\s\-\sTournament\ssummary") 

54 

55 re_SummaryTourneyInfo = re.compile(u"""\s:\s 

56 ((?P<LIMIT>No\sLimit|Limit|LIMIT|Pot\sLimit)\s)? 

57 (?P<GAME>.+)? 

58 \((?P<TOURNO>[0-9]+)\)(\s-\sLate\s(r|R)egistration)?\s+ 

59 (Player\s:\s(?P<PNAME>.*)\s+)? 

60 Buy-In\s:\s(?P<BUYIN>(?P<BIAMT>.+?)\s\+\s(?P<BIRAKE>.+?)(\s\+\s(?P<BIBOUNTY>.+))?|Freeroll|Gratuit|Ticket\suniquement|Free|Ticket)\s+ 

61 (Rebuy\scost\s:\s(?P<REBUY>(?P<REBUYAMT>.+)\s\+\s(?P<REBUYRAKE>.+))\s+)? 

62 (Addon\scost\s:\s(?P<ADDON>(?P<ADDONAMT>.+)\s\+\s(?P<ADDONRAKE>.+))\s+)? 

63 (Your\srebuys\s:\s(?P<PREBUYS>\d+)\s+)? 

64 (Your\saddons\s:\s(?P<PADDONS>\d+)\s+)? 

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

66 (Total\srebuys\s:\s\d+\s+)? 

67 (Total\saddons\s:\s\d+\s+)? 

68 (Prizepool\s:\s(?P<PRIZEPOOL1>[.0-9%(LS)s]+)\s+)? 

69 (Mode\s:\s(?P<MODE>.+)?\s+)? 

70 (Type\s:\s(?P<TYPE>.+)?\s+)? 

71 (Speed\s:\s(?P<SPEED>.+)?\s+)? 

72 (Flight\sID\s:\s.+\s+)? 

73 (Levels\s:\s.+\s+)? 

74 (Total\srebuys\s:\s(?P<TREBUYS>\d+)\s+)? 

75 (Total\saddons\s:\s(?P<TADDONS>\d+)\s+)? 

76 (Prizepool\s:\s(?P<PRIZEPOOL2>[.0-9%(LS)s]+)\s+)? 

77 Tournament\sstarted\s(?P<DATETIME>[0-9]{4}\/[0-9]{2}\/[0-9]{2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}\sUTC)\s+ 

78 (?P<BLAH>You\splayed\s.+)\s+ 

79 You\sfinished\sin\s(?P<RANK>[.0-9]+)(st|nd|rd|th)?\splace\s+ 

80 (You\swon\s((?P<WINNINGS>[.0-9%(LS)s]+))?(\s\+\s)?(Ticket\s(?P<TICKET>[.0-9%(LS)s]+))?(\s\+\s)?(Bounty\s(?P<BOUNTY>[.0-9%(LS)s]+))?)? 

81 """ % substitutions ,re.VERBOSE|re.MULTILINE) 

82 

83 re_GameType = re.compile("""<h1>((?P<LIMIT>No Limit|Pot Limit) (?P<GAME>Hold\'em|Omaha))</h1>""") 

84 

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

86 

87 re_Player = re.compile(u"""(?P<RANK>\d+)<\/td><td width="30%">(?P<PNAME>.+?)<\/td><td width="60%">(?P<WINNINGS>.+?)</td>""") 

88 

89 re_Details = re.compile(u"""<p class="text">(?P<LABEL>.+?) : (?P<VALUE>.+?)</p>""") 

90 re_Prizepool = re.compile(u"""<div class="title2">.+: (?P<PRIZEPOOL>[0-9,]+)""") 

91 

92 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]+)") 

93 re_Ticket = re.compile(u""" / (?P<TTYPE>Ticket (?P<VALUE>[0-9.]+)&euro;|Tremplin Winamax Poker Tour|Starting Block Winamax Poker Tour|Finale Freeroll Mobile 2012|SNG Freeroll Mobile 2012)""") 

94 

95 codepage = ("utf8", "cp1252") 

96 

97 @staticmethod 

98 def getSplitRe(self, head): 

99 re_SplitTourneys = re.compile("Winamax\sPoker\s-\sTournament\ssummary") 

100 m = re.search("<!DOCTYPE html PUBLIC", head) 

101 if m != None: 

102 self.hhtype = "html" 

103 else: 

104 self.hhtype = "summary" 

105 return re_SplitTourneys 

106 

107 def parseSummary(self): 

108 if self.hhtype == "summary": 

109 self.parseSummaryFile() 

110 elif self.hhtype == "html": 

111 self.parseSummaryHtml() 

112 

113 def parseSummaryHtml(self): 

114 self.currency = "EUR" 

115 soup = BeautifulSoup(self.summaryText) 

116 tl = soup.findAll('div', {"class":"left_content"}) 

117 

118 ps = soup.findAll('p', {"class": "text"}) 

119 for p in ps: 

120 for m in self.re_Details.finditer(str(p)): 

121 mg = m.groupdict() 

122 #print mg 

123 if mg['LABEL'] == 'Buy-in': 

124 mg['VALUE'] = mg['VALUE'].replace(u"&euro;", "") 

125 mg['VALUE'] = mg['VALUE'].replace(u"+", "") 

126 mg['VALUE'] = mg['VALUE'].strip(" $") 

127 bi, fee = mg['VALUE'].split(" ") 

128 self.buyin = int(100*Decimal(bi)) 

129 self.fee = int(100*Decimal(fee)) 

130 #print "DEBUG: bi: '%s' fee: '%s" % (self.buyin, self.fee) 

131 if mg['LABEL'] == 'Nombre de joueurs inscrits': 

132 self.entries = mg['VALUE'] 

133 if mg['LABEL'] == 'D\xc3\xa9but du tournoi': 

134 self.startTime = datetime.datetime.strptime(mg['VALUE'], "%d-%m-%Y %H:%M") 

135 if mg['LABEL'] == 'Nombre de joueurs max': 

136 # Max seats i think 

137 pass 

138 

139 div = soup.findAll('div', {"class": "title2"}) 

140 for m in self.re_Prizepool.finditer(str(div)): 

141 mg = m.groupdict() 

142 #print mg 

143 self.prizepool = mg['PRIZEPOOL'].replace(u',','.') 

144 

145 

146 for m in self.re_GameType.finditer(str(tl[0])): 

147 mg = m.groupdict() 

148 #print mg 

149 self.gametype['limitType'] = self.limits[mg['LIMIT']] 

150 self.gametype['category'] = self.games[mg['GAME']][1] 

151 else: 

152 #FIXME: No gametype 

153 # Quitte or Double, Starting Block Winamax Poker Tour 

154 # Do not contain enough the gametype. 

155 # Lookup the tid from the db, if it exists get the gametype info from there, otherwise ParseError 

156 log.warning(("WinamaxSummary.parseSummary: Gametype unknown defaulting to NLHE")) 

157 self.gametype['limitType'] = 'nl' 

158 self.gametype['category'] = 'holdem' 

159 

160 for m in self.re_Player.finditer(str(tl[0])): 

161 winnings = 0 

162 mg = m.groupdict() 

163 rank = mg['RANK'] 

164 name = mg['PNAME'] 

165 if rank!='...': 

166 rank = int(mg['RANK']) 

167 #print "DEUBG: mg: '%s'" % mg 

168 is_satellite = self.re_Ticket.search(mg['WINNINGS']) 

169 if is_satellite: 

170 # Ticket 

171 if is_satellite.group('VALUE'): 

172 winnings = self.convert_to_decimal(is_satellite.group('VALUE')) 

173 else: # Value not specified 

174 rank = 1 

175 # FIXME: Do lookup here 

176 # Tremplin Winamax Poker Tour 

177 # Starting Block Winamax Poker Tour 

178 pass 

179 # For stallites, any ticket means 1st 

180 if winnings > 0: 

181 rank = 1 

182 else: 

183 winnings = self.convert_to_decimal(mg['WINNINGS']) 

184 

185 winnings = int(100*Decimal(winnings)) 

186 #print "DEBUG: %s) %s: %s" %(rank, name, winnings) 

187 self.addPlayer(rank, name, winnings, self.currency, None, None, None) 

188 

189 

190 for m in self.re_TourNo.finditer(self.summaryText): 

191 mg = m.groupdict() 

192 #print mg 

193 self.tourNo = mg['TOURNO'] 

194 

195 def parseSummaryFile(self): 

196 m = self.re_SummaryTourneyInfo.search(self.summaryText) 

197 if m == None: 

198 tmp = self.summaryText[0:200] 

199 log.error(("WinamaxSummary.parseSummaryFromFile: '%s'") % tmp) 

200 raise FpdbParseError 

201 

202 mg = m.groupdict() 

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

204 

205 if 'LIMIT' in mg and mg['LIMIT'] != None: 

206 self.gametype['limitType'] = self.limits[mg['LIMIT']] 

207 self.gametype['category'] = self.games[mg['GAME']][1] 

208 else: 

209 #FIXME: No gametype 

210 # Quitte or Double, Starting Block Winamax Poker Tour 

211 # Do not contain enough the gametype. 

212 # Lookup the tid from the db, if it exists get the gametype info from there, otherwise ParseError 

213 log.warning(("WinamaxSummary.parseSummary: Gametype unknown defaulting to NLHE")) 

214 self.gametype['limitType'] = 'nl' 

215 self.gametype['category'] = 'holdem' 

216 self.tourneyName = mg['GAME'] 

217 if 'ENTRIES' in mg: 

218 self.entries = mg['ENTRIES'] 

219 if 'PRIZEPOOL1' in mg and mg['PRIZEPOOL1'] != None: 

220 self.prizepool = int(100*self.convert_to_decimal(mg['PRIZEPOOL1'])) 

221 if 'PRIZEPOOL2' in mg and mg['PRIZEPOOL2'] != None: 

222 self.prizepool = int(100*self.convert_to_decimal(mg['PRIZEPOOL2'])) 

223 if 'DATETIME' in mg: 

224 self.startTime = datetime.datetime.strptime(mg['DATETIME'], "%Y/%m/%d %H:%M:%S UTC") 

225 

226 #FIXME: buyinCurrency and currency not detected 

227 self.buyinCurrency = 'EUR' 

228 self.currency = 'EUR' 

229 

230 if 'BUYIN' in mg: 

231 #print "DEBUG: BUYIN '%s'" % mg['BUYIN'] 

232 if mg['BUYIN'] in ('Gratuit', 'Freeroll', 'Ticket uniquement', 'Ticket'): 

233 self.buyin = 0 

234 self.fee = 0 

235 self.buyinCurrency = "FREE" 

236 else: 

237 if mg['BUYIN'].find(u"€")!=-1: 

238 self.buyinCurrency="EUR" 

239 elif mg['BUYIN'].find("FPP")!=-1: 

240 self.buyinCurrency="WIFP" 

241 elif mg['BUYIN'].find("Free")!=-1: 

242 self.buyinCurrency="WIFP" 

243 else: 

244 self.buyinCurrency="play" 

245 

246 if mg['BIBOUNTY'] != None and mg['BIRAKE'] != None: 

247 self.koBounty = int(100*Decimal(self.convert_to_decimal(mg['BIRAKE'].strip('\r')))) 

248 self.isKO = True 

249 mg['BIRAKE'] = mg['BIBOUNTY'].strip('\r') 

250 

251 rake = mg['BIRAKE'].strip('\r') 

252 self.buyin = int(100*self.convert_to_decimal(mg['BIAMT'])) 

253 self.fee = int(100*self.convert_to_decimal(rake)) 

254 

255 if self.buyin == 0 and self.fee == 0: 

256 self.buyinCurrency = "FREE" 

257 

258 if 'REBUY' in mg and mg['REBUY'] != None: 

259 self.isRebuy = True 

260 rebuyrake = mg['REBUYRAKE'].strip('\r') 

261 rebuyamt = int(100*self.convert_to_decimal(mg['REBUYAMT'])) 

262 rebuyfee = int(100*self.convert_to_decimal(rebuyrake)) 

263 self.rebuyCost = rebuyamt + rebuyfee 

264 if 'ADDON' in mg and mg['ADDON'] != None: 

265 self.isAddOn = True 

266 addonrake = mg['ADDONRAKE'].strip('\r') 

267 addonamt = int(100*self.convert_to_decimal(mg['ADDONAMT'])) 

268 addonfee = int(100*self.convert_to_decimal(addonrake)) 

269 self.addOnCost = addonamt + addonfee 

270 

271 if 'TOURNO' in mg: 

272 self.tourNo = mg['TOURNO'] 

273 #self.maxseats = 

274 if int(self.entries) <= 10: #FIXME: obv not a great metric 

275 self.isSng = True 

276 if 'MODE' in mg and mg['MODE'] != None: 

277 if 'sng' in mg['MODE']: 

278 self.isSng = True 

279 if 'SPEED' in mg and mg['SPEED'] != None: 

280 if mg['SPEED']=='turbo': 

281 self.speed = 'Hyper' 

282 elif mg['SPEED']=='semiturbo': 

283 self.speed = 'Turbo' 

284 

285 if 'PNAME' in mg and mg['PNAME'] is not None: 

286 name = mg['PNAME'].strip('\r') 

287 rank = mg['RANK'] 

288 if rank!='...': 

289 rank = int(mg['RANK']) 

290 winnings = 0 

291 rebuyCount = None 

292 addOnCount = None 

293 koCount = None 

294 

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

296 if mg['WINNINGS'].find(u"€")!=-1: 

297 self.currency="EUR" 

298 elif mg['WINNINGS'].find("FPP")!=-1: 

299 self.currency="WIFP" 

300 elif mg['WINNINGS'].find("Free")!=-1: 

301 self.currency="WIFP" 

302 else: 

303 self.currency="play" 

304 winnings = int(100*self.convert_to_decimal(mg['WINNINGS'])) 

305 if 'PREBUYS' in mg and mg['PREBUYS'] != None: 

306 rebuyCount = int(mg['PREBUYS']) 

307 if 'PADDONS' in mg and mg['PADDONS'] != None: 

308 addOnCount = int(mg['PADDONS']) 

309 

310 

311 if 'TICKET' in mg and mg['TICKET'] != None: 

312 winnings += int(100*self.convert_to_decimal(mg['TICKET'])) 

313 

314 if 'BOUNTY' in mg and mg['BOUNTY'] != None: 

315 koCount = 100*self.convert_to_decimal(mg['BOUNTY']) / Decimal(self.koBounty) 

316 if winnings == 0: 

317 if mg['BOUNTY'].find(u"€")!=-1: 

318 self.currency="EUR" 

319 elif mg['BOUNTY'].find("FPP")!=-1: 

320 self.currency="WIFP" 

321 elif mg['BOUNTY'].find("Free")!=-1: 

322 self.currency="WIFP" 

323 else: 

324 self.currency="play" 

325 

326 #print "DEBUG: addPlayer(%s, %s, %s, %s, %s, %s, %s)" %(rank, name, winnings, self.currency, rebuyCount, addOnCount, koCount) 

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

328 

329 def convert_to_decimal(self, string): 

330 dec = self.clearMoneyString(string) 

331 dec = Decimal(dec) 

332 return dec 

333