Merge branch 'master' of git://git.assembla.com/fpdb-sql
Conflicts: pyfpdb/Hand.py
This commit is contained in:
commit
7351749b7a
|
@ -88,12 +88,32 @@ class Site:
|
|||
self.font_size = node.getAttribute("font_size")
|
||||
self.use_frames = node.getAttribute("use_frames")
|
||||
self.enabled = fix_tf(node.getAttribute("enabled"), default = True)
|
||||
self.xpad = node.getAttribute("xpad")
|
||||
self.ypad = node.getAttribute("ypad")
|
||||
self.layout = {}
|
||||
|
||||
for layout_node in node.getElementsByTagName('layout'):
|
||||
lo = Layout(layout_node)
|
||||
self.layout[lo.max] = lo
|
||||
|
||||
# Site defaults
|
||||
if self.xpad == "": self.xpad = 1
|
||||
else: self.xpad = int(self.xpad)
|
||||
|
||||
if self.ypad == "": self.ypad = 0
|
||||
else: self.ypad = int(self.ypad)
|
||||
|
||||
if self.font_size == "": self.font_size = 7
|
||||
else: self.font_size = int(self.font_size)
|
||||
|
||||
if self.hudopacity == "": self.hudopacity = 1.0
|
||||
else: self.hudopacity = float(self.hudopacity)
|
||||
|
||||
if self.use_frames == "": self.use_frames = False
|
||||
if self.font == "": self.font = "Sans"
|
||||
if self.hudbgcolor == "": self.hudbgcolor = "000000"
|
||||
if self.hudfgcolor == "": self.hudfgcolor = "FFFFFF"
|
||||
|
||||
def __str__(self):
|
||||
temp = "Site = " + self.site_name + "\n"
|
||||
for key in dir(self):
|
||||
|
@ -119,9 +139,16 @@ class Stat:
|
|||
class Game:
|
||||
def __init__(self, node):
|
||||
self.game_name = node.getAttribute("game_name")
|
||||
self.db = node.getAttribute("db")
|
||||
self.rows = int( node.getAttribute("rows") )
|
||||
self.cols = int( node.getAttribute("cols") )
|
||||
self.xpad = node.getAttribute("xpad")
|
||||
self.ypad = node.getAttribute("ypad")
|
||||
|
||||
# Defaults
|
||||
if self.xpad == "": self.xpad = 1
|
||||
else: self.xpad = int(self.xpad)
|
||||
if self.ypad == "": self.ypad = 0
|
||||
else: self.ypad = int(self.ypad)
|
||||
|
||||
aux_text = node.getAttribute("aux")
|
||||
aux_list = aux_text.split(',')
|
||||
|
@ -146,9 +173,10 @@ class Game:
|
|||
|
||||
def __str__(self):
|
||||
temp = "Game = " + self.game_name + "\n"
|
||||
temp = temp + " db = %s\n" % self.db
|
||||
temp = temp + " rows = %d\n" % self.rows
|
||||
temp = temp + " cols = %d\n" % self.cols
|
||||
temp = temp + " xpad = %d\n" % self.xpad
|
||||
temp = temp + " ypad = %d\n" % self.ypad
|
||||
temp = temp + " aux = %s\n" % self.aux
|
||||
|
||||
for stat in self.stats.keys():
|
||||
|
@ -631,6 +659,8 @@ class Config:
|
|||
parms["font"] = self.supported_sites[site].font
|
||||
parms["font_size"] = self.supported_sites[site].font_size
|
||||
parms["enabled"] = self.supported_sites[site].enabled
|
||||
parms["xpad"] = self.supported_sites[site].xpad
|
||||
parms["ypad"] = self.supported_sites[site].ypad
|
||||
return parms
|
||||
|
||||
def set_site_parameters(self, site_name, converter = None, decoder = None,
|
||||
|
@ -681,9 +711,10 @@ class Config:
|
|||
param = {}
|
||||
if self.supported_games.has_key(name):
|
||||
param['game_name'] = self.supported_games[name].game_name
|
||||
param['db'] = self.supported_games[name].db
|
||||
param['rows'] = self.supported_games[name].rows
|
||||
param['cols'] = self.supported_games[name].cols
|
||||
param['xpad'] = self.supported_games[name].xpad
|
||||
param['ypad'] = self.supported_games[name].ypad
|
||||
param['aux'] = self.supported_games[name].aux
|
||||
return param
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@ import SQL
|
|||
import Card
|
||||
|
||||
class Database:
|
||||
def __init__(self, c, db_name, game):
|
||||
def __init__(self, c, db_name = None, game = None, sql = None): # db_name and game not used any more
|
||||
print "\ncreating Database instance, sql =", sql
|
||||
self.fdb = fpdb_db.fpdb_db() # sets self.fdb.db self.fdb.cursor and self.fdb.sql
|
||||
self.fdb.do_connect(c)
|
||||
self.connection = self.fdb.db
|
||||
|
@ -48,7 +49,12 @@ class Database:
|
|||
self.import_options = c.get_import_parameters()
|
||||
self.type = db_params['db-type']
|
||||
self.backend = db_params['db-backend']
|
||||
self.sql = SQL.Sql(game = game, type = self.type, db_server = db_params['db-server'])
|
||||
self.db_server = db_params['db-server']
|
||||
# where possible avoid creating new SQL instance by using the global one passed in
|
||||
if sql == None:
|
||||
self.sql = SQL.Sql(type = self.type, db_server = db_params['db-server'])
|
||||
else:
|
||||
self.sql = sql
|
||||
self.connection.rollback()
|
||||
|
||||
# To add to config:
|
||||
|
@ -81,6 +87,8 @@ class Database:
|
|||
#row = cur.fetchone()
|
||||
self.saveActions = False if self.import_options['saveActions'] == False else True
|
||||
|
||||
def do_connect(self, c):
|
||||
self.fdb.do_connect(c)
|
||||
|
||||
def commit(self):
|
||||
self.fdb.db.commit()
|
||||
|
@ -88,6 +96,19 @@ class Database:
|
|||
def close_connection(self):
|
||||
self.connection.close()
|
||||
|
||||
def disconnect(self, due_to_error=False):
|
||||
"""Disconnects the DB (rolls back if param is true, otherwise commits"""
|
||||
self.fdb.disconnect(due_to_error)
|
||||
|
||||
def reconnect(self, due_to_error=False):
|
||||
"""Reconnects the DB"""
|
||||
self.fdb.reconnect(due_to_error=False)
|
||||
|
||||
def get_backend_name(self):
|
||||
"""Reconnects the DB"""
|
||||
return self.fdb.get_backend_name()
|
||||
|
||||
|
||||
def get_table_name(self, hand_id):
|
||||
c = self.connection.cursor()
|
||||
c.execute(self.sql.query['get_table_name'], (hand_id, ))
|
||||
|
@ -138,12 +159,8 @@ class Database:
|
|||
cards = {}
|
||||
c = self.connection.cursor()
|
||||
c.execute(self.sql.query['get_common_cards'], [hand])
|
||||
colnames = [desc[0] for desc in c.description]
|
||||
for row in c.fetchall():
|
||||
s_dict = {}
|
||||
for name, val in zip(colnames, row):
|
||||
s_dict[name] = val
|
||||
cards['common'] = (self.convert_cards(s_dict))
|
||||
# row = c.fetchone()
|
||||
cards['common'] = c.fetchone()
|
||||
return cards
|
||||
|
||||
def convert_cards(self, d):
|
||||
|
@ -326,7 +343,6 @@ class Database:
|
|||
if 'updateHudCache' not in settings or settings['updateHudCache'] != 'drop':
|
||||
fpdb_simple.storeHudCache(self.backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData)
|
||||
t5 = time()
|
||||
fpdb_simple.store_board_cards(cursor, hands_id, board_values, board_suits)
|
||||
t6 = time()
|
||||
if self.saveActions:
|
||||
fpdb_simple.storeActions(cursor, hands_players_ids, action_types, allIns, action_amounts, actionNos)
|
||||
|
@ -361,8 +377,6 @@ class Database:
|
|||
if 'updateHudCache' not in settings or settings['updateHudCache'] != 'drop':
|
||||
fpdb_simple.storeHudCache(self.backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData)
|
||||
|
||||
fpdb_simple.store_board_cards(cursor, hands_id, board_values, board_suits)
|
||||
|
||||
if self.saveActions:
|
||||
fpdb_simple.storeActions(cursor, hands_players_ids, action_types, allIns, action_amounts, actionNos)
|
||||
return hands_id
|
||||
|
|
|
@ -30,12 +30,11 @@ import fpdb_db
|
|||
import FpdbSQLQueries
|
||||
|
||||
class Filters(threading.Thread):
|
||||
def __init__(self, db, settings, config, qdict, display = {},debug=True):
|
||||
def __init__(self, db, config, qdict, display = {}, debug=True):
|
||||
self.debug=debug
|
||||
#print "start of GraphViewer constructor"
|
||||
self.db=db
|
||||
self.cursor=db.cursor
|
||||
self.settings=settings
|
||||
self.sql=qdict
|
||||
self.conf = config
|
||||
self.display = display
|
||||
|
@ -235,7 +234,7 @@ class Filters(threading.Thread):
|
|||
|
||||
def __set_hero_name(self, w, site):
|
||||
self.heroes[site] = w.get_text()
|
||||
# print "DEBUG: settings heroes[%s]: %s"%(site, self.heroes[site])
|
||||
# print "DEBUG: setting heroes[%s]: %s"%(site, self.heroes[site])
|
||||
|
||||
def createSiteLine(self, hbox, site):
|
||||
cb = gtk.CheckButton(site)
|
||||
|
@ -556,23 +555,12 @@ def main(argv=None):
|
|||
config = Configuration.Config()
|
||||
db = None
|
||||
|
||||
settings = {}
|
||||
|
||||
settings.update(config.get_db_parameters())
|
||||
settings.update(config.get_tv_parameters())
|
||||
settings.update(config.get_import_parameters())
|
||||
settings.update(config.get_default_paths())
|
||||
|
||||
db = fpdb_db.fpdb_db()
|
||||
db.connect(settings['db-backend'],
|
||||
settings['db-host'],
|
||||
settings['db-databaseName'],
|
||||
settings['db-user'],
|
||||
settings['db-password'])
|
||||
db.do_connect(config)
|
||||
|
||||
qdict = FpdbSQLQueries.FpdbSQLQueries(db.get_backend_name())
|
||||
|
||||
i = Filters(db, settings, config, qdict)
|
||||
i = Filters(db, config, qdict)
|
||||
main_window = gtk.Window()
|
||||
main_window.connect('destroy', destroy)
|
||||
main_window.add(i.get_vbox())
|
||||
|
|
|
@ -248,43 +248,6 @@ class FpdbSQLQueries:
|
|||
self.query['createHandsTable'] = """ """
|
||||
|
||||
|
||||
################################
|
||||
# Create Gametypes
|
||||
################################
|
||||
|
||||
if(self.dbname == 'MySQL InnoDB'):
|
||||
self.query['createBoardCardsTable'] = """CREATE TABLE BoardCards (
|
||||
id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
|
||||
handId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handId) REFERENCES Hands(id),
|
||||
card1Value smallint NOT NULL,
|
||||
card1Suit char(1) NOT NULL,
|
||||
card2Value smallint NOT NULL,
|
||||
card2Suit char(1) NOT NULL,
|
||||
card3Value smallint NOT NULL,
|
||||
card3Suit char(1) NOT NULL,
|
||||
card4Value smallint NOT NULL,
|
||||
card4Suit char(1) NOT NULL,
|
||||
card5Value smallint NOT NULL,
|
||||
card5Suit char(1) NOT NULL)
|
||||
ENGINE=INNODB"""
|
||||
elif(self.dbname == 'PostgreSQL'):
|
||||
self.query['createBoardCardsTable'] = """CREATE TABLE BoardCards (
|
||||
id BIGSERIAL, PRIMARY KEY (id),
|
||||
handId BIGINT, FOREIGN KEY (handId) REFERENCES Hands(id),
|
||||
card1Value smallint,
|
||||
card1Suit char(1),
|
||||
card2Value smallint,
|
||||
card2Suit char(1),
|
||||
card3Value smallint,
|
||||
card3Suit char(1),
|
||||
card4Value smallint,
|
||||
card4Suit char(1),
|
||||
card5Value smallint,
|
||||
card5Suit char(1))"""
|
||||
elif(self.dbname == 'SQLite'):
|
||||
self.query['createBoardCardsTable'] = """ """
|
||||
|
||||
|
||||
################################
|
||||
# Create TourneyTypes
|
||||
################################
|
||||
|
@ -1550,136 +1513,6 @@ class FpdbSQLQueries:
|
|||
elif(self.dbname == 'SQLite'):
|
||||
self.query['playerStatsByPosition'] = """ """
|
||||
|
||||
if(self.dbname == 'MySQL InnoDB'):
|
||||
self.query['playerStatsByPositionAndHoleCards'] = """
|
||||
SELECT
|
||||
concat(upper(stats.limitType), ' '
|
||||
,concat(upper(substring(stats.category,1,1)),substring(stats.category,2) ), ' '
|
||||
,stats.name, ' $'
|
||||
,cast(trim(leading ' ' from
|
||||
case when stats.bigBlind < 100 then format(stats.bigBlind/100.0,2)
|
||||
else format(stats.bigBlind/100.0,0)
|
||||
end ) as char)
|
||||
) AS Game
|
||||
,case when stats.PlPosition = -2 then 'BB'
|
||||
when stats.PlPosition = -1 then 'SB'
|
||||
when stats.PlPosition = 0 then 'Btn'
|
||||
when stats.PlPosition = 1 then 'CO'
|
||||
when stats.PlPosition = 2 then 'MP'
|
||||
when stats.PlPosition = 5 then 'EP'
|
||||
else '??'
|
||||
end AS PlPosition
|
||||
/*,stats.n*/,hprof2.n
|
||||
/*,stats.vpip*/,0
|
||||
/*,stats.pfr*/,0
|
||||
/*,stats.saw_f*/,0
|
||||
/*,stats.sawsd*/,0
|
||||
/*,stats.wtsdwsf*/,0
|
||||
/*,stats.wmsd*/,0
|
||||
/*,stats.FlAFq*/,0
|
||||
/*,stats.TuAFq*/,0
|
||||
/*,stats.RvAFq*/,0
|
||||
/*,stats.PoFAFq*/,0
|
||||
/* if you have handsactions data the next 3 fields should give same answer as
|
||||
following 3 commented out fields */
|
||||
/*,stats.Net
|
||||
,stats.BBper100
|
||||
,stats.Profitperhand*/
|
||||
,format(hprof2.sum_profit/100.0,2) AS Net
|
||||
/*,format((hprof2.sum_profit/(stats.bigBlind+0.0)) / (stats.n/100.0),2)*/,0
|
||||
AS BBlPer100
|
||||
,hprof2.profitperhand AS Profitperhand
|
||||
,format(hprof2.variance,2) AS Variance
|
||||
FROM
|
||||
(select /* stats from hudcache */
|
||||
gt.base
|
||||
,gt.category
|
||||
,upper(gt.limitType) as limitType
|
||||
,s.name
|
||||
,gt.bigBlind
|
||||
,hc.gametypeId
|
||||
,case when hc.position = 'B' then -2
|
||||
when hc.position = 'S' then -1
|
||||
when hc.position = 'D' then 0
|
||||
when hc.position = 'C' then 1
|
||||
when hc.position = 'M' then 2
|
||||
when hc.position = 'E' then 5
|
||||
else 9
|
||||
end as PlPosition
|
||||
,sum(HDs) AS n
|
||||
,format(100.0*sum(street0VPI)/sum(HDs),1) AS vpip
|
||||
,format(100.0*sum(street0Aggr)/sum(HDs),1) AS pfr
|
||||
,format(100.0*sum(street1Seen)/sum(HDs),1) AS saw_f
|
||||
,format(100.0*sum(sawShowdown)/sum(HDs),1) AS sawsd
|
||||
,case when sum(street1Seen) = 0 then '-'
|
||||
else format(100.0*sum(sawShowdown)/sum(street1Seen),1)
|
||||
end AS wtsdwsf
|
||||
,case when sum(sawShowdown) = 0 then '-'
|
||||
end AS wtsdwsf
|
||||
,case when sum(sawShowdown) = 0 then '-'
|
||||
else format(100.0*sum(wonAtSD)/sum(sawShowdown),1)
|
||||
end AS wmsd
|
||||
,case when sum(street1Seen) = 0 then '-'
|
||||
else format(100.0*sum(street1Aggr)/sum(street1Seen),1)
|
||||
end AS FlAFq
|
||||
,case when sum(street2Seen) = 0 then '-'
|
||||
else format(100.0*sum(street2Aggr)/sum(street2Seen),1)
|
||||
end AS TuAFq
|
||||
,case when sum(street3Seen) = 0 then '-'
|
||||
else format(100.0*sum(street3Aggr)/sum(street3Seen),1)
|
||||
end AS RvAFq
|
||||
,case when sum(street1Seen)+sum(street2Seen)+sum(street3Seen) = 0 then '-'
|
||||
else format(100.0*(sum(street1Aggr)+sum(street2Aggr)+sum(street3Aggr))
|
||||
/(sum(street1Seen)+sum(street2Seen)+sum(street3Seen)),1)
|
||||
end AS PoFAFq
|
||||
,format(sum(totalProfit)/100.0,2) AS Net
|
||||
,format((sum(totalProfit)/(gt.bigBlind+0.0)) / (sum(HDs)/100.0),2)
|
||||
AS BBper100
|
||||
,format( (sum(totalProfit)/100.0) / sum(HDs), 4) AS Profitperhand
|
||||
from Gametypes gt
|
||||
inner join Sites s on s.Id = gt.siteId
|
||||
inner join HudCache hc on hc.gameTypeId = gt.Id
|
||||
where hc.playerId in <player_test>
|
||||
# use <gametype_test> here ?
|
||||
group by gt.base
|
||||
,gt.category
|
||||
,upper(gt.limitType)
|
||||
,s.name
|
||||
,gt.bigBlind
|
||||
,hc.gametypeId
|
||||
,PlPosition
|
||||
) stats
|
||||
inner join
|
||||
( select # profit from handsplayers/handsactions
|
||||
hprof.gameTypeId,
|
||||
case when hprof.position = 'B' then -2
|
||||
when hprof.position = 'S' then -1
|
||||
when hprof.position in ('3','4') then 2
|
||||
when hprof.position in ('6','7') then 5
|
||||
else hprof.position
|
||||
end as PlPosition,
|
||||
sum(hprof.profit) as sum_profit,
|
||||
avg(hprof.profit/100.0) as profitperhand,
|
||||
variance(hprof.profit/100.0) as variance,
|
||||
count(*) as n
|
||||
from
|
||||
(select hp.handId, h.gameTypeId, hp.position, hp.winnings, SUM(ha.amount) as costs
|
||||
, hp.winnings - SUM(ha.amount) as profit
|
||||
from HandsPlayers hp
|
||||
inner join Hands h ON h.id = hp.handId
|
||||
left join HandsActions ha ON ha.handsPlayerId = hp.id
|
||||
where hp.playerId in <player_test>
|
||||
# use <gametype_test> here ?
|
||||
and hp.tourneysPlayersId IS NULL
|
||||
and ((hp.card1Value = <first_card> and hp.card2Value = <second_card>) or (hp.card1Value = <second_card> and hp.card2Value = <first_card>))
|
||||
group by hp.handId, h.gameTypeId, hp.position, hp.winnings
|
||||
) hprof
|
||||
group by hprof.gameTypeId, PlPosition
|
||||
) hprof2
|
||||
on ( hprof2.gameTypeId = stats.gameTypeId
|
||||
and hprof2.PlPosition = stats.PlPosition)
|
||||
order by stats.category, stats.limittype, stats.bigBlind, cast(stats.PlPosition as signed)
|
||||
"""
|
||||
if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL') or (self.dbname == 'SQLite'):
|
||||
self.query['getGames'] = """SELECT DISTINCT category from Gametypes"""
|
||||
|
||||
|
|
|
@ -43,13 +43,13 @@ import Filters
|
|||
|
||||
class GuiGraphViewer (threading.Thread):
|
||||
|
||||
def __init__(self, db, settings, querylist, config, debug=True):
|
||||
def __init__(self, querylist, config, debug=True):
|
||||
"""Constructor for GraphViewer"""
|
||||
self.debug=debug
|
||||
#print "start of GraphViewer constructor"
|
||||
self.db=db
|
||||
self.cursor=db.cursor
|
||||
self.settings=settings
|
||||
self.db = fpdb_db.fpdb_db() # sets self.fdb.db self.fdb.cursor and self.fdb.sql
|
||||
self.db.do_connect(config)
|
||||
|
||||
self.sql = querylist
|
||||
self.conf = config
|
||||
|
||||
|
@ -63,7 +63,7 @@ class GuiGraphViewer (threading.Thread):
|
|||
"Button2" : True
|
||||
}
|
||||
|
||||
self.filters = Filters.Filters(db, settings, config, querylist, display = filters_display)
|
||||
self.filters = Filters.Filters(self.db, config, querylist, display = filters_display)
|
||||
self.filters.registerButton1Name("Refresh Graph")
|
||||
self.filters.registerButton1Callback(self.generateGraph)
|
||||
self.filters.registerButton2Name("Export to File")
|
||||
|
@ -146,7 +146,7 @@ class GuiGraphViewer (threading.Thread):
|
|||
for site in sites:
|
||||
if sites[site] == True:
|
||||
sitenos.append(siteids[site])
|
||||
self.cursor.execute(self.sql.query['getPlayerId'], (heroes[site],))
|
||||
self.db.cursor.execute(self.sql.query['getPlayerId'], (heroes[site],))
|
||||
result = self.db.cursor.fetchall()
|
||||
if len(result) == 1:
|
||||
playerids.append(result[0][0])
|
||||
|
@ -226,7 +226,7 @@ class GuiGraphViewer (threading.Thread):
|
|||
|
||||
#print "DEBUG: sql query:"
|
||||
#print tmp
|
||||
self.cursor.execute(tmp)
|
||||
self.db.cursor.execute(tmp)
|
||||
#returns (HandId,Winnings,Costs,Profit)
|
||||
winnings = self.db.cursor.fetchall()
|
||||
self.db.db.rollback()
|
||||
|
|
|
@ -66,7 +66,7 @@ class GuiPlayerStats (threading.Thread):
|
|||
"Button2" : True
|
||||
}
|
||||
|
||||
self.filters = Filters.Filters(self.db, settings, config, querylist, display = filters_display)
|
||||
self.filters = Filters.Filters(self.db, config, querylist, display = filters_display)
|
||||
self.filters.registerButton1Name("_Filters")
|
||||
self.filters.registerButton1Callback(self.showDetailFilter)
|
||||
self.filters.registerButton2Name("_Refresh")
|
||||
|
@ -227,11 +227,6 @@ class GuiPlayerStats (threading.Thread):
|
|||
if not flags: holecards = False
|
||||
else: holecards = flags[0]
|
||||
|
||||
|
||||
self.stats_table = gtk.Table(1, 1, False)
|
||||
self.stats_table.set_col_spacings(4)
|
||||
self.stats_table.show()
|
||||
|
||||
tmp = self.sql.query[query]
|
||||
tmp = self.refineQuery(tmp, flags, playerids, sitenos, limits, seats, groups, dates)
|
||||
self.cursor.execute(tmp)
|
||||
|
@ -279,10 +274,6 @@ class GuiPlayerStats (threading.Thread):
|
|||
|
||||
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])]
|
||||
|
|
|
@ -20,6 +20,7 @@ import pygtk
|
|||
pygtk.require('2.0')
|
||||
import gtk
|
||||
import os
|
||||
from time import time, strftime
|
||||
|
||||
import fpdb_import
|
||||
import fpdb_db
|
||||
|
@ -58,21 +59,50 @@ class GuiPositionalStats (threading.Thread):
|
|||
"Button2" : False
|
||||
}
|
||||
|
||||
self.filters = Filters.Filters(self.db, settings, config, querylist, display = filters_display)
|
||||
self.filters = Filters.Filters(self.db, config, querylist, display = filters_display)
|
||||
self.filters.registerButton1Name("Refresh")
|
||||
self.filters.registerButton1Callback(self.refreshStats)
|
||||
|
||||
# ToDo: store in config
|
||||
# ToDo: create popup to adjust column config
|
||||
# columns to display, keys match column name returned by sql, values in tuple are:
|
||||
# is column displayed, column heading, xalignment, formatting
|
||||
self.columns = [ ["game", True, "Game", 0.0, "%s"]
|
||||
, ["hand", False, "Hand", 0.0, "%s"] # true not allowed for this line
|
||||
, ["plposition", False, "Posn", 1.0, "%s"] # true not allowed for this line (set in code)
|
||||
, ["n", True, "Hds", 1.0, "%d"]
|
||||
, ["avgseats", True, "Seats", 1.0, "%3.1f"]
|
||||
, ["vpip", True, "VPIP", 1.0, "%3.1f"]
|
||||
, ["pfr", True, "PFR", 1.0, "%3.1f"]
|
||||
, ["pf3", True, "PF3", 1.0, "%3.1f"]
|
||||
, ["steals", True, "Steals", 1.0, "%3.1f"]
|
||||
, ["saw_f", True, "Saw_F", 1.0, "%3.1f"]
|
||||
, ["sawsd", True, "SawSD", 1.0, "%3.1f"]
|
||||
, ["wtsdwsf", True, "WtSDwsF", 1.0, "%3.1f"]
|
||||
, ["wmsd", True, "W$SD", 1.0, "%3.1f"]
|
||||
, ["flafq", True, "FlAFq", 1.0, "%3.1f"]
|
||||
, ["tuafq", True, "TuAFq", 1.0, "%3.1f"]
|
||||
, ["rvafq", True, "RvAFq", 1.0, "%3.1f"]
|
||||
, ["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"]
|
||||
, ["bb100xr", True, "bbxr/100", 1.0, "%4.2f"]
|
||||
, ["variance", True, "Variance", 1.0, "%5.2f"]
|
||||
]
|
||||
|
||||
self.stat_table = None
|
||||
self.stats_frame = None
|
||||
self.stats_vbox = None
|
||||
|
||||
self.main_hbox = gtk.HBox(False, 0)
|
||||
self.main_hbox.show()
|
||||
|
||||
statsFrame = gtk.Frame("Stats:")
|
||||
statsFrame.set_label_align(0.0, 0.0)
|
||||
statsFrame.show()
|
||||
self.stats_frame = gtk.VBox(False, 0)
|
||||
self.stats_frame = gtk.Frame()
|
||||
self.stats_frame.set_label_align(0.0, 0.0)
|
||||
self.stats_frame.show()
|
||||
self.stats_vbox = gtk.VBox(False, 0)
|
||||
self.stats_vbox.show()
|
||||
|
||||
# This could be stored in config eventually, or maybe configured in this window somehow.
|
||||
# Each posncols element is the name of a column returned by the sql
|
||||
|
@ -90,11 +120,11 @@ class GuiPositionalStats (threading.Thread):
|
|||
, "PoFAFq", "Net($)", "bb/100", "$/hand", "Variance", "Hds"
|
||||
)
|
||||
|
||||
self.fillStatsFrame(self.stats_frame)
|
||||
statsFrame.add(self.stats_frame)
|
||||
self.fillStatsFrame(self.stats_vbox)
|
||||
self.stats_frame.add(self.stats_vbox)
|
||||
|
||||
self.main_hbox.pack_start(self.filters.get_vbox())
|
||||
self.main_hbox.pack_start(statsFrame)
|
||||
self.main_hbox.pack_start(self.stats_frame)
|
||||
|
||||
|
||||
def get_vbox(self):
|
||||
|
@ -107,9 +137,12 @@ class GuiPositionalStats (threading.Thread):
|
|||
print "DEBUG: activesite set to %s" %(self.activesite)
|
||||
|
||||
def refreshStats(self, widget, data):
|
||||
try: self.stats_table.destroy()
|
||||
try: self.stats_vbox.destroy()
|
||||
except AttributeError: pass
|
||||
self.fillStatsFrame(self.stats_frame)
|
||||
self.stats_vbox = gtk.VBox(False, 0)
|
||||
self.stats_vbox.show()
|
||||
self.stats_frame.add(self.stats_vbox)
|
||||
self.fillStatsFrame(self.stats_vbox)
|
||||
|
||||
def fillStatsFrame(self, vbox):
|
||||
sites = self.filters.getSites()
|
||||
|
@ -144,66 +177,104 @@ class GuiPositionalStats (threading.Thread):
|
|||
self.createStatsTable(vbox, playerids, sitenos, limits, seats, dates)
|
||||
|
||||
def createStatsTable(self, vbox, playerids, sitenos, limits, seats, dates):
|
||||
self.stats_table = gtk.Table(1, 1, False) # gtk table expands as required
|
||||
self.stats_table.set_col_spacings(4)
|
||||
self.stats_table.show()
|
||||
vbox.add(self.stats_table)
|
||||
|
||||
starttime = time()
|
||||
colalias,colshow,colheading,colxalign,colformat = 0,1,2,3,4
|
||||
row = 0
|
||||
col = 0
|
||||
for t in self.posnheads:
|
||||
l = gtk.Label(self.posnheads[col])
|
||||
l.show()
|
||||
self.stats_table.attach(l, col, col+1, row, row+1, yoptions=gtk.SHRINK)
|
||||
col +=1
|
||||
|
||||
tmp = self.sql.query['playerStatsByPosition']
|
||||
tmp = self.refineQuery(tmp, playerids, sitenos, limits, seats, dates)
|
||||
self.cursor.execute(tmp)
|
||||
result = self.cursor.fetchall()
|
||||
colnames = [desc[0].lower() for desc in self.cursor.description]
|
||||
|
||||
liststore = gtk.ListStore(*([str] * len(colnames)))
|
||||
view = gtk.TreeView(model=liststore)
|
||||
view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
|
||||
vbox.pack_start(view, expand=False, padding=3)
|
||||
# left-aligned cells:
|
||||
textcell = gtk.CellRendererText()
|
||||
# centred cells:
|
||||
textcell50 = gtk.CellRendererText()
|
||||
textcell50.set_property('xalign', 0.5)
|
||||
# right-aligned cells:
|
||||
numcell = gtk.CellRendererText()
|
||||
numcell.set_property('xalign', 1.0)
|
||||
listcols = []
|
||||
|
||||
for t in self.posnheads:
|
||||
listcols.append(gtk.TreeViewColumn(self.posnheads[col]))
|
||||
view.append_column(listcols[col])
|
||||
if col == 0:
|
||||
listcols[col].pack_start(textcell, expand=True)
|
||||
listcols[col].add_attribute(textcell, 'text', col)
|
||||
listcols[col].set_expand(True)
|
||||
elif col in (1, 2):
|
||||
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)
|
||||
col +=1
|
||||
|
||||
# Code below to be used when full column data structures implemented like in player stats:
|
||||
|
||||
# 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 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)
|
||||
# #listcols[col].set_alignment(column[colxalign]) # no effect?
|
||||
|
||||
rows = len(result)
|
||||
colnames = [desc[0].lower() for desc in self.cursor.description]
|
||||
|
||||
last_game,last_seats,sqlrow = "","",0
|
||||
while sqlrow < rows:
|
||||
if(row%2 == 0):
|
||||
bgcolor = "white"
|
||||
else:
|
||||
bgcolor = "lightgrey"
|
||||
rowprinted=0
|
||||
treerow = []
|
||||
avgcol = colnames.index('avgseats')
|
||||
for col,colname in enumerate(self.posncols):
|
||||
if colname in colnames:
|
||||
sqlcol = colnames.index(colname)
|
||||
else:
|
||||
continue
|
||||
eb = gtk.EventBox()
|
||||
eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bgcolor))
|
||||
# print blank row between levels:
|
||||
if result[sqlrow][sqlcol]:
|
||||
if sqlrow == 0:
|
||||
l = gtk.Label(result[sqlrow][sqlcol])
|
||||
value = result[sqlrow][sqlcol]
|
||||
rowprinted=1
|
||||
elif result[sqlrow][0] != last_game:
|
||||
l = gtk.Label(' ')
|
||||
value = ' '
|
||||
elif 'show' in seats and seats['show'] and result[sqlrow][avgcol] != last_seats:
|
||||
l = gtk.Label(' ')
|
||||
value = ' '
|
||||
else:
|
||||
l = gtk.Label(result[sqlrow][sqlcol])
|
||||
value = result[sqlrow][sqlcol]
|
||||
rowprinted=1
|
||||
else:
|
||||
l = gtk.Label(' ')
|
||||
if col == 0:
|
||||
l.set_alignment(xalign=0.0, yalign=0.5)
|
||||
elif col == 1:
|
||||
l.set_alignment(xalign=0.5, yalign=0.5)
|
||||
value = ' '
|
||||
if value and value != -999:
|
||||
treerow.append(value)
|
||||
else:
|
||||
l.set_alignment(xalign=1.0, yalign=0.5)
|
||||
eb.add(l)
|
||||
self.stats_table.attach(eb, col, col+1, row+1, row+2, yoptions=gtk.SHRINK)
|
||||
l.show()
|
||||
eb.show()
|
||||
treerow.append(' ')
|
||||
iter = liststore.append(treerow)
|
||||
last_game = result[sqlrow][0]
|
||||
last_seats = result[sqlrow][avgcol]
|
||||
if rowprinted:
|
||||
|
@ -220,50 +291,36 @@ class GuiPositionalStats (threading.Thread):
|
|||
|
||||
# blank row between main stats and totals:
|
||||
col = 0
|
||||
if(row%2 == 0):
|
||||
bgcolor = "white"
|
||||
else:
|
||||
bgcolor = "lightgrey"
|
||||
eb = gtk.EventBox()
|
||||
eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bgcolor))
|
||||
l = gtk.Label(' ')
|
||||
eb.add(l)
|
||||
self.stats_table.attach(eb, col, col+1, row+1, row+2, yoptions=gtk.SHRINK)
|
||||
l.show()
|
||||
eb.show()
|
||||
treerow = [' ' for x in self.posncols]
|
||||
iter = liststore.append(treerow)
|
||||
row = row + 1
|
||||
|
||||
for sqlrow in range(rows):
|
||||
if(row%2 == 0):
|
||||
bgcolor = "white"
|
||||
else:
|
||||
bgcolor = "lightgrey"
|
||||
treerow = []
|
||||
for col,colname in enumerate(self.posncols):
|
||||
if colname in colnames:
|
||||
sqlcol = colnames.index(colname)
|
||||
elif colname != "plposition":
|
||||
continue
|
||||
eb = gtk.EventBox()
|
||||
eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bgcolor))
|
||||
if colname == 'plposition':
|
||||
l = gtk.Label('Totals')
|
||||
value = 'Totals'
|
||||
elif result[sqlrow][sqlcol]:
|
||||
l = gtk.Label(result[sqlrow][sqlcol])
|
||||
value = result[sqlrow][sqlcol]
|
||||
else:
|
||||
l = gtk.Label(' ')
|
||||
if col == 0:
|
||||
l.set_alignment(xalign=0.0, yalign=0.5)
|
||||
elif col == 1:
|
||||
l.set_alignment(xalign=0.5, yalign=0.5)
|
||||
value = ' '
|
||||
if value and value != -999:
|
||||
treerow.append(value)
|
||||
else:
|
||||
l.set_alignment(xalign=1.0, yalign=0.5)
|
||||
eb.add(l)
|
||||
self.stats_table.attach(eb, col, col+1, row+1, row+2, yoptions=gtk.SHRINK)
|
||||
l.show()
|
||||
eb.show()
|
||||
treerow.append(' ')
|
||||
iter = liststore.append(treerow)
|
||||
row = row + 1
|
||||
vbox.show_all()
|
||||
|
||||
self.db.db.rollback()
|
||||
print "Positional Stats page displayed in %4.2f seconds" % (time() - starttime)
|
||||
#end def fillStatsFrame(self, vbox):
|
||||
|
||||
def refineQuery(self, query, playerids, sitenos, limits, seats, dates):
|
||||
|
|
|
@ -34,10 +34,13 @@ import gobject
|
|||
|
||||
# FreePokerTools modules
|
||||
from Mucked import Aux_Window
|
||||
from Mucked import Seat_Window
|
||||
from Mucked import Aux_Seats
|
||||
|
||||
class Hello(Aux_Window):
|
||||
"""A 'Hello World' Aux_Window demo."""
|
||||
def create(self):
|
||||
print "creating Hello"
|
||||
# This demo simply creates a label in a window.
|
||||
self.container = gtk.Window()
|
||||
self.container.add(gtk.Label("Hello World"))
|
||||
|
@ -99,15 +102,18 @@ class Hello_plus(Aux_Window):
|
|||
# hands played that was updated in the "update_data()" function.
|
||||
self.label.set_text("Hello %s\nYou have played %d hands\n on %s." % (self.hero, self.hands_played, self.site))
|
||||
|
||||
class Hello_Menu(Aux_Window):
|
||||
"""A 'Hello World' Aux_Window demo."""
|
||||
def create(self):
|
||||
# This demo puts a menu item on the HUD mainwindow.
|
||||
self.item = gtk.MenuItem('Print cards')
|
||||
self.hud.menu.append(self.item)
|
||||
self.item.connect("activate", self.print_cards)
|
||||
self.item.show()
|
||||
class Hello_Seats(Aux_Seats):
|
||||
"""A 'Hello World' Seat_Window demo."""
|
||||
|
||||
def print_cards(self, *args):
|
||||
# callback for the menu item
|
||||
print "cards =", self.hud.cards
|
||||
def create_contents(self, container, i):
|
||||
container.label = gtk.Label("empty")
|
||||
container.add(container.label)
|
||||
container.show_all()
|
||||
|
||||
def update_contents(self, container, i):
|
||||
if i == "common": return
|
||||
id = self.get_id_from_seat(i)
|
||||
if id == None:
|
||||
container.label.set_text("empty")
|
||||
else:
|
||||
container.label.set_text("player = %s" % self.hud.stat_dict[id]['screen_name'])
|
||||
|
|
|
@ -339,30 +339,30 @@ class Hud:
|
|||
Stats.do_tip(window.e_box[r][c], tip)
|
||||
|
||||
def topify_window(self, window):
|
||||
"""Set the specified gtk window to stayontop in MS Windows."""
|
||||
|
||||
def windowEnumerationHandler(hwnd, resultList):
|
||||
'''Callback for win32gui.EnumWindows() to generate list of window handles.'''
|
||||
resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
|
||||
|
||||
unique_name = 'unique name for finding this window'
|
||||
real_name = window.get_title()
|
||||
window.set_title(unique_name)
|
||||
tl_windows = []
|
||||
win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
|
||||
|
||||
for w in tl_windows:
|
||||
if w[1] == unique_name:
|
||||
# """Set the specified gtk window to stayontop in MS Windows."""
|
||||
#
|
||||
# def windowEnumerationHandler(hwnd, resultList):
|
||||
# '''Callback for win32gui.EnumWindows() to generate list of window handles.'''
|
||||
# resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
|
||||
# unique_name = 'unique name for finding this window'
|
||||
# real_name = window.get_title()
|
||||
# window.set_title(unique_name)
|
||||
# tl_windows = []
|
||||
# win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
|
||||
#
|
||||
# for w in tl_windows:
|
||||
# if w[1] == unique_name:
|
||||
self.main_window.parentgdkhandle = gtk.gdk.window_foreign_new(long(self.table.number))
|
||||
self.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0])
|
||||
# self.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0])
|
||||
self.main_window.gdkhandle = self.main_window.window
|
||||
self.main_window.gdkhandle.set_transient_for(self.main_window.parentgdkhandle)
|
||||
|
||||
style = win32gui.GetWindowLong(self.table.number, win32con.GWL_EXSTYLE)
|
||||
style |= win32con.WS_CLIPCHILDREN
|
||||
win32gui.SetWindowLong(self.table.number, win32con.GWL_EXSTYLE, style)
|
||||
break
|
||||
# break
|
||||
|
||||
window.set_title(real_name)
|
||||
# window.set_title(real_name)
|
||||
|
||||
class Stat_Window:
|
||||
|
||||
|
@ -445,10 +445,10 @@ class Stat_Window:
|
|||
|
||||
Stats.do_tip(e_box[r][c], 'stuff')
|
||||
if usegtkframes:
|
||||
grid.attach(self.frame[r][c], c, c+1, r, r+1, xpadding = 0, ypadding = 0)
|
||||
grid.attach(self.frame[r][c], c, c+1, r, r+1, xpadding = game.xpad, ypadding = game.ypad)
|
||||
self.frame[r][c].add(e_box[r][c])
|
||||
else:
|
||||
grid.attach(e_box[r][c], c, c+1, r, r+1, xpadding = 0, ypadding = 0)
|
||||
grid.attach(e_box[r][c], c, c+1, r, r+1, xpadding = game.xpad, ypadding = game.ypad)
|
||||
label[r].append( gtk.Label('xxx') )
|
||||
|
||||
if usegtkframes:
|
||||
|
@ -473,6 +473,7 @@ class Popup_window:
|
|||
def __init__(self, parent, stat_window):
|
||||
self.sb_click = 0
|
||||
self.stat_window = stat_window
|
||||
self.parent = parent
|
||||
|
||||
# create the popup window
|
||||
self.window = gtk.Window()
|
||||
|
@ -532,11 +533,15 @@ class Popup_window:
|
|||
# db_connection.close_connection()
|
||||
stat_dict = stat_window.parent.stat_dict
|
||||
pu_text = ""
|
||||
mo_text = ""
|
||||
for s in stat_list:
|
||||
number = Stats.do_stat(stat_dict, player = int(stat_window.player_id), stat = s)
|
||||
mo_text += number[5] + " " + number[4] + "\n"
|
||||
pu_text += number[3] + "\n"
|
||||
|
||||
|
||||
self.lab.set_text(pu_text)
|
||||
Stats.do_tip(self.lab, mo_text)
|
||||
self.window.show_all()
|
||||
|
||||
self.window.set_transient_for(stat_window.window)
|
||||
|
@ -572,25 +577,25 @@ class Popup_window:
|
|||
def topify_window(self, window):
|
||||
"""Set the specified gtk window to stayontop in MS Windows."""
|
||||
|
||||
def windowEnumerationHandler(hwnd, resultList):
|
||||
'''Callback for win32gui.EnumWindows() to generate list of window handles.'''
|
||||
resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
|
||||
# def windowEnumerationHandler(hwnd, resultList):
|
||||
# '''Callback for win32gui.EnumWindows() to generate list of window handles.'''
|
||||
# resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
|
||||
|
||||
unique_name = 'unique name for finding this window'
|
||||
real_name = window.get_title()
|
||||
window.set_title(unique_name)
|
||||
tl_windows = []
|
||||
win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
|
||||
# unique_name = 'unique name for finding this window'
|
||||
# real_name = window.get_title()
|
||||
# window.set_title(unique_name)
|
||||
# tl_windows = []
|
||||
# win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
|
||||
|
||||
for w in tl_windows:
|
||||
if w[1] == unique_name:
|
||||
# for w in tl_windows:
|
||||
# if w[1] == unique_name:
|
||||
window.set_transient_for(self.parent.main_window)
|
||||
style = win32gui.GetWindowLong(self.table.number, win32con.GWL_EXSTYLE)
|
||||
style |= win32con.WS_CLIPCHILDREN
|
||||
win32gui.SetWindowLong(self.table.number, win32con.GWL_EXSTYLE, style)
|
||||
break
|
||||
# break
|
||||
|
||||
window.set_title(real_name)
|
||||
# window.set_title(real_name)
|
||||
|
||||
if __name__== "__main__":
|
||||
main_window = gtk.Window()
|
||||
|
|
236
pyfpdb/Mucked.py
236
pyfpdb/Mucked.py
|
@ -37,27 +37,18 @@ import Configuration
|
|||
import Database
|
||||
import Card
|
||||
|
||||
class Aux_Window:
|
||||
class Aux_Window(object):
|
||||
def __init__(self, hud, params, config):
|
||||
self.hud = hud
|
||||
self.params = params
|
||||
self.config = config
|
||||
|
||||
def update_data(self, *args):
|
||||
pass
|
||||
|
||||
def update_gui(self, *args):
|
||||
pass
|
||||
|
||||
def create(self, *args):
|
||||
pass
|
||||
|
||||
def relocate(self, *args):
|
||||
pass
|
||||
|
||||
def save_layout(self, *args):
|
||||
pass
|
||||
|
||||
# Override these methods as needed
|
||||
def update_data(self, *args): pass
|
||||
def update_gui(self, *args): pass
|
||||
def create(self, *args): pass
|
||||
def relocate(self, *args): pass
|
||||
def save_layout(self, *args): pass
|
||||
def destroy(self):
|
||||
try:
|
||||
self.container.destroy()
|
||||
|
@ -89,14 +80,19 @@ class Aux_Window:
|
|||
pb.copy_area(30*j, 42*i, 30, 42, temp_pb, 0, 0)
|
||||
return temp_pb
|
||||
|
||||
def split_cards(self, card):
|
||||
if card == 'xx': return ('B', 'S')
|
||||
return (card[0], card[1].upper())
|
||||
|
||||
def has_cards(self, cards):
|
||||
"""Returns the number of cards in the list."""
|
||||
n = 0
|
||||
for c in cards:
|
||||
if c in set('shdc'): return True
|
||||
return False
|
||||
if c != None and c > 0: n = n + 1
|
||||
return n
|
||||
|
||||
def get_id_from_seat(self, seat):
|
||||
"""Determine player id from seat number, given stat_dict."""
|
||||
for id, dict in self.hud.stat_dict.iteritems():
|
||||
if seat == dict['seat']:
|
||||
return id
|
||||
return None
|
||||
|
||||
class Stud_mucked(Aux_Window):
|
||||
def __init__(self, hud, config, params):
|
||||
|
@ -329,87 +325,151 @@ class Stud_cards:
|
|||
self.seen_cards[(c, r)].set_from_pixbuf(self.card_images[0])
|
||||
self.eb[(c, r)].set_tooltip_text('')
|
||||
|
||||
class Flop_Mucked(Aux_Window):
|
||||
"""Aux_Window class for displaying mucked cards for flop games."""
|
||||
class Seat_Window(gtk.Window):
|
||||
"""Subclass gtk.Window for the seat windows."""
|
||||
|
||||
class Aux_Seats(Aux_Window):
|
||||
"""A super class to display an aux_window at each seat."""
|
||||
|
||||
def __init__(self, hud, config, params):
|
||||
self.hud = hud # hud object that this aux window supports
|
||||
self.config = config # configuration object for this aux window to use
|
||||
self.params = params # dict aux params from config
|
||||
self.positions = {} # dict of window positions
|
||||
# self.rel_positions = {} # dict of window positions, relative to the table origin
|
||||
self.displayed_cards = False
|
||||
self.displayed = False # the seat windows are displayed
|
||||
self.uses_timer = False # the Aux_seats object uses a timer to control hiding
|
||||
self.timer_on = False # bool = Ture if the timeout for removing the cards is on
|
||||
self.card_images = self.get_card_images()
|
||||
|
||||
# placeholders that should be overridden--so we don't throw errors
|
||||
def create_contents(self): pass
|
||||
def update_contents(self): pass
|
||||
|
||||
def create(self):
|
||||
self.adj = self.hud.adj_seats(0, self.config)
|
||||
self.adj = self.hud.adj_seats(0, self.config) # move adj_seats to aux and get rid of it in Hud.py
|
||||
loc = self.config.get_aux_locations(self.params['name'], int(self.hud.max))
|
||||
|
||||
self.m_windows = {} # windows to put the card images in
|
||||
self.eb = {} # event boxes so we can interact with the mucked cards
|
||||
self.seen_cards = {} # image objects to stash the cards in
|
||||
|
||||
for i in (range(1, self.hud.max + 1) + ['common']):
|
||||
if i == 'common':
|
||||
(x, y) = self.params['layout'][self.hud.max].common
|
||||
else:
|
||||
(x, y) = loc[self.adj[i]]
|
||||
self.m_windows[i] = gtk.Window()
|
||||
self.m_windows[i] = Seat_Window()
|
||||
self.m_windows[i].set_decorated(False)
|
||||
self.m_windows[i].set_property("skip-taskbar-hint", True)
|
||||
self.m_windows[i].set_transient_for(self.hud.main_window)
|
||||
self.m_windows[i].set_focus_on_map(False)
|
||||
self.eb[i] = gtk.EventBox()
|
||||
self.eb[i].connect("button_press_event", self.button_press_cb)
|
||||
self.m_windows[i].connect("configure_event", self.configure_event_cb, i)
|
||||
self.m_windows[i].add(self.eb[i])
|
||||
self.seen_cards[i] = gtk.image_new_from_pixbuf(self.card_images[('B', 'H')])
|
||||
self.eb[i].add(self.seen_cards[i])
|
||||
self.positions[i] = (int(x) + self.hud.table.x, int(y) + self.hud.table.y)
|
||||
# self.rel_positions[i] = (int(x), int(y))
|
||||
self.m_windows[i].move(self.positions[i][0], self.positions[i][1])
|
||||
if self.params.has_key('opacity'):
|
||||
self.m_windows[i].set_opacity(float(self.params['opacity']))
|
||||
|
||||
# the create_contents method is supplied by the subclass
|
||||
self.create_contents(self.m_windows[i], i)
|
||||
|
||||
self.m_windows[i].show_all()
|
||||
if self.uses_timer:
|
||||
self.m_windows[i].hide()
|
||||
|
||||
def update_gui(self, new_hand_id):
|
||||
"""Prepare and show the mucked cards."""
|
||||
if self.displayed_cards:
|
||||
self.hide_mucked_cards()
|
||||
self.displayed_cards = False
|
||||
for (i, cards) in self.hud.cards.iteritems():
|
||||
if self.has_cards(cards):
|
||||
"""Update the gui, LDO."""
|
||||
for i in self.m_windows.keys():
|
||||
self.update_contents(self.m_windows[i], i)
|
||||
|
||||
# Methods likely to be of use for any Seat_Window implementation
|
||||
def destroy(self):
|
||||
"""Destroy all of the seat windows."""
|
||||
for i in self.m_windows.keys():
|
||||
self.m_windows[i].destroy()
|
||||
del(self.m_windows[i])
|
||||
|
||||
# Methods likely to be useful for mucked card windows (or similar) only
|
||||
def hide(self):
|
||||
"""Hide the seat windows."""
|
||||
for (i, w) in self.m_windows.iteritems():
|
||||
w.hide()
|
||||
self.displayed = False
|
||||
|
||||
def save_layout(self, *args):
|
||||
"""Save new layout back to the aux element in the config file."""
|
||||
new_locs = {}
|
||||
# print "adj =", self.adj
|
||||
for (i, pos) in self.positions.iteritems():
|
||||
if i != 'common':
|
||||
new_locs[self.adj[int(i)]] = (pos[0] - self.hud.table.x, pos[1] - self.hud.table.y)
|
||||
else:
|
||||
new_locs[i] = (pos[0] - self.hud.table.x, pos[1] - self.hud.table.y)
|
||||
self.config.edit_aux_layout(self.params['name'], self.hud.max, locations = new_locs)
|
||||
|
||||
def configure_event_cb(self, widget, event, i, *args):
|
||||
self.positions[i] = widget.get_position()
|
||||
# self.rel_positions[i] = (self.positions[i][0] - self.hud.table.x, self.positions[i][1] - self.hud.table.y)
|
||||
|
||||
class Flop_Mucked(Aux_Seats):
|
||||
"""Aux_Window class for displaying mucked cards for flop games."""
|
||||
|
||||
def __init__(self, hud, config, params):
|
||||
super(Flop_Mucked, self).__init__(hud, config, params)
|
||||
self.card_images = self.get_card_images()
|
||||
self.uses_timer = True # this Aux_seats object uses a timer to control hiding
|
||||
|
||||
def create_contents(self, container, i):
|
||||
"""Create the widgets for showing the contents of the Aux_seats window."""
|
||||
container.eb = gtk.EventBox()
|
||||
container.eb.connect("button_press_event", self.button_press_cb)
|
||||
container.add(container.eb)
|
||||
container.seen_cards = gtk.image_new_from_pixbuf(self.card_images[0])
|
||||
container.eb.add(container.seen_cards)
|
||||
|
||||
def update_contents(self, container, i):
|
||||
if not self.hud.cards.has_key(i): return
|
||||
cards = self.hud.cards[i]
|
||||
n_cards = self.has_cards(cards)
|
||||
if n_cards > 1:
|
||||
|
||||
# scratch is a working pixbuf, used to assemble the image
|
||||
scratch = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8,
|
||||
int(self.params['card_wd'])*len(cards)/2,
|
||||
int(self.params['card_wd'])*n_cards,
|
||||
int(self.params['card_ht']))
|
||||
x = 0 # x coord where the next card starts in scratch
|
||||
for card in [cards[k:k+2] for k in xrange(0, len(cards), 2)]:
|
||||
for card in cards:
|
||||
# concatenate each card image to scratch
|
||||
self.card_images[self.split_cards(card)].copy_area(0, 0,
|
||||
if card == None or card ==0:
|
||||
break
|
||||
self.card_images[card].copy_area(0, 0,
|
||||
int(self.params['card_wd']), int(self.params['card_ht']),
|
||||
scratch, x, 0)
|
||||
x = x + int(self.params['card_wd'])
|
||||
self.seen_cards[i].set_from_pixbuf(scratch)
|
||||
# self.m_windows[i].show_all()
|
||||
self.m_windows[i].resize(1,1)
|
||||
self.m_windows[i].show()
|
||||
self.m_windows[i].move(self.positions[i][0], self.positions[i][1]) # here is where I move back
|
||||
self.displayed_cards = True
|
||||
container.seen_cards.set_from_pixbuf(scratch)
|
||||
container.resize(1,1)
|
||||
container.show()
|
||||
container.move(self.positions[i][0], self.positions[i][1]) # here is where I move back
|
||||
self.displayed = True
|
||||
if i != "common":
|
||||
self.m_windows[i].eb.set_tooltip_text(self.hud.stat_dict[i]['screen_name'])
|
||||
|
||||
for stats in self.hud.stat_dict.itervalues():
|
||||
self.eb[stats['seat']].set_tooltip_text(stats['screen_name'])
|
||||
def update_gui(self, new_hand_id):
|
||||
"""Prepare and show the mucked cards."""
|
||||
if self.displayed: self.hide()
|
||||
|
||||
if self.displayed_cards and float(self.params['timeout']) > 0:
|
||||
# See how many players showed a hand. Skip if only 1 shows (= hero)
|
||||
n_sd = 0
|
||||
for (i, cards) in self.hud.cards.iteritems():
|
||||
n_cards = self.has_cards(cards)
|
||||
if n_cards > 0:
|
||||
n_sd = n_sd + 1
|
||||
if n_sd < 2:
|
||||
print "skipping, n_sd =", n_sd
|
||||
return
|
||||
|
||||
super(Flop_Mucked, self).update_gui(new_hand_id)
|
||||
|
||||
if self.displayed and float(self.params['timeout']) > 0:
|
||||
self.timer_on = True
|
||||
gobject.timeout_add(int(1000*float(self.params['timeout'])), self.timed_out)
|
||||
|
||||
def destroy(self):
|
||||
"""Destroy all of the mucked windows."""
|
||||
for w in self.m_windows.values():
|
||||
w.destroy()
|
||||
|
||||
def timed_out(self):
|
||||
# this is the callback from the timeout
|
||||
|
||||
|
@ -418,15 +478,9 @@ class Flop_Mucked(Aux_Window):
|
|||
if not self.timer_on:
|
||||
return False
|
||||
else:
|
||||
self.hide_mucked_cards()
|
||||
self.hide()
|
||||
return False
|
||||
|
||||
def hide_mucked_cards(self):
|
||||
"""Hide the mucked card windows."""
|
||||
for (i, w) in self.m_windows.iteritems():
|
||||
w.hide()
|
||||
self.displayed_cards = False
|
||||
|
||||
def button_press_cb(self, widget, event, *args):
|
||||
"""Handle button clicks in the event boxes."""
|
||||
|
||||
|
@ -444,58 +498,14 @@ class Flop_Mucked(Aux_Window):
|
|||
self.timer_on = False
|
||||
else:
|
||||
self.timer_on = False
|
||||
self.hide_mucked_cards()
|
||||
self.hide()
|
||||
|
||||
elif event.button == 1: # left button event
|
||||
window = widget.get_parent()
|
||||
window.begin_move_drag(event.button, int(event.x_root), int(event.y_root), event.time)
|
||||
|
||||
def configure_event_cb(self, widget, event, i, *args):
|
||||
self.positions[i] = widget.get_position()
|
||||
# self.rel_positions[i] = (self.positions[i][0] - self.hud.table.x, self.positions[i][1] - self.hud.table.y)
|
||||
|
||||
def expose_all(self):
|
||||
for (i, cards) in self.hud.cards.iteritems():
|
||||
self.m_windows[i].show()
|
||||
self.m_windows[i].move(self.positions[i][0], self.positions[i][1]) # here is where I move back
|
||||
self.displayed_cards = True
|
||||
|
||||
def save_layout(self, *args):
|
||||
"""Save new layout back to the aux element in the config file."""
|
||||
new_locs = {}
|
||||
# print "adj =", self.adj
|
||||
for (i, pos) in self.positions.iteritems():
|
||||
if i != 'common':
|
||||
new_locs[self.adj[int(i)]] = (pos[0] - self.hud.table.x, pos[1] - self.hud.table.y)
|
||||
else:
|
||||
new_locs[i] = (pos[0] - self.hud.table.x, pos[1] - self.hud.table.y)
|
||||
self.config.edit_aux_layout(self.params['name'], self.hud.max, locations = new_locs)
|
||||
|
||||
# This test program doesn't work
|
||||
|
||||
#if __name__== "__main__":
|
||||
#
|
||||
# def destroy(*args): # call back for terminating the main eventloop
|
||||
# gtk.main_quit() # used only for testing
|
||||
#
|
||||
# def process_new_hand(source, condition, db_connection): #callback from stdin watch -- testing only
|
||||
## there is a new hand_id to be processed
|
||||
## just read it and pass it to update
|
||||
# new_hand_id = sys.stdin.readline()
|
||||
# new_hand_id = new_hand_id.rstrip() # remove trailing whitespace
|
||||
# m.update_data(new_hand_id, db_connection)
|
||||
# m.update_gui(new_hand_id)
|
||||
# return(True)
|
||||
#
|
||||
# config = Configuration.Config()
|
||||
# db_connection = Database.Database(config, 'fpdbTEST', '')
|
||||
# main_window = gtk.Window()
|
||||
# main_window.set_keep_above(True)
|
||||
# main_window.connect("destroy", destroy)
|
||||
#
|
||||
# aux_to_call = "stud_mucked"
|
||||
# aux_params = config.get_aux_parameters(aux_to_call)
|
||||
# m = eval("%s(None, config, aux_params)" % aux_params['class'])
|
||||
#
|
||||
# s_id = gobject.io_add_watch(sys.stdin, gobject.IO_IN, process_new_hand, db_connection)
|
||||
# gtk.main()
|
||||
self.displayed = True
|
||||
|
|
|
@ -542,18 +542,13 @@ class Sql:
|
|||
|
||||
self.query['get_common_cards'] = """
|
||||
select
|
||||
card1Value AS card1value,
|
||||
card1Suit AS card1suit,
|
||||
card2Value AS card2value,
|
||||
card2Suit AS card2suit,
|
||||
card3Value AS card3value,
|
||||
card3Suit AS card3suit,
|
||||
card4Value AS card4value,
|
||||
card4Suit AS card4suit,
|
||||
card5Value AS card5value,
|
||||
card5Suit AS card5suit
|
||||
from BoardCards
|
||||
where handId = %s
|
||||
boardcard1,
|
||||
boardcard2,
|
||||
boardcard3,
|
||||
boardcard4,
|
||||
boardcard5
|
||||
from Hands
|
||||
where Id = %s
|
||||
"""
|
||||
|
||||
self.query['get_action_from_hand'] = """
|
||||
|
|
|
@ -231,7 +231,7 @@ def discover_nt_by_name(c, tablename):
|
|||
titles = {}
|
||||
win32gui.EnumWindows(win_enum_handler, titles)
|
||||
for hwnd in titles:
|
||||
print "Tbales.py: tablename =", tablename, "title =", titles[hwnd]
|
||||
#print "Tables.py: tablename =", tablename, "title =", titles[hwnd]
|
||||
try:
|
||||
# this can blow up in XP on some windows, eg firefox displaying http://docs.python.org/tutorial/classes.html
|
||||
if not tablename in titles[hwnd]: continue
|
||||
|
@ -314,6 +314,10 @@ def get_site_from_exe(c, exe):
|
|||
return params['site_name']
|
||||
return None
|
||||
|
||||
def everleaf_decode_table(tw):
|
||||
# 2 - Tournament ID: 573256 - NL Hold'em - 150/300 blinds - Good luck <username>! - [Connection is ...]
|
||||
pass
|
||||
|
||||
def pokerstars_decode_table(tw):
|
||||
# Extract poker information from the window title. This is not needed for
|
||||
# fpdb, since all that information is available in the db via new_hand_number.
|
||||
|
|
|
@ -92,6 +92,8 @@ if __name__=="__main__":
|
|||
print "game =", table.get_game()
|
||||
|
||||
fake = fake_hud(table)
|
||||
print "fake =", fake
|
||||
gobject.timeout_add(100, check_on_table, table, fake)
|
||||
print "calling main"
|
||||
gtk.main()
|
||||
|
||||
|
|
|
@ -65,8 +65,11 @@ class Table(Table_Window):
|
|||
print "x = %s y = %s width = %s height = %s" % (x, y, width, height)
|
||||
self.x = int(x) + b_width
|
||||
self.y = int(y) + tb_height
|
||||
self.height = int(height) - b_width - tb_height
|
||||
self.width = int(width) - 2*b_width
|
||||
self.width = width - x
|
||||
self.height = height - y
|
||||
print "x = %s y = %s width = %s height = %s" % (self.x, self.y, self.width, self.height)
|
||||
#self.height = int(height) - b_width - tb_height
|
||||
#self.width = int(width) - 2*b_width
|
||||
|
||||
self.exe = self.get_nt_exe(hwnd)
|
||||
self.title = titles[hwnd]
|
||||
|
@ -76,12 +79,13 @@ class Table(Table_Window):
|
|||
self.gdkhandle = gtk.gdk.window_foreign_new(long(self.window))
|
||||
|
||||
def get_geometry(self):
|
||||
|
||||
if not win32gui.IsWindow(self.window): # window closed
|
||||
if not win32gui.IsWindow(self.number): # window closed
|
||||
return None
|
||||
|
||||
try:
|
||||
(x, y, width, height) = win32gui.GetWindowRect(hwnd)
|
||||
(x, y, width, height) = win32gui.GetWindowRect(self.number)
|
||||
width = width - x
|
||||
height = height - y
|
||||
return {'x' : int(x) + b_width,
|
||||
'y' : int(y) + tb_height,
|
||||
'width' : int(height) - b_width - tb_height,
|
||||
|
@ -116,27 +120,32 @@ class Table(Table_Window):
|
|||
def topify(self, hud):
|
||||
"""Set the specified gtk window to stayontop in MS Windows."""
|
||||
|
||||
def windowEnumerationHandler(hwnd, resultList):
|
||||
'''Callback for win32gui.EnumWindows() to generate list of window handles.'''
|
||||
resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
|
||||
|
||||
unique_name = 'unique name for finding this window'
|
||||
real_name = hud.main_window.get_title()
|
||||
hud.main_window.set_title(unique_name)
|
||||
tl_windows = []
|
||||
win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
|
||||
|
||||
for w in tl_windows:
|
||||
if w[1] == unique_name:
|
||||
hud.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0])
|
||||
# def windowEnumerationHandler(hwnd, resultList):
|
||||
# '''Callback for win32gui.EnumWindows() to generate list of window handles.'''
|
||||
# resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
|
||||
#
|
||||
# unique_name = 'unique name for finding this window'
|
||||
# real_name = hud.main_window.get_title()
|
||||
# hud.main_window.set_title(unique_name)
|
||||
# tl_windows = []
|
||||
# win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
|
||||
#
|
||||
# for w in tl_windows:
|
||||
# if w[1] == unique_name:
|
||||
# hud.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0])
|
||||
hud.main_window.gdkhandle = hud.main_window.window
|
||||
hud.main_window.gdkhandle.set_transient_for(self.gdkhandle)
|
||||
rect = self.gdkhandle.get_frame_extents()
|
||||
(innerx, innery) = self.gdkhandle.get_origin()
|
||||
b_width = rect.x - innerx
|
||||
tb_height = rect.y - innery
|
||||
#
|
||||
# style = win32gui.GetWindowLong(self.number, win32con.GWL_EXSTYLE)
|
||||
# style |= win32con.WS_CLIPCHILDREN
|
||||
# win32gui.SetWindowLong(self.number, win32con.GWL_EXSTYLE, style)
|
||||
break
|
||||
# break
|
||||
|
||||
hud.main_window.set_title(real_name)
|
||||
# hud.main_window.set_title(real_name)
|
||||
|
||||
def win_enum_handler(hwnd, titles):
|
||||
titles[hwnd] = win32gui.GetWindowText(hwnd)
|
||||
|
|
|
@ -32,7 +32,7 @@ import pygtk
|
|||
pygtk.require('2.0')
|
||||
import gtk
|
||||
|
||||
import fpdb_db
|
||||
|
||||
import fpdb_simple
|
||||
import GuiBulkImport
|
||||
import GuiPlayerStats
|
||||
|
@ -41,6 +41,8 @@ import GuiTableViewer
|
|||
import GuiAutoImport
|
||||
import GuiGraphViewer
|
||||
import GuiSessionViewer
|
||||
import SQL
|
||||
import Database
|
||||
import FpdbSQLQueries
|
||||
import Configuration
|
||||
|
||||
|
@ -178,20 +180,21 @@ class fpdb:
|
|||
def dia_load_profile(self, widget, data=None):
|
||||
"""Dialogue to select a file to load a profile from"""
|
||||
if self.obtain_global_lock() == 0: # returns 0 if successful
|
||||
try:
|
||||
chooser = gtk.FileChooserDialog(title="Please select a profile file to load",
|
||||
action=gtk.FILE_CHOOSER_ACTION_OPEN,
|
||||
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
|
||||
chooser.set_filename(self.profile)
|
||||
#try:
|
||||
# chooser = gtk.FileChooserDialog(title="Please select a profile file to load",
|
||||
# action=gtk.FILE_CHOOSER_ACTION_OPEN,
|
||||
# buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
|
||||
# chooser.set_filename(self.profile)
|
||||
|
||||
response = chooser.run()
|
||||
chooser.destroy()
|
||||
if response == gtk.RESPONSE_OK:
|
||||
self.load_profile(chooser.get_filename())
|
||||
elif response == gtk.RESPONSE_CANCEL:
|
||||
print 'User cancelled loading profile'
|
||||
except:
|
||||
pass
|
||||
# response = chooser.run()
|
||||
# chooser.destroy()
|
||||
# if response == gtk.RESPONSE_OK:
|
||||
# self.load_profile(chooser.get_filename())
|
||||
# elif response == gtk.RESPONSE_CANCEL:
|
||||
# print 'User cancelled loading profile'
|
||||
#except:
|
||||
# pass
|
||||
self.load_profile()
|
||||
self.release_global_lock()
|
||||
#end def dia_load_profile
|
||||
|
||||
|
@ -203,22 +206,23 @@ class fpdb:
|
|||
try:
|
||||
dia_confirm = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING,
|
||||
buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm deleting and recreating tables")
|
||||
diastring = "Please confirm that you want to (re-)create the tables. If there already are tables in the database "+self.db.database+" on "+self.db.host+" they will be deleted."
|
||||
diastring = "Please confirm that you want to (re-)create the tables. If there already are tables in the database " \
|
||||
+self.db.fdb.database+" on "+self.db.fdb.host+" they will be deleted."
|
||||
dia_confirm.format_secondary_text(diastring)#todo: make above string with bold for db, host and deleted
|
||||
|
||||
response = dia_confirm.run()
|
||||
dia_confirm.destroy()
|
||||
if response == gtk.RESPONSE_YES:
|
||||
if self.db.backend == self.fdb_lock.MYSQL_INNODB:
|
||||
if self.db.fdb.backend == self.fdb_lock.fdb.MYSQL_INNODB:
|
||||
# mysql requires locks on all tables or none - easier to release this lock
|
||||
# than lock all the other tables
|
||||
# ToDo: lock all other tables so that lock doesn't have to be released
|
||||
self.release_global_lock()
|
||||
lock_released = True
|
||||
self.db.recreate_tables()
|
||||
self.db.fdb.recreate_tables()
|
||||
else:
|
||||
# for other dbs use same connection as holds global lock
|
||||
self.fdb_lock.recreate_tables()
|
||||
self.fdb_lock.fdb.recreate_tables()
|
||||
elif response == gtk.RESPONSE_NO:
|
||||
print 'User cancelled recreating tables'
|
||||
except:
|
||||
|
@ -346,6 +350,7 @@ class fpdb:
|
|||
|
||||
def load_profile(self):
|
||||
"""Loads profile from the provided path name."""
|
||||
self.config = Configuration.Config(file=options.config, dbname=options.dbname)
|
||||
self.settings = {}
|
||||
if (os.sep=="/"):
|
||||
self.settings['os']="linuxmac"
|
||||
|
@ -358,17 +363,13 @@ class fpdb:
|
|||
self.settings.update(self.config.get_import_parameters())
|
||||
self.settings.update(self.config.get_default_paths())
|
||||
|
||||
if self.db!=None:
|
||||
if self.db != None and self.db.fdb != None:
|
||||
self.db.disconnect()
|
||||
|
||||
self.db = fpdb_db.fpdb_db()
|
||||
#print "end of fpdb.load_profile, databaseName:",self.settings['db-databaseName']
|
||||
self.db.connect(self.settings['db-backend'],
|
||||
self.settings['db-host'],
|
||||
self.settings['db-databaseName'],
|
||||
self.settings['db-user'],
|
||||
self.settings['db-password'])
|
||||
if self.db.wrongDbVersion:
|
||||
self.sql = SQL.Sql(type = self.settings['db-type'], db_server = self.settings['db-server'])
|
||||
self.db = Database.Database(self.config, sql = self.sql)
|
||||
|
||||
if self.db.fdb.wrongDbVersion:
|
||||
diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
|
||||
|
||||
label = gtk.Label("An invalid DB version or missing tables have been detected.")
|
||||
|
@ -386,9 +387,16 @@ class fpdb:
|
|||
response = diaDbVersionWarning.run()
|
||||
diaDbVersionWarning.destroy()
|
||||
|
||||
if self.status_bar == None:
|
||||
self.status_bar = gtk.Label("Status: Connected to %s database named %s on host %s"%(self.db.get_backend_name(),self.db.fdb.database, self.db.fdb.host))
|
||||
self.main_vbox.pack_end(self.status_bar, False, True, 0)
|
||||
self.status_bar.show()
|
||||
else:
|
||||
self.status_bar.set_text("Status: Connected to %s database named %s on host %s" % (self.db.get_backend_name(),self.db.fdb.database, self.db.fdb.host))
|
||||
|
||||
# Database connected to successfully, load queries to pass on to other classes
|
||||
self.querydict = FpdbSQLQueries.FpdbSQLQueries(self.db.get_backend_name())
|
||||
self.db.db.rollback()
|
||||
self.db.connection.rollback()
|
||||
#end def load_profile
|
||||
|
||||
def not_implemented(self, widget, data=None):
|
||||
|
@ -397,13 +405,9 @@ class fpdb:
|
|||
|
||||
def obtain_global_lock(self):
|
||||
print "\nTaking global lock ..."
|
||||
self.fdb_lock = fpdb_db.fpdb_db()
|
||||
self.fdb_lock.connect(self.settings['db-backend'],
|
||||
self.settings['db-host'],
|
||||
self.settings['db-databaseName'],
|
||||
self.settings['db-user'],
|
||||
self.settings['db-password'])
|
||||
return self.fdb_lock.get_global_lock()
|
||||
self.fdb_lock = Database.Database(self.config, sql = self.sql)
|
||||
self.fdb_lock.do_connect(self.config)
|
||||
return self.fdb_lock.fdb.get_global_lock()
|
||||
#end def obtain_global_lock
|
||||
|
||||
def quit(self, widget, data=None):
|
||||
|
@ -414,9 +418,9 @@ class fpdb:
|
|||
#end def quit_cliecked
|
||||
|
||||
def release_global_lock(self):
|
||||
self.fdb_lock.db.rollback()
|
||||
self.fdb_lock.disconnect()
|
||||
print "Global lock released."
|
||||
self.fdb_lock.fdb.db.rollback()
|
||||
self.fdb_lock.fdb.disconnect()
|
||||
print "Global lock released.\n"
|
||||
#end def release_global_lock
|
||||
|
||||
def tab_abbreviations(self, widget, data=None):
|
||||
|
@ -465,7 +469,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
|||
def tab_table_viewer(self, widget, data=None):
|
||||
"""opens a table viewer tab"""
|
||||
#print "start of tab_table_viewer"
|
||||
new_tv_thread=GuiTableViewer.GuiTableViewer(self.db, self.settings)
|
||||
new_tv_thread=GuiTableViewer.GuiTableViewer(self.db.fdb, self.settings)
|
||||
self.threads.append(new_tv_thread)
|
||||
tv_tab=new_tv_thread.get_vbox()
|
||||
self.add_and_display_tab(tv_tab, "Table Viewer")
|
||||
|
@ -474,7 +478,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
|||
def tabGraphViewer(self, widget, data=None):
|
||||
"""opens a graph viewer tab"""
|
||||
#print "start of tabGraphViewer"
|
||||
new_gv_thread=GuiGraphViewer.GuiGraphViewer(self.db, self.settings, self.querydict, self.config)
|
||||
new_gv_thread = GuiGraphViewer.GuiGraphViewer(self.querydict, self.config)
|
||||
self.threads.append(new_gv_thread)
|
||||
gv_tab=new_gv_thread.get_vbox()
|
||||
self.add_and_display_tab(gv_tab, "Graphs")
|
||||
|
@ -483,8 +487,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
|||
def __init__(self):
|
||||
self.threads = []
|
||||
self.db = None
|
||||
self.config = Configuration.Config(file=options.config, dbname=options.dbname)
|
||||
self.load_profile()
|
||||
self.status_bar = None
|
||||
|
||||
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||
self.window.connect("delete_event", self.delete_event)
|
||||
|
@ -519,11 +522,8 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
|||
|
||||
self.tab_main_help(None, None)
|
||||
|
||||
self.status_bar = gtk.Label("Status: Connected to %s database named %s on host %s"%(self.db.get_backend_name(),self.db.database, self.db.host))
|
||||
self.main_vbox.pack_end(self.status_bar, False, True, 0)
|
||||
self.status_bar.show()
|
||||
|
||||
self.window.show()
|
||||
self.load_profile()
|
||||
sys.stderr.write("fpdb starting ...")
|
||||
#end def __init__
|
||||
|
||||
|
|
|
@ -243,7 +243,6 @@ class fpdb_db:
|
|||
self.cursor.execute(self.sql.query['createPlayersTable'])
|
||||
self.cursor.execute(self.sql.query['createAutoratesTable'])
|
||||
self.cursor.execute(self.sql.query['createHandsTable'])
|
||||
self.cursor.execute(self.sql.query['createBoardCardsTable'])
|
||||
self.cursor.execute(self.sql.query['createTourneyTypesTable'])
|
||||
self.cursor.execute(self.sql.query['createTourneysTable'])
|
||||
self.cursor.execute(self.sql.query['createTourneysPlayersTable'])
|
||||
|
@ -568,17 +567,18 @@ class fpdb_db:
|
|||
print "analyze took", atime, "seconds"
|
||||
#end def analyzeDB
|
||||
|
||||
# Currently uses an exclusive lock on the Hands table as a global lock
|
||||
# Currently uses an exclusive lock on the Players table as a global lock
|
||||
# ( Changed because Hands is used in Database.init() )
|
||||
# Return values are Unix style, 0 for success, positive integers for errors
|
||||
# 1 = generic error
|
||||
# 2 = hands table does not exist (error message is suppressed)
|
||||
# 2 = players table does not exist (error message is suppressed)
|
||||
def get_global_lock(self):
|
||||
if self.backend == self.MYSQL_INNODB:
|
||||
try:
|
||||
self.cursor.execute( "lock tables Hands write" )
|
||||
self.cursor.execute( "lock tables Players write" )
|
||||
except:
|
||||
# Table 'fpdb.hands' doesn't exist
|
||||
if str(sys.exc_value).find(".Hands' doesn't exist") >= 0:
|
||||
# Table 'fpdb.players' doesn't exist
|
||||
if str(sys.exc_value).find(".Players' doesn't exist") >= 0:
|
||||
return(2)
|
||||
print "Error! failed to obtain global lock. Close all programs accessing " \
|
||||
+ "database (including fpdb) and try again (%s)." \
|
||||
|
@ -586,11 +586,11 @@ class fpdb_db:
|
|||
return(1)
|
||||
elif self.backend == self.PGSQL:
|
||||
try:
|
||||
self.cursor.execute( "lock table Hands in exclusive mode nowait" )
|
||||
self.cursor.execute( "lock table Players in exclusive mode nowait" )
|
||||
#print "... after lock table, status =", self.cursor.statusmessage
|
||||
except:
|
||||
# relation "hands" does not exist
|
||||
if str(sys.exc_value).find('relation "hands" does not exist') >= 0:
|
||||
# relation "players" does not exist
|
||||
if str(sys.exc_value).find('relation "players" does not exist') >= 0:
|
||||
return(2)
|
||||
print "Error! failed to obtain global lock. Close all programs accessing " \
|
||||
+ "database (including fpdb) and try again (%s)." \
|
||||
|
|
|
@ -31,6 +31,7 @@ import re
|
|||
|
||||
import fpdb_simple
|
||||
import fpdb_db
|
||||
import Database
|
||||
import fpdb_parse_logic
|
||||
import Configuration
|
||||
|
||||
|
@ -57,7 +58,8 @@ class Importer:
|
|||
self.settings = settings
|
||||
self.caller = caller
|
||||
self.config = config
|
||||
self.fdb = None
|
||||
self.database = None # database will be the main db interface eventually
|
||||
self.fdb = None # fdb may disappear or just hold the simple db connection
|
||||
self.cursor = None
|
||||
self.filelist = {}
|
||||
self.dirlist = {}
|
||||
|
@ -75,6 +77,7 @@ class Importer:
|
|||
self.settings.setdefault("minPrint", 30)
|
||||
self.settings.setdefault("handCount", 0)
|
||||
|
||||
self.database = Database.Database(self.config) # includes .connection and .sql variables
|
||||
self.fdb = fpdb_db.fpdb_db() # sets self.fdb.db self.fdb.cursor and self.fdb.sql
|
||||
self.fdb.do_connect(self.config)
|
||||
self.fdb.db.rollback()
|
||||
|
@ -393,7 +396,8 @@ class Importer:
|
|||
|
||||
try:
|
||||
handsId = fpdb_parse_logic.mainParser( self.settings, self.fdb
|
||||
, self.siteIds[site], category, hand, self.config)
|
||||
, self.siteIds[site], category, hand
|
||||
, self.config, self.database )
|
||||
self.fdb.db.commit()
|
||||
|
||||
stored += 1
|
||||
|
|
|
@ -21,10 +21,13 @@ import fpdb_simple
|
|||
import Database
|
||||
|
||||
#parses a holdem hand
|
||||
def mainParser(settings, fdb, siteID, category, hand, config):
|
||||
def mainParser(settings, fdb, siteID, category, hand, config, db = None):
|
||||
backend = settings['db-backend']
|
||||
#This is redundant - hopefully fdb will be a Database object in an interation soon
|
||||
db = Database.Database(config, 'fpdb', '')
|
||||
if db == None:
|
||||
#This is redundant - hopefully fdb will be a Database object in an iteration soon
|
||||
db = Database.Database(c = config, sql = None)
|
||||
else:
|
||||
db = db
|
||||
category = fpdb_simple.recogniseCategory(hand[0])
|
||||
|
||||
base = "hold" if category == "holdem" or category == "omahahi" or category == "omahahilo" else "stud"
|
||||
|
|
|
@ -1136,16 +1136,6 @@ def storeActions(cursor, handsPlayersIds, actionTypes, allIns, actionAmounts, ac
|
|||
cursor.executemany("INSERT INTO HandsActions (handsPlayerId, street, actionNo, action, allIn, amount) VALUES (%s, %s, %s, %s, %s, %s)", inserts)
|
||||
#end def storeActions
|
||||
|
||||
def store_board_cards(cursor, hands_id, board_values, board_suits):
|
||||
#stores into table board_cards
|
||||
cursor.execute ("""INSERT INTO BoardCards (handId, card1Value, card1Suit,
|
||||
card2Value, card2Suit, card3Value, card3Suit, card4Value, card4Suit,
|
||||
card5Value, card5Suit) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
|
||||
(hands_id, board_values[0], board_suits[0], board_values[1], board_suits[1],
|
||||
board_values[2], board_suits[2], board_values[3], board_suits[3],
|
||||
board_values[4], board_suits[4]))
|
||||
#end def store_board_cards
|
||||
|
||||
def storeHands(backend, conn, cursor, site_hand_no, gametype_id
|
||||
,hand_start_time, names, tableName, maxSeats, hudCache,
|
||||
board_values, board_suits):
|
||||
|
|
Loading…
Reference in New Issue
Block a user