Coverage for GuiTourneyGraphViewer.py: 0%

191 statements  

« prev     ^ index     » next       coverage.py v7.6.3, created at 2024-10-14 11:07 +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 

19from __future__ import print_function 

20from __future__ import division 

21 

22from past.utils import old_div 

23import os 

24import sys 

25from time import time 

26from PyQt5.QtWidgets import QFrame, QScrollArea, QSplitter, QVBoxLayout, QMessageBox 

27import Database 

28import Filters 

29# import Charset 

30 

31try: 

32 calluse = not "matplotlib" in sys.modules 

33 import matplotlib 

34 

35 if calluse: 

36 try: 

37 matplotlib.use("qt5agg") 

38 except ValueError as e: 

39 print(e) 

40 from matplotlib.figure import Figure 

41 from matplotlib.backends.backend_qt5agg import FigureCanvas 

42 from matplotlib.font_manager import FontProperties 

43 from numpy import cumsum 

44except ImportError as inst: 

45 print( 

46 ( 

47 """Failed to load libs for graphing, graphing will not function. Please install numpy and matplotlib if you want to use graphs.""" 

48 ) 

49 ) 

50 print( 

51 ( 

52 """This is of no consequence for other parts of the program, e.g. import and HUD are NOT affected by this problem.""" 

53 ) 

54 ) 

55 print("ImportError: %s" % inst.args) 

56import logging 

57 

58log = logging.getLogger("sessionViewer") 

59 

60 

61class GuiTourneyGraphViewer(QSplitter): 

62 def __init__(self, querylist, config, parent, colors, debug=True): 

63 """Constructor for GraphViewer""" 

64 QSplitter.__init__(self, parent) 

65 self.sql = querylist 

66 self.conf = config 

67 self.debug = debug 

68 self.parent = parent 

69 self.colors = colors 

70 self.db = Database.Database(self.conf, sql=self.sql) 

71 

72 filters_display = { 

73 "Heroes": True, 

74 "Sites": True, 

75 "Games": False, # cash game 

76 "Tourney": True, 

77 "TourneyCat": True, 

78 "TourneyLim": True, 

79 "TourneyBuyin": True, 

80 "Currencies": True, 

81 "Limits": False, 

82 "LimitSep": True, 

83 "LimitType": True, 

84 "Type": True, 

85 "UseType": "tour", 

86 "Seats": False, 

87 "SeatSep": True, 

88 "Dates": True, 

89 "Groups": False, 

90 "Button1": True, 

91 "Button2": True, 

92 } 

93 

94 self.filters = Filters.Filters(self.db, display=filters_display) 

95 self.filters.registerButton1Name("Refresh Graph") 

96 self.filters.registerButton1Callback(self.generateGraph) 

97 self.filters.registerButton2Name("Export to File") 

98 self.filters.registerButton2Callback(self.exportGraph) 

99 

100 scroll = QScrollArea() 

101 scroll.setWidget(self.filters) 

102 self.addWidget(scroll) 

103 

104 frame = QFrame() 

105 frame.setStyleSheet(f'background-color: {self.colors["background"]}') 

106 self.graphBox = QVBoxLayout() 

107 frame.setLayout(self.graphBox) 

108 self.addWidget(frame) 

109 self.setStretchFactor(0, 0) 

110 self.setStretchFactor(1, 1) 

111 

112 self.fig = None 

113 self.canvas = None 

114 

115 self.db.rollback() 

116 self.exportFile = None 

117 

118 def clearGraphData(self): 

119 try: 

120 if self.canvas: 

121 self.graphBox.removeWidget(self.canvas) 

122 except (AttributeError, RuntimeError) as e: 

123 # Handle specific exceptions related to widget removal 

124 log.error(f"Error removing widget: {e}") 

125 pass 

126 

127 if self.fig is not None: 

128 self.fig.clear() 

129 

130 self.fig = Figure(figsize=(5.0, 4.0), dpi=100) 

131 self.fig.patch.set_facecolor(self.colors["background"]) 

132 

133 if self.canvas is not None: 

134 self.canvas.destroy() 

135 

136 self.canvas = FigureCanvas(self.fig) 

137 self.canvas.setParent(self) 

138 

139 def generateGraph(self, widget): 

140 self.clearGraphData() 

141 

142 sitenos = [] 

143 playerids = [] 

144 

145 sites = self.filters.getSites() 

146 heroes = self.filters.getHeroes() 

147 siteids = self.filters.getSiteIds() 

148 

149 games = self.filters.getGames() 

150 names = "" 

151 

152 for site in sites: 

153 sitenos.append(siteids[site]) 

154 _hname = heroes.get(site, "") 

155 if not _hname: 

156 raise ValueError(f"Hero name not found for site {site}") 

157 result = self.db.get_player_id(self.conf, site, _hname) 

158 if result is not None: 

159 playerids.append(int(result)) 

160 names = names + "\n" + _hname + " on " + site 

161 

162 if not sitenos: 

163 print("No sites selected - defaulting to PokerStars") 

164 self.db.rollback() 

165 return 

166 

167 if not playerids: 

168 print("No player ids found") 

169 self.db.rollback() 

170 return 

171 

172 self.ax = self.fig.add_subplot(111) 

173 starttime = time() 

174 green = self.getData(playerids, sitenos, games) 

175 print("Graph generated in: %s" % (time() - starttime)) 

176 

177 self.ax.set_xlabel("Tournaments", color=self.colors["foreground"]) 

178 self.ax.set_facecolor(self.colors["background"]) 

179 self.ax.tick_params(axis="x", colors=self.colors["foreground"]) 

180 self.ax.tick_params(axis="y", colors=self.colors["foreground"]) 

181 self.ax.spines["left"].set_color(self.colors["foreground"]) 

182 self.ax.spines["right"].set_color(self.colors["foreground"]) 

183 self.ax.spines["top"].set_color(self.colors["foreground"]) 

184 self.ax.spines["bottom"].set_color(self.colors["foreground"]) 

185 self.ax.set_ylabel("$", color=self.colors["foreground"]) 

186 self.ax.grid(color=self.colors["grid"], linestyle=":", linewidth=0.2) 

187 if green is None or len(green) == 0: 

188 self.ax.set_title("No Data for Player(s) Found", color=self.colors["foreground"]) 

189 green = [ 

190 0.0, 

191 0.0, 

192 0.0, 

193 0.0, 

194 500.0, 

195 1000.0, 

196 900.0, 

197 800.0, 

198 700.0, 

199 600.0, 

200 500.0, 

201 400.0, 

202 300.0, 

203 200.0, 

204 100.0, 

205 0.0, 

206 500.0, 

207 1000.0, 

208 1000.0, 

209 1000.0, 

210 1000.0, 

211 1000.0, 

212 1000.0, 

213 1000.0, 

214 1000.0, 

215 1000.0, 

216 1000.0, 

217 1000.0, 

218 1000.0, 

219 1000.0, 

220 875.0, 

221 750.0, 

222 625.0, 

223 500.0, 

224 375.0, 

225 250.0, 

226 125.0, 

227 0.0, 

228 0.0, 

229 0.0, 

230 0.0, 

231 500.0, 

232 1000.0, 

233 900.0, 

234 800.0, 

235 700.0, 

236 600.0, 

237 500.0, 

238 400.0, 

239 300.0, 

240 200.0, 

241 100.0, 

242 0.0, 

243 500.0, 

244 1000.0, 

245 1000.0, 

246 ] 

247 

248 self.ax.plot(green, color="green", label="Tournaments: %d\nProfit: $%.2f" % (len(green), green[-1])) 

249 self.graphBox.addWidget(self.canvas) 

250 self.canvas.show() 

251 self.canvas.draw() 

252 else: 

253 self.ax.set_title("Tournament Results" + names, color=self.colors["foreground"]) 

254 self.ax.plot(green, color="green", label="Tournaments: %d\nProfit: $%.2f" % (len(green), green[-1])) 

255 self.ax.legend( 

256 loc="upper left", 

257 fancybox=True, 

258 shadow=True, 

259 prop=FontProperties(size="smaller"), 

260 facecolor=self.colors["background"], 

261 labelcolor=self.colors["foreground"], 

262 ) 

263 self.graphBox.addWidget(self.canvas) 

264 self.canvas.draw() 

265 

266 def getData(self, names, sites, Tourneys): 

267 tmp = self.sql.query["tourneyGraphType"] 

268 start_date, end_date = self.filters.getDates() 

269 tourneys = self.filters.getTourneyTypes() 

270 tourneysCat = self.filters.getTourneyCat() 

271 tourneysLim = self.filters.getTourneyLim() 

272 tourneysBuyin = self.filters.getTourneyBuyin() 

273 

274 currencies = {"EUR": "EUR", "USD": "USD", "": "T$"} 

275 currencytest = str(tuple(currencies.values())) 

276 currencytest = currencytest.replace(",)", ")") 

277 currencytest = currencytest.replace("u'", "'") 

278 currencytest = "AND tt.currency in %s" % currencytest 

279 

280 nametest = str(tuple(names)) 

281 sitetest = str(tuple(sites)) 

282 tourneystest = str(tuple(tourneys)) 

283 tourneysCattest = str(tuple(tourneysCat)) 

284 tourneysLimtest = str(tuple(tourneysLim)) 

285 tourneysBuyintest = str(tuple(int(buyin.split(",")[0]) for buyin in tourneysBuyin if buyin != "None")) 

286 tourneystest = tourneystest.replace("None", '"None"') 

287 tourneysBuyintest = tourneysBuyintest.replace("None", '"None"') 

288 

289 tmp = tmp.replace("<player_test>", nametest) 

290 tmp = tmp.replace("<site_test>", sitetest) 

291 tmp = tmp.replace("<startdate_test>", start_date) 

292 tmp = tmp.replace("<enddate_test>", end_date) 

293 tmp = tmp.replace("<currency_test>", currencytest) 

294 tmp = tmp.replace("<tourney_cat>", tourneysCattest) 

295 tmp = tmp.replace("<tourney_lim>", tourneysLimtest) 

296 tmp = tmp.replace("<tourney_buyin>", tourneysBuyintest) 

297 tmp = tmp.replace("<tourney_test>", tourneystest) 

298 tmp = tmp.replace(",)", ")") 

299 

300 print("DEBUG: sql query:", tmp) 

301 

302 self.db.cursor.execute(tmp) 

303 winnings = self.db.cursor.fetchall() 

304 self.db.rollback() 

305 

306 if len(winnings) == 0: 

307 return None 

308 

309 green = [float(x[1]) for x in winnings] 

310 greenline = cumsum(green) 

311 return old_div(greenline, 100) 

312 

313 def exportGraph(self): 

314 if self.fig is None: 

315 return 

316 

317 else: 

318 path = os.getcwd() 

319 path = path + "/graph.png" 

320 self.fig.savefig(path) 

321 msg = QMessageBox() 

322 msg.setWindowTitle("FPDB 3 info") 

323 mess = "Your graph is saved in " + path 

324 msg.setText(mess) 

325 msg.exec() 

326 

327 

328if __name__ == "__main__": 

329 import Configuration 

330 

331 config = Configuration.Config() 

332 

333 settings = {} 

334 

335 settings.update(config.get_db_parameters()) 

336 settings.update(config.get_import_parameters()) 

337 settings.update(config.get_default_paths()) 

338 

339 from PyQt5.QtWidgets import QApplication, QMainWindow 

340 

341 app = QApplication([]) 

342 import SQL 

343 

344 sql = SQL.Sql(db_server=settings["db-server"]) 

345 

346 colors = {"background": "#19232D", "foreground": "#9DA9B5", "grid": "#4D4D4D", "line_up": "g", "line_down": "r"} 

347 

348 i = GuiTourneyGraphViewer(sql, config, None, colors) 

349 main_window = QMainWindow() 

350 main_window.setCentralWidget(i) 

351 main_window.show() 

352 main_window.resize(1400, 800) 

353 app.exec_()