Coverage for GuiTourneyGraphViewer.py: 0%
191 statements
« prev ^ index » next coverage.py v7.6.3, created at 2024-10-15 19:33 +0000
« prev ^ index » next coverage.py v7.6.3, created at 2024-10-15 19:33 +0000
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
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.
19from __future__ import print_function
20from __future__ import division
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
31try:
32 calluse = not "matplotlib" in sys.modules
33 import matplotlib
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
58log = logging.getLogger("sessionViewer")
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)
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 }
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)
100 scroll = QScrollArea()
101 scroll.setWidget(self.filters)
102 self.addWidget(scroll)
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)
112 self.fig = None
113 self.canvas = None
115 self.db.rollback()
116 self.exportFile = None
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
127 if self.fig is not None:
128 self.fig.clear()
130 self.fig = Figure(figsize=(5.0, 4.0), dpi=100)
131 self.fig.patch.set_facecolor(self.colors["background"])
133 if self.canvas is not None:
134 self.canvas.destroy()
136 self.canvas = FigureCanvas(self.fig)
137 self.canvas.setParent(self)
139 def generateGraph(self, widget):
140 self.clearGraphData()
142 sitenos = []
143 playerids = []
145 sites = self.filters.getSites()
146 heroes = self.filters.getHeroes()
147 siteids = self.filters.getSiteIds()
149 games = self.filters.getGames()
150 names = ""
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
162 if not sitenos:
163 print("No sites selected - defaulting to PokerStars")
164 self.db.rollback()
165 return
167 if not playerids:
168 print("No player ids found")
169 self.db.rollback()
170 return
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))
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 ]
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()
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()
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
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"')
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(",)", ")")
300 print("DEBUG: sql query:", tmp)
302 self.db.cursor.execute(tmp)
303 winnings = self.db.cursor.fetchall()
304 self.db.rollback()
306 if len(winnings) == 0:
307 return None
309 green = [float(x[1]) for x in winnings]
310 greenline = cumsum(green)
311 return old_div(greenline, 100)
313 def exportGraph(self):
314 if self.fig is None:
315 return
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()
328if __name__ == "__main__":
329 import Configuration
331 config = Configuration.Config()
333 settings = {}
335 settings.update(config.get_db_parameters())
336 settings.update(config.get_import_parameters())
337 settings.update(config.get_default_paths())
339 from PyQt5.QtWidgets import QApplication, QMainWindow
341 app = QApplication([])
342 import SQL
344 sql = SQL.Sql(db_server=settings["db-server"])
346 colors = {"background": "#19232D", "foreground": "#9DA9B5", "grid": "#4D4D4D", "line_up": "g", "line_down": "r"}
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_()