Merge branch 'master' of git://git.assembla.com/fpdb-sql

This commit is contained in:
Worros 2009-05-09 10:34:46 +09:30
commit e2d8a58620
7 changed files with 202 additions and 77 deletions

View File

@ -42,9 +42,15 @@ class Filters(threading.Thread):
self.sites = {} self.sites = {}
self.games = {} self.games = {}
self.limits = {} self.limits = {}
self.seats = {}
self.siteid = {} self.siteid = {}
self.heroes = {} self.heroes = {}
# text used on screen stored here so that it can be configured
self.filterText = {'limitsall':'All', 'limitsnone':'None', 'limitsshow':'Show Limits'
,'seatsbetween':'Between:', 'seatsand':'And:', 'seatsand':'Show Seats'
}
# For use in date ranges. # For use in date ranges.
self.start_date = gtk.Entry(max=12) self.start_date = gtk.Entry(max=12)
self.end_date = gtk.Entry(max=12) self.end_date = gtk.Entry(max=12)
@ -89,6 +95,16 @@ class Filters(threading.Thread):
self.fillLimitsFrame(vbox, display) self.fillLimitsFrame(vbox, display)
limitsFrame.add(vbox) limitsFrame.add(vbox)
# Seats
seatsFrame = gtk.Frame("Seats:")
seatsFrame.set_label_align(0.0, 0.0)
seatsFrame.show()
vbox = gtk.VBox(False, 0)
self.sbSeats = {}
self.fillSeatsFrame(vbox)
seatsFrame.add(vbox)
dateFrame = gtk.Frame("Date:") dateFrame = gtk.Frame("Date:")
dateFrame.set_label_align(0.0, 0.0) dateFrame.set_label_align(0.0, 0.0)
dateFrame.show() dateFrame.show()
@ -97,9 +113,9 @@ class Filters(threading.Thread):
self.fillDateFrame(vbox) self.fillDateFrame(vbox)
dateFrame.add(vbox) dateFrame.add(vbox)
self.Button1=gtk.Button("Unamed 1") self.Button1=gtk.Button("Unnamed 1")
self.Button2=gtk.Button("Unamed 2") self.Button2=gtk.Button("Unnamed 2")
#self.exportButton.connect("clicked", self.exportGraph, "show clicked") #self.exportButton.connect("clicked", self.exportGraph, "show clicked")
self.Button2.set_sensitive(False) self.Button2.set_sensitive(False)
@ -107,6 +123,7 @@ class Filters(threading.Thread):
self.mainVBox.add(sitesFrame) self.mainVBox.add(sitesFrame)
self.mainVBox.add(gamesFrame) self.mainVBox.add(gamesFrame)
self.mainVBox.add(limitsFrame) self.mainVBox.add(limitsFrame)
self.mainVBox.add(seatsFrame)
self.mainVBox.add(dateFrame) self.mainVBox.add(dateFrame)
self.mainVBox.add(self.Button1) self.mainVBox.add(self.Button1)
self.mainVBox.add(self.Button2) self.mainVBox.add(self.Button2)
@ -114,19 +131,21 @@ class Filters(threading.Thread):
self.mainVBox.show_all() self.mainVBox.show_all()
# Should do this cleaner # Should do this cleaner
if display["Heroes"] == False: if "Heroes" not in display or display["Heroes"] == False:
playerFrame.hide() playerFrame.hide()
if display["Sites"] == False: if "Sites" not in display or display["Sites"] == False:
sitesFrame.hide() sitesFrame.hide()
if display["Games"] == False: if "Games" not in display or display["Games"] == False:
gamesFrame.hide() gamesFrame.hide()
if display["Limits"] == False: if "Limits" not in display or display["Limits"] == False:
limitsFrame.hide() limitsFrame.hide()
if display["Dates"] == False: if "Seats" not in display or display["Seats"] == False:
seatsFrame.hide()
if "Dates" not in display or display["Dates"] == False:
dateFrame.hide() dateFrame.hide()
if display["Button1"] == False: if "Button1" not in display or display["Button1"] == False:
self.Button1.hide() self.Button1.hide()
if display["Button2"] == False: if "Button2" not in display or display["Button2"] == False:
self.Button2.hide() self.Button2.hide()
def get_vbox(self): def get_vbox(self):
@ -150,6 +169,11 @@ class Filters(threading.Thread):
ltuple.append(l) ltuple.append(l)
return ltuple return ltuple
def getSeats(self):
self.seats['from'] = self.sbSeats['from'].get_value_as_int()
self.seats['to'] = self.sbSeats['to'].get_value_as_int()
return self.seats
def getDates(self): def getDates(self):
return self.__get_dates() return self.__get_dates()
@ -196,8 +220,8 @@ class Filters(threading.Thread):
cb.connect('clicked', self.__set_game_select, game) cb.connect('clicked', self.__set_game_select, game)
hbox.pack_start(cb, False, False, 0) hbox.pack_start(cb, False, False, 0)
def createLimitLine(self, hbox, limit): def createLimitLine(self, hbox, limit, ltext):
cb = gtk.CheckButton(str(limit)) cb = gtk.CheckButton(str(ltext))
cb.connect('clicked', self.__set_limit_select, limit) cb.connect('clicked', self.__set_limit_select, limit)
hbox.pack_start(cb, False, False, 0) hbox.pack_start(cb, False, False, 0)
if limit != "None": if limit != "None":
@ -234,6 +258,11 @@ class Filters(threading.Thread):
for cb in self.cbLimits.values(): for cb in self.cbLimits.values():
cb.set_active(False) cb.set_active(False)
def __set_seat_select(self, w, seat):
#print "__set_seat_select: seat =", seat, "active =", w.get_active()
self.seats[seat] = w.get_active()
print "self.seats[%s] set to %s" %(seat, self.seats[seat])
def fillPlayerFrame(self, vbox): def fillPlayerFrame(self, vbox):
for site in self.conf.get_supported_sites(): for site in self.conf.get_supported_sites():
pathHBox = gtk.HBox(False, 0) pathHBox = gtk.HBox(False, 0)
@ -282,20 +311,47 @@ class Filters(threading.Thread):
vbox1.pack_start(hbox, False, False, 0) vbox1.pack_start(hbox, False, False, 0)
else: else:
vbox2.pack_start(hbox, False, False, 0) vbox2.pack_start(hbox, False, False, 0)
self.cbLimits[line[0]] = self.createLimitLine(hbox, line[0]) self.cbLimits[line[0]] = self.createLimitLine(hbox, line[0], line[0])
if "LimitSep" in display and display["LimitSep"] == True and len(result) >= 2: if "LimitSep" in display and display["LimitSep"] == True and len(result) >= 2:
hbox = gtk.HBox(False, 0) hbox = gtk.HBox(False, 0)
vbox.pack_start(hbox, False, True, 0) vbox.pack_start(hbox, False, True, 0)
self.cbAllLimits = self.createLimitLine(hbox, "All") self.cbAllLimits = self.createLimitLine(hbox, 'all', self.filterText['limitsall'])
hbox = gtk.HBox(False, 0) hbox = gtk.HBox(False, 0)
vbox.pack_start(hbox, False, True, 0) vbox.pack_start(hbox, False, True, 0)
self.cbNoLimits = self.createLimitLine(hbox, "None") self.cbNoLimits = self.createLimitLine(hbox, 'none', self.filterText['limitsnone'])
hbox = gtk.HBox(False, 0) hbox = gtk.HBox(False, 0)
vbox.pack_start(hbox, False, True, 0) vbox.pack_start(hbox, False, True, 0)
cb = self.createLimitLine(hbox, "Separate levels") cb = self.createLimitLine(hbox, 'show', self.filterText['limitsshow'])
else: else:
print "INFO: No games returned from database" print "INFO: No games returned from database"
def fillSeatsFrame(self, vbox):
hbox = gtk.HBox(False, 0)
vbox.pack_start(hbox, False, True, 0)
lbl_from = gtk.Label(self.filterText['seatsbetween'])
lbl_to = gtk.Label(self.filterText['seatsand'])
adj1 = gtk.Adjustment(value=2, lower=2, upper=10, step_incr=1, page_incr=1, page_size=0)
sb1 = gtk.SpinButton(adjustment=adj1, climb_rate=0.0, digits=0)
adj2 = gtk.Adjustment(value=10, lower=2, upper=10, step_incr=1, page_incr=1, page_size=0)
sb2 = gtk.SpinButton(adjustment=adj2, climb_rate=0.0, digits=0)
cb = gtk.CheckButton(self.filterText['seatsand'])
cb.connect('clicked', self.__set_seat_select, 'show')
hbox.pack_start(lbl_from, expand=False, padding=3)
hbox.pack_start(sb1, False, False, 0)
hbox.pack_start(lbl_to, expand=False, padding=3)
hbox.pack_start(sb2, False, False, 0)
hbox = gtk.HBox(False, 0)
vbox.pack_start(hbox, False, True, 0)
hbox.pack_start(cb, False, False, 0)
self.sbSeats['from'] = sb1
self.sbSeats['to'] = sb2
self.sbSeats['show'] = cb
self.seats['show'] = False
def fillCardsFrame(self, vbox): def fillCardsFrame(self, vbox):
hbox1 = gtk.HBox(True,0) hbox1 = gtk.HBox(True,0)
hbox1.show() hbox1.show()

View File

@ -632,7 +632,7 @@ class FpdbSQLQueries:
SELECT SELECT
concat(upper(stats.limitType), ' ' concat(upper(stats.limitType), ' '
,concat(upper(substring(stats.category,1,1)),substring(stats.category,2) ), ' ' ,concat(upper(substring(stats.category,1,1)),substring(stats.category,2) ), ' '
,stats.name, ' $' ,stats.name, ' '
,cast(stats.bigBlindDesc as char) ,cast(stats.bigBlindDesc as char)
) AS Game ) AS Game
,stats.n ,stats.n
@ -654,6 +654,7 @@ class FpdbSQLQueries:
,case when hprof2.variance = -999 then '-' ,case when hprof2.variance = -999 then '-'
else format(hprof2.variance, 2) else format(hprof2.variance, 2)
end AS Variance end AS Variance
,stats.AvgSeats
FROM FROM
(select /* stats from hudcache */ (select /* stats from hudcache */
gt.base gt.base
@ -696,11 +697,13 @@ class FpdbSQLQueries:
,format((sum(totalProfit/(gt.bigBlind+0.0))) / (sum(HDs)/100.0),2) ,format((sum(totalProfit/(gt.bigBlind+0.0))) / (sum(HDs)/100.0),2)
AS BBper100 AS BBper100
,format( (sum(totalProfit)/100.0) / sum(HDs), 4) AS Profitperhand ,format( (sum(totalProfit)/100.0) / sum(HDs), 4) AS Profitperhand
,format( avg(activeSeats), 1) AS AvgSeats
from Gametypes gt from Gametypes gt
inner join Sites s on s.Id = gt.siteId inner join Sites s on s.Id = gt.siteId
inner join HudCache hc on hc.gameTypeId = gt.Id inner join HudCache hc on hc.gameTypeId = gt.Id
where hc.playerId in <player_test> where hc.playerId in <player_test>
and <gtbigBlind_test> and <gtbigBlind_test>
and hc.activeSeats <seats_test>
group by gt.base group by gt.base
,gt.category ,gt.category
,upper(gt.limitType) ,upper(gt.limitType)
@ -728,12 +731,12 @@ class FpdbSQLQueries:
group by hprof.gtId group by hprof.gtId
) hprof2 ) hprof2
on hprof2.gtId = stats.gtId on hprof2.gtId = stats.gtId
order by stats.category, stats.limittype, stats.bigBlindDesc""" order by stats.category, stats.limittype, stats.bigBlindDesc <orderbyseats>"""
elif(self.dbname == 'PostgreSQL'): elif(self.dbname == 'PostgreSQL'):
self.query['playerStats'] = """ self.query['playerStats'] = """
SELECT upper(stats.limitType) || ' ' SELECT upper(stats.limitType) || ' '
|| initcap(stats.category) || ' ' || initcap(stats.category) || ' '
|| stats.name || ' $' || stats.name || ' '
|| stats.bigBlindDesc AS Game || stats.bigBlindDesc AS Game
,stats.n ,stats.n
,stats.vpip ,stats.vpip
@ -754,6 +757,7 @@ class FpdbSQLQueries:
,case when hprof2.variance = -999 then '-' ,case when hprof2.variance = -999 then '-'
else to_char(hprof2.variance, '0D00') else to_char(hprof2.variance, '0D00')
end AS Variance end AS Variance
,AvgSeats
FROM FROM
(select gt.base (select gt.base
,gt.category ,gt.category
@ -762,7 +766,7 @@ class FpdbSQLQueries:
,<selectgt.bigBlind> AS bigBlindDesc ,<selectgt.bigBlind> AS bigBlindDesc
,<hcgametypeId> AS gtId ,<hcgametypeId> AS gtId
,sum(HDs) as n ,sum(HDs) as n
,to_char(100.0*sum(street0VPI)/sum(HDs),'90D0') AS vpip ,to_char(100.0*sum(street0VPI)/sum(HDs),'990D0') AS vpip
,to_char(100.0*sum(street0Aggr)/sum(HDs),'90D0') AS pfr ,to_char(100.0*sum(street0Aggr)/sum(HDs),'90D0') AS pfr
,case when sum(street0_3b4bchance) = 0 then '0' ,case when sum(street0_3b4bchance) = 0 then '0'
else to_char(100.0*sum(street0_3b4bdone)/sum(street0_3b4bchance),'90D0') else to_char(100.0*sum(street0_3b4bdone)/sum(street0_3b4bchance),'90D0')
@ -795,11 +799,13 @@ class FpdbSQLQueries:
,to_char((sum(totalProfit/(gt.bigBlind+0.0))) / (sum(HDs)/100.0), '990D00') ,to_char((sum(totalProfit/(gt.bigBlind+0.0))) / (sum(HDs)/100.0), '990D00')
AS BBper100 AS BBper100
,to_char(sum(totalProfit/100.0) / (sum(HDs)+0.0), '990D0000') AS Profitperhand ,to_char(sum(totalProfit/100.0) / (sum(HDs)+0.0), '990D0000') AS Profitperhand
,to_char(avg(activeSeats),'90D0') AS AvgSeats
from Gametypes gt from Gametypes gt
inner join Sites s on s.Id = gt.siteId inner join Sites s on s.Id = gt.siteId
inner join HudCache hc on hc.gameTypeId = gt.Id inner join HudCache hc on hc.gameTypeId = gt.Id
where hc.playerId in <player_test> where hc.playerId in <player_test>
and <gtbigBlind_test> and <gtbigBlind_test>
and hc.activeSeats <seats_test>
group by gt.base group by gt.base
,gt.category ,gt.category
,upper(gt.limitType) ,upper(gt.limitType)
@ -827,7 +833,7 @@ class FpdbSQLQueries:
group by hprof.gtId group by hprof.gtId
) hprof2 ) hprof2
on hprof2.gtId = stats.gtId on hprof2.gtId = stats.gtId
order by stats.base, stats.limittype, stats.bigBlindDesc""" order by stats.base, stats.limittype, stats.bigBlindDesc <orderbyseats>"""
elif(self.dbname == 'SQLite'): elif(self.dbname == 'SQLite'):
self.query['playerStats'] = """ """ self.query['playerStats'] = """ """
@ -836,7 +842,7 @@ class FpdbSQLQueries:
SELECT SELECT
concat(upper(stats.limitType), ' ' concat(upper(stats.limitType), ' '
,concat(upper(substring(stats.category,1,1)),substring(stats.category,2) ), ' ' ,concat(upper(substring(stats.category,1,1)),substring(stats.category,2) ), ' '
,stats.name, ' $' ,stats.name, ' '
,cast(stats.bigBlindDesc as char) ,cast(stats.bigBlindDesc as char)
) AS Game ) AS Game
,case when stats.PlPosition = -2 then 'BB' ,case when stats.PlPosition = -2 then 'BB'
@ -866,6 +872,7 @@ class FpdbSQLQueries:
,case when hprof2.variance = -999 then '-' ,case when hprof2.variance = -999 then '-'
else format(hprof2.variance, 2) else format(hprof2.variance, 2)
end AS Variance end AS Variance
,stats.AvgSeats
FROM FROM
(select /* stats from hudcache */ (select /* stats from hudcache */
gt.base gt.base
@ -916,17 +923,20 @@ class FpdbSQLQueries:
,format((sum(totalProfit/(gt.bigBlind+0.0))) / (sum(HDs)/100.0),2) ,format((sum(totalProfit/(gt.bigBlind+0.0))) / (sum(HDs)/100.0),2)
AS BBper100 AS BBper100
,format( (sum(totalProfit)/100.0) / sum(HDs), 4) AS Profitperhand ,format( (sum(totalProfit)/100.0) / sum(HDs), 4) AS Profitperhand
,format( avg(activeSeats), 1) AS AvgSeats
from Gametypes gt from Gametypes gt
inner join Sites s on s.Id = gt.siteId inner join Sites s on s.Id = gt.siteId
inner join HudCache hc on hc.gameTypeId = gt.Id inner join HudCache hc on hc.gameTypeId = gt.Id
where hc.playerId in <player_test> where hc.playerId in <player_test>
and <gtbigBlind_test> and <gtbigBlind_test>
and hc.activeSeats <seats_test>
group by gt.base group by gt.base
,gt.category ,gt.category
,upper(gt.limitType) ,upper(gt.limitType)
,s.name ,s.name
<groupbygt.bigBlind> <groupbygt.bigBlind>
,gtId ,gtId
<groupbyseats>
,PlPosition ,PlPosition
) stats ) stats
inner join inner join
@ -957,14 +967,15 @@ class FpdbSQLQueries:
) hprof2 ) hprof2
on ( hprof2.gtId = stats.gtId on ( hprof2.gtId = stats.gtId
and hprof2.PlPosition = stats.PlPosition) and hprof2.PlPosition = stats.PlPosition)
order by stats.category, stats.limitType, stats.bigBlindDesc, cast(stats.PlPosition as signed) order by stats.category, stats.limitType, stats.bigBlindDesc
<orderbyseats>, cast(stats.PlPosition as signed)
""" """
elif(self.dbname == 'PostgreSQL'): elif(self.dbname == 'PostgreSQL'):
self.query['playerStatsByPosition'] = """ self.query['playerStatsByPosition'] = """
select /* stats from hudcache */ select /* stats from hudcache */
upper(stats.limitType) || ' ' upper(stats.limitType) || ' '
|| upper(substr(stats.category,1,1)) || substr(stats.category,2) || ' ' || upper(substr(stats.category,1,1)) || substr(stats.category,2) || ' '
|| stats.name || ' $' || stats.name || ' '
|| stats.bigBlindDesc AS Game || stats.bigBlindDesc AS Game
,case when stats.PlPosition = -2 then 'BB' ,case when stats.PlPosition = -2 then 'BB'
when stats.PlPosition = -1 then 'SB' when stats.PlPosition = -1 then 'SB'
@ -993,6 +1004,7 @@ class FpdbSQLQueries:
,case when hprof2.variance = -999 then '-' ,case when hprof2.variance = -999 then '-'
else to_char(hprof2.variance, '0D00') else to_char(hprof2.variance, '0D00')
end AS Variance end AS Variance
,stats.AvgSeats
FROM FROM
(select /* stats from hudcache */ (select /* stats from hudcache */
gt.base gt.base
@ -1010,7 +1022,7 @@ class FpdbSQLQueries:
else 9 else 9
end AS PlPosition end AS PlPosition
,sum(HDs) AS n ,sum(HDs) AS n
,to_char(round(100.0*sum(street0VPI)/sum(HDs)),'90D0') AS vpip ,to_char(round(100.0*sum(street0VPI)/sum(HDs)),'990D0') AS vpip
,to_char(round(100.0*sum(street0Aggr)/sum(HDs)),'90D0') AS pfr ,to_char(round(100.0*sum(street0Aggr)/sum(HDs)),'90D0') AS pfr
,case when sum(street0_3b4bchance) = 0 then '0' ,case when sum(street0_3b4bchance) = 0 then '0'
else to_char(100.0*sum(street0_3b4bdone)/sum(street0_3b4bchance),'90D0') else to_char(100.0*sum(street0_3b4bdone)/sum(street0_3b4bchance),'90D0')
@ -1046,17 +1058,20 @@ class FpdbSQLQueries:
,case when sum(HDs) = 0 then '0' ,case when sum(HDs) = 0 then '0'
else to_char( (sum(totalProfit)/100.0) / sum(HDs), '90D0000') else to_char( (sum(totalProfit)/100.0) / sum(HDs), '90D0000')
end AS Profitperhand end AS Profitperhand
,to_char(avg(activeSeats),'90D0') AS AvgSeats
from Gametypes gt from Gametypes gt
inner join Sites s on (s.Id = gt.siteId) inner join Sites s on (s.Id = gt.siteId)
inner join HudCache hc on (hc.gameTypeId = gt.Id) inner join HudCache hc on (hc.gameTypeId = gt.Id)
where hc.playerId in <player_test> where hc.playerId in <player_test>
and <gtbigBlind_test> and <gtbigBlind_test>
and hc.activeSeats <seats_test>
group by gt.base group by gt.base
,gt.category ,gt.category
,upper(gt.limitType) ,upper(gt.limitType)
,s.name ,s.name
<groupbygt.bigBlind> <groupbygt.bigBlind>
,gtId ,gtId
<groupbyseats>
,PlPosition ,PlPosition
) stats ) stats
inner join inner join
@ -1087,7 +1102,8 @@ class FpdbSQLQueries:
) hprof2 ) hprof2
on ( hprof2.gtId = stats.gtId on ( hprof2.gtId = stats.gtId
and hprof2.PlPosition = stats.PlPosition) and hprof2.PlPosition = stats.PlPosition)
order by stats.category, stats.limitType, stats.bigBlindDesc, cast(stats.PlPosition as smallint) order by stats.category, stats.limitType, stats.bigBlindDesc
<orderbyseats>, cast(stats.PlPosition as smallint)
""" """
elif(self.dbname == 'SQLite'): elif(self.dbname == 'SQLite'):
self.query['playerStatsByPosition'] = """ """ self.query['playerStatsByPosition'] = """ """

View File

@ -72,6 +72,9 @@ class GuiBulkImport():
self.importer.setCallHud(False) self.importer.setCallHud(False)
starttime = time() starttime = time()
(stored, dups, partial, errs, ttime) = self.importer.runImport() (stored, dups, partial, errs, ttime) = self.importer.runImport()
ttime = time() - starttime
if ttime == 0:
ttime = 1
print 'GuiBulkImport.import_dir done: Stored: %d \tDuplicates: %d \tPartial: %d \tErrors: %d in %s seconds - %d/sec'\ print 'GuiBulkImport.import_dir done: Stored: %d \tDuplicates: %d \tPartial: %d \tErrors: %d in %s seconds - %d/sec'\
% (stored, dups, partial, errs, ttime, stored / ttime) % (stored, dups, partial, errs, ttime, stored / ttime)
self.importer.clearFileList() self.importer.clearFileList()

View File

@ -92,6 +92,7 @@ class GuiPlayerStats (threading.Thread):
heroes = self.filters.getHeroes() heroes = self.filters.getHeroes()
siteids = self.filters.getSiteIds() siteids = self.filters.getSiteIds()
limits = self.filters.getLimits() limits = self.filters.getLimits()
seats = self.filters.getSeats()
sitenos = [] sitenos = []
playerids = [] playerids = []
@ -115,11 +116,11 @@ class GuiPlayerStats (threading.Thread):
print "No limits found" print "No limits found"
return return
self.createStatsTable(vbox, playerids, sitenos, limits) self.createStatsTable(vbox, playerids, sitenos, limits, seats)
def createStatsTable(self, vbox, playerids, sitenos, limits): def createStatsTable(self, vbox, playerids, sitenos, limits, seats):
tmp = self.sql.query['playerStats'] tmp = self.sql.query['playerStats']
tmp = self.refineQuery(tmp, playerids, sitenos, limits) tmp = self.refineQuery(tmp, playerids, sitenos, limits, seats)
self.cursor.execute(tmp) self.cursor.execute(tmp)
result = self.cursor.fetchall() result = self.cursor.fetchall()
cols = 18 cols = 18
@ -163,7 +164,7 @@ class GuiPlayerStats (threading.Thread):
self.db.db.commit() self.db.db.commit()
#end def fillStatsFrame(self, vbox): #end def fillStatsFrame(self, vbox):
def refineQuery(self, query, playerids, sitenos, limits): def refineQuery(self, query, playerids, sitenos, limits, seats):
if playerids: if playerids:
nametest = str(tuple(playerids)) nametest = str(tuple(playerids))
nametest = nametest.replace("L", "") nametest = nametest.replace("L", "")
@ -172,6 +173,19 @@ class GuiPlayerStats (threading.Thread):
else: else:
query = query.replace("<player_test>", "1 = 2") query = query.replace("<player_test>", "1 = 2")
if seats:
query = query.replace('<seats_test>', 'between ' + str(seats['from']) + ' and ' + str(seats['to']))
if 'show' in seats and seats['show']:
query = query.replace('<groupbyseats>', ',hc.activeSeats')
query = query.replace('<orderbyseats>', ',stats.AvgSeats')
else:
query = query.replace('<groupbyseats>', '')
query = query.replace('<orderbyseats>', '')
else:
query = query.replace('<seats_test>', 'between 0 and 100')
query = query.replace('<groupbyseats>', '')
query = query.replace('<orderbyseats>', '')
if [x for x in limits if str(x).isdigit()]: if [x for x in limits if str(x).isdigit()]:
blindtest = str(tuple([x for x in limits if str(x).isdigit()])) blindtest = str(tuple([x for x in limits if str(x).isdigit()]))
blindtest = blindtest.replace("L", "") blindtest = blindtest.replace("L", "")
@ -180,7 +194,7 @@ class GuiPlayerStats (threading.Thread):
else: else:
query = query.replace("<gtbigBlind_test>", "gt.bigBlind = -1 ") query = query.replace("<gtbigBlind_test>", "gt.bigBlind = -1 ")
groupLevels = "Separate" not in str(limits) groupLevels = "show" not in str(limits)
if groupLevels: if groupLevels:
if self.db.backend == self.MYSQL_INNODB: if self.db.backend == self.MYSQL_INNODB:
bigblindselect = """concat(trim(leading ' ' from bigblindselect = """concat(trim(leading ' ' from
@ -207,20 +221,23 @@ class GuiPlayerStats (threading.Thread):
then to_char(max(gt.bigBlind)/100.0,'90D00') then to_char(max(gt.bigBlind)/100.0,'90D00')
else to_char(max(gt.bigBlind)/100.0,'999990') else to_char(max(gt.bigBlind)/100.0,'999990')
end) """ end) """
bigblindselect = "cast('' as char)" # avoid odd effects when some posns and/or seats
# are missing from some limits (dunno why cast is
# needed but it says "unknown type" otherwise?!
query = query.replace("<selectgt.bigBlind>", bigblindselect) query = query.replace("<selectgt.bigBlind>", bigblindselect)
query = query.replace("<groupbygt.bigBlind>", "") query = query.replace("<groupbygt.bigBlind>", "")
query = query.replace("<hcgametypeId>", "-1") query = query.replace("<hcgametypeId>", "-1")
query = query.replace("<hgameTypeId>", "-1") query = query.replace("<hgameTypeId>", "-1")
else: else:
if self.db.backend == self.MYSQL_INNODB: if self.db.backend == self.MYSQL_INNODB:
bigblindselect = """trim(leading ' ' from bigblindselect = """concat('$', trim(leading ' ' from
case when gt.bigBlind < 100 case when gt.bigBlind < 100
then format(gt.bigBlind/100.0, 2) then format(gt.bigBlind/100.0, 2)
else format(gt.bigBlind/100.0, 0) else format(gt.bigBlind/100.0, 0)
end end
) """ ) ) """
else: else:
bigblindselect = """trim(leading ' ' from bigblindselect = """'$' || trim(leading ' ' from
case when gt.bigBlind < 100 case when gt.bigBlind < 100
then to_char(gt.bigBlind/100.0,'90D00') then to_char(gt.bigBlind/100.0,'90D00')
else to_char(gt.bigBlind/100.0,'999990') else to_char(gt.bigBlind/100.0,'999990')

View File

@ -51,6 +51,7 @@ class GuiPositionalStats (threading.Thread):
"Games" : False, "Games" : False,
"Limits" : True, "Limits" : True,
"LimitSep" : True, "LimitSep" : True,
"Seats" : True,
"Dates" : False, "Dates" : False,
"Button1" : True, "Button1" : True,
"Button2" : False "Button2" : False
@ -79,12 +80,14 @@ class GuiPositionalStats (threading.Thread):
# To miss columns out remove them from both tuples (the 1st 2 elements should always be included). # To miss columns out remove them from both tuples (the 1st 2 elements should always be included).
# To change the heading just edit the second list element as required # To change the heading just edit the second list element as required
# If the first list element does not match a query column that pair is ignored # If the first list element does not match a query column that pair is ignored
self.posncols = ( "game", "plposition", "vpip", "pfr", "pf3", "steals" self.posncols = ( "game", "avgseats", "plposition", "vpip", "pfr", "pf3", "steals"
, "saw_f", "sawsd", "wtsdwsf", "wmsd", "flafq", "tuafq", "rvafq" , "saw_f", "sawsd", "wtsdwsf", "wmsd", "flafq", "tuafq", "rvafq"
, "pofafq", "net", "bbper100", "profitperhand", "variance", "n" ) , "pofafq", "net", "bbper100", "profitperhand", "variance", "n"
self.posnheads = ( "Game", "Posn", "VPIP", "PFR", "PF3", "Steals" )
self.posnheads = ( "Game", "Seats", "Posn", "VPIP", "PFR", "PF3", "Steals"
, "Saw_F", "SawSD", "WtSDwsF", "W$SD", "FlAFq", "TuAFq", "RvAFq" , "Saw_F", "SawSD", "WtSDwsF", "W$SD", "FlAFq", "TuAFq", "RvAFq"
, "PoFAFq", "Net($)", "BB/100", "$/hand", "Variance", "Hds" ) , "PoFAFq", "Net($)", "BB/100", "$/hand", "Variance", "Hds"
)
self.fillStatsFrame(self.stats_frame) self.fillStatsFrame(self.stats_frame)
statsFrame.add(self.stats_frame) statsFrame.add(self.stats_frame)
@ -112,6 +115,7 @@ class GuiPositionalStats (threading.Thread):
heroes = self.filters.getHeroes() heroes = self.filters.getHeroes()
siteids = self.filters.getSiteIds() siteids = self.filters.getSiteIds()
limits = self.filters.getLimits() limits = self.filters.getLimits()
seats = self.filters.getSeats()
sitenos = [] sitenos = []
playerids = [] playerids = []
@ -135,11 +139,11 @@ class GuiPositionalStats (threading.Thread):
print "No limits found" print "No limits found"
return return
self.createStatsTable(vbox, playerids, sitenos, limits) self.createStatsTable(vbox, playerids, sitenos, limits, seats)
def createStatsTable(self, vbox, playerids, sitenos, limits): def createStatsTable(self, vbox, playerids, sitenos, limits, seats):
tmp = self.sql.query['playerStatsByPosition'] tmp = self.sql.query['playerStatsByPosition']
tmp = self.refineQuery(tmp, playerids, sitenos, limits) tmp = self.refineQuery(tmp, playerids, sitenos, limits, seats)
self.cursor.execute(tmp) self.cursor.execute(tmp)
result = self.cursor.fetchall() result = self.cursor.fetchall()
self.stats_table = gtk.Table(1, 1, False) # gtk table expands as required self.stats_table = gtk.Table(1, 1, False) # gtk table expands as required
@ -158,14 +162,14 @@ class GuiPositionalStats (threading.Thread):
self.stats_table.attach(l, col, col+1, row, row+1, yoptions=gtk.SHRINK) self.stats_table.attach(l, col, col+1, row, row+1, yoptions=gtk.SHRINK)
col +=1 col +=1
last_game = "" last_game,last_seats,sqlrow = "","",0
sqlrow = 0
while sqlrow < rows: while sqlrow < rows:
if(row%2 == 0): if(row%2 == 0):
bgcolor = "white" bgcolor = "white"
else: else:
bgcolor = "lightgrey" bgcolor = "lightgrey"
rowprinted=0 rowprinted=0
avgcol = colnames.index('avgseats')
for col,colname in enumerate(self.posncols): for col,colname in enumerate(self.posncols):
if colname in colnames: if colname in colnames:
sqlcol = colnames.index(colname) sqlcol = colnames.index(colname)
@ -174,7 +178,15 @@ class GuiPositionalStats (threading.Thread):
eb = gtk.EventBox() eb = gtk.EventBox()
eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bgcolor)) eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bgcolor))
# print blank row between levels: # print blank row between levels:
if result[sqlrow][sqlcol] and (sqlrow == 0 or result[sqlrow][0] == last_game): if result[sqlrow][sqlcol]:
if sqlrow == 0:
l = gtk.Label(result[sqlrow][sqlcol])
rowprinted=1
elif result[sqlrow][0] != last_game:
l = gtk.Label(' ')
elif 'show' in seats and seats['show'] and result[sqlrow][avgcol] != last_seats:
l = gtk.Label(' ')
else:
l = gtk.Label(result[sqlrow][sqlcol]) l = gtk.Label(result[sqlrow][sqlcol])
rowprinted=1 rowprinted=1
else: else:
@ -190,13 +202,14 @@ class GuiPositionalStats (threading.Thread):
l.show() l.show()
eb.show() eb.show()
last_game = result[sqlrow][0] last_game = result[sqlrow][0]
last_seats = result[sqlrow][avgcol]
if rowprinted: if rowprinted:
sqlrow = sqlrow+1 sqlrow = sqlrow+1
row = row + 1 row = row + 1
# show totals at bottom # show totals at bottom
tmp = self.sql.query['playerStats'] tmp = self.sql.query['playerStats']
tmp = self.refineQuery(tmp, playerids, sitenos, limits) tmp = self.refineQuery(tmp, playerids, sitenos, limits, seats)
self.cursor.execute(tmp) self.cursor.execute(tmp)
result = self.cursor.fetchall() result = self.cursor.fetchall()
@ -251,7 +264,7 @@ class GuiPositionalStats (threading.Thread):
self.db.db.rollback() self.db.db.rollback()
#end def fillStatsFrame(self, vbox): #end def fillStatsFrame(self, vbox):
def refineQuery(self, query, playerids, sitenos, limits): def refineQuery(self, query, playerids, sitenos, limits, seats):
if playerids: if playerids:
nametest = str(tuple(playerids)) nametest = str(tuple(playerids))
nametest = nametest.replace("L", "") nametest = nametest.replace("L", "")
@ -260,6 +273,19 @@ class GuiPositionalStats (threading.Thread):
else: else:
query = query.replace("<player_test>", "1 = 2") query = query.replace("<player_test>", "1 = 2")
if seats:
query = query.replace('<seats_test>', 'between ' + str(seats['from']) + ' and ' + str(seats['to']))
if 'show' in seats and seats['show']:
query = query.replace('<groupbyseats>', ',hc.activeSeats')
query = query.replace('<orderbyseats>', ',stats.AvgSeats')
else:
query = query.replace('<groupbyseats>', '')
query = query.replace('<orderbyseats>', '')
else:
query = query.replace('<seats_test>', 'between 0 and 100')
query = query.replace('<groupbyseats>', '')
query = query.replace('<orderbyseats>', '')
if [x for x in limits if str(x).isdigit()]: if [x for x in limits if str(x).isdigit()]:
blindtest = str(tuple([x for x in limits if str(x).isdigit()])) blindtest = str(tuple([x for x in limits if str(x).isdigit()]))
blindtest = blindtest.replace("L", "") blindtest = blindtest.replace("L", "")
@ -268,15 +294,16 @@ class GuiPositionalStats (threading.Thread):
else: else:
query = query.replace("<gtbigBlind_test>", "gt.bigBlind = -1 ") query = query.replace("<gtbigBlind_test>", "gt.bigBlind = -1 ")
groupLevels = "Separate" not in str(limits) groupLevels = "show" not in str(limits)
if groupLevels: if groupLevels:
if self.db.backend == self.MYSQL_INNODB: if self.db.backend == self.MYSQL_INNODB:
bigblindselect = """concat(trim(leading ' ' from bigblindselect = """concat('$'
,trim(leading ' ' from
case when min(gt.bigBlind) < 100 case when min(gt.bigBlind) < 100
then format(min(gt.bigBlind)/100.0, 2) then format(min(gt.bigBlind)/100.0, 2)
else format(min(gt.bigBlind)/100.0, 0) else format(min(gt.bigBlind)/100.0, 0)
end) end)
,' - ' ,' - $'
,trim(leading ' ' from ,trim(leading ' ' from
case when max(gt.bigBlind) < 100 case when max(gt.bigBlind) < 100
then format(max(gt.bigBlind)/100.0, 2) then format(max(gt.bigBlind)/100.0, 2)
@ -284,31 +311,35 @@ class GuiPositionalStats (threading.Thread):
end) end)
) """ ) """
else: else:
bigblindselect = """trim(leading ' ' from bigblindselect = """'$' ||
trim(leading ' ' from
case when min(gt.bigBlind) < 100 case when min(gt.bigBlind) < 100
then to_char(min(gt.bigBlind)/100.0,'90D00') then to_char(min(gt.bigBlind)/100.0,'90D00')
else to_char(min(gt.bigBlind)/100.0,'999990') else to_char(min(gt.bigBlind)/100.0,'999990')
end) end)
|| ' - ' || || ' - $' ||
trim(leading ' ' from trim(leading ' ' from
case when max(gt.bigBlind) < 100 case when max(gt.bigBlind) < 100
then to_char(max(gt.bigBlind)/100.0,'90D00') then to_char(max(gt.bigBlind)/100.0,'90D00')
else to_char(max(gt.bigBlind)/100.0,'999990') else to_char(max(gt.bigBlind)/100.0,'999990')
end) """ end) """
bigblindselect = "cast('' as char)" # avoid odd effects when some posns and/or seats
# are missing from some limits (dunno why cast is
# needed but it says "unknown type" otherwise?!
query = query.replace("<selectgt.bigBlind>", bigblindselect) query = query.replace("<selectgt.bigBlind>", bigblindselect)
query = query.replace("<groupbygt.bigBlind>", "") query = query.replace("<groupbygt.bigBlind>", "")
query = query.replace("<hcgametypeId>", "-1") query = query.replace("<hcgametypeId>", "-1")
query = query.replace("<hgameTypeId>", "-1") query = query.replace("<hgameTypeId>", "-1")
else: else:
if self.db.backend == self.MYSQL_INNODB: if self.db.backend == self.MYSQL_INNODB:
bigblindselect = """trim(leading ' ' from bigblindselect = """concat('$', trim(leading ' ' from
case when gt.bigBlind < 100 case when gt.bigBlind < 100
then format(gt.bigBlind/100.0, 2) then format(gt.bigBlind/100.0, 2)
else format(gt.bigBlind/100.0, 0) else format(gt.bigBlind/100.0, 0)
end end
) """ ) )"""
else: else:
bigblindselect = """trim(leading ' ' from bigblindselect = """'$' || trim(leading ' ' from
case when gt.bigBlind < 100 case when gt.bigBlind < 100
then to_char(gt.bigBlind/100.0,'90D00') then to_char(gt.bigBlind/100.0,'90D00')
else to_char(gt.bigBlind/100.0,'999990') else to_char(gt.bigBlind/100.0,'999990')

View File

@ -62,6 +62,8 @@ class fpdb_db:
self.db=MySQLdb.connect(host = host, user = user, passwd = password, db = database, use_unicode=True) self.db=MySQLdb.connect(host = host, user = user, passwd = password, db = database, use_unicode=True)
elif backend==self.PGSQL: elif backend==self.PGSQL:
import psycopg2 import psycopg2
import psycopg2.extensions
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
# If DB connection is made over TCP, then the variables # If DB connection is made over TCP, then the variables
# host, user and password are required # host, user and password are required
print "host=%s user=%s pass=%s." % (host, user, password) print "host=%s user=%s pass=%s." % (host, user, password)

View File

@ -1331,12 +1331,12 @@ def recognisePlayerIDs(cursor, names, site_id):
if len(ids) != len(names): if len(ids) != len(names):
notfound = [n for n in names if n not in ids] # make list of names not in database notfound = [n for n in names if n not in ids] # make list of names not in database
if notfound: # insert them into database if notfound: # insert them into database
cursor.executemany("INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")", [[n] for n in notfound]) cursor.executemany("INSERT INTO Players (name, siteId) VALUES (%s, "+str(site_id)+")", [(n,) for n in notfound])
q2 = "SELECT name,id FROM Players WHERE name=%s" % " OR name=".join(["%s" for n in notfound]) q2 = "SELECT name,id FROM Players WHERE name=%s" % " OR name=".join(["%s" for n in notfound])
cursor.execute(q2, notfound) # get their new ids cursor.execute(q2, notfound) # get their new ids
tmp = dict(cursor.fetchall()) tmp = cursor.fetchall()
for n in tmp: # put them all into the same dict for n,id in tmp: # put them all into the same dict
ids[n] = tmp[n] ids[n] = id
# return them in the SAME ORDER that they came in in the names argument, rather than the order they came out of the DB # return them in the SAME ORDER that they came in in the names argument, rather than the order they came out of the DB
return [ids[n] for n in names] return [ids[n] for n in names]
#end def recognisePlayerIDs #end def recognisePlayerIDs