Coverage for iPokerSummary.py: 0%

183 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-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#import L10n 

19#_ = L10n.get_translation() 

20 

21from decimal_wrapper import Decimal 

22import datetime 

23 

24from Exceptions import FpdbParseError 

25from HandHistoryConverter import * 

26from TourneySummary import * 

27 

28 

29class iPokerSummary(TourneySummary): 

30 substitutions = { 

31 'LS' : u"\$|\xe2\x82\xac|\xe2\u201a\xac|\u20ac|\xc2\xa3|\£|RSD|kr|", 

32 'PLYR': r'(?P<PNAME>[^"]+)', 

33 'NUM' : r'.,0-9', 

34 'NUM2': r'\b((?:\d{1,3}(?:\s\d{3})*)|(?:\d+))\b', # Regex pattern for matching numbers with spaces 

35 } 

36 currencies = { u'€':'EUR', '$':'USD', '':'T$', u'£':'GBP', 'RSD': 'RSD', 'kr': 'SEK'} 

37 

38 months = { 'Jan':1, 'Feb':2, 'Mar':3, 'Apr':4, 'May':5, 'Jun':6, 'Jul':7, 'Aug':8, 'Sep':9, 'Oct':10, 'Nov':11, 'Dec':12} 

39 

40 limits = { 'No limit':'nl', 

41 'Pot limit':'pl', 

42 'Limit':'fl', 

43 'NL':'nl', 

44 'SL':'nl', 

45 u'БЛ':'nl', 

46 'PL':'pl', 

47 'LP':'pl', 

48 'L':'fl', 

49 'LZ':'fl', 

50 } 

51 games = { # base, category 

52 '7 Card Stud' : ('stud','studhi'), 

53 '7 Card Stud Hi-Lo' : ('stud','studhilo'), 

54 '7 Card Stud HiLow': ('stud', 'studhilo'), 

55 '5 Card Stud' : ('stud','5_studhi'), 

56 'Holdem' : ('hold','holdem'), 

57 'Six Plus Holdem' : ('hold','6_holdem'), 

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

59 'Omaha Hi-Lo' : ('hold','omahahilo'), 

60 } 

61 

62 re_Identify = re.compile(u'<game\sgamecode=') 

63 re_client = re.compile(r'<client_version>(?P<CLIENT>.*?)</client_version>') 

64 re_GameType = re.compile(r""" 

65 <gametype>(?P<GAME>((?P<CATEGORY>(5|7)\sCard\sStud(\sHi\-Lo)?(\sHiLow)?|(Six\sPlus\s)?Holdem|Omaha(\sHi\-Lo)?(\sHiLow)?)?\s?(?P<LIMIT>NL|SL|L|LZ|PL|БЛ|LP|No\slimit|Pot\slimit|Limit))|LH\s(?P<LSB>[%(NUM)s]+)(%(LS)s)?/(?P<LBB>[%(NUM)s]+)(%(LS)s)?.+?) 

66 (\s(%(LS)s)?(?P<SB>[%(NUM)s]+)(%(LS)s)?/(%(LS)s)?(?P<BB>[%(NUM)s]+))?(%(LS)s)?(\sAnte\s(%(LS)s)?(?P<ANTE>[%(NUM)s]+)(%(LS)s)?)?</gametype>\s+? 

67 <tablename>(?P<TABLE>.+)?</tablename>\s+? 

68 (<(tablecurrency|tournamentcurrency)>.*</(tablecurrency|tournamentcurrency)>\s+?)? 

69 (<smallblind>.+</smallblind>\s+?)? 

70 (<bigblind>.+</bigblind>\s+?)? 

71 <duration>.+</duration>\s+? 

72 <gamecount>.+</gamecount>\s+? 

73 <startdate>(?P<DATETIME>.+)</startdate>\s+? 

74 <currency>(?P<CURRENCY>.+)</currency>\s+? 

75 <nickname>(?P<HERO>.+)</nickname> 

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

77 

78 re_GameInfoTrny = re.compile(r""" 

79 (?:(<tour(?:nament)?code>(?P<TOURNO>\d+)</tour(?:nament)?code>))| 

80 (?:(<tournamentname>(?P<NAME>[^<]*)</tournamentname>))| 

81 (?:(<rewarddrawn>(?P<REWARD>[%(NUM2)s%(LS)s]+)</rewarddrawn>))|  

82 (?:(<place>(?P<PLACE>.+?)</place>))| 

83 (?:(<buyin>(?P<BIAMT>[%(NUM2)s%(LS)s]+)\s\+\s)?(?P<BIRAKE>[%(NUM2)s%(LS)s]+)\s\+\s(?P<BIRAKE2>[%(NUM2)s%(LS)s]+)</buyin>)| 

84 (?:(<totalbuyin>(?P<TOTBUYIN>.*)</totalbuyin>))| 

85 (?:(<win>(%(LS)s)?(?P<WIN>[%(NUM2)s%(LS)s]+)</win>)) 

86 """ % substitutions, re.VERBOSE) 

87 re_GameInfoTrny2 = re.compile(r""" 

88 (?:(<tour(?:nament)?code>(?P<TOURNO>\d+)</tour(?:nament)?code>))| 

89 (?:(<tournamentname>(?P<NAME>[^<]*)</tournamentname>))| 

90 (?:(<place>(?P<PLACE>.+?)</place>))| 

91 (?:(<buyin>(?P<BIAMT>[%(NUM2)s%(LS)s]+)\s\+\s)?(?P<BIRAKE>[%(NUM2)s%(LS)s]+)</buyin>)| 

92 (?:(<totalbuyin>(?P<TOTBUYIN>[%(NUM2)s%(LS)s]+)</totalbuyin>))| 

93 (?:(<win>(%(LS)s)?(?P<WIN>.+?|[%(NUM2)s%(LS)s]+)</win>)) 

94 """ % substitutions, re.VERBOSE) 

95 re_Buyin = re.compile(r"""(?P<BUYIN>[%(NUM)s]+)""" % substitutions, re.MULTILINE|re.VERBOSE) 

96 re_TourNo = re.compile(r'(?P<TOURNO>\d+)$', re.MULTILINE) 

97 re_TotalBuyin = re.compile(r"""(?P<BUYIN>(?P<BIAMT>[%(LS)s%(NUM)s]+)\s\+\s?(?P<BIRAKE>[%(LS)s%(NUM)s]+)?)""" % substitutions, re.MULTILINE|re.VERBOSE) 

98 re_DateTime1 = re.compile("""(?P<D>[0-9]{2})\-(?P<M>[a-zA-Z]{3})\-(?P<Y>[0-9]{4})\s+(?P<H>[0-9]+):(?P<MIN>[0-9]+)(:(?P<S>[0-9]+))?""", re.MULTILINE) 

99 re_DateTime2 = re.compile("""(?P<D>[0-9]{2})[\/\.](?P<M>[0-9]{2})[\/\.](?P<Y>[0-9]{4})\s+(?P<H>[0-9]+):(?P<MIN>[0-9]+)(:(?P<S>[0-9]+))?""", re.MULTILINE) 

100 re_DateTime3 = re.compile("""(?P<Y>[0-9]{4})\/(?P<M>[0-9]{2})\/(?P<D>[0-9]{2})\s+(?P<H>[0-9]+):(?P<MIN>[0-9]+)(:(?P<S>[0-9]+))?""", re.MULTILINE) 

101 re_Place = re.compile(r"""(?:(<place>(?P<PLACE>.+?)</place>))""" % substitutions, re.VERBOSE) 

102 re_FPP = re.compile(r'Pts\s') 

103 

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

105 

106 @staticmethod 

107 def getSplitRe(self, head): 

108 re_SplitTourneys = re.compile("PokerStars Tournament ") 

109 return re_SplitTourneys 

110 

111 

112 def parseSummary(self): 

113 m = self.re_GameType.search(self.summaryText) 

114 if not m: 

115 tmp = self.summaryText[0:200] 

116 log.error(("iPokerSummary.determineGameType: '%s'") % tmp) 

117 raise FpdbParseError 

118 

119 mg = m.groupdict() 

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

121 

122 if 'SB' in mg and mg['SB'] != None: 

123 tmp = self.summaryText[0:200] 

124 log.error(("iPokerSummary.parseSummary: Text does not appear to be a tournament '%s'") % tmp) 

125 raise FpdbParseError 

126 else: 

127 tourney = True 

128# self.gametype['limitType'] =  

129 if 'GAME' in mg: 

130 if mg['CATEGORY'] is None: 

131 (self.info['base'], self.info['category']) = ('hold', '5_omahahi') 

132 else: 

133 (self.gametype['base'], self.gametype['category']) = self.games[mg['CATEGORY']] 

134 if 'LIMIT' in mg: 

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

136 

137 m2 = self.re_DateTime1.search(mg['DATETIME']) 

138 if m2: 

139 month = self.months[m2.group('M')] 

140 sec = m2.group('S') 

141 if m2.group('S') == None: 

142 sec = '00' 

143 datetimestr = "%s/%s/%s %s:%s:%s" % (m2.group('Y'), month,m2.group('D'),m2.group('H'),m2.group('MIN'),sec) 

144 self.startTime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S") 

145 else: 

146 try: 

147 self.startTime = datetime.datetime.strptime(mg['DATETIME'], '%Y-%m-%d %H:%M:%S') 

148 except ValueError: 

149 date_match = self.re_DateTime2.search(mg['DATETIME']) 

150 if date_match != None: 

151 datestr = '%d/%m/%Y %H:%M:%S' if '/' in mg['DATETIME'] else '%d.%m.%Y %H:%M:%S' 

152 if date_match.group('S') == None: 

153 datestr = '%d/%m/%Y %H:%M' 

154 else: 

155 date_match1 = self.re_DateTime3.search(mg['DATETIME']) 

156 datestr = '%Y/%m/%d %H:%M:%S' 

157 if date_match1 == None: 

158 log.error(("iPokerSummary.parseSummary Could not read datetime")) 

159 raise FpdbParseError 

160 if date_match1.group('S') == None: 

161 datestr = '%Y/%m/%d %H:%M' 

162 self.startTime = datetime.datetime.strptime(mg['DATETIME'], datestr) 

163 

164 if not mg['CURRENCY'] or mg['CURRENCY']=='fun': 

165 self.buyinCurrency = 'play' 

166 else: 

167 self.buyinCurrency = mg['CURRENCY'] 

168 self.currency = self.buyinCurrency 

169 

170 mt = self.re_TourNo.search(mg['TABLE']) 

171 if mt: 

172 self.tourNo = mt.group('TOURNO') 

173 else: 

174 tourNo = mg['TABLE'].split(',')[-1].strip().split(' ')[0] 

175 if tourNo.isdigit(): 

176 self.tourNo = tourNo 

177 

178 if tourney: 

179 re_client_split = '.'.join(self.re_client.split('.')[:2]) 

180 if re_client_split == '23.5': #betclic fr 

181 matches = list(self.re_GameInfoTrny.finditer(self.summaryText)) 

182 if len(matches) > 0: 

183 mg2 = {'TOURNO': None, 'NAME': None, 'REWARD': None, 'PLACE': None, 'BIAMT': None, 'BIRAKE': None, 'BIRAKE2': None, 'TOTBUYIN': None, 'WIN': None} 

184 mg2['TOURNO'] = matches[0].group('TOURNO') 

185 mg2['NAME'] = matches[1].group('NAME') 

186 mg2['REWARD'] = matches[2].group('REWARD') 

187 mg2['PLACE'] = matches[3].group('PLACE') 

188 mg2['BIAMT'] = matches[4].group('BIAMT') 

189 mg2['BIRAKE'] = matches[4].group('BIRAKE') 

190 mg2['BIRAKE2'] = matches[4].group('BIRAKE2') 

191 mg2['TOTBUYIN'] = matches[5].group('TOTBUYIN') 

192 mg2['WIN'] = matches[6].group('WIN') 

193 

194 self.buyin = 0 

195 self.fee = 0 

196 self.prizepool = None 

197 self.entries = None 

198 

199 if mg2['TOURNO']: 

200 self.tourNo = mg2['TOURNO'] 

201 #if mg2['CURRENCY']: 

202 #self.currency = self.currencies[mg2['CURRENCY']] 

203 rank, winnings = None, None 

204 if 'PLACE' in mg2 and self.re_Place.search(mg2['PLACE']): 

205 rank = int(mg2['PLACE']) 

206 winnings = int(100*self.convert_to_decimal(mg2['WIN'])) 

207 

208 self.tourneyName = mg2['NAME'].replace(" " + self.tourNo, "") 

209 

210 if not mg2['BIRAKE'] and mg2['TOTBUYIN']: 

211 m3 = self.re_TotalBuyin.search(mg2['TOTBUYIN']) 

212 if m3: 

213 mg2 = m3.groupdict() 

214 elif mg2['BIAMT']: mg2['BIRAKE'] = '0' 

215 if mg2['BIAMT'] and mg2['BIRAKE']: 

216 self.buyin = int(100*self.convert_to_decimal(mg2['BIAMT'])) 

217 self.fee = int(100*self.convert_to_decimal(mg2['BIRAKE'])) 

218 if 'BIRAKE1' in mg2 and mg2['BIRAKE1']: 

219 self.buyin += int(100*self.convert_to_decimal(mg2['BIRAKE1'])) 

220 if self.re_FPP.match(mg2['BIAMT']): 

221 self.buyinCurrency = 'FPP' 

222 else: 

223 self.buyin = 0 

224 self.fee = 0 

225 if self.buyin == 0: 

226 self.buyinCurrency = 'FREE' 

227 hero = mg['HERO'] 

228 self.addPlayer(rank, hero, winnings, self.currency, None, None, None) 

229 else: 

230 raise FpdbHandPartial(hid=self.tourNo) 

231 if self.tourNo is None: 

232 log.error(("iPokerSummary.parseSummary: Could Not Parse tourNo")) 

233 raise FpdbParseError 

234 

235 else: 

236 matches = list(self.re_GameInfoTrny2.finditer(self.summaryText)) 

237 if len(matches) > 0: 

238 mg2 = {'TOURNO': None, 'NAME': None, 'PLACE': None, 'BIAMT': None, 'BIRAKE': None, 'TOTBUYIN': None, 'WIN': None} 

239 mg2['TOURNO'] = matches[0].group('TOURNO') 

240 mg2['NAME'] = matches[1].group('NAME') 

241 mg2['PLACE'] = matches[2].group('PLACE') 

242 mg2['BIAMT'] = matches[3].group('BIAMT') 

243 mg2['BIRAKE'] = matches[3].group('BIRAKE') 

244 mg2['TOTBUYIN'] = matches[4].group('TOTBUYIN') 

245 mg2['WIN'] = matches[5].group('WIN') 

246 

247 

248 self.buyin = 0 

249 self.fee = 0 

250 self.prizepool = None 

251 self.entries = None 

252 

253 if mg2['TOURNO']: 

254 self.tourNo = mg2['TOURNO'] 

255 #if mg2['CURRENCY']: 

256 #self.currency = self.currencies[mg2['CURRENCY']] 

257 rank, winnings = None, None 

258 if 'PLACE' in mg2 and mg2['PLACE'] != 'N/A': 

259 rank = int(mg2['PLACE']) 

260 if mg2['WIN'] and mg2['WIN'] != 'N/A': 

261 winnings = int(100*self.convert_to_decimal(mg2['WIN'])) 

262 

263 self.tourneyName = mg2['NAME'].replace(" " + self.tourNo, "") 

264 

265 if not mg2['BIRAKE'] and mg2['TOTBUYIN']: 

266 m3 = self.re_TotalBuyin.search(mg2['TOTBUYIN']) 

267 if m3: 

268 mg2 = m3.groupdict() 

269 elif mg2['BIAMT']: mg2['BIRAKE'] = '0' 

270 if mg2['BIAMT'] and mg2['BIRAKE']: 

271 self.buyin = int(100*self.convert_to_decimal(mg2['BIAMT'])) 

272 self.fee = int(100*self.convert_to_decimal(mg2['BIRAKE'])) 

273 if 'BIRAKE1' in mg2 and mg2['BIRAKE1']: 

274 self.buyin += int(100*self.convert_to_decimal(mg2['BIRAKE1'])) 

275 if self.re_FPP.match(mg2['BIAMT']): 

276 self.buyinCurrency = 'FPP' 

277 else: 

278 self.buyin = 0 

279 self.fee = 0 

280 if self.buyin == 0: 

281 self.buyinCurrency = 'FREE' 

282 hero = mg['HERO'] 

283 self.addPlayer(rank, hero, winnings, self.currency, None, None, None) 

284 else: 

285 raise FpdbHandPartial(hid=self.tourNo) 

286 if self.tourNo is None: 

287 log.error(("iPokerSummary.parseSummary: Could Not Parse tourNo")) 

288 raise FpdbParseError 

289 else: 

290 tmp = self.summaryText[0:200] 

291 log.error(("iPokerSummary.determineGameType: Text does not appear to be a tournament '%s'") % tmp) 

292 raise FpdbParseError 

293 

294 

295 def convert_to_decimal(self, string): 

296 dec = self.clearMoneyString(string) 

297 m = self.re_Buyin.search(dec) 

298 if m: 

299 dec = Decimal(m.group('BUYIN')) 

300 else: 

301 dec = 0 

302 return dec 

303