From 49aa8921e39427aa0a697b281170fabe414a446a Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 19 Dec 2008 16:52:32 +0900 Subject: [PATCH 1/4] Grapher: Update to support mutiple sites and players Makes sites actually selectable via checkboxes. Removed the sitename from the graph string for the moment - How that string is generated needs a major overhaul --- pyfpdb/FpdbSQLQueries.py | 9 +++- pyfpdb/GuiGraphViewer.py | 78 ++++++++++++++++++++++++---------- pyfpdb/HUD_config.xml.example | 2 +- pyfpdb/psnlheparser-mct.tgz | Bin 26184 -> 0 bytes 4 files changed, 63 insertions(+), 26 deletions(-) delete mode 100644 pyfpdb/psnlheparser-mct.tgz diff --git a/pyfpdb/FpdbSQLQueries.py b/pyfpdb/FpdbSQLQueries.py index 07fa15bb..9afdc28f 100644 --- a/pyfpdb/FpdbSQLQueries.py +++ b/pyfpdb/FpdbSQLQueries.py @@ -635,6 +635,11 @@ class FpdbSQLQueries: elif(self.dbname == 'SQLite'): self.query['getPlayerId'] = """SELECT id from Players where name = %s""" + if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'): + self.query['getSiteId'] = """SELECT id from Sites where name = %s""" + elif(self.dbname == 'SQLite'): + self.query['getSiteId'] = """SELECT id from Sites where name = %s""" + if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL'): self.query['getRingProfitAllHandsPlayerIdSite'] = """ SELECT hp.handId, hp.winnings, coalesce(hp.ante,0) + SUM(ha.amount) @@ -643,8 +648,8 @@ class FpdbSQLQueries: INNER JOIN Players pl ON hp.playerId = pl.id INNER JOIN Hands h ON h.id = hp.handId INNER JOIN HandsActions ha ON ha.handPlayerId = hp.id - WHERE pl.name = %s - AND pl.siteId = %s + where pl.id in + AND pl.siteId in AND hp.tourneysPlayersId IS NULL GROUP BY hp.handId, hp.winnings, h.handStart, hp.ante ORDER BY h.handStart""" diff --git a/pyfpdb/GuiGraphViewer.py b/pyfpdb/GuiGraphViewer.py index 94732295..a0a2e326 100644 --- a/pyfpdb/GuiGraphViewer.py +++ b/pyfpdb/GuiGraphViewer.py @@ -50,22 +50,27 @@ class GuiGraphViewer (threading.Thread): try: self.canvas.destroy() except AttributeError: pass - # Whaich sites are selected? - # TODO: - # What hero names for the selected site? - # TODO: + sitenos = [] + playerids = [] - name = self.heroes[self.sites] + # Which sites are selected? + for site in self.sites: + if self.sites[site] == True: + sitenos.append(self.siteid[site]) + self.cursor.execute(self.sql.query['getPlayerId'], (self.heroes[site],)) + result = self.db.cursor.fetchall() + if len(result) == 1: + playerids.append(result[0][0]) - if self.sites == "PokerStars": - site=2 - sitename="PokerStars: " - elif self.sites=="Full Tilt": - site=1 - sitename="Full Tilt: " - else: - print "invalid text in site selection in graph, defaulting to PS" - site=2 + if sitenos == []: + #Should probably pop up here. + print "No sites selected - defaulting to PokerStars" + sitenos = [2] + + + if playerids == []: + print "No player ids found" + return self.fig = Figure(figsize=(5,4), dpi=100) @@ -74,7 +79,7 @@ class GuiGraphViewer (threading.Thread): #Get graph data from DB starttime = time() - line = self.getRingProfitGraph(name, site) + line = self.getRingProfitGraph(playerids, sitenos) print "Graph generated in: %s" %(time() - starttime) self.ax.set_title("Profit graph for ring games") @@ -87,7 +92,8 @@ class GuiGraphViewer (threading.Thread): #TODO: Do something useful like alert user print "No hands returned by graph query" else: - text = "All Hands, " + sitename + str(name) + "\nProfit: $" + str(line[-1]) + "\nTotal Hands: " + str(len(line)) +# text = "All Hands, " + sitename + str(name) + "\nProfit: $" + str(line[-1]) + "\nTotal Hands: " + str(len(line)) + text = "All Hands, " + "\nProfit: $" + str(line[-1]) + "\nTotal Hands: " + str(len(line)) self.ax.annotate(text, xy=(10, -10), @@ -103,8 +109,26 @@ class GuiGraphViewer (threading.Thread): self.canvas.show() #end of def showClicked - def getRingProfitGraph(self, name, site): - self.cursor.execute(self.sql.query['getRingProfitAllHandsPlayerIdSite'], (name, site)) + def getRingProfitGraph(self, names, sites): + tmp = self.sql.query['getRingProfitAllHandsPlayerIdSite'] +# print "DEBUG: getRingProfitGraph" + + #Buggered if I can find a way to do this 'nicely' take a list of intergers and longs + # and turn it into a tuple readale by sql. + # [5L] into (5) not (5,) and [5L, 2829L] into (5, 2829) + nametest = str(tuple(names)) + sitetest = str(tuple(sites)) + nametest = nametest.replace("L", "") + nametest = nametest.replace(",)",")") + sitetest = sitetest.replace(",)",")") + + #Must be a nicer way to deal with tuples of size 1 ie. (2,) - which makes sql barf + tmp = tmp.replace("", nametest) + tmp = tmp.replace("", sitetest) + +# print "DEBUG: sql query:" +# print tmp + self.cursor.execute(tmp) #returns (HandId,Winnings,Costs,Profit) winnings = self.db.cursor.fetchall() @@ -125,7 +149,6 @@ class GuiGraphViewer (threading.Thread): pname.set_text(player) pname.set_width_chars(20) hbox.pack_start(pname, False, True, 0) - #TODO: Need to connect a callback here pname.connect("changed", self.__set_hero_name, site) #TODO: Look at GtkCompletion - to fill out usernames pname.show() @@ -134,7 +157,7 @@ class GuiGraphViewer (threading.Thread): def __set_hero_name(self, w, site): self.heroes[site] = w.get_text() - print "DEBUG: settings heroes[%s]: %s"%(site, self.heroes[site]) +# print "DEBUG: settings heroes[%s]: %s"%(site, self.heroes[site]) def createSiteLine(self, hbox, site): cb = gtk.CheckButton(site) @@ -144,8 +167,9 @@ class GuiGraphViewer (threading.Thread): def __set_site_select(self, w, site): # This doesn't behave as intended - self.site only allows 1 site for the moment. - self.sites = site - print "self.sites set to %s" %(self.sites) + print w.get_active() + self.sites[site] = w.get_active() + print "self.sites[%s] set to %s" %(site, self.sites[site]) def fillPlayerFrame(self, vbox): for site in self.conf.supported_sites.keys(): @@ -162,6 +186,13 @@ class GuiGraphViewer (threading.Thread): vbox.pack_start(hbox, False, True, 0) hbox.show() self.createSiteLine(hbox, site) + #Get db site id for filtering later + self.cursor.execute(self.sql.query['getSiteId'], (site)) + result = self.db.cursor.fetchall() + if len(result) == 1: + self.siteid[site] = result[0][0] + else: + print "Either 0 or more than one site matched - EEK" def fillDateFrame(self, vbox): # Hat tip to Mika Bostrom - calendar code comes from PokerStats @@ -261,7 +292,8 @@ class GuiGraphViewer (threading.Thread): self.sql=querylist self.conf = config - self.sites = "PokerStars" + self.sites = {} + self.siteid = {} self.heroes = {} # For use in date ranges. diff --git a/pyfpdb/HUD_config.xml.example b/pyfpdb/HUD_config.xml.example index 355c9d2f..bb48c482 100644 --- a/pyfpdb/HUD_config.xml.example +++ b/pyfpdb/HUD_config.xml.example @@ -49,7 +49,7 @@ - + diff --git a/pyfpdb/psnlheparser-mct.tgz b/pyfpdb/psnlheparser-mct.tgz deleted file mode 100644 index b04c80183ec34f4a740acfe9b0f9bebfbcf8e36d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26184 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 z 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 Y^1)&MzteJi9f=iZ()H#E3(k}O1NKQU4FCWD From 2d700820f42ec95edb21213d1e2bbeb65fb46ea7 Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 19 Dec 2008 16:58:24 +0900 Subject: [PATCH 2/4] Add Everleaf to DB init process Should these come from config on startup...? --- pyfpdb/fpdb_db.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyfpdb/fpdb_db.py b/pyfpdb/fpdb_db.py index e51538ee..8c0ab66e 100644 --- a/pyfpdb/fpdb_db.py +++ b/pyfpdb/fpdb_db.py @@ -177,6 +177,7 @@ class fpdb_db: self.cursor.execute("INSERT INTO Settings VALUES (118);") self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'Full Tilt Poker', 'USD');") self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'PokerStars', 'USD');") + self.cursor.execute("INSERT INTO Sites VALUES (DEFAULT, 'Everleaf', 'USD');") self.cursor.execute("INSERT INTO TourneyTypes VALUES (DEFAULT, 1, 0, 0, 0, False);") #end def fillDefaultData From db6a8c5b31adbf665e52e95bbd71fb5fa856686e Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 19 Dec 2008 17:21:58 +0900 Subject: [PATCH 3/4] Grapher: Make date ranges work - MySQL --- pyfpdb/FpdbSQLQueries.py | 2 ++ pyfpdb/GuiGraphViewer.py | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/pyfpdb/FpdbSQLQueries.py b/pyfpdb/FpdbSQLQueries.py index 9afdc28f..4df2fa75 100644 --- a/pyfpdb/FpdbSQLQueries.py +++ b/pyfpdb/FpdbSQLQueries.py @@ -650,6 +650,8 @@ class FpdbSQLQueries: INNER JOIN HandsActions ha ON ha.handPlayerId = hp.id where pl.id in AND pl.siteId in + AND h.handStart > '' + AND h.handStart < '' AND hp.tourneysPlayersId IS NULL GROUP BY hp.handId, hp.winnings, h.handStart, hp.ante ORDER BY h.handStart""" diff --git a/pyfpdb/GuiGraphViewer.py b/pyfpdb/GuiGraphViewer.py index a0a2e326..ae8895ff 100644 --- a/pyfpdb/GuiGraphViewer.py +++ b/pyfpdb/GuiGraphViewer.py @@ -112,6 +112,12 @@ class GuiGraphViewer (threading.Thread): def getRingProfitGraph(self, names, sites): tmp = self.sql.query['getRingProfitAllHandsPlayerIdSite'] # print "DEBUG: getRingProfitGraph" + start_date, end_date = self.__get_dates() + + if start_date == '': + start_date = '1970-01-01' + if end_date == '': + end_date = '2020-12-12' #Buggered if I can find a way to do this 'nicely' take a list of intergers and longs # and turn it into a tuple readale by sql. @@ -125,6 +131,8 @@ class GuiGraphViewer (threading.Thread): #Must be a nicer way to deal with tuples of size 1 ie. (2,) - which makes sql barf tmp = tmp.replace("", nametest) tmp = tmp.replace("", sitetest) + tmp = tmp.replace("", start_date) + tmp = tmp.replace("", end_date) # print "DEBUG: sql query:" # print tmp From 659f0bb508aefd11f29a90a75b49101b6defb4fc Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 19 Dec 2008 17:27:18 +0900 Subject: [PATCH 4/4] Grapher: Fix Postgres to work again --- pyfpdb/FpdbSQLQueries.py | 6 ++++-- pyfpdb/GuiGraphViewer.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pyfpdb/FpdbSQLQueries.py b/pyfpdb/FpdbSQLQueries.py index 4df2fa75..fe170c8c 100644 --- a/pyfpdb/FpdbSQLQueries.py +++ b/pyfpdb/FpdbSQLQueries.py @@ -663,8 +663,10 @@ class FpdbSQLQueries: INNER JOIN Players pl ON hp.playerId = pl.id INNER JOIN Hands h ON h.id = hp.handId INNER JOIN HandsActions ha ON ha.handPlayerId = hp.id - WHERE pl.name = %s - AND pl.siteId = %s + where pl.id in + AND pl.siteId in + AND h.handStart > '' + AND h.handStart < '' AND hp.tourneysPlayersId IS NULL GROUP BY hp.handId, hp.winnings, h.handStart ORDER BY h.handStart""" diff --git a/pyfpdb/GuiGraphViewer.py b/pyfpdb/GuiGraphViewer.py index ae8895ff..8026a2c7 100644 --- a/pyfpdb/GuiGraphViewer.py +++ b/pyfpdb/GuiGraphViewer.py @@ -195,7 +195,7 @@ class GuiGraphViewer (threading.Thread): hbox.show() self.createSiteLine(hbox, site) #Get db site id for filtering later - self.cursor.execute(self.sql.query['getSiteId'], (site)) + self.cursor.execute(self.sql.query['getSiteId'], (site,)) result = self.db.cursor.fetchall() if len(result) == 1: self.siteid[site] = result[0][0]