Merge branch 'master' of git://git.assembla.com/fpdboz

This commit is contained in:
grindi 2009-10-25 14:23:08 +03:00
commit aff69287ff
14 changed files with 309 additions and 173 deletions

9
files/fpdb.desktop Normal file
View File

@ -0,0 +1,9 @@
[Desktop Entry]
Name=Free Poker Database
Comment=Online Poker Tracker + HUD
Exec=/usr/bin/fpdb
Icon=fpdb-icon.png
Terminal=true
Type=Application
Categories=Utility

BIN
gfx/fpdb-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
gfx/fpdb-icon2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
gfx/magnified_cards.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

View File

@ -1,3 +1,9 @@
free-poker-tools (0.11.3+git20091023) unstable; urgency=low
* Snapshot release
-- Mika Bostrom <bostik+fpdb@bostik.iki.fi> Wed, 21 Oct 2009 16:47:12 +0300
free-poker-tools (0.10.99) unstable; urgency=low free-poker-tools (0.10.99) unstable; urgency=low
* Initial packaging release. * Initial packaging release.

View File

@ -1 +1 @@
/usr/share/python-support/python-fpdb/fpdb/fpdb.py /usr/bin/fpdb /usr/share/pyshared/fpdb/fpdb.py /usr/bin/fpdb

View File

@ -35,7 +35,13 @@ import xml.dom.minidom
from xml.dom.minidom import Node from xml.dom.minidom import Node
import logging, logging.config import logging, logging.config
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf")) import ConfigParser
try: # local path
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf"))
except ConfigParser.NoSectionError: # debian package path
logging.config.fileConfig('/usr/share/python-fpdb/logging.conf')
log = logging.getLogger("config") log = logging.getLogger("config")
log.debug("config logger initialised") log.debug("config logger initialised")

View File

@ -46,7 +46,13 @@ import Tourney
from Exceptions import * from Exceptions import *
import logging, logging.config import logging, logging.config
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf")) import ConfigParser
try: # local path
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf"))
except ConfigParser.NoSectionError: # debian package path
logging.config.fileConfig('/usr/share/python-fpdb/logging.conf')
log = logging.getLogger('db') log = logging.getLogger('db')

View File

@ -36,6 +36,8 @@ class GuiPlayerStats (threading.Thread):
self.main_window = mainwin self.main_window = mainwin
self.sql = querylist self.sql = querylist
self.liststore = None
self.MYSQL_INNODB = 2 self.MYSQL_INNODB = 2
self.PGSQL = 3 self.PGSQL = 3
self.SQLITE = 4 self.SQLITE = 4
@ -79,30 +81,30 @@ class GuiPlayerStats (threading.Thread):
# ToDo: store in config # ToDo: store in config
# ToDo: create popup to adjust column config # ToDo: create popup to adjust column config
# columns to display, keys match column name returned by sql, values in tuple are: # columns to display, keys match column name returned by sql, values in tuple are:
# is column displayed, column heading, xalignment, formatting # is column displayed, column heading, xalignment, formatting, celltype
self.columns = [ ["game", True, "Game", 0.0, "%s"] self.columns = [ ["game", True, "Game", 0.0, "%s", "str"]
, ["hand", False, "Hand", 0.0, "%s"] # true not allowed for this line , ["hand", False, "Hand", 0.0, "%s", "str"] # true not allowed for this line
, ["plposition", False, "Posn", 1.0, "%s"] # true not allowed for this line (set in code) , ["plposition", False, "Posn", 1.0, "%s", "str"] # true not allowed for this line (set in code)
, ["pname", False, "Name", 0.0, "%s"] # true not allowed for this line (set in code) , ["pname", False, "Name", 0.0, "%s", "str"] # true not allowed for this line (set in code)
, ["n", True, "Hds", 1.0, "%d"] , ["n", True, "Hds", 1.0, "%d", "str"]
, ["avgseats", False, "Seats", 1.0, "%3.1f"] , ["avgseats", False, "Seats", 1.0, "%3.1f", "str"]
, ["vpip", True, "VPIP", 1.0, "%3.1f"] , ["vpip", True, "VPIP", 1.0, "%3.1f", "str"]
, ["pfr", True, "PFR", 1.0, "%3.1f"] , ["pfr", True, "PFR", 1.0, "%3.1f", "str"]
, ["pf3", True, "PF3", 1.0, "%3.1f"] , ["pf3", True, "PF3", 1.0, "%3.1f", "str"]
, ["steals", True, "Steals", 1.0, "%3.1f"] , ["steals", True, "Steals", 1.0, "%3.1f", "str"]
, ["saw_f", True, "Saw_F", 1.0, "%3.1f"] , ["saw_f", True, "Saw_F", 1.0, "%3.1f", "str"]
, ["sawsd", True, "SawSD", 1.0, "%3.1f"] , ["sawsd", True, "SawSD", 1.0, "%3.1f", "str"]
, ["wtsdwsf", True, "WtSDwsF", 1.0, "%3.1f"] , ["wtsdwsf", True, "WtSDwsF", 1.0, "%3.1f", "str"]
, ["wmsd", True, "W$SD", 1.0, "%3.1f"] , ["wmsd", True, "W$SD", 1.0, "%3.1f", "str"]
, ["flafq", True, "FlAFq", 1.0, "%3.1f"] , ["flafq", True, "FlAFq", 1.0, "%3.1f", "str"]
, ["tuafq", True, "TuAFq", 1.0, "%3.1f"] , ["tuafq", True, "TuAFq", 1.0, "%3.1f", "str"]
, ["rvafq", True, "RvAFq", 1.0, "%3.1f"] , ["rvafq", True, "RvAFq", 1.0, "%3.1f", "str"]
, ["pofafq", False, "PoFAFq", 1.0, "%3.1f"] , ["pofafq", False, "PoFAFq", 1.0, "%3.1f", "str"]
, ["net", True, "Net($)", 1.0, "%6.2f"] , ["net", True, "Net($)", 1.0, "%6.2f", "cash"]
, ["bbper100", True, "bb/100", 1.0, "%4.2f"] , ["bbper100", True, "bb/100", 1.0, "%4.2f", "str"]
, ["rake", True, "Rake($)", 1.0, "%6.2f"] , ["rake", True, "Rake($)", 1.0, "%6.2f", "cash"]
, ["bb100xr", True, "bbxr/100", 1.0, "%4.2f"] , ["bb100xr", True, "bbxr/100", 1.0, "%4.2f", "str"]
, ["variance", True, "Variance", 1.0, "%5.2f"] , ["variance", True, "Variance", 1.0, "%5.2f", "str"]
] ]
# Detail filters: This holds the data used in the popup window, extra values are # Detail filters: This holds the data used in the popup window, extra values are
@ -235,10 +237,37 @@ class GuiPlayerStats (threading.Thread):
print "Stats page displayed in %4.2f seconds" % (time() - starttime) print "Stats page displayed in %4.2f seconds" % (time() - starttime)
#end def fillStatsFrame(self, vbox): #end def fillStatsFrame(self, vbox):
def reset_style_render_func(self, treeviewcolumn, cell, model, iter):
cell.set_property('foreground', 'black')
def ledger_style_render_func(self, tvcol, cell, model, iter):
str = cell.get_property('text')
if '-' in str:
str = str.replace("-", "")
str = "(%s)" %(str)
cell.set_property('text', str)
cell.set_property('foreground', 'red')
else:
cell.set_property('foreground', 'green')
return
def sortcols(self, col, n):
#This doesn't actually work yet
if n == 0:
# Card values can stay the same for the moment.
return
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())
def addTable(self, vbox, query, flags, playerids, sitenos, limits, type, seats, groups, dates): def addTable(self, vbox, query, flags, playerids, sitenos, limits, type, seats, groups, dates):
counter = 0
row = 0 row = 0
sqlrow = 0 sqlrow = 0
colalias,colshow,colheading,colxalign,colformat = 0,1,2,3,4 colalias,colshow,colheading,colxalign,colformat,coltype = 0,1,2,3,4,5
if not flags: holecards = False if not flags: holecards = False
else: holecards = flags[0] else: holecards = flags[0]
@ -252,8 +281,8 @@ class GuiPlayerStats (threading.Thread):
cols_to_show = [x for x in self.columns if x[colshow]] cols_to_show = [x for x in self.columns if x[colshow]]
hgametypeid_idx = colnames.index('hgametypeid') hgametypeid_idx = colnames.index('hgametypeid')
liststore = gtk.ListStore(*([str] * len(cols_to_show))) self.liststore = gtk.ListStore(*([str] * len(cols_to_show)))
view = gtk.TreeView(model=liststore) view = gtk.TreeView(model=self.liststore)
view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH) view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
#vbox.pack_start(view, expand=False, padding=3) #vbox.pack_start(view, expand=False, padding=3)
vbox.add(view) vbox.add(view)
@ -263,6 +292,7 @@ class GuiPlayerStats (threading.Thread):
numcell = gtk.CellRendererText() numcell = gtk.CellRendererText()
numcell.set_property('xalign', 1.0) numcell.set_property('xalign', 1.0)
listcols = [] listcols = []
idx = 0
# Create header row eg column: ("game", True, "Game", 0.0, "%s") # Create header row eg column: ("game", True, "Game", 0.0, "%s")
for col, column in enumerate(cols_to_show): for col, column in enumerate(cols_to_show):
@ -272,6 +302,9 @@ class GuiPlayerStats (threading.Thread):
s = column[colheading] s = column[colheading]
listcols.append(gtk.TreeViewColumn(s)) listcols.append(gtk.TreeViewColumn(s))
view.append_column(listcols[col]) view.append_column(listcols[col])
#listcols[col].set_clickable(True)
#listcols[col].set_sort_indicator(True)
#listcols[col].connect("clicked", self.sortcols, idx)
if column[colformat] == '%s': if column[colformat] == '%s':
if column[colxalign] == 0.0: if column[colxalign] == 0.0:
listcols[col].pack_start(textcell, expand=True) listcols[col].pack_start(textcell, expand=True)
@ -285,6 +318,11 @@ class GuiPlayerStats (threading.Thread):
listcols[col].add_attribute(numcell, 'text', col) listcols[col].add_attribute(numcell, 'text', col)
listcols[col].set_expand(True) listcols[col].set_expand(True)
#listcols[col].set_alignment(column[colxalign]) # no effect? #listcols[col].set_alignment(column[colxalign]) # no effect?
if column[coltype] == 'cash':
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
rows = len(result) # +1 for title row rows = len(result) # +1 for title row
@ -325,7 +363,7 @@ class GuiPlayerStats (threading.Thread):
treerow.append(column[colformat] % value) treerow.append(column[colformat] % value)
else: else:
treerow.append(' ') treerow.append(' ')
iter = liststore.append(treerow) iter = self.liststore.append(treerow)
sqlrow += 1 sqlrow += 1
row += 1 row += 1
vbox.show_all() vbox.show_all()

312
pyfpdb/GuiSessionViewer.py Normal file → Executable file
View File

@ -15,6 +15,7 @@
#In the "official" distribution you can find the license in #In the "official" distribution you can find the license in
#agpl-3.0.txt in the docs folder of the package. #agpl-3.0.txt in the docs folder of the package.
import sys
import threading import threading
import pygtk import pygtk
pygtk.require('2.0') pygtk.require('2.0')
@ -22,7 +23,11 @@ import gtk
import os import os
from time import time, strftime, localtime from time import time, strftime, localtime
try: try:
from numpy import diff, nonzero from numpy import diff, nonzero, sum, cumsum, max, mina
import matplotlib.finance
# from matplotlib.dates import DateFormatter, WeekdayLocator, HourLocator, \
# DayLocator, MONDAY, timezone
except: except:
print """Failed to load numpy in Session Viewer""" print """Failed to load numpy in Session Viewer"""
print """This is of no consequence as the module currently doesn't do anything.""" print """This is of no consequence as the module currently doesn't do anything."""
@ -34,10 +39,13 @@ import Filters
import FpdbSQLQueries import FpdbSQLQueries
class GuiSessionViewer (threading.Thread): class GuiSessionViewer (threading.Thread):
def __init__(self, config, querylist, debug=True): def __init__(self, config, querylist, mainwin, debug=True):
self.debug = debug self.debug = debug
self.conf = config self.conf = config
self.sql = querylist self.sql = querylist
self.liststore = None
self.MYSQL_INNODB = 2 self.MYSQL_INNODB = 2
self.PGSQL = 3 self.PGSQL = 3
self.SQLITE = 4 self.SQLITE = 4
@ -56,55 +64,63 @@ class GuiSessionViewer (threading.Thread):
self.filterText = {'handhead':'Hand Breakdown for all levels listed above' self.filterText = {'handhead':'Hand Breakdown for all levels listed above'
} }
filters_display = { "Heroes" : True, filters_display = { "Heroes" : True,
"Sites" : True, "Sites" : True,
"Games" : False, "Games" : False,
"Limits" : True, "Limits" : True,
"LimitSep" : True, "LimitSep" : True,
"Seats" : True, "LimitType" : True,
"SeatSep" : True, "Type" : True,
"Dates" : False, "Seats" : True,
"Groups" : True, "SeatSep" : True,
"Button1" : True, "Dates" : True,
"Button2" : True "Groups" : True,
"GroupsAll" : True,
"Button1" : True,
"Button2" : True
} }
self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display) self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display)
self.filters.registerButton2Name("_Refresh") self.filters.registerButton1Name("_Refresh")
self.filters.registerButton2Callback(self.refreshStats) self.filters.registerButton1Callback(self.refreshStats)
# ToDo: store in config # ToDo: store in config
# ToDo: create popup to adjust column config # ToDo: create popup to adjust column config
# columns to display, keys match column name returned by sql, values in tuple are: # columns to display, keys match column name returned by sql, values in tuple are:
# is column displayed, column heading, xalignment, formatting # is column displayed, column heading, xalignment, formatting
self.columns = [ ("game", True, "Game", 0.0, "%s") self.columns = [ ("sid", True, "SID", 0.0, "%s")
, ("hand", False, "Hand", 0.0, "%s") # true not allowed for this line , ("hand", False, "Hand", 0.0, "%s") # true not allowed for this line
, ("n", True, "Hds", 1.0, "%d") , ("n", True, "Hds", 1.0, "%d")
, ("avgseats", True, "Seats", 1.0, "%3.1f") , ("start", True, "Start", 1.0, "%d")
, ("vpip", True, "VPIP", 1.0, "%3.1f") , ("end", True, "End", 1.0, "%d")
, ("pfr", True, "PFR", 1.0, "%3.1f") , ("hph", True, "Hands/h", 1.0, "%d")
, ("pf3", True, "PF3", 1.0, "%3.1f") , ("profit", True, "Profit", 1.0, "%s")
, ("steals", True, "Steals", 1.0, "%3.1f") #, ("avgseats", True, "Seats", 1.0, "%3.1f")
, ("saw_f", True, "Saw_F", 1.0, "%3.1f") #, ("vpip", True, "VPIP", 1.0, "%3.1f")
, ("sawsd", True, "SawSD", 1.0, "%3.1f") #, ("pfr", True, "PFR", 1.0, "%3.1f")
, ("wtsdwsf", True, "WtSDwsF", 1.0, "%3.1f") #, ("pf3", True, "PF3", 1.0, "%3.1f")
, ("wmsd", True, "W$SD", 1.0, "%3.1f") #, ("steals", True, "Steals", 1.0, "%3.1f")
, ("flafq", True, "FlAFq", 1.0, "%3.1f") #, ("saw_f", True, "Saw_F", 1.0, "%3.1f")
, ("tuafq", True, "TuAFq", 1.0, "%3.1f") #, ("sawsd", True, "SawSD", 1.0, "%3.1f")
, ("rvafq", True, "RvAFq", 1.0, "%3.1f") #, ("wtsdwsf", True, "WtSDwsF", 1.0, "%3.1f")
, ("pofafq", False, "PoFAFq", 1.0, "%3.1f") #, ("wmsd", True, "W$SD", 1.0, "%3.1f")
, ("net", True, "Net($)", 1.0, "%6.2f") #, ("flafq", True, "FlAFq", 1.0, "%3.1f")
, ("bbper100", True, "BB/100", 1.0, "%4.2f") #, ("tuafq", True, "TuAFq", 1.0, "%3.1f")
, ("rake", True, "Rake($)", 1.0, "%6.2f") #, ("rvafq", True, "RvAFq", 1.0, "%3.1f")
, ("variance", True, "Variance", 1.0, "%5.2f") #, ("pofafq", False, "PoFAFq", 1.0, "%3.1f")
#, ("net", True, "Net($)", 1.0, "%6.2f")
#, ("bbper100", True, "BB/100", 1.0, "%4.2f")
#, ("rake", True, "Rake($)", 1.0, "%6.2f")
#, ("variance", True, "Variance", 1.0, "%5.2f")
] ]
self.stats_frame = None self.stats_frame = None
self.stats_vbox = None self.stats_vbox = None
self.detailFilters = [] # the data used to enhance the sql select self.detailFilters = [] # the data used to enhance the sql select
self.main_hbox = gtk.HBox(False, 0) #self.main_hbox = gtk.HBox(False, 0)
self.main_hbox.show() #self.main_hbox.show()
self.main_hbox = gtk.HPaned()
self.stats_frame = gtk.Frame() self.stats_frame = gtk.Frame()
self.stats_frame.show() self.stats_frame.show()
@ -112,21 +128,23 @@ class GuiSessionViewer (threading.Thread):
self.stats_vbox = gtk.VBox(False, 0) self.stats_vbox = gtk.VBox(False, 0)
self.stats_vbox.show() self.stats_vbox.show()
self.stats_frame.add(self.stats_vbox) self.stats_frame.add(self.stats_vbox)
self.fillStatsFrame(self.stats_vbox) # self.fillStatsFrame(self.stats_vbox)
self.main_hbox.pack_start(self.filters.get_vbox())
self.main_hbox.pack_start(self.stats_frame, expand=True, fill=True)
################################
#self.main_hbox.pack_start(self.filters.get_vbox())
#self.main_hbox.pack_start(self.stats_frame, expand=True, fill=True)
self.main_hbox.pack1(self.filters.get_vbox())
self.main_hbox.pack2(self.stats_frame)
self.main_hbox.show()
# make sure Hand column is not displayed # make sure Hand column is not displayed
[x for x in self.columns if x[0] == 'hand'][0][1] == False #[x for x in self.columns if x[0] == 'hand'][0][1] = False
def get_vbox(self): def get_vbox(self):
"""returns the vbox of this thread""" """returns the vbox of this thread"""
return self.main_hbox return self.main_hbox
def refreshStats(self, widget, data): def refreshStats(self, widget, data):
try: self.stats_vbox.destroy() try: self.stats_vbox.destroy()
except AttributeError: pass except AttributeError: pass
@ -202,6 +220,31 @@ class GuiSessionViewer (threading.Thread):
print "Stats page displayed in %4.2f seconds" % (time() - starttime) print "Stats page displayed in %4.2f seconds" % (time() - starttime)
#end def fillStatsFrame(self, vbox): #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): def addTable(self, vbox, query, flags, playerids, sitenos, limits, seats):
row = 0 row = 0
sqlrow = 0 sqlrow = 0
@ -209,105 +252,114 @@ class GuiSessionViewer (threading.Thread):
if not flags: holecards = False if not flags: holecards = False
else: holecards = flags[0] else: holecards = flags[0]
# pre-fetch some constant values:
cols_to_show = [x for x in self.columns if x[colshow]]
self.stats_table = gtk.Table(1, 1, False) self.liststore = gtk.ListStore(*([str] * len(cols_to_show)))
self.stats_table.set_col_spacings(4)
self.stats_table.show() view = gtk.TreeView(model=self.liststore)
view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
self.db.cursor.execute("""select UNIX_TIMESTAMP(handStart) as time, id from Hands ORDER BY time""") 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)
# 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
"""
self.db.cursor.execute(q)
THRESHOLD = 1800 THRESHOLD = 1800
hands = self.db.cursor.fetchall() hands = self.db.cursor.fetchall()
# Take that list and create an array of the time between hands
times = map(lambda x:long(x[0]), hands) times = map(lambda x:long(x[0]), hands)
handids = map(lambda x:int(x[1]), hands) handids = map(lambda x:int(x[1]), hands)
winnings = map(lambda x:float(x[4]), hands)
print "DEBUG: len(times) %s" %(len(times)) print "DEBUG: len(times) %s" %(len(times))
diffs = diff(times) diffs = diff(times) # This array is the difference in starttime between consecutive hands
print "DEBUG: len(diffs) %s" %(len(diffs)) index = nonzero(diff(times) > THRESHOLD) # This array represents the indexes into 'times' for start/end times of sessions
index = nonzero(diff(times) > THRESHOLD) # ie. times[index[0][0]] is the end of the first session
print "DEBUG: len(index[0]) %s" %(len(index[0])) #print "DEBUG: len(index[0]) %s" %(len(index[0]))
print "DEBUG: index %s" %(index) #print "DEBUG: index %s" %(index)
print "DEBUG: index[0][0] %s" %(index[0][0]) #print "DEBUG: index[0][0] %s" %(index[0][0])
total = 0 total = 0
last_idx = 0 last_idx = 0
lowidx = 0
uppidx = 0
opens = []
closes = []
highs = []
lows = []
results = []
cum_sum = cumsum(winnings)
cum_sum = cum_sum/100
# Take all results and format them into a list for feeding into gui model.
for i in range(len(index[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]) sid = i # Session id
hds = index[0][i] - last_idx # Number of hands in session
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)
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)
total = total + (index[0][i] - last_idx) total = total + (index[0][i] - last_idx)
last_idx = index[0][i] + 1 last_idx = index[0][i] + 1
print "Total: ", total for row in results:
# iter = self.liststore.append(row)
# colnames = [desc[0].lower() for desc in self.cursor.description]
# print "DEBUG: highs = %s" % highs
# # pre-fetch some constant values: print "DEBUG: lows = %s" % lows
# cols_to_show = [x for x in self.columns if x[colshow]] print "DEBUG: opens = %s" % opens
# hgametypeid_idx = colnames.index('hgametypeid') print "DEBUG: closes = %s" % closes
#
# liststore = gtk.ListStore(*([str] * len(cols_to_show)))
# view = gtk.TreeView(model=liststore)
# view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
# vbox.pack_start(view, expand=False, padding=3)
# textcell = gtk.CellRendererText()
# 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):
# 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])
# if column[colformat] == '%s':
# if col == 1 and holecards:
# listcols[col].pack_start(textcell, expand=True)
# else:
# listcols[col].pack_start(textcell, expand=False)
# listcols[col].add_attribute(textcell, 'text', col)
# else:
# listcols[col].pack_start(numcell, expand=False)
# listcols[col].add_attribute(numcell, 'text', col)
#
# rows = len(result) # +1 for title row
#
# while sqlrow < rows:
# treerow = []
# if(row%2 == 0):
# bgcolor = "white"
# else:
# bgcolor = "lightgrey"
# for col,column in enumerate(cols_to_show):
# if column[colalias] in colnames:
# value = result[sqlrow][colnames.index(column[colalias])]
# else:
# if column[colalias] == 'game':
# if holecards:
# value = Card.twoStartCardString( result[sqlrow][hgametypeid_idx] )
# else:
# minbb = result[sqlrow][colnames.index('minbigblind')]
# maxbb = result[sqlrow][colnames.index('maxbigblind')]
# value = result[sqlrow][colnames.index('limittype')] + ' ' \
# + result[sqlrow][colnames.index('category')].title() + ' ' \
# + result[sqlrow][colnames.index('name')] + ' $'
# if 100 * int(minbb/100.0) != minbb:
# value += '%.2f' % (minbb/100.0)
# else:
# value += '%.0f' % (minbb/100.0)
# if minbb != maxbb:
# if 100 * int(maxbb/100.0) != maxbb:
# value += ' - $' + '%.2f' % (maxbb/100.0)
# else:
# value += ' - $' + '%.0f' % (maxbb/100.0)
# else:
# continue
# if value and value != -999:
# treerow.append(column[colformat] % value)
# else:
# treerow.append(' ')
# iter = liststore.append(treerow)
# sqlrow += 1
# row += 1
vbox.show_all() vbox.show_all()
def main(argv=None):
config = Configuration.Config()
i = GuiBulkImport(settings, config)
if __name__ == '__main__':
sys.exit(main())

View File

@ -37,7 +37,13 @@ import gettext
gettext.install('fpdb') gettext.install('fpdb')
import logging, logging.config import logging, logging.config
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf")) import ConfigParser
try:
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf"))
except ConfigParser.NoSectionError: # debian package path
logging.config.fileConfig('/usr/share/python-fpdb/logging.conf')
log = logging.getLogger("parser") log = logging.getLogger("parser")
import pygtk import pygtk

View File

@ -155,12 +155,6 @@ class fpdb:
def dia_database_stats(self, widget, data=None): def dia_database_stats(self, widget, data=None):
self.warning_box("Unimplemented: Database Stats") self.warning_box("Unimplemented: Database Stats")
def dia_database_sessions(self, widget, data=None):
new_sessions_thread = GuiSessionViewer.GuiSessionViewer(self.config, self.sql)
self.threads.append(new_sessions_thread)
sessions_tab=new_sessions_thread.get_vbox()
self.add_and_display_tab(sessions_tab, "Sessions")
def dia_delete_db_parts(self, widget, data=None): def dia_delete_db_parts(self, widget, data=None):
self.warning_box("Unimplemented: Delete Database Parts") self.warning_box("Unimplemented: Delete Database Parts")
self.obtain_global_lock() self.obtain_global_lock()
@ -368,6 +362,7 @@ class fpdb:
<menuitem action="playerdetails"/> <menuitem action="playerdetails"/>
<menuitem action="playerstats"/> <menuitem action="playerstats"/>
<menuitem action="posnstats"/> <menuitem action="posnstats"/>
<menuitem action="sessionstats"/>
<menuitem action="sessionreplay"/> <menuitem action="sessionreplay"/>
<menuitem action="tableviewer"/> <menuitem action="tableviewer"/>
</menu> </menu>
@ -377,7 +372,6 @@ class fpdb:
<menuitem action="createtabs"/> <menuitem action="createtabs"/>
<menuitem action="rebuildhudcache"/> <menuitem action="rebuildhudcache"/>
<menuitem action="stats"/> <menuitem action="stats"/>
<menuitem action="sessions"/>
</menu> </menu>
<menu action="help"> <menu action="help">
<menuitem action="Abbrev"/> <menuitem action="Abbrev"/>
@ -409,6 +403,7 @@ class fpdb:
('playerdetails', None, 'Player _Details (todo)', None, 'Player Details (todo)', self.not_implemented), ('playerdetails', None, 'Player _Details (todo)', None, 'Player Details (todo)', self.not_implemented),
('playerstats', None, '_Player Stats (tabulated view)', '<control>P', 'Player Stats (tabulated view)', self.tab_player_stats), ('playerstats', None, '_Player Stats (tabulated view)', '<control>P', 'Player Stats (tabulated view)', self.tab_player_stats),
('posnstats', None, 'P_ositional Stats (tabulated view)', '<control>O', 'Positional Stats (tabulated view)', self.tab_positional_stats), ('posnstats', None, 'P_ositional Stats (tabulated view)', '<control>O', 'Positional Stats (tabulated view)', self.tab_positional_stats),
('sessionstats', None, 'Session Stats', None, 'Session Stats', self.tab_session_stats),
('sessionreplay', None, '_Session Replayer (todo)', None, 'Session Replayer (todo)', self.not_implemented), ('sessionreplay', None, '_Session Replayer (todo)', None, 'Session Replayer (todo)', self.not_implemented),
('tableviewer', None, 'Poker_table Viewer (mostly obselete)', None, 'Poker_table Viewer (mostly obselete)', self.tab_table_viewer), ('tableviewer', None, 'Poker_table Viewer (mostly obselete)', None, 'Poker_table Viewer (mostly obselete)', self.tab_table_viewer),
('database', None, '_Database'), ('database', None, '_Database'),
@ -417,7 +412,6 @@ class fpdb:
('createtabs', None, 'Create or Recreate _Tables', None, 'Create or Recreate Tables ', self.dia_recreate_tables), ('createtabs', None, 'Create or Recreate _Tables', None, 'Create or Recreate Tables ', self.dia_recreate_tables),
('rebuildhudcache', None, 'Rebuild HUD Cache', None, 'Rebuild HUD Cache', self.dia_recreate_hudcache), ('rebuildhudcache', None, 'Rebuild HUD Cache', None, 'Rebuild HUD Cache', self.dia_recreate_hudcache),
('stats', None, '_Statistics (todo)', None, 'View Database Statistics', self.dia_database_stats), ('stats', None, '_Statistics (todo)', None, 'View Database Statistics', self.dia_database_stats),
('sessions', None, 'Sessions', None, 'View Sessions', self.dia_database_sessions),
('help', None, '_Help'), ('help', None, '_Help'),
('Abbrev', None, '_Abbrevations (todo)', None, 'List of Abbrevations', self.tab_abbreviations), ('Abbrev', None, '_Abbrevations (todo)', None, 'List of Abbrevations', self.tab_abbreviations),
('About', None, 'A_bout', None, 'About the program', self.dia_about), ('About', None, 'A_bout', None, 'About the program', self.dia_about),
@ -554,6 +548,12 @@ class fpdb:
ps_tab=new_ps_thread.get_vbox() ps_tab=new_ps_thread.get_vbox()
self.add_and_display_tab(ps_tab, "Positional Stats") self.add_and_display_tab(ps_tab, "Positional Stats")
def tab_session_stats(self, widget, data=None):
new_ps_thread = GuiSessionViewer.GuiSessionViewer(self.config, self.sql, self.window)
self.threads.append(new_ps_thread)
ps_tab=new_ps_thread.get_vbox()
self.add_and_display_tab(ps_tab, "Session Stats")
def tab_main_help(self, widget, data=None): def tab_main_help(self, widget, data=None):
"""Displays a tab with the main fpdb help screen""" """Displays a tab with the main fpdb help screen"""
mh_tab=gtk.Label("""Welcome to Fpdb! mh_tab=gtk.Label("""Welcome to Fpdb!

View File

@ -43,7 +43,13 @@ import Configuration
import Exceptions import Exceptions
import logging, logging.config import logging, logging.config
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf")) import ConfigParser
try:
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf"))
except ConfigParser.NoSectionError: # debian package path
logging.config.fileConfig('/usr/share/python-fpdb/logging.conf')
log = logging.getLogger('importer') log = logging.getLogger('importer')
# database interface modules # database interface modules

View File

@ -5,7 +5,7 @@ from distutils.core import setup
setup(name = 'fpdb', setup(name = 'fpdb',
description = 'Free Poker Database', description = 'Free Poker Database',
version = '0.10.999', version = '0.11.3',
author = 'FPDB team', author = 'FPDB team',
author_email = 'fpdb-main@lists.sourceforge.net', author_email = 'fpdb-main@lists.sourceforge.net',
packages = ['fpdb'], packages = ['fpdb'],
@ -13,5 +13,12 @@ setup(name = 'fpdb',
data_files = [ data_files = [
('/usr/share/doc/python-fpdb', ('/usr/share/doc/python-fpdb',
['docs/readme.txt', 'docs/release-notes.txt', ['docs/readme.txt', 'docs/release-notes.txt',
'docs/tabledesign.html', 'THANKS.txt'])] 'docs/tabledesign.html', 'THANKS.txt']),
('/usr/share/pixmaps',
['gfx/fpdb-icon.png']),
('/usr/share/applications',
['files/fpdb.desktop']),
('/usr/share/python-fpdb',
['pyfpdb/logging.conf'])
]
) )