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

Conflicts:
	pyfpdb/FulltiltToFpdb.py
This commit is contained in:
Worros 2010-07-28 11:49:07 +08:00
commit 0cd5b50b2f
12 changed files with 319 additions and 718 deletions

View File

@ -1,3 +1,34 @@
free-poker-tools (0.20.902-1) unstable; urgency=low
* New snapshot release; .901 was broken for FTP
-- Mika Bostrom <bostik@iki.fi> Sat, 24 Jul 2010 09:05:57 +0300
free-poker-tools (0.20.901-1) unstable; urgency=low
* Snapshot release before oncoming 0.21
-- Mika Bostrom <bostik@iki.fi> Thu, 22 Jul 2010 23:32:47 +0300
free-poker-tools (0.20.1-1) unstable; urgency=low
* 0.20.1 release
-- Mika Bostrom <bostik@iki.fi> Thu, 22 Jul 2010 08:47:39 +0300
free-poker-tools (0.20-2) unstable; urgency=low
* Fix executable script shebangs: there is no /usr/bin/python2 (nor
/usr/bin/python3) symlink on Debian or Ubuntu
-- Mika Bostrom <bostik+fpdb@bostik.iki.fi> Thu, 08 Jul 2010 21:29:40 +0300
free-poker-tools (0.20-1) unstable; urgency=low
* 0.20 release
-- Mika Bostrom <bostik+fpdb@bostik.iki.fi> Thu, 08 Jul 2010 11:25:36 +0300
free-poker-tools (0.20~git20100630) unstable; urgency=low
* Snapshot release

View File

@ -357,6 +357,7 @@ class Game:
class Database:
def __init__(self, node):
self.db_name = node.getAttribute("db_name")
self.db_desc = node.getAttribute("db_desc")
self.db_server = node.getAttribute("db_server").lower()
self.db_ip = node.getAttribute("db_ip")
self.db_user = node.getAttribute("db_user")
@ -817,6 +818,9 @@ class Config:
try: db['db-databaseName'] = name
except: pass
try: db['db-desc'] = self.supported_databases[name].db_desc
except: pass
try: db['db-host'] = self.supported_databases[name].db_ip
except: pass
@ -834,20 +838,29 @@ class Config:
return db
def set_db_parameters(self, db_name = 'fpdb', db_ip = None, db_user = None,
db_pass = None, db_server = None):
db_pass = None, db_desc = None, db_server = None,
default = "False"):
db_node = self.get_db_node(db_name)
default = default.lower()
defaultb = string_to_bool(default, False)
if db_node != None:
if db_desc is not None: db_node.setAttribute("db_desc", db_desc)
if db_ip is not None: db_node.setAttribute("db_ip", db_ip)
if db_user is not None: db_node.setAttribute("db_user", db_user)
if db_pass is not None: db_node.setAttribute("db_pass", db_pass)
if db_server is not None: db_node.setAttribute("db_server", db_server)
if db_type is not None: db_node.setAttribute("db_type", db_type)
if defaultb: db_node.setAttribute("default", default)
elif db_node.hasAttribute("default"):
db_node.removeAttribute("default")
if self.supported_databases.has_key(db_name):
if db_desc is not None: self.supported_databases[db_name].dp_desc = db_desc
if db_ip is not None: self.supported_databases[db_name].dp_ip = db_ip
if db_user is not None: self.supported_databases[db_name].dp_user = db_user
if db_pass is not None: self.supported_databases[db_name].dp_pass = db_pass
if db_server is not None: self.supported_databases[db_name].dp_server = db_server
if db_type is not None: self.supported_databases[db_name].dp_type = db_type
self.supported_databases[db_name].db_selected = defaultb
if defaultb:
self.db_selected = db_name
return
def get_backend(self, name):

View File

@ -74,7 +74,7 @@ except ImportError:
use_numpy = False
DB_VERSION = 136
DB_VERSION = 138
# Variance created as sqlite has a bunch of undefined aggregate functions.
@ -147,7 +147,6 @@ class Database:
{'tab':'Hands', 'col':'gametypeId', 'drop':0}
, {'tab':'HandsPlayers', 'col':'handId', 'drop':0}
, {'tab':'HandsPlayers', 'col':'playerId', 'drop':0}
, {'tab':'HandsPlayers', 'col':'tourneyTypeId', 'drop':0}
, {'tab':'HandsPlayers', 'col':'tourneysPlayersId', 'drop':0}
, {'tab':'HudCache', 'col':'gametypeId', 'drop':1}
, {'tab':'HudCache', 'col':'playerId', 'drop':0}
@ -168,7 +167,6 @@ class Database:
{'fktab':'Hands', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
, {'fktab':'HandsPlayers', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1}
, {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1}
, {'fktab':'HandsPlayers', 'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes', 'rcol':'id', 'drop':1}
, {'fktab':'HandsPlayers', 'fkcol':'tourneysPlayersId','rtab':'TourneysPlayers','rcol':'id', 'drop':1}
, {'fktab':'HandsActions', 'fkcol':'handsPlayerId', 'rtab':'HandsPlayers', 'rcol':'id', 'drop':1}
, {'fktab':'HudCache', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
@ -1641,7 +1639,6 @@ class Database:
pdata[p]['street3Bets'],
pdata[p]['street4Bets'],
pdata[p]['position'],
pdata[p]['tourneyTypeId'],
pdata[p]['tourneysPlayersIds'],
pdata[p]['startCards'],
pdata[p]['street0_3BChance'],
@ -1983,17 +1980,21 @@ class Database:
(hand.tourNo, hand.siteId)
)
result=cursor.fetchone()
#print "result of fetching TT by number and site:",result
if result:
tourneyTypeId = result[0]
else:
# Check for an existing TTypeId that matches tourney info, if not found create it
#print "info that we use to get TT by detail:", hand.siteId, hand.buyinCurrency, hand.buyin, hand.fee, hand.gametype['category'], hand.gametype['limitType'], hand.isKO, hand.isRebuy, hand.isAddOn, hand.speed, hand.isShootout, hand.isMatrix
#print "the query:",self.sql.query['getTourneyTypeId'].replace('%s', self.sql.query['placeholder'])
cursor.execute (self.sql.query['getTourneyTypeId'].replace('%s', self.sql.query['placeholder']),
(hand.siteId, hand.buyinCurrency, hand.buyin, hand.fee, hand.gametype['category'], hand.gametype['limitType'], hand.isKO,
hand.isRebuy, hand.isRebuy, hand.speed, hand.isShootout, hand.isMatrix, hand.added, hand.addedCurrency)
hand.isRebuy, hand.isAddOn, hand.speed, hand.isShootout, hand.isMatrix)
)
result=cursor.fetchone()
#print "result of fetching TT by details:",result
try:
tourneyTypeId = result[0]
except TypeError: #this means we need to create a new entry

View File

@ -146,13 +146,14 @@ or None if we fail to get the info """
tourno = t.group('TOURNO')
hand.tourNo = tourno
hand.tablename = t.group('TABLE')
#TODO we should fetch info including buyincurrency, buyin and fee from URL:
# https://www.poker4ever.com/tourney/%TOURNEY_NUMBER%
# Believe Everleaf time is GMT/UTC, no transation necessary
# Stars format (Nov 10 2008): 2008/11/07 12:38:49 CET [2008/11/07 7:38:49 ET]
# or : 2008/11/07 12:38:49 ET
# Not getting it in my HH files yet, so using
# 2008/11/10 3:58:52 ET
#TODO: Do conversion from GMT to ET
#TODO: Need some date functions to convert to different timezones (Date::Manip for perl rocked for this)
hand.startTime = datetime.datetime.strptime(m.group('DATETIME'), "%Y/%m/%d - %H:%M:%S")
return

View File

@ -229,12 +229,21 @@ class Filters(threading.Thread):
return self.numHands
#end def getNumHands
def getNumTourneys(self):
return self.numTourneys
#end def getNumTourneys
def getSites(self):
return self.sites
#end def getSites
def getTourneyTypes(self):
return self.tourneyTypes
#end def getTourneyTypes
def getGames(self):
return self.games
#end def getGames
def getSiteIds(self):
return self.siteid
@ -316,6 +325,7 @@ class Filters(threading.Thread):
liststore.append(_nt)
self.__set_hero_name(pname, site)
#end def createPlayerLine
def __set_hero_name(self, w, site):
_name = w.get_text()
@ -338,6 +348,20 @@ class Filters(threading.Thread):
cb.connect('clicked', self.__set_site_select, site)
cb.set_active(True)
hbox.pack_start(cb, False, False, 0)
#end def createSiteLine
def __set_tourney_type_select(self, w, tourneyType):
#print w.get_active()
self.tourneyTypes[tourneyType] = w.get_active()
log.debug("self.tourney_types[%s] set to %s" %(tourneyType, self.tourneyTypes[tourneyType]))
#end def __set_tourney_type_select
def createTourneyTypeLine(self, hbox, tourneyType):
cb = gtk.CheckButton(str(tourneyType))
cb.connect('clicked', self.__set_tourney_type_select, tourneyType)
hbox.pack_start(cb, False, False, 0)
cb.set_active(True)
#end def createTourneyTypeLine
def createGameLine(self, hbox, game):
cb = gtk.CheckButton(game)
@ -357,6 +381,7 @@ class Filters(threading.Thread):
#print w.get_active()
self.sites[site] = w.get_active()
log.debug("self.sites[%s] set to %s" %(site, self.sites[site]))
#end def __set_site_select
def __set_game_select(self, w, game):
#print w.get_active()
@ -505,6 +530,7 @@ class Filters(threading.Thread):
#print "__set_seat_select: seat =", seat, "active =", w.get_active()
self.seats[seat] = w.get_active()
log.debug( "self.seats[%s] set to %s" %(seat, self.seats[seat]) )
#end def __set_seat_select
def __set_group_select(self, w, group):
#print "__set_seat_select: seat =", seat, "active =", w.get_active()
@ -552,6 +578,7 @@ class Filters(threading.Thread):
hbox.pack_start(phands, False, False, 0)
phands.connect("changed", self.__set_num_hands, site)
top_hbox.pack_start(showb, expand=False, padding=1)
#end def fillPlayerFrame
def fillSitesFrame(self, vbox):
top_hbox = gtk.HBox(False, 0)
@ -583,6 +610,33 @@ class Filters(threading.Thread):
# self.siteid[site] = result[0][0]
#else:
# print "Either 0 or more than one site matched - EEK"
#end def fillSitesFrame
def fillTourneyTypesFrame(self, vbox):
top_hbox = gtk.HBox(False, 0)
vbox.pack_start(top_hbox, False, False, 0)
lbl_title = gtk.Label(self.filterText['tourneyTypesTitle'])
lbl_title.set_alignment(xalign=0.0, yalign=0.5)
top_hbox.pack_start(lbl_title, expand=True, padding=3)
showb = gtk.Button(label="hide", stock=None, use_underline=True)
showb.set_alignment(xalign=1.0, yalign=0.5)
showb.connect('clicked', self.__toggle_box, 'tourneyTypes')
top_hbox.pack_start(showb, expand=False, padding=1)
vbox1 = gtk.VBox(False, 0)
vbox.pack_start(vbox1, False, False, 0)
self.boxes['tourneyTypes'] = vbox1
result = self.db.getTourneyTypesIds()
if len(result) >= 1:
for line in result:
hbox = gtk.HBox(False, 0)
vbox1.pack_start(hbox, False, True, 0)
self.createTourneyTypeLine(hbox, line[0])
else:
print "INFO: No tourney types returned from database"
log.info("No tourney types returned from database")
#end def fillTourneyTypesFrame
def fillGamesFrame(self, vbox):
top_hbox = gtk.HBox(False, 0)
@ -859,6 +913,7 @@ class Filters(threading.Thread):
for w in self.mainVBox.get_children():
w.destroy()
self.make_filter()
#end def __refresh
def __toggle_box(self, widget, entry):
if self.boxes[entry].props.visible:

View File

@ -33,17 +33,32 @@ log = logging.getLogger("maintdbs")
import Exceptions
import Database
import SQL
class GuiDatabase:
# columns in liststore:
MODEL_DBMS = 0
MODEL_NAME = 1
MODEL_DESC = 2
MODEL_USER = 3
MODEL_PASS = 4
MODEL_HOST = 5
MODEL_DFLT = 6
MODEL_DFLTIC = 7
MODEL_STATUS = 8
MODEL_STATIC = 9
# columns in listview:
COL_DBMS = 0
COL_NAME = 1
COL_DESC = 2
COL_USER = 3
COL_PASS = 4
COL_HOST = 5
COL_ICON = 6
COL_DFLT = 6
COL_ICON = 7
def __init__(self, config, mainwin, dia):
self.config = config
@ -56,9 +71,9 @@ class GuiDatabase:
#gtk.Widget.set_size_request(self.vbox, 700, 400);
# list of databases in self.config.supported_databases:
self.liststore = gtk.ListStore(str, str, str, str
,str, str, str, str) #object, gtk.gdk.Pixbuf)
# dbms, name, comment, user, pass, ip, status(, icon?)
self.liststore = gtk.ListStore(str, str, str, str, str
,str, str, str, str, str)
# dbms, name, comment, user, passwd, host, "", default_icon, status, icon
# this is how to add a filter:
#
# # Creation of the filter, from the model
@ -70,11 +85,12 @@ class GuiDatabase:
self.listview = gtk.TreeView(model=self.liststore)
self.listview.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_NONE)
self.listcols = []
self.changes = False
scrolledwindow = gtk.ScrolledWindow()
scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
scrolledwindow.add(self.listview)
self.vbox.pack_start(scrolledwindow, expand=True, fill=True, padding=0)
self.scrolledwindow = gtk.ScrolledWindow()
self.scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.scrolledwindow.add(self.listview)
self.vbox.pack_start(self.scrolledwindow, expand=True, fill=True, padding=0)
refreshbutton = gtk.Button("Refresh")
refreshbutton.connect("clicked", self.refresh, None)
@ -87,18 +103,28 @@ class GuiDatabase:
col = self.addTextColumn("Username", 3, True)
col = self.addTextColumn("Password", 4, True)
col = self.addTextColumn("Host", 5, True)
col = self.addTextObjColumn("", 6)
col = self.addTextObjColumn("Default", 6, 6)
col = self.addTextObjColumn("Status", 7, 8)
#self.listview.get_selection().set_mode(gtk.SELECTION_SINGLE)
#self.listview.get_selection().connect("changed", self.on_selection_changed)
self.listview.add_events(gtk.gdk.BUTTON_PRESS_MASK)
self.listview.connect('button_press_event', self.selectTest)
self.loadDbs()
self.dia.connect('response', self.dialog_response_cb)
#self.dia.connect('response', self.dialog_response_cb)
except:
err = traceback.extract_tb(sys.exc_info()[2])[-1]
print 'guidbmaint: '+ err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
def dialog_response_cb(self, dialog, response_id):
# this is called whether close button is pressed or window is closed
log.info('dialog_response_cb: response_id='+str(response_id))
#if self.changes:
# self.config.save()
dialog.destroy()
return(response_id)
def get_dialog(self):
@ -125,6 +151,7 @@ class GuiDatabase:
def edited_cb(self, cell, path, new_text, user_data):
liststore, col = user_data
log.info('edited_cb: col = '+str(col))
valid = True
name = self.liststore[path][self.COL_NAME]
@ -138,10 +165,11 @@ class GuiDatabase:
self.config.set_db_parameters( db_server = self.liststore[path][self.COL_DBMS]
, db_name = name
, db_desc = self.liststore[path][self.COL_DESC]
, db_ip = self.liststore[path][self.COL_HOST]
, db_user = self.liststore[path][self.COL_USER]
, db_pass = self.liststore[path][self.COL_PASS] )
self.changes = True
return
def check_new_name(self, path, new_text):
@ -152,38 +180,73 @@ class GuiDatabase:
#TODO: popup an error message telling user names must be unique
return name_ok
def addTextObjColumn(self, title, n):
def addTextObjColumn(self, title, viewcol, storecol, editable=False):
col = gtk.TreeViewColumn(title)
self.listview.append_column(col)
cRenderT = gtk.CellRendererText()
cRenderT.set_property("wrap-mode", pango.WRAP_WORD_CHAR)
col.pack_start(cRenderT, False)
col.add_attribute(cRenderT, 'text', n)
col.add_attribute(cRenderT, 'text', storecol)
cRenderP = gtk.CellRendererPixbuf()
col.pack_start(cRenderP, False)
col.add_attribute(cRenderP, 'stock-id', n+1)
col.pack_start(cRenderP, True)
col.add_attribute(cRenderP, 'stock-id', storecol+1)
col.set_max_width(1000)
col.set_spacing(0) # no effect
self.listcols.append(col)
#col.set_clickable(True)
#col.connect("clicked", self.sortCols, p)
col.set_clickable(True)
col.connect("clicked", self.sortCols, viewcol)
return(col)
def selectTest(self, widget, event):
if event.button == 1: # and event.type == gtk.gdk._2BUTTON_PRESS:
pthinfo = self.listview.get_path_at_pos( int(event.x), int(event.y) )
if pthinfo is not None:
path, col, cellx, celly = pthinfo
row = path[0]
if col == self.listcols[self.COL_DFLT]:
if self.liststore[row][self.MODEL_STATUS] == 'ok' and self.liststore[row][self.MODEL_DFLTIC] is None:
self.setDefaultDB(row)
def setDefaultDB(self, row):
print "set new defaultdb:", row, self.liststore[row][self.MODEL_NAME]
for r in xrange(len(self.liststore)):
if r == row:
self.liststore[r][self.MODEL_DFLTIC] = gtk.STOCK_APPLY
default = "True"
else:
self.liststore[r][self.MODEL_DFLTIC] = None
default = "False"
self.config.set_db_parameters( db_server = self.liststore[r][self.COL_DBMS]
, db_name = self.liststore[r][self.COL_NAME]
, db_desc = self.liststore[r][self.COL_DESC]
, db_ip = self.liststore[r][self.COL_HOST]
, db_user = self.liststore[r][self.COL_USER]
, db_pass = self.liststore[r][self.COL_PASS]
, default = default
)
self.changes = True
return
def loadDbs(self):
self.liststore.clear()
self.listcols = []
self.dbs = [] # list of tuples: (dbms, name, comment, user, passwd, host, status, icon)
#self.listcols = []
dia = self.info_box2(None, 'Testing database connections ... ', "", False, False)
while gtk.events_pending():
gtk.mainiteration()
try:
# want to fill: dbms, name, comment, user, passwd, host, status(, icon?)
# want to fill: dbms, name, comment, user, passwd, host, default, status, icon
for name in self.config.supported_databases: #db_ip/db_user/db_pass/db_server
dbms = self.config.supported_databases[name].db_server # mysql/postgresql/sqlite
dbms_num = self.config.get_backend(dbms) # 2 / 3 / 4
comment = ""
comment = self.config.supported_databases[name].db_desc
if dbms == 'sqlite':
user = ""
passwd = ""
@ -191,22 +254,30 @@ class GuiDatabase:
user = self.config.supported_databases[name].db_user
passwd = self.config.supported_databases[name].db_pass
host = self.config.supported_databases[name].db_ip
default = (name == self.config.db_selected)
default_icon = None
if default: default_icon = gtk.STOCK_APPLY
status = ""
icon = None
err_msg = ""
db = Database.Database(self.config, sql = None, autoconnect = False)
sql = SQL.Sql(db_server=dbms)
db = Database.Database(self.config, sql = sql, autoconnect = False)
# try to connect to db, set status and err_msg if it fails
try:
# is creating empty db for sqlite ... mod db.py further?
# add noDbTables flag to db.py?
log.debug("loaddbs: trying to connect to: %s/%s, %s, %s/%s" % (str(dbms_num),dbms,name,user,passwd))
db.connect(backend=dbms_num, host=host, database=name, user=user, password=passwd, create=False)
if db.connected:
log.debug(" connected ok")
status = 'ok'
icon = gtk.STOCK_APPLY
if db.wrongDbVersion:
status = 'old'
icon = gtk.STOCK_INFO
else:
log.debug(" not connected but no exception")
except Exceptions.FpdbMySQLAccessDenied:
err_msg = "MySQL Server reports: Access denied. Are your permissions set correctly?"
status = "failed"
@ -230,13 +301,17 @@ class GuiDatabase:
+ err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1]) )
status = "failed"
icon = gtk.STOCK_CANCEL
if err_msg:
log.info( 'db connection to '+str(dbms_num)+','+host+','+name+','+user+','+passwd+' failed: '
+ err_msg )
b = gtk.Button(name)
b.show()
iter = self.liststore.append( (dbms, name, comment, user, passwd, host, status, icon) )
iter = self.liststore.append( (dbms, name, comment, user, passwd, host, "", default_icon, status, icon) )
self.info_box2(dia[0], "finished.", "", False, True)
self.listview.show()
scrolledwindow.show()
self.scrolledwindow.show()
self.vbox.show()
self.dia.set_focus(self.listview)
@ -249,13 +324,16 @@ class GuiDatabase:
def sortCols(self, col, n):
try:
log.info('sortcols n='+str(n))
if not col.get_sort_indicator() or 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,grid))
log.info('sortcols len(listcols)='+str(len(self.listcols)))
for i in xrange(len(self.listcols)):
log.info('sortcols i='+str(i))
self.listcols[i].set_sort_indicator(False)
self.listcols[n].set_sort_indicator(True)
# use this listcols[col].set_sort_indicator(True)
@ -264,10 +342,69 @@ class GuiDatabase:
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] )
log.info('sortCols error: ' + str(sys.exc_info()) )
def refresh(self, widget, data):
self.loadDbs()
def info_box(self, dia, str1, str2, run, destroy):
if dia is None:
#if run:
btns = gtk.BUTTONS_NONE
btns = gtk.BUTTONS_OK
dia = gtk.MessageDialog( parent=self.main_window, flags=gtk.DIALOG_DESTROY_WITH_PARENT
, type=gtk.MESSAGE_INFO, buttons=(btns), message_format=str1 )
# try to remove buttons!
# (main message is in inverse video if no buttons, so try removing them after
# creating dialog)
# NO! message just goes back to inverse video :-( use info_box2 instead
for c in dia.vbox.get_children():
if isinstance(c, gtk.HButtonBox):
for d in c.get_children():
log.info('child: '+str(d)+' is a '+str(d.__class__))
if isinstance(d, gtk.Button):
log.info('removing button '+str(d))
c.remove(d)
if str2:
dia.format_secondary_text(str2)
else:
dia.set_markup(str1)
if str2:
dia.format_secondary_text(str2)
dia.show()
response = None
if run: response = dia.run()
if destroy: dia.destroy()
return (dia, response)
def info_box2(self, dia, str1, str2, run, destroy):
if dia is None:
# create dialog and add icon and label
btns = (gtk.BUTTONS_OK)
btns = None
# messagedialog puts text in inverse colors if no buttons are displayed??
#dia = gtk.MessageDialog( parent=self.main_window, flags=gtk.DIALOG_DESTROY_WITH_PARENT
# , type=gtk.MESSAGE_INFO, buttons=(btns), message_format=str1 )
dia = gtk.Dialog( parent=self.main_window, flags=gtk.DIALOG_DESTROY_WITH_PARENT
, title="" ) # , buttons=btns
vbox = dia.vbox
h = gtk.HBox(False, 2)
i = gtk.Image()
i.set_from_stock(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_DIALOG)
l = gtk.Label(str1)
h.pack_start(i, padding=5)
h.pack_start(l, padding=5)
vbox.pack_start(h)
else:
# add extra label
vbox = dia.vbox
vbox.pack_start( gtk.Label(str1) )
dia.show_all()
response = None
if run: response = dia.run()
if destroy: dia.destroy()
return (dia, response)
if __name__=="__main__":

View File

@ -1,290 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#Copyright 2008-2010 Steffen Schaumburg
#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU Affero General Public License as published by
#the Free Software Foundation, version 3 of the License.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU Affero General Public License
#along with this program. If not, see <http://www.gnu.org/licenses/>.
#In the "official" distribution you can find the license in agpl-3.0.txt.
import threading
import pygtk
pygtk.require('2.0')
import gtk
import os
import fpdb_import
from Exceptions import *
class GuiTableViewer (threading.Thread):
def hudDivide (self, a, b):
if b==0:
return "n/a"
else:
return str(int((a/float(b))*100))+"%"
#end def hudDivide
def browse_clicked(self, widget, data):
"""runs when user clicks browse on tv tab"""
#print "start of table_viewer.browser_clicked"
current_path=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter())
dia_chooser = gtk.FileChooserDialog(title="Please choose the file for which you want to open the Table Viewer",
action=gtk.FILE_CHOOSER_ACTION_OPEN,
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
#dia_chooser.set_current_folder(pathname)
dia_chooser.set_filename(current_path)
#dia_chooser.set_select_multiple(select_multiple) #not in tv, but want this in bulk import
response = dia_chooser.run()
if response == gtk.RESPONSE_OK:
#print dia_chooser.get_filename(), 'selected'
self.filename_tbuffer.set_text(dia_chooser.get_filename())
elif response == gtk.RESPONSE_CANCEL:
print 'Closed, no files selected'
dia_chooser.destroy()
#end def table_viewer.browse_clicked
def prepare_data(self):
"""prepares the data for display by refresh_clicked, returns a 2D array"""
#print "start of prepare_data"
arr=[]
#first prepare the header row
if (self.category=="holdem" or self.category=="omahahi" or self.category=="omahahilo"):
tmp=("Name", "HDs", "VPIP", "PFR", "PF3B", "ST")
tmp+=("FS", "FB")
tmp+=("CB", )
tmp+=("2B", "3B")
tmp+=("AF", "FF", "AT", "FT", "AR", "FR")
tmp+=("WtSD", "W$wsF", "W$SD")
else:
raise FpdbError("reimplement stud")
arr.append(tmp)
#then the data rows
for player in range(len(self.player_names)):
tmp=[]
p_name = Charset.to_gui(self.player_names[player][0])
tmp.append(p_name)
seatCount=len(self.player_names)
if seatCount>=8:
minSeats,maxSeats=7,10
elif seatCount==7:
minSeats,maxSeats=6,10
elif seatCount==6 or seatCount==5:
minSeats,maxSeats=seatCount-1,seatCount+1
elif seatCount==4:
minSeats,maxSeats=4,5
elif seatCount==2 or seatCount==3:
minSeats,maxSeats=seatCount,seatCount
else:
FpdbError("invalid seatCount")
self.cursor.execute("SELECT * FROM HudCache WHERE gametypeId=%s AND playerId=%s AND activeSeats>=%s AND activeSeats<=%s", (self.gametype_id, self.player_ids[player][0], minSeats, maxSeats))
rows=self.cursor.fetchall()
row=[]
for field_no in range(len(rows[0])):
row.append(rows[0][field_no])
for row_no in range(len(rows)):
if row_no==0:
pass
else:
for field_no in range(len(rows[row_no])):
if field_no<=3:
pass
else:
#print "in prep data, row_no:",row_no,"field_no:",field_no
row[field_no]+=rows[row_no][field_no]
tmp.append(str(row[6]))#Hands
tmp.append(self.hudDivide(row[7],row[6])) #VPIP
tmp.append(self.hudDivide(row[8],row[6])) #PFR
tmp.append(self.hudDivide(row[10],row[9])+" ("+str(row[9])+")") #PF3B
tmp.append(self.hudDivide(row[31],row[30])+" ("+str(row[30])+")") #ST
tmp.append(self.hudDivide(row[35],row[34])+" ("+str(row[34])+")") #FS
tmp.append(self.hudDivide(row[33],row[32])+" ("+str(row[32])+")") #FB
tmp.append(self.hudDivide(row[37],row[36])+" ("+str(row[36])+")") #CB
tmp.append(self.hudDivide(row[39],row[38])+" ("+str(row[38])+")") #2B
tmp.append(self.hudDivide(row[41],row[40])+" ("+str(row[40])+")") #3B
tmp.append(self.hudDivide(row[16],row[11])+" ("+str(row[11])+")") #AF
tmp.append(self.hudDivide(row[24],row[20])+" ("+str(row[20])+")") #FF
tmp.append(self.hudDivide(row[17],row[12])+" ("+str(row[12])+")") #AT
tmp.append(self.hudDivide(row[25],row[21])+" ("+str(row[21])+")") #FT
tmp.append(self.hudDivide(row[18],row[13])+" ("+str(row[13])+")") #AR
tmp.append(self.hudDivide(row[26],row[22])+" ("+str(row[22])+")") #FR
tmp.append(self.hudDivide(row[15],row[11])) #WtSD
tmp.append(self.hudDivide(row[28],row[11])) #W$wSF
tmp.append(self.hudDivide(row[29],row[15])+" ("+str(row[15])+")") #W$@SD
arr.append(tmp)
return arr
#end def table_viewer.prepare_data
def refresh_clicked(self, widget, data):
"""runs when user clicks refresh"""
#print "start of table_viewer.refresh_clicked"
arr=self.prepare_data()
try: self.data_table.destroy()
except AttributeError: pass
self.data_table=gtk.Table(rows=len(arr), columns=len(arr[0]), homogeneous=False)
self.main_vbox.pack_start(self.data_table)
self.data_table.show()
for row in range(len(arr)):
for column in range (len(arr[row])):
eventBox=gtk.EventBox()
new_label=gtk.Label(arr[row][column])
if row%2==0: #
bg_col="white"
if column==0 or (column>=5 and column<=10):
bg_col="lightgrey"
else:
bg_col="lightgrey"
if column==0 or (column>=5 and column<=10):
bg_col="grey"
#style = eventBox.get_style()
#style.font.height=8
#eventBox.set_style(style)
eventBox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bg_col))
eventBox.add(new_label)
self.data_table.attach(child=eventBox, left_attach=column, right_attach=column+1, top_attach=row, bottom_attach=row+1)
eventBox.show()
new_label.show()
#end def table_viewer.refresh_clicked
def read_names_clicked(self, widget, data):
"""runs when user clicks read names"""
#print "start of table_viewer.read_names_clicked"
self.db.reconnect()
self.cursor=self.db.get_cursor()
#self.hands_id=self.last_read_hand_id
self.cursor.execute("SELECT gametypeId FROM Hands WHERE id=%s", (self.hands_id, ))
self.gametype_id=self.cursor.fetchone()[0]
self.cursor.execute("SELECT category FROM Gametypes WHERE id=%s", (self.gametype_id, ))
self.category=self.cursor.fetchone()[0]
#print "self.gametype_id", self.gametype_id," category:", self.category, " self.hands_id:", self.hands_id
self.cursor.execute("""SELECT DISTINCT Players.id FROM HandsPlayers
INNER JOIN Players ON HandsPlayers.playerId=Players.id
WHERE handId=%s""", (self.hands_id, ))
self.player_ids=self.cursor.fetchall()
#print "self.player_ids:",self.player_ids
self.cursor.execute("""SELECT DISTINCT Players.name FROM HandsPlayers
INNER JOIN Players ON HandsPlayers.playerId=Players.id
WHERE handId=%s""", (self.hands_id, ))
self.player_names=self.cursor.fetchall()
#print "self.player_names:",self.player_names
#end def table_viewer.read_names_clicked
def import_clicked(self, widget, data):
"""runs when user clicks import"""
#print "start of table_viewer.import_clicked"
self.inputFile=self.filename_tbuffer.get_text(self.filename_tbuffer.get_start_iter(), self.filename_tbuffer.get_end_iter())
self.importer = fpdb_import.Importer(self, self.settings, self.config)
self.importer.setMinPrint(0)
self.importer.setQuiet(False)
self.importer.setFailOnError(False)
self.importer.setHandCount(0)
self.importer.addImportFile(self.inputFile)
self.importer.runImport()
self.hands_id=self.importer.handsId
#end def table_viewer.import_clicked
def all_clicked(self, widget, data):
"""runs when user clicks all"""
#print "start of table_viewer.all_clicked"
self.import_clicked(widget, data)
self.read_names_clicked(widget, data)
self.refresh_clicked(widget, data)
#end def table_viewer.all_clicked
def get_vbox(self):
"""returns the vbox of this thread"""
return self.main_vbox
#end def get_vbox
def __init__(self, db, settings, config=None, debug=True):
"""Constructor for table_viewer"""
self.debug=debug
#print "start of table_viewer constructor"
self.db = db
self.cursor = db.get_cursor()
self.settings = settings
self.config = config
self.main_vbox = gtk.VBox(False, 0)
self.main_vbox.show()
self.settings_hbox = gtk.HBox(False, 0)
self.main_vbox.pack_end(self.settings_hbox, False, True, 0)
self.settings_hbox.show()
self.filename_label = gtk.Label("Path of history file")
self.settings_hbox.pack_start(self.filename_label, False, False)
self.filename_label.show()
self.filename_tbuffer=gtk.TextBuffer()
self.filename_tbuffer.set_text(self.settings['hud-defaultPath'])
self.filename_tview=gtk.TextView(self.filename_tbuffer)
self.settings_hbox.pack_start(self.filename_tview, True, True, padding=5)
self.filename_tview.show()
self.browse_button=gtk.Button("Browse...")
self.browse_button.connect("clicked", self.browse_clicked, "Browse clicked")
self.settings_hbox.pack_start(self.browse_button, False, False)
self.browse_button.show()
self.button_hbox = gtk.HBox(False, 0)
self.main_vbox.pack_end(self.button_hbox, False, True, 0)
self.button_hbox.show()
#self.import_button = gtk.Button("Import")
#self.import_button.connect("clicked", self.import_clicked, "Import clicked")
#self.button_hbox.add(self.import_button)
#self.import_button.show()
#self.read_names_button = gtk.Button("Read Names")
#self.read_names_button.connect("clicked", self.read_names_clicked, "Read clicked")
#self.button_hbox.add(self.read_names_button)
#self.read_names_button.show()
#self.refresh_button = gtk.Button("Show/Refresh data")
#self.refresh_button.connect("clicked", self.refresh_clicked, "Refresh clicked")
#self.button_hbox.add(self.refresh_button)
#self.refresh_button.show()
self.all_button = gtk.Button("Import&Read&Refresh")
self.all_button.connect("clicked", self.all_clicked, "All clicked")
self.button_hbox.add(self.all_button)
self.all_button.show()
#end of table_viewer.__init__

View File

@ -392,9 +392,9 @@ class Sql:
self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
siteId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
currency varchar(4) NOT NULL,
buyIn INT NOT NULL,
fee INT NOT NULL,
currency varchar(4),
buyIn INT,
fee INT,
category varchar(9) NOT NULL,
limitType char(2) NOT NULL,
buyInChips INT,
@ -423,9 +423,9 @@ class Sql:
self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
id SERIAL, PRIMARY KEY (id),
siteId INT NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
currency varchar(4) NOT NULL,
buyin INT NOT NULL,
fee INT NOT NULL,
currency varchar(4),
buyin INT,
fee INT,
category varchar(9),
limitType char(2),
buyInChips INT,
@ -453,9 +453,9 @@ class Sql:
self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
id INTEGER PRIMARY KEY,
siteId INT NOT NULL,
currency VARCHAR(4) NOT NULL,
buyin INT NOT NULL,
fee INT NOT NULL,
currency VARCHAR(4),
buyin INT,
fee INT,
category TEXT,
limitType TEXT,
buyInChips INT,
@ -560,7 +560,6 @@ class Sql:
comment text,
commentTs DATETIME,
tourneysPlayersId BIGINT UNSIGNED, FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id),
tourneyTypeId SMALLINT UNSIGNED, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
wonWhenSeenStreet1 FLOAT,
wonWhenSeenStreet2 FLOAT,
@ -677,7 +676,6 @@ class Sql:
comment text,
commentTs timestamp without time zone,
tourneysPlayersId BIGINT, FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id),
tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
wonWhenSeenStreet1 FLOAT,
wonWhenSeenStreet2 FLOAT,
@ -793,7 +791,6 @@ class Sql:
comment TEXT,
commentTs REAL,
tourneysPlayersId INT,
tourneyTypeId INT,
wonWhenSeenStreet1 REAL,
wonWhenSeenStreet2 REAL,
@ -2447,6 +2444,8 @@ class Sql:
) hprof2
on hprof2.gtId = stats.gtId
order by stats.category, stats.limittype, stats.bigBlindDesc desc <orderbyseats>"""
#elif db_server == 'sqlite': #TODO
# self.query['playerStats'] = """ """
else: # assume postgres
self.query['playerStats'] = """
SELECT upper(stats.limitType) || ' '
@ -2550,8 +2549,6 @@ class Sql:
) hprof2
on hprof2.gtId = stats.gtId
order by stats.base, stats.limittype, stats.bigBlindDesc desc <orderbyseats>"""
#elif db_server == 'sqlite':
# self.query['playerStats'] = """ """
if db_server == 'mysql':
self.query['playerStatsByPosition'] = """
@ -2989,7 +2986,7 @@ class Sql:
when hp.position = '9' then 'E'
else 'E'
end AS hc_position
,hp.tourneyTypeId
,t.tourneyTypeId
,date_format(h.startTime, 'd%y%m%d')
,count(1)
,sum(wonWhenSeenStreet1)
@ -3063,12 +3060,14 @@ class Sql:
,sum(hp.street4Raises)
FROM HandsPlayers hp
INNER JOIN Hands h ON (h.id = hp.handId)
INNER JOIN TourneysPlayers tp ON (tp.id = hp.tourneysPlayersId)
INNER JOIN Tourneys t ON (t.id = tp.tourneyId)
<where_clause>
GROUP BY h.gametypeId
,hp.playerId
,h.seats
,hc_position
,hp.tourneyTypeId
,t.tourneyTypeId
,date_format(h.startTime, 'd%y%m%d')
"""
elif db_server == 'postgresql':
@ -3168,7 +3167,7 @@ class Sql:
when hp.position = '9' then 'E'
else 'E'
end AS hc_position
,hp.tourneyTypeId
,t.tourneyTypeId
,'d' || to_char(h.startTime, 'YYMMDD')
,count(1)
,sum(wonWhenSeenStreet1)
@ -3242,12 +3241,14 @@ class Sql:
,sum(CAST(hp.street4Raises as integer))
FROM HandsPlayers hp
INNER JOIN Hands h ON (h.id = hp.handId)
INNER JOIN TourneysPlayers tp ON (tp.id = hp.tourneysPlayersId)
INNER JOIN Tourneys t ON (t.id = tp.tourneyId)
<where_clause>
GROUP BY h.gametypeId
,hp.playerId
,h.seats
,hc_position
,hp.tourneyTypeId
,t.tourneyTypeId
,to_char(h.startTime, 'YYMMDD')
"""
else: # assume sqlite
@ -3347,7 +3348,7 @@ class Sql:
when hp.position = '9' then 'E'
else 'E'
end AS hc_position
,hp.tourneyTypeId
,t.tourneyTypeId
,'d' || substr(strftime('%Y%m%d', h.startTime),3,7)
,count(1)
,sum(wonWhenSeenStreet1)
@ -3421,12 +3422,14 @@ class Sql:
,sum(CAST(hp.street4Raises as integer))
FROM HandsPlayers hp
INNER JOIN Hands h ON (h.id = hp.handId)
INNER JOIN TourneysPlayers tp ON (tp.id = hp.tourneysPlayersId)
INNER JOIN Tourneys t ON (t.id = tp.tourneyId)
<where_clause>
GROUP BY h.gametypeId
,hp.playerId
,h.seats
,hc_position
,hp.tourneyTypeId
,t.tourneyTypeId
,'d' || substr(strftime('%Y%m%d', h.startTime),3,7)
"""
@ -3698,8 +3701,6 @@ class Sql:
AND speed=%s
AND shootout=%s
AND matrix=%s
AND added=%s
AND addedCurrency=%s
"""
self.query['insertTourneyType'] = """INSERT INTO TourneyTypes
@ -3860,7 +3861,6 @@ class Sql:
street3Bets,
street4Bets,
position,
tourneyTypeId,
tourneysPlayersId,
startCards,
street0_3BChance,
@ -3919,7 +3919,7 @@ class Sql:
%s, %s, %s, %s, %s,
%s, %s, %s, %s, %s,
%s, %s, %s, %s, %s,
%s, %s
%s
)"""
################################

View File

@ -63,68 +63,12 @@ class TourneyFilters(Filters.Filters):
self.make_filter()
#end def __init__
def __calendar_dialog(self, widget, entry):
d = gtk.Window(gtk.WINDOW_TOPLEVEL)
d.set_title('Pick a date')
vb = gtk.VBox()
cal = gtk.Calendar()
vb.pack_start(cal, expand=False, padding=0)
btn = gtk.Button('Done')
btn.connect('clicked', self.__get_date, cal, entry, d)
vb.pack_start(btn, expand=False, padding=4)
d.add(vb)
d.set_position(gtk.WIN_POS_MOUSE)
d.show_all()
#end def __calendar_dialog
def __clear_dates(self, w):
self.start_date.set_text('')
self.end_date.set_text('')
#end def __clear_dates
def __get_dates(self):
# self.day_start gives user's start of day in hours
offset = int(self.day_start * 3600) # calc day_start in seconds
t1 = self.start_date.get_text()
t2 = self.end_date.get_text()
if t1 == '':
t1 = '1970-01-02'
if t2 == '':
t2 = '2020-12-12'
s1 = strptime(t1, "%Y-%m-%d") # make time_struct
s2 = strptime(t2, "%Y-%m-%d")
e1 = mktime(s1) + offset # s1 is localtime, but returned time since epoch is UTC, then add the
e2 = mktime(s2) + offset # s2 is localtime, but returned time since epoch is UTC
e2 = e2 + 24 * 3600 - 1 # date test is inclusive, so add 23h 59m 59s to e2
adj_t1 = strftime("%Y-%m-%d %H:%M:%S", gmtime(e1)) # make adjusted string including time
adj_t2 = strftime("%Y-%m-%d %H:%M:%S", gmtime(e2))
log.info("t1="+t1+" adj_t1="+adj_t1+'.')
return (adj_t1, adj_t2)
#end def __get_dates
def __refresh(self, widget, entry):
def __refresh(self, widget, entry): #identical with Filters
for w in self.mainVBox.get_children():
w.destroy()
self.make_filter()
#end def __refresh
def __set_hero_name(self, w, site):
_name = w.get_text()
# get_text() returns a str but we want internal variables to be unicode:
_guiname = unicode(_name)
self.heroes[site] = _guiname
#log.debug("setting heroes[%s]: %s"%(site, self.heroes[site]))
#end def __set_hero_name
def __set_num_tourneys(self, w, val):
try:
self.numTourneys = int(w.get_text())
@ -133,25 +77,7 @@ class TourneyFilters(Filters.Filters):
print "setting numTourneys:", self.numTourneys
#end def __set_num_tourneys
def __set_seat_select(self, w, seat):
#print "__set_seat_select: seat =", seat, "active =", w.get_active()
self.seats[seat] = w.get_active()
log.debug( "self.seats[%s] set to %s" %(seat, self.seats[seat]) )
#end def __set_seat_select
def __set_site_select(self, w, site):
#print w.get_active()
self.sites[site] = w.get_active()
log.debug("self.sites[%s] set to %s" %(site, self.sites[site]))
#end def __set_site_select
def __set_tourney_type_select(self, w, tourneyType):
#print w.get_active()
self.tourneyTypes[tourneyType] = w.get_active()
log.debug("self.tourney_types[%s] set to %s" %(tourneyType, self.tourneyTypes[tourneyType]))
#end def __set_tourney_type_select
def __toggle_box(self, widget, entry):
def __toggle_box(self, widget, entry): #identical with Filters
if self.boxes[entry].props.visible:
self.boxes[entry].hide()
widget.set_label("show")
@ -160,259 +86,6 @@ class TourneyFilters(Filters.Filters):
widget.set_label("hide")
#end def __toggle_box
def createPlayerLine(self, hbox, site, player):
log.debug('add:"%s"' % player)
label = gtk.Label(site +" id:")
hbox.pack_start(label, False, False, 3)
pname = gtk.Entry()
pname.set_text(player)
pname.set_width_chars(20)
hbox.pack_start(pname, False, True, 0)
#pname.connect("changed", self.__set_hero_name, site)
# Added EntryCompletion but maybe comboBoxEntry is more flexible? (e.g. multiple choices)
completion = gtk.EntryCompletion()
pname.set_completion(completion)
liststore = gtk.ListStore(gobject.TYPE_STRING)
completion.set_model(liststore)
completion.set_text_column(0)
names = self.db.get_player_names(self.conf, self.siteid[site]) # (config=self.conf, site_id=None, like_player_name="%")
for n in names: # list of single-element "tuples"
_n = Charset.to_gui(n[0])
_nt = (_n, )
liststore.append(_nt)
self.__set_hero_name(pname, site)
#end def createPlayerLine
def createSiteLine(self, hbox, site):
cb = gtk.CheckButton(site)
cb.connect('clicked', self.__set_site_select, site)
cb.set_active(True)
hbox.pack_start(cb, False, False, 0)
#end def createSiteLine
def createTourneyTypeLine(self, hbox, tourneyType):
cb = gtk.CheckButton(str(tourneyType))
cb.connect('clicked', self.__set_tourney_type_select, tourneyType)
hbox.pack_start(cb, False, False, 0)
cb.set_active(True)
#end def createTourneyTypeLine
def fillDateFrame(self, vbox):
# Hat tip to Mika Bostrom - calendar code comes from PokerStats
top_hbox = gtk.HBox(False, 0)
vbox.pack_start(top_hbox, False, False, 0)
lbl_title = gtk.Label(self.filterText['datestitle'])
lbl_title.set_alignment(xalign=0.0, yalign=0.5)
top_hbox.pack_start(lbl_title, expand=True, padding=3)
showb = gtk.Button(label="hide", stock=None, use_underline=True)
showb.set_alignment(xalign=1.0, yalign=0.5)
showb.connect('clicked', self.__toggle_box, 'dates')
top_hbox.pack_start(showb, expand=False, padding=1)
vbox1 = gtk.VBox(False, 0)
vbox.pack_start(vbox1, False, False, 0)
self.boxes['dates'] = vbox1
hbox = gtk.HBox()
vbox1.pack_start(hbox, False, True, 0)
lbl_start = gtk.Label('From:')
btn_start = gtk.Button()
btn_start.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
btn_start.connect('clicked', self.__calendar_dialog, self.start_date)
hbox.pack_start(lbl_start, expand=False, padding=3)
hbox.pack_start(btn_start, expand=False, padding=3)
hbox.pack_start(self.start_date, expand=False, padding=2)
#New row for end date
hbox = gtk.HBox()
vbox1.pack_start(hbox, False, True, 0)
lbl_end = gtk.Label(' To:')
btn_end = gtk.Button()
btn_end.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
btn_end.connect('clicked', self.__calendar_dialog, self.end_date)
btn_clear = gtk.Button(label=' Clear Dates ')
btn_clear.connect('clicked', self.__clear_dates)
hbox.pack_start(lbl_end, expand=False, padding=3)
hbox.pack_start(btn_end, expand=False, padding=3)
hbox.pack_start(self.end_date, expand=False, padding=2)
hbox.pack_start(btn_clear, expand=False, padding=15)
#end def fillDateFrame
def fillPlayerFrame(self, vbox, display):
top_hbox = gtk.HBox(False, 0)
vbox.pack_start(top_hbox, False, False, 0)
lbl_title = gtk.Label(self.filterText['playerstitle'])
lbl_title.set_alignment(xalign=0.0, yalign=0.5)
top_hbox.pack_start(lbl_title, expand=True, padding=3)
showb = gtk.Button(label="refresh", stock=None, use_underline=True)
showb.set_alignment(xalign=1.0, yalign=0.5)
showb.connect('clicked', self.__refresh, 'players')
vbox1 = gtk.VBox(False, 0)
vbox.pack_start(vbox1, False, False, 0)
self.boxes['players'] = vbox1
for site in self.conf.get_supported_sites():
hBox = gtk.HBox(False, 0)
vbox1.pack_start(hBox, False, True, 0)
player = self.conf.supported_sites[site].screen_name
_pname = Charset.to_gui(player)
self.createPlayerLine(hBox, site, _pname)
hbox = gtk.HBox(False, 0)
vbox1.pack_start(hbox, False, False, 0)
#cb = gtk.CheckButton(self.filterText['groupsall'])
#cb.connect('clicked', self.__set_group_select, 'allplayers')
#hbox.pack_start(cb, False, False, 0)
#self.sbGroups['allplayers'] = cb
#self.groups['allplayers'] = False
#lbl = gtk.Label('Min # Hands:')
#lbl.set_alignment(xalign=1.0, yalign=0.5)
#hbox.pack_start(lbl, expand=True, padding=3)
#phands = gtk.Entry()
#phands.set_text('0')
#phands.set_width_chars(8)
#hbox.pack_start(phands, False, False, 0)
#phands.connect("changed", self.__set_num_hands, site)
top_hbox.pack_start(showb, expand=False, padding=1)
#end def fillPlayerFrame
def fillSeatsFrame(self, vbox, display):
hbox = gtk.HBox(False, 0)
vbox.pack_start(hbox, False, False, 0)
lbl_title = gtk.Label(self.filterText['seatstitle'])
lbl_title.set_alignment(xalign=0.0, yalign=0.5)
hbox.pack_start(lbl_title, expand=True, padding=3)
showb = gtk.Button(label="hide", stock=None, use_underline=True)
showb.set_alignment(xalign=1.0, yalign=0.5)
showb.connect('clicked', self.__toggle_box, 'seats')
hbox.pack_start(showb, expand=False, padding=1)
vbox1 = gtk.VBox(False, 0)
vbox.pack_start(vbox1, False, False, 0)
self.boxes['seats'] = vbox1
hbox = gtk.HBox(False, 0)
vbox1.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)
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)
self.sbSeats['from'] = sb1
self.sbSeats['to'] = sb2
#end def fillSeatsFrame
def fillSitesFrame(self, vbox):
top_hbox = gtk.HBox(False, 0)
top_hbox.show()
vbox.pack_start(top_hbox, False, False, 0)
lbl_title = gtk.Label(self.filterText['sitestitle'])
lbl_title.set_alignment(xalign=0.0, yalign=0.5)
top_hbox.pack_start(lbl_title, expand=True, padding=3)
showb = gtk.Button(label="hide", stock=None, use_underline=True)
showb.set_alignment(xalign=1.0, yalign=0.5)
showb.connect('clicked', self.__toggle_box, 'sites')
showb.show()
top_hbox.pack_start(showb, expand=False, padding=1)
vbox1 = gtk.VBox(False, 0)
self.boxes['sites'] = vbox1
vbox.pack_start(vbox1, False, False, 0)
for site in self.conf.get_supported_sites():
hbox = gtk.HBox(False, 0)
vbox1.pack_start(hbox, False, True, 0)
self.createSiteLine(hbox, site)
#end def fillSitesFrame
def fillTourneyTypesFrame(self, vbox):
top_hbox = gtk.HBox(False, 0)
vbox.pack_start(top_hbox, False, False, 0)
lbl_title = gtk.Label(self.filterText['tourneyTypesTitle'])
lbl_title.set_alignment(xalign=0.0, yalign=0.5)
top_hbox.pack_start(lbl_title, expand=True, padding=3)
showb = gtk.Button(label="hide", stock=None, use_underline=True)
showb.set_alignment(xalign=1.0, yalign=0.5)
showb.connect('clicked', self.__toggle_box, 'tourneyTypes')
top_hbox.pack_start(showb, expand=False, padding=1)
vbox1 = gtk.VBox(False, 0)
vbox.pack_start(vbox1, False, False, 0)
self.boxes['tourneyTypes'] = vbox1
result = self.db.getTourneyTypesIds()
if len(result) >= 1:
for line in result:
hbox = gtk.HBox(False, 0)
vbox1.pack_start(hbox, False, True, 0)
self.createTourneyTypeLine(hbox, line[0])
else:
print "INFO: No tourney types returned from database"
log.info("No tourney types returned from database")
#end def fillTourneyTypesFrame
def getDates(self):
return self.__get_dates()
#end def getDates
def getHeroes(self):
return self.heroes
#end def getHeroes
def getNumTourneys(self):
return self.numTourneys
#end def getNumTourneys
def getSeats(self):
if 'from' in self.sbSeats:
self.seats['from'] = self.sbSeats['from'].get_value_as_int()
if 'to' in self.sbSeats:
self.seats['to'] = self.sbSeats['to'].get_value_as_int()
return self.seats
#end def getSeats
def getSiteIds(self):
return self.siteid
#end def getSiteIds
def getSites(self):
return self.sites
#end def getSites
def getTourneyTypes(self):
return self.tourneyTypes
#end def getTourneyTypes
def get_vbox(self):
"""returns the vbox of this thread"""
return self.mainVBox
#end def get_vbox
def make_filter(self):
self.tourneyTypes = {}
#self.tourneys = {}
@ -526,15 +199,4 @@ class TourneyFilters(Filters.Filters):
# make sure any locks on db are released:
self.db.rollback()
#end def make_filter
def registerButton2Name(self, title):
self.Button2.set_label(title)
self.label['button2'] = title
#end def registerButton2Name
def registerButton2Callback(self, callback):
self.Button2.connect("clicked", callback, "clicked")
self.Button2.set_sensitive(True)
self.callback['button2'] = callback
#end def registerButton2Callback
#end class TourneyFilters

View File

@ -107,7 +107,6 @@ import ImapFetcher
import GuiRingPlayerStats
import GuiTourneyPlayerStats
import GuiPositionalStats
import GuiTableViewer
import GuiAutoImport
import GuiGraphViewer
import GuiSessionViewer
@ -117,7 +116,7 @@ import Configuration
import Exceptions
import Stats
VERSION = "0.20.1 plus git"
VERSION = "0.20.901 plus git"
class fpdb:
@ -306,8 +305,8 @@ class fpdb:
dia.destroy()
def dia_maintain_dbs(self, widget, data=None):
self.warning_box("Unimplemented: Maintain Databases")
return
#self.warning_box("Unimplemented: Maintain Databases")
#return
if len(self.tab_names) == 1:
if self.obtain_global_lock("dia_maintain_dbs"): # returns true if successful
# only main tab has been opened, open dialog
@ -321,8 +320,14 @@ class fpdb:
prefs = GuiDatabase.GuiDatabase(self.config, self.window, dia)
response = dia.run()
if response == gtk.RESPONSE_ACCEPT:
log.info('saving updated db data')
# save updated config
self.config.save()
self.load_profile()
for name in self.config.supported_databases: #db_ip/db_user/db_pass/db_server
log.info('fpdb: name,desc='+name+','+self.config.supported_databases[name].db_desc)
else:
log.info('guidb response was '+str(response))
self.release_global_lock()
@ -547,23 +552,14 @@ class fpdb:
# self.release_global_lock()
# lock_released = True
self.db.recreate_tables()
# find any guibulkimport windows and clear player cache:
# find any guibulkimport/guiautoimport windows and clear player cache:
for t in self.threads:
if isinstance(t, GuiBulkImport.GuiBulkImport):
if isinstance(t, GuiBulkImport.GuiBulkImport) or isinstance(t, GuiAutoImport.GuiAutoImport):
t.importer.database.resetPlayerIDs()
self.release_global_lock()
#else:
# for other dbs use same connection as holds global lock
# self.fdb_lock.fdb.recreate_tables()
# TODO: figure out why this seems to be necessary
dia_restart = gtk.MessageDialog(parent=self.window, flags=0, type=gtk.MESSAGE_WARNING,
buttons=(gtk.BUTTONS_OK), message_format="Restart fpdb")
diastring = "Fpdb now needs to close. Please restart it."
dia_restart.format_secondary_text(diastring)
dia_restart.run()
dia_restart.destroy()
self.quit(None, None)
elif response == gtk.RESPONSE_NO:
self.release_global_lock()
print 'User cancelled recreating tables'
@ -801,7 +797,6 @@ class fpdb:
<menuitem action="tourneyplayerstats"/>
<menuitem action="posnstats"/>
<menuitem action="sessionstats"/>
<menuitem action="tableviewer"/>
</menu>
<menu action="database">
<menuitem action="maintaindbs"/>
@ -839,12 +834,11 @@ class fpdb:
('hudConfigurator', None, '_HUD Configurator', '<control>H', 'HUD Configurator', self.diaHudConfigurator),
('graphs', None, '_Graphs', '<control>G', 'Graphs', self.tabGraphViewer),
('ringplayerstats', None, 'Ring _Player Stats (tabulated view)', '<control>P', 'Ring Player Stats (tabulated view)', self.tab_ring_player_stats),
('tourneyplayerstats', None, '_Tourney Player Stats (tabulated view)', '<control>T', 'Tourney Player Stats (tabulated view)', self.tab_tourney_player_stats),
('tourneyplayerstats', None, '_Tourney Player Stats (tabulated view, mysql only)', '<control>T', 'Tourney Player Stats (tabulated view, mysql only)', self.tab_tourney_player_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),
('tableviewer', None, 'Poker_table Viewer (mostly obselete)', None, 'Poker_table Viewer (mostly obselete)', self.tab_table_viewer),
('database', None, '_Database'),
('maintaindbs', None, '_Maintain Databases (todo)', None, 'Maintain Databases', self.dia_maintain_dbs),
('maintaindbs', None, '_Maintain Databases', None, 'Maintain Databases', self.dia_maintain_dbs),
('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),
('rebuildindexes', None, 'Rebuild DB Indexes', None, 'Rebuild DB Indexes', self.dia_rebuild_indexes),
@ -1071,13 +1065,6 @@ This program is free/libre open source software licensed partially under the AGP
You can find the full license texts in agpl-3.0.txt, gpl-2.0.txt and gpl-3.0.txt in the fpdb installation directory.""")
self.add_and_display_tab(mh_tab, "Help")
def tab_table_viewer(self, widget, data=None):
"""opens a table viewer tab"""
new_tv_thread = GuiTableViewer.GuiTableViewer(self.db, self.settings, self.config)
self.threads.append(new_tv_thread)
tv_tab = new_tv_thread.get_vbox()
self.add_and_display_tab(tv_tab, "Table Viewer")
def tabGraphViewer(self, widget, data=None):
"""opens a graph viewer tab"""
new_gv_thread = GuiGraphViewer.GuiGraphViewer(self.sql, self.config, self.window)

View File

@ -1,5 +1,5 @@
[loggers]
keys=root,fpdb,logview,parser,importer,config,db,hud,filter
keys=root,fpdb,logview,parser,importer,config,db,hud,filter,maintdbs
[handlers]
keys=consoleHandler,rotatingFileHandler
@ -17,6 +17,12 @@ handlers=consoleHandler,rotatingFileHandler
qualname=fpdb
propagate=0
[logger_maintdbs]
level=INFO
handlers=consoleHandler,rotatingFileHandler
qualname=maintdbs
propagate=0
[logger_logview]
level=INFO
handlers=consoleHandler,rotatingFileHandler

View File

@ -13,14 +13,12 @@ from distutils.core import setup
setup(name = 'fpdb',
description = 'Free Poker Database',
version = '0.12',
version = '0.20',
author = 'FPDB team',
author_email = 'fpdb-main@lists.sourceforge.net',
packages = ['fpdb'],
package_dir = { 'fpdb' : 'pyfpdb' },
data_files = [
('/usr/share/doc/python-fpdb',
['THANKS.txt']),
('/usr/share/pixmaps',
['gfx/fpdb-icon.png', 'gfx/fpdb-icon2.png',
'gfx/fpdb-cards.png'