Merge branch 'master' of git://git.assembla.com/fpdboz
This commit is contained in:
commit
e18a1f2f93
|
@ -427,7 +427,8 @@ class Database:
|
|||
print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||
|
||||
def get_stats_from_hand( self, hand, type # type is "ring" or "tour"
|
||||
, hud_params = {'aggregate_tour':False, 'aggregate_ring':False, 'hud_style':'A', 'agg_bb_mult':100}
|
||||
, hud_params = {'aggregate_tour':False, 'aggregate_ring':False, 'hud_style':'A', 'hud_days':30, 'agg_bb_mult':100
|
||||
,'h_aggregate_tour':False, 'h_aggregate_ring':False, 'h_hud_style':'S', 'h_hud_days':30, 'h_agg_bb_mult':100}
|
||||
, hero_id = -1
|
||||
):
|
||||
aggregate = hud_params['aggregate_tour'] if type == "tour" else hud_params['aggregate_ring']
|
||||
|
|
|
@ -98,34 +98,6 @@ class GuiGraphViewer (threading.Thread):
|
|||
|
||||
self.db.rollback()
|
||||
|
||||
#################################
|
||||
#
|
||||
# self.db.cursor.execute("""select UNIX_TIMESTAMP(handStart) as time, id from Hands ORDER BY time""")
|
||||
# THRESHOLD = 1800
|
||||
# hands = self.db.cursor.fetchall()
|
||||
#
|
||||
# times = map(lambda x:long(x[0]), hands)
|
||||
# handids = map(lambda x:int(x[1]), hands)
|
||||
# print "DEBUG: len(times) %s" %(len(times))
|
||||
# diffs = diff(times)
|
||||
# print "DEBUG: len(diffs) %s" %(len(diffs))
|
||||
# index = nonzero(diff(times) > THRESHOLD)
|
||||
# print "DEBUG: len(index[0]) %s" %(len(index[0]))
|
||||
# print "DEBUG: index %s" %(index)
|
||||
# print "DEBUG: index[0][0] %s" %(index[0][0])
|
||||
#
|
||||
# total = 0
|
||||
#
|
||||
# last_idx = 0
|
||||
# for i in range(len(index[0])):
|
||||
# print "Hands in session %4s: %4s Start: %s End: %s Total: %s" %(i, index[0][i] - last_idx, strftime("%d/%m/%Y %H:%M", localtime(times[last_idx])), strftime("%d/%m/%Y %H:%M", localtime(times[index[0][i]])), times[index[0][i]] - times[last_idx])
|
||||
# total = total + (index[0][i] - last_idx)
|
||||
# last_idx = index[0][i] + 1
|
||||
#
|
||||
# print "Total: ", total
|
||||
#################################
|
||||
|
||||
|
||||
def get_vbox(self):
|
||||
"""returns the vbox of this thread"""
|
||||
return self.mainHBox
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#In the "official" distribution you can find the license in
|
||||
#agpl-3.0.txt in the docs folder of the package.
|
||||
|
||||
import traceback
|
||||
import threading
|
||||
import pygtk
|
||||
pygtk.require('2.0')
|
||||
|
@ -29,7 +30,11 @@ import Database
|
|||
import fpdb_db
|
||||
import Filters
|
||||
|
||||
colalias,colshow,colheading,colxalign,colformat,coltype = 0,1,2,3,4,5
|
||||
ranks = {'x':0, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, 'T':10, 'J':11, 'Q':12, 'K':13, 'A':14}
|
||||
|
||||
class GuiPlayerStats (threading.Thread):
|
||||
|
||||
def __init__(self, config, querylist, mainwin, debug=True):
|
||||
self.debug = debug
|
||||
self.conf = config
|
||||
|
@ -248,26 +253,65 @@ class GuiPlayerStats (threading.Thread):
|
|||
cell.set_property('text', str)
|
||||
cell.set_property('foreground', 'red')
|
||||
else:
|
||||
cell.set_property('foreground', 'green')
|
||||
cell.set_property('foreground', 'darkgreen')
|
||||
|
||||
return
|
||||
|
||||
def sortnums(self, model, iter1, iter2, n):
|
||||
try:
|
||||
ret = 0
|
||||
a = self.liststore.get_value(iter1, n)
|
||||
b = self.liststore.get_value(iter2, n)
|
||||
if 'f' in self.cols_to_show[n][4]:
|
||||
try: a = float(a)
|
||||
except: a = 0.0
|
||||
try: b = float(b)
|
||||
except: b = 0.0
|
||||
if n == 0:
|
||||
a1,a2,a3 = ranks[a[0]], ranks[a[1]], (a+'o')[2]
|
||||
b1,b2,b3 = ranks[b[0]], ranks[b[1]], (b+'o')[2]
|
||||
if a1 > b1 or ( a1 == b1 and (a2 > b2 or (a2 == b2 and a3 > b3) ) ):
|
||||
ret = 1
|
||||
else:
|
||||
ret = -1
|
||||
else:
|
||||
if a < b:
|
||||
ret = -1
|
||||
elif a == b:
|
||||
ret = 0
|
||||
else:
|
||||
ret = 1
|
||||
#print "n =", n, "iter1[n] =", self.liststore.get_value(iter1,n), "iter2[n] =", self.liststore.get_value(iter2,n), "ret =", ret
|
||||
except:
|
||||
err = traceback.extract_tb(sys.exc_info()[2])
|
||||
print "***sortnums error: " + str(sys.exc_info()[1])
|
||||
print "\n".join( [e[0]+':'+str(e[1])+" "+e[2] for e in err] )
|
||||
|
||||
return(ret)
|
||||
|
||||
def sortcols(self, col, n):
|
||||
#This doesn't actually work yet
|
||||
if n == 0:
|
||||
# Card values can stay the same for the moment.
|
||||
return
|
||||
try:
|
||||
#This doesn't actually work yet - clicking heading in top section sorts bottom section :-(
|
||||
if col.get_sort_order() == gtk.SORT_ASCENDING:
|
||||
col.set_sort_order(gtk.SORT_DESCENDING)
|
||||
else:
|
||||
col.set_sort_order(gtk.SORT_ASCENDING)
|
||||
self.liststore.set_sort_column_id(n, col.get_sort_order())
|
||||
self.liststore.set_sort_func(n, self.sortnums, n)
|
||||
for i in xrange(len(self.listcols)):
|
||||
self.listcols[i].set_sort_indicator(False)
|
||||
self.listcols[n].set_sort_indicator(True)
|
||||
# use this listcols[col].set_sort_indicator(True)
|
||||
# to turn indicator off for other cols
|
||||
except:
|
||||
err = traceback.extract_tb(sys.exc_info()[2])
|
||||
print "***sortcols error: " + str(sys.exc_info()[1])
|
||||
print "\n".join( [e[0]+':'+str(e[1])+" "+e[2] for e in err] )
|
||||
|
||||
def addTable(self, vbox, query, flags, playerids, sitenos, limits, type, seats, groups, dates):
|
||||
counter = 0
|
||||
row = 0
|
||||
sqlrow = 0
|
||||
colalias,colshow,colheading,colxalign,colformat,coltype = 0,1,2,3,4,5
|
||||
if not flags: holecards = False
|
||||
else: holecards = flags[0]
|
||||
|
||||
|
@ -278,10 +322,10 @@ class GuiPlayerStats (threading.Thread):
|
|||
colnames = [desc[0].lower() for desc in self.cursor.description]
|
||||
|
||||
# pre-fetch some constant values:
|
||||
cols_to_show = [x for x in self.columns if x[colshow]]
|
||||
self.cols_to_show = [x for x in self.columns if x[colshow]]
|
||||
hgametypeid_idx = colnames.index('hgametypeid')
|
||||
|
||||
self.liststore = gtk.ListStore(*([str] * len(cols_to_show)))
|
||||
self.liststore = gtk.ListStore(*([str] * len(self.cols_to_show)))
|
||||
view = gtk.TreeView(model=self.liststore)
|
||||
view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
|
||||
#vbox.pack_start(view, expand=False, padding=3)
|
||||
|
@ -291,44 +335,45 @@ class GuiPlayerStats (threading.Thread):
|
|||
textcell50.set_property('xalign', 0.5)
|
||||
numcell = gtk.CellRendererText()
|
||||
numcell.set_property('xalign', 1.0)
|
||||
listcols = []
|
||||
idx = 0
|
||||
self.listcols = []
|
||||
|
||||
# Create header row eg column: ("game", True, "Game", 0.0, "%s")
|
||||
for col, column in enumerate(cols_to_show):
|
||||
for col, column in enumerate(self.cols_to_show):
|
||||
if column[colalias] == 'game' and holecards:
|
||||
s = [x for x in self.columns if x[colalias] == 'hand'][0][colheading]
|
||||
else:
|
||||
s = column[colheading]
|
||||
listcols.append(gtk.TreeViewColumn(s))
|
||||
view.append_column(listcols[col])
|
||||
#listcols[col].set_clickable(True)
|
||||
#listcols[col].set_sort_indicator(True)
|
||||
#listcols[col].connect("clicked", self.sortcols, idx)
|
||||
self.listcols.append(gtk.TreeViewColumn(s))
|
||||
view.append_column(self.listcols[col])
|
||||
if column[colformat] == '%s':
|
||||
if column[colxalign] == 0.0:
|
||||
listcols[col].pack_start(textcell, expand=True)
|
||||
listcols[col].add_attribute(textcell, 'text', col)
|
||||
self.listcols[col].pack_start(textcell, expand=True)
|
||||
self.listcols[col].add_attribute(textcell, 'text', col)
|
||||
else:
|
||||
listcols[col].pack_start(textcell50, expand=True)
|
||||
listcols[col].add_attribute(textcell50, 'text', col)
|
||||
listcols[col].set_expand(True)
|
||||
self.listcols[col].pack_start(textcell50, expand=True)
|
||||
self.listcols[col].add_attribute(textcell50, 'text', col)
|
||||
self.listcols[col].set_expand(True)
|
||||
else:
|
||||
listcols[col].pack_start(numcell, expand=True)
|
||||
listcols[col].add_attribute(numcell, 'text', col)
|
||||
listcols[col].set_expand(True)
|
||||
#listcols[col].set_alignment(column[colxalign]) # no effect?
|
||||
self.listcols[col].pack_start(numcell, expand=True)
|
||||
self.listcols[col].add_attribute(numcell, 'text', col)
|
||||
self.listcols[col].set_expand(True)
|
||||
#self.listcols[col].set_alignment(column[colxalign]) # no effect?
|
||||
if holecards:
|
||||
self.listcols[col].set_clickable(True)
|
||||
self.listcols[col].connect("clicked", self.sortcols, col)
|
||||
if col == 0:
|
||||
self.listcols[col].set_sort_order(gtk.SORT_DESCENDING)
|
||||
self.listcols[col].set_sort_indicator(True)
|
||||
if column[coltype] == 'cash':
|
||||
listcols[col].set_cell_data_func(numcell, self.ledger_style_render_func)
|
||||
self.listcols[col].set_cell_data_func(numcell, self.ledger_style_render_func)
|
||||
else:
|
||||
listcols[col].set_cell_data_func(numcell, self.reset_style_render_func)
|
||||
idx = idx+1
|
||||
self.listcols[col].set_cell_data_func(numcell, self.reset_style_render_func)
|
||||
|
||||
rows = len(result) # +1 for title row
|
||||
|
||||
while sqlrow < rows:
|
||||
treerow = []
|
||||
for col,column in enumerate(cols_to_show):
|
||||
for col,column in enumerate(self.cols_to_show):
|
||||
if column[colalias] in colnames:
|
||||
value = result[sqlrow][colnames.index(column[colalias])]
|
||||
if column[colalias] == 'plposition':
|
||||
|
|
|
@ -21,10 +21,17 @@ import pygtk
|
|||
pygtk.require('2.0')
|
||||
import gtk
|
||||
import os
|
||||
import traceback
|
||||
from time import time, strftime, localtime
|
||||
try:
|
||||
import matplotlib
|
||||
matplotlib.use('GTK')
|
||||
from matplotlib.figure import Figure
|
||||
from matplotlib.backends.backend_gtk import FigureCanvasGTK as FigureCanvas
|
||||
from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NavigationToolbar
|
||||
from matplotlib.finance import candlestick2
|
||||
|
||||
from numpy import diff, nonzero, sum, cumsum, max, mina
|
||||
import matplotlib.finance
|
||||
# from matplotlib.dates import DateFormatter, WeekdayLocator, HourLocator, \
|
||||
# DayLocator, MONDAY, timezone
|
||||
|
||||
|
@ -50,6 +57,11 @@ class GuiSessionViewer (threading.Thread):
|
|||
self.PGSQL = 3
|
||||
self.SQLITE = 4
|
||||
|
||||
self.fig = None
|
||||
self.canvas = None
|
||||
self.ax = None
|
||||
self.graphBox = None
|
||||
|
||||
# create new db connection to avoid conflicts with other threads
|
||||
self.db = Database.Database(self.conf, sql=self.sql)
|
||||
self.cursor = self.db.cursor
|
||||
|
@ -67,17 +79,17 @@ class GuiSessionViewer (threading.Thread):
|
|||
filters_display = { "Heroes" : True,
|
||||
"Sites" : True,
|
||||
"Games" : False,
|
||||
"Limits" : True,
|
||||
"LimitSep" : True,
|
||||
"LimitType" : True,
|
||||
"Limits" : False,
|
||||
"LimitSep" : False,
|
||||
"LimitType" : False,
|
||||
"Type" : True,
|
||||
"Seats" : True,
|
||||
"SeatSep" : True,
|
||||
"Seats" : False,
|
||||
"SeatSep" : False,
|
||||
"Dates" : True,
|
||||
"Groups" : True,
|
||||
"GroupsAll" : True,
|
||||
"Groups" : False,
|
||||
"GroupsAll" : False,
|
||||
"Button1" : True,
|
||||
"Button2" : True
|
||||
"Button2" : False
|
||||
}
|
||||
|
||||
self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display)
|
||||
|
@ -182,17 +194,20 @@ class GuiSessionViewer (threading.Thread):
|
|||
print "No limits found"
|
||||
return
|
||||
|
||||
self.createStatsTable(vbox, playerids, sitenos, limits, seats)
|
||||
self.createStatsPane(vbox, playerids, sitenos, limits, seats)
|
||||
|
||||
def createStatsTable(self, vbox, playerids, sitenos, limits, seats):
|
||||
def createStatsPane(self, vbox, playerids, sitenos, limits, seats):
|
||||
starttime = time()
|
||||
|
||||
# Display summary table at top of page
|
||||
# 3rd parameter passes extra flags, currently includes:
|
||||
# holecards - whether to display card breakdown (True/False)
|
||||
flags = [False]
|
||||
self.addTable(vbox, 'playerDetailedStats', flags, playerids, sitenos, limits, seats)
|
||||
(results, opens, closes, highs, lows) = self.generateDatasets(playerids, sitenos, limits, seats)
|
||||
|
||||
|
||||
|
||||
self.graphBox = gtk.VBox(False, 0)
|
||||
self.graphBox.show()
|
||||
self.generateGraph(opens, closes, highs, lows)
|
||||
|
||||
vbox.pack_start(self.graphBox)
|
||||
# Separator
|
||||
sep = gtk.HSeparator()
|
||||
vbox.pack_start(sep, expand=False, padding=3)
|
||||
|
@ -212,92 +227,24 @@ class GuiSessionViewer (threading.Thread):
|
|||
vbox1.show()
|
||||
swin.add_with_viewport(vbox1)
|
||||
|
||||
# Detailed table
|
||||
flags = [True]
|
||||
self.addTable(vbox1, 'playerDetailedStats', flags, playerids, sitenos, limits, seats)
|
||||
self.addTable(vbox1, results)
|
||||
|
||||
self.db.rollback()
|
||||
print "Stats page displayed in %4.2f seconds" % (time() - starttime)
|
||||
#end def fillStatsFrame(self, vbox):
|
||||
|
||||
def generateGraph(self, vbox, data):
|
||||
fig = figure()
|
||||
fig.subplots_adjust(bottom=0.2)
|
||||
ax = fig.add_subplot(111)
|
||||
ax.xaxis.set_major_locator(mondays)
|
||||
ax.xaxis.set_minor_locator(alldays)
|
||||
ax.xaxis.set_major_formatter(weekFormatter)
|
||||
#ax.xaxis.set_minor_formatter(dayFormatter)
|
||||
#plot_day_summary(ax, quotes, ticksize=3)
|
||||
# candlestick(ax, quotes, width=0.6)
|
||||
# candlestick2(ax, opens, closes, highs, lows, width=4, colorup='k', colordown='r', alpha=0.75)
|
||||
# Represent the open, close as a bar line and high low range as a vertical line.
|
||||
# ax : an Axes instance to plot to
|
||||
# width : the bar width in points
|
||||
# colorup : the color of the lines where close >= open
|
||||
# colordown : the color of the lines where close < open
|
||||
# alpha : bar transparency
|
||||
# return value is lineCollection, barCollection
|
||||
ax.xaxis_date()
|
||||
ax.autoscale_view()
|
||||
setp( gca().get_xticklabels(), rotation=45, horizontalalignment='right')
|
||||
|
||||
show()
|
||||
|
||||
|
||||
def addTable(self, vbox, query, flags, playerids, sitenos, limits, seats):
|
||||
row = 0
|
||||
sqlrow = 0
|
||||
colalias,colshow,colheading,colxalign,colformat = 0,1,2,3,4
|
||||
if not flags: holecards = False
|
||||
else: holecards = flags[0]
|
||||
|
||||
# pre-fetch some constant values:
|
||||
cols_to_show = [x for x in self.columns if x[colshow]]
|
||||
|
||||
self.liststore = gtk.ListStore(*([str] * len(cols_to_show)))
|
||||
|
||||
view = gtk.TreeView(model=self.liststore)
|
||||
view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
|
||||
vbox.add(view)
|
||||
textcell = gtk.CellRendererText()
|
||||
textcell50 = gtk.CellRendererText()
|
||||
textcell50.set_property('xalign', 0.5)
|
||||
numcell = gtk.CellRendererText()
|
||||
numcell.set_property('xalign', 1.0)
|
||||
listcols = []
|
||||
|
||||
# Create header row eg column: ("game", True, "Game", 0.0, "%s")
|
||||
for col, column in enumerate(cols_to_show):
|
||||
s = column[colheading]
|
||||
listcols.append(gtk.TreeViewColumn(s))
|
||||
view.append_column(listcols[col])
|
||||
if column[colformat] == '%s':
|
||||
if column[colxalign] == 0.0:
|
||||
listcols[col].pack_start(textcell, expand=True)
|
||||
listcols[col].add_attribute(textcell, 'text', col)
|
||||
else:
|
||||
listcols[col].pack_start(textcell50, expand=True)
|
||||
listcols[col].add_attribute(textcell50, 'text', col)
|
||||
listcols[col].set_expand(True)
|
||||
else:
|
||||
listcols[col].pack_start(numcell, expand=True)
|
||||
listcols[col].add_attribute(numcell, 'text', col)
|
||||
listcols[col].set_expand(True)
|
||||
|
||||
def generateDatasets(self, playerids, sitenos, limits, seats):
|
||||
# Get a list of all handids and their timestampts
|
||||
# FIXME: Will probably want to be able to filter this list eventually
|
||||
# FIXME: Join on handsplayers for Hero to get other useful stuff like total profit?
|
||||
q = """
|
||||
select UNIX_TIMESTAMP(h.handStart) as time, hp.handId, hp.startCash, hp.winnings, hp.totalProfit
|
||||
from HandsPlayers hp
|
||||
inner join Hands h on (h.id = hp.handId)
|
||||
inner join Gametypes gt on (gt.Id = h.gameTypeId)
|
||||
inner join Sites s on (s.Id = gt.siteId)
|
||||
inner join Players p on (p.Id = hp.playerId)
|
||||
where hp.playerId in (2)
|
||||
order by time
|
||||
"""
|
||||
#FIXME: Query still need to filter on blind levels
|
||||
|
||||
q = self.sql.query['sessionStats']
|
||||
start_date, end_date = self.filters.getDates()
|
||||
q = q.replace("<datestest>", " between '" + start_date + "' and '" + end_date + "'")
|
||||
|
||||
nametest = str(tuple(playerids))
|
||||
nametest = nametest.replace("L", "")
|
||||
nametest = nametest.replace(",)",")")
|
||||
q = q.replace("<player_test>", nametest)
|
||||
self.db.cursor.execute(q)
|
||||
THRESHOLD = 1800
|
||||
hands = self.db.cursor.fetchall()
|
||||
|
@ -329,30 +276,121 @@ order by time
|
|||
for i in range(len(index[0])):
|
||||
sid = i # Session id
|
||||
hds = index[0][i] - last_idx # Number of hands in session
|
||||
if hds > 0:
|
||||
stime = strftime("%d/%m/%Y %H:%M", localtime(times[last_idx])) # Formatted start time
|
||||
etime = strftime("%d/%m/%Y %H:%M", localtime(times[index[0][i]])) # Formatted end time
|
||||
hph = (times[index[0][i]] - times[last_idx])/60 # Hands per hour
|
||||
won = sum(winnings[last_idx:index[0][i]])/100.0
|
||||
hwm = max(cum_sum[last_idx:index[0][i]])
|
||||
lwm = min(cum_sum[last_idx:index[0][i]])
|
||||
print "DEBUG: range: (%s, %s) - (min, max): (%s, %s)" %(last_idx, index[0][i], hwm, lwm)
|
||||
#print "DEBUG: range: (%s, %s) - (min, max): (%s, %s)" %(last_idx, index[0][i], hwm, lwm)
|
||||
|
||||
results.append([sid, hds, stime, etime, hph, won])
|
||||
opens.append((sum(winnings[:last_idx]))/100)
|
||||
closes.append((sum(winnings[:index[0][i]]))/100)
|
||||
highs.append(hwm)
|
||||
lows.append(lwm)
|
||||
print "Hands in session %4s: %4s Start: %s End: %s HPH: %s Profit: %s" %(sid, hds, stime, etime, hph, won)
|
||||
#print "Hands in session %4s: %4s Start: %s End: %s HPH: %s Profit: %s" %(sid, hds, stime, etime, hph, won)
|
||||
total = total + (index[0][i] - last_idx)
|
||||
last_idx = index[0][i] + 1
|
||||
|
||||
return (results, opens, closes, highs, lows)
|
||||
|
||||
def clearGraphData(self):
|
||||
|
||||
try:
|
||||
try:
|
||||
if self.canvas:
|
||||
self.graphBox.remove(self.canvas)
|
||||
except:
|
||||
pass
|
||||
|
||||
if self.fig != None:
|
||||
self.fig.clear()
|
||||
self.fig = Figure(figsize=(5,4), dpi=100)
|
||||
if self.canvas is not None:
|
||||
self.canvas.destroy()
|
||||
|
||||
self.canvas = FigureCanvas(self.fig) # a gtk.DrawingArea
|
||||
except:
|
||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||
print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||
raise
|
||||
|
||||
|
||||
def generateGraph(self, opens, closes, highs, lows):
|
||||
self.clearGraphData()
|
||||
|
||||
#FIXME: Weird - first data entry is crashing this for me
|
||||
opens = opens[1:]
|
||||
closes = closes[1:]
|
||||
highs = highs[1:]
|
||||
lows = lows[1:]
|
||||
# print "DEBUG:"
|
||||
# print "highs = %s" % highs
|
||||
# print "lows = %s" % lows
|
||||
# print "opens = %s" % opens
|
||||
# print "closes = %s" % closes
|
||||
# print "len(highs): %s == len(lows): %s" %(len(highs), len(lows))
|
||||
# print "len(opens): %s == len(closes): %s" %(len(opens), len(closes))
|
||||
#
|
||||
# for i in range(len(highs)):
|
||||
# print "DEBUG: (%s, %s, %s, %s)" %(lows[i], opens[i], closes[i], highs[i])
|
||||
# print "DEBUG: diffs h/l: %s o/c: %s" %(lows[i] - highs[i], opens[i] - closes[i])
|
||||
|
||||
self.ax = self.fig.add_subplot(111)
|
||||
|
||||
self.ax.set_title("Session candlestick graph")
|
||||
|
||||
#Set axis labels and grid overlay properites
|
||||
self.ax.set_xlabel("Sessions", fontsize = 12)
|
||||
self.ax.set_ylabel("$", fontsize = 12)
|
||||
self.ax.grid(color='g', linestyle=':', linewidth=0.2)
|
||||
|
||||
candlestick2(self.ax, opens, closes, highs, lows, width=0.50, colordown='r', colorup='g', alpha=1.00)
|
||||
self.graphBox.add(self.canvas)
|
||||
self.canvas.show()
|
||||
self.canvas.draw()
|
||||
|
||||
def addTable(self, vbox, results):
|
||||
row = 0
|
||||
sqlrow = 0
|
||||
colalias,colshow,colheading,colxalign,colformat = 0,1,2,3,4
|
||||
|
||||
# pre-fetch some constant values:
|
||||
cols_to_show = [x for x in self.columns if x[colshow]]
|
||||
|
||||
self.liststore = gtk.ListStore(*([str] * len(cols_to_show)))
|
||||
for row in results:
|
||||
iter = self.liststore.append(row)
|
||||
|
||||
print "DEBUG: highs = %s" % highs
|
||||
print "DEBUG: lows = %s" % lows
|
||||
print "DEBUG: opens = %s" % opens
|
||||
print "DEBUG: closes = %s" % closes
|
||||
view = gtk.TreeView(model=self.liststore)
|
||||
view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
|
||||
vbox.add(view)
|
||||
textcell = gtk.CellRendererText()
|
||||
textcell50 = gtk.CellRendererText()
|
||||
textcell50.set_property('xalign', 0.5)
|
||||
numcell = gtk.CellRendererText()
|
||||
numcell.set_property('xalign', 1.0)
|
||||
listcols = []
|
||||
|
||||
# Create header row eg column: ("game", True, "Game", 0.0, "%s")
|
||||
for col, column in enumerate(cols_to_show):
|
||||
s = column[colheading]
|
||||
listcols.append(gtk.TreeViewColumn(s))
|
||||
view.append_column(listcols[col])
|
||||
if column[colformat] == '%s':
|
||||
if column[colxalign] == 0.0:
|
||||
listcols[col].pack_start(textcell, expand=True)
|
||||
listcols[col].add_attribute(textcell, 'text', col)
|
||||
else:
|
||||
listcols[col].pack_start(textcell50, expand=True)
|
||||
listcols[col].add_attribute(textcell50, 'text', col)
|
||||
listcols[col].set_expand(True)
|
||||
else:
|
||||
listcols[col].pack_start(numcell, expand=True)
|
||||
listcols[col].add_attribute(numcell, 'text', col)
|
||||
listcols[col].set_expand(True)
|
||||
|
||||
vbox.show_all()
|
||||
|
||||
|
|
|
@ -116,11 +116,7 @@ class HUD_main(object):
|
|||
# called by an event in the HUD, to kill this specific HUD
|
||||
if table in self.hud_dict:
|
||||
self.hud_dict[table].kill()
|
||||
try:
|
||||
# throws exception in windows sometimes (when closing using main_window menu?)
|
||||
self.hud_dict[table].main_window.destroy()
|
||||
except:
|
||||
pass
|
||||
self.vb.remove(self.hud_dict[table].tablehudlabel)
|
||||
del(self.hud_dict[table])
|
||||
self.main_window.resize(1,1)
|
||||
|
@ -131,7 +127,7 @@ class HUD_main(object):
|
|||
def idle_func():
|
||||
|
||||
gtk.gdk.threads_enter()
|
||||
try:
|
||||
try: # TODO: seriously need to decrease the scope of this block.. what are we expecting to error?
|
||||
newlabel = gtk.Label("%s - %s" % (table.site, table_name))
|
||||
self.vb.add(newlabel)
|
||||
newlabel.show()
|
||||
|
@ -174,12 +170,13 @@ class HUD_main(object):
|
|||
# function idle_func() to be run by the gui thread, at its leisure.
|
||||
def idle_func():
|
||||
gtk.gdk.threads_enter()
|
||||
try:
|
||||
# try:
|
||||
self.hud_dict[table_name].update(new_hand_id, config)
|
||||
[aw.update_gui(new_hand_id) for aw in self.hud_dict[table_name].aux_windows]
|
||||
return False
|
||||
finally:
|
||||
# finally:
|
||||
gtk.gdk.threads_leave()
|
||||
return False
|
||||
|
||||
gobject.idle_add(idle_func)
|
||||
|
||||
def read_stdin(self): # This is the thread function
|
||||
|
|
|
@ -63,7 +63,12 @@ class Aux_Window(object):
|
|||
card_images = 53 * [0]
|
||||
suits = ('s', 'h', 'd', 'c')
|
||||
ranks = (14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2)
|
||||
pb = gtk.gdk.pixbuf_new_from_file(self.config.execution_path(self.params['deck']))
|
||||
deckimg = self.params['deck']
|
||||
try:
|
||||
pb = gtk.gdk.pixbuf_new_from_file(self.config.execution_path(deckimg))
|
||||
except:
|
||||
stockpath = '/usr/share/python-fpdb/' + deckimg
|
||||
pb = gtk.gdk.pixbuf_new_from_file(stockpath)
|
||||
|
||||
for j in range(0, 13):
|
||||
for i in range(0, 4):
|
||||
|
|
|
@ -2475,6 +2475,33 @@ class Sql:
|
|||
GROUP BY h.handStart, hp.handId, hp.totalProfit
|
||||
ORDER BY h.handStart"""
|
||||
|
||||
####################################
|
||||
# Session stats query
|
||||
####################################
|
||||
if db_server == 'mysql':
|
||||
self.query['sessionStats'] = """
|
||||
SELECT UNIX_TIMESTAMP(h.handStart) as time, hp.handId, hp.startCash, hp.winnings, hp.totalProfit
|
||||
FROM HandsPlayers hp
|
||||
INNER JOIN Hands h on (h.id = hp.handId)
|
||||
INNER JOIN Gametypes gt on (gt.Id = h.gameTypeId)
|
||||
INNER JOIN Sites s on (s.Id = gt.siteId)
|
||||
INNER JOIN Players p on (p.Id = hp.playerId)
|
||||
WHERE hp.playerId in <player_test>
|
||||
AND date_format(h.handStart, '%Y-%m-%d') <datestest>
|
||||
ORDER by time"""
|
||||
elif db_server == 'postgresql':
|
||||
self.query['sessionStats'] = """
|
||||
SELECT EXTRACT(epoch from h.handStart) as time, hp.handId, hp.startCash, hp.winnings, hp.totalProfit
|
||||
FROM HandsPlayers hp
|
||||
INNER JOIN Hands h on (h.id = hp.handId)
|
||||
INNER JOIN Gametypes gt on (gt.Id = h.gameTypeId)
|
||||
INNER JOIN Sites s on (s.Id = gt.siteId)
|
||||
INNER JOIN Players p on (p.Id = hp.playerId)
|
||||
WHERE hp.playerId in <player_test>
|
||||
AND h.handStart <datestest>
|
||||
ORDER by time"""
|
||||
elif db_server == 'sqlite':
|
||||
self.query['sessionStats'] = """ """
|
||||
|
||||
####################################
|
||||
# Queries to rebuild/modify hudcache
|
||||
|
|
|
@ -657,17 +657,15 @@ def ffreq4(stat_dict, player):
|
|||
|
||||
if __name__== "__main__":
|
||||
c = Configuration.Config()
|
||||
db_connection = Database.Database(c, 'fpdb', 'holdem')
|
||||
db_connection = Database.Database(c)
|
||||
h = db_connection.get_last_hand()
|
||||
stat_dict = db_connection.get_stats_from_hand(h)
|
||||
stat_dict = db_connection.get_stats_from_hand(h, "ring")
|
||||
|
||||
for player in stat_dict.keys():
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'vpip')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'vpip_0')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'pfr')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'pfr_0')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'wtsd')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'profit100_0')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'profit100')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'saw_f')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'n')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'fold_f')
|
||||
|
@ -675,14 +673,13 @@ if __name__== "__main__":
|
|||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'steal')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'f_SB_steal')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'f_BB_steal')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'three_B_0')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'three_B')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'WMsF')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq1')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq2')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq3')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq4')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_123')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'a_freq_123_0')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'cb1')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'cb2')
|
||||
print "player = ", player, do_stat(stat_dict, player = player, stat = 'cb3')
|
||||
|
@ -694,13 +691,15 @@ if __name__== "__main__":
|
|||
print "\n"
|
||||
|
||||
print "\n\nLegal stats:"
|
||||
print "(add _0 to name to display with 0 decimal places, _1 to display with 1, etc)\n"
|
||||
for attr in dir():
|
||||
if attr.startswith('__'): continue
|
||||
if attr in ("Configuration", "Database", "GInitiallyUnowned", "gtk", "pygtk",
|
||||
"player", "c", "db_connection", "do_stat", "do_tip", "stat_dict",
|
||||
"h"): continue
|
||||
"h", "re", "re_Percent", "re_Places"): continue
|
||||
print "%-14s %s" % (attr, eval("%s.__doc__" % (attr)))
|
||||
# print " <pu_stat pu_stat_name = \"%s\"> </pu_stat>" % (attr)
|
||||
print
|
||||
|
||||
db_connection.close_connection
|
||||
|
||||
|
|
|
@ -42,6 +42,10 @@ else:
|
|||
pass
|
||||
#print "debug - not changing path"
|
||||
|
||||
if os.name == 'nt':
|
||||
import win32api
|
||||
import win32con
|
||||
|
||||
print "Python " + sys.version[0:3] + '...\n'
|
||||
|
||||
import traceback
|
||||
|
@ -78,7 +82,7 @@ import FpdbSQLQueries
|
|||
import Configuration
|
||||
from Exceptions import *
|
||||
|
||||
VERSION = "0.11"
|
||||
VERSION = "0.12"
|
||||
|
||||
class fpdb:
|
||||
def tab_clicked(self, widget, tab_name):
|
||||
|
@ -618,8 +622,58 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
|||
|
||||
self.window.show()
|
||||
self.load_profile()
|
||||
|
||||
self.statusIcon = gtk.StatusIcon()
|
||||
self.statusIcon.set_from_stock(gtk.STOCK_HOME)
|
||||
self.statusIcon.set_tooltip("Free Poker Database")
|
||||
self.statusIcon.connect('activate', self.statusicon_activate)
|
||||
self.statusMenu = gtk.Menu()
|
||||
menuItem = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
|
||||
menuItem.connect('activate', self.dia_about)
|
||||
self.statusMenu.append(menuItem)
|
||||
menuItem = gtk.ImageMenuItem(gtk.STOCK_QUIT)
|
||||
menuItem.connect('activate', self.quit)
|
||||
self.statusMenu.append(menuItem)
|
||||
self.statusIcon.connect('popup-menu', self.statusicon_menu, self.statusMenu)
|
||||
self.statusIcon.set_visible(True)
|
||||
|
||||
self.window.connect('window-state-event', self.window_state_event_cb)
|
||||
sys.stderr.write("fpdb starting ...")
|
||||
|
||||
def window_state_event_cb(self, window, event):
|
||||
print "window_state_event", event
|
||||
if event.changed_mask & gtk.gdk.WINDOW_STATE_ICONIFIED:
|
||||
# -20 = GWL_EXSTYLE can't find it in the pywin32 libs
|
||||
#bits = win32api.GetWindowLong(self.window.window.handle, -20)
|
||||
#bits = bits ^ (win32con.WS_EX_TOOLWINDOW | win32con.WS_EX_APPWINDOW)
|
||||
|
||||
#win32api.SetWindowLong(self.window.window.handle, -20, bits)
|
||||
|
||||
if event.new_window_state & gtk.gdk.WINDOW_STATE_ICONIFIED:
|
||||
self.window.hide()
|
||||
self.window.set_skip_taskbar_hint(True)
|
||||
self.window.set_skip_pager_hint(True)
|
||||
else:
|
||||
self.window.set_skip_taskbar_hint(False)
|
||||
self.window.set_skip_pager_hint(False)
|
||||
# Tell GTK not to propagate this signal any further
|
||||
return True
|
||||
|
||||
def statusicon_menu(self, widget, button, time, data = None):
|
||||
# we don't need to pass data here, since we do keep track of most all
|
||||
# our variables .. the example code that i looked at for this
|
||||
# didn't use any long scope variables.. which might be an alright
|
||||
# idea too sometime
|
||||
if button == 3:
|
||||
if data:
|
||||
data.show_all()
|
||||
data.popup(None, None, None, 3, time)
|
||||
pass
|
||||
|
||||
def statusicon_activate(self, widget, data = None):
|
||||
self.window.show()
|
||||
self.window.present()
|
||||
|
||||
def warning_box(self, str, diatitle="FPDB WARNING"):
|
||||
diaWarning = gtk.Dialog(title=diatitle, parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user