Merge branch 'master' of git://git.assembla.com/fpdb-sql
Conflicts: pyfpdb/Hand.py
This commit is contained in:
commit
7351749b7a
|
@ -86,14 +86,34 @@ class Site:
|
||||||
self.aux_window = node.getAttribute("aux_window")
|
self.aux_window = node.getAttribute("aux_window")
|
||||||
self.font = node.getAttribute("font")
|
self.font = node.getAttribute("font")
|
||||||
self.font_size = node.getAttribute("font_size")
|
self.font_size = node.getAttribute("font_size")
|
||||||
self.use_frames = node.getAttribute("use_frames")
|
self.use_frames = node.getAttribute("use_frames")
|
||||||
self.enabled = fix_tf(node.getAttribute("enabled"), default = True)
|
self.enabled = fix_tf(node.getAttribute("enabled"), default = True)
|
||||||
|
self.xpad = node.getAttribute("xpad")
|
||||||
|
self.ypad = node.getAttribute("ypad")
|
||||||
self.layout = {}
|
self.layout = {}
|
||||||
|
|
||||||
for layout_node in node.getElementsByTagName('layout'):
|
for layout_node in node.getElementsByTagName('layout'):
|
||||||
lo = Layout(layout_node)
|
lo = Layout(layout_node)
|
||||||
self.layout[lo.max] = lo
|
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):
|
def __str__(self):
|
||||||
temp = "Site = " + self.site_name + "\n"
|
temp = "Site = " + self.site_name + "\n"
|
||||||
for key in dir(self):
|
for key in dir(self):
|
||||||
|
@ -119,9 +139,16 @@ class Stat:
|
||||||
class Game:
|
class Game:
|
||||||
def __init__(self, node):
|
def __init__(self, node):
|
||||||
self.game_name = node.getAttribute("game_name")
|
self.game_name = node.getAttribute("game_name")
|
||||||
self.db = node.getAttribute("db")
|
|
||||||
self.rows = int( node.getAttribute("rows") )
|
self.rows = int( node.getAttribute("rows") )
|
||||||
self.cols = int( node.getAttribute("cols") )
|
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_text = node.getAttribute("aux")
|
||||||
aux_list = aux_text.split(',')
|
aux_list = aux_text.split(',')
|
||||||
|
@ -146,9 +173,10 @@ class Game:
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
temp = "Game = " + self.game_name + "\n"
|
temp = "Game = " + self.game_name + "\n"
|
||||||
temp = temp + " db = %s\n" % self.db
|
|
||||||
temp = temp + " rows = %d\n" % self.rows
|
temp = temp + " rows = %d\n" % self.rows
|
||||||
temp = temp + " cols = %d\n" % self.cols
|
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
|
temp = temp + " aux = %s\n" % self.aux
|
||||||
|
|
||||||
for stat in self.stats.keys():
|
for stat in self.stats.keys():
|
||||||
|
@ -631,6 +659,8 @@ class Config:
|
||||||
parms["font"] = self.supported_sites[site].font
|
parms["font"] = self.supported_sites[site].font
|
||||||
parms["font_size"] = self.supported_sites[site].font_size
|
parms["font_size"] = self.supported_sites[site].font_size
|
||||||
parms["enabled"] = self.supported_sites[site].enabled
|
parms["enabled"] = self.supported_sites[site].enabled
|
||||||
|
parms["xpad"] = self.supported_sites[site].xpad
|
||||||
|
parms["ypad"] = self.supported_sites[site].ypad
|
||||||
return parms
|
return parms
|
||||||
|
|
||||||
def set_site_parameters(self, site_name, converter = None, decoder = None,
|
def set_site_parameters(self, site_name, converter = None, decoder = None,
|
||||||
|
@ -681,9 +711,10 @@ class Config:
|
||||||
param = {}
|
param = {}
|
||||||
if self.supported_games.has_key(name):
|
if self.supported_games.has_key(name):
|
||||||
param['game_name'] = self.supported_games[name].game_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['rows'] = self.supported_games[name].rows
|
||||||
param['cols'] = self.supported_games[name].cols
|
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
|
param['aux'] = self.supported_games[name].aux
|
||||||
return param
|
return param
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,8 @@ import SQL
|
||||||
import Card
|
import Card
|
||||||
|
|
||||||
class Database:
|
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 = fpdb_db.fpdb_db() # sets self.fdb.db self.fdb.cursor and self.fdb.sql
|
||||||
self.fdb.do_connect(c)
|
self.fdb.do_connect(c)
|
||||||
self.connection = self.fdb.db
|
self.connection = self.fdb.db
|
||||||
|
@ -48,7 +49,12 @@ class Database:
|
||||||
self.import_options = c.get_import_parameters()
|
self.import_options = c.get_import_parameters()
|
||||||
self.type = db_params['db-type']
|
self.type = db_params['db-type']
|
||||||
self.backend = db_params['db-backend']
|
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()
|
self.connection.rollback()
|
||||||
|
|
||||||
# To add to config:
|
# To add to config:
|
||||||
|
@ -81,13 +87,28 @@ class Database:
|
||||||
#row = cur.fetchone()
|
#row = cur.fetchone()
|
||||||
self.saveActions = False if self.import_options['saveActions'] == False else True
|
self.saveActions = False if self.import_options['saveActions'] == False else True
|
||||||
|
|
||||||
|
def do_connect(self, c):
|
||||||
|
self.fdb.do_connect(c)
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
self.fdb.db.commit()
|
self.fdb.db.commit()
|
||||||
|
|
||||||
def close_connection(self):
|
def close_connection(self):
|
||||||
self.connection.close()
|
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):
|
def get_table_name(self, hand_id):
|
||||||
c = self.connection.cursor()
|
c = self.connection.cursor()
|
||||||
c.execute(self.sql.query['get_table_name'], (hand_id, ))
|
c.execute(self.sql.query['get_table_name'], (hand_id, ))
|
||||||
|
@ -138,12 +159,8 @@ class Database:
|
||||||
cards = {}
|
cards = {}
|
||||||
c = self.connection.cursor()
|
c = self.connection.cursor()
|
||||||
c.execute(self.sql.query['get_common_cards'], [hand])
|
c.execute(self.sql.query['get_common_cards'], [hand])
|
||||||
colnames = [desc[0] for desc in c.description]
|
# row = c.fetchone()
|
||||||
for row in c.fetchall():
|
cards['common'] = c.fetchone()
|
||||||
s_dict = {}
|
|
||||||
for name, val in zip(colnames, row):
|
|
||||||
s_dict[name] = val
|
|
||||||
cards['common'] = (self.convert_cards(s_dict))
|
|
||||||
return cards
|
return cards
|
||||||
|
|
||||||
def convert_cards(self, d):
|
def convert_cards(self, d):
|
||||||
|
@ -326,7 +343,6 @@ class Database:
|
||||||
if 'updateHudCache' not in settings or settings['updateHudCache'] != 'drop':
|
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.storeHudCache(self.backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData)
|
||||||
t5 = time()
|
t5 = time()
|
||||||
fpdb_simple.store_board_cards(cursor, hands_id, board_values, board_suits)
|
|
||||||
t6 = time()
|
t6 = time()
|
||||||
if self.saveActions:
|
if self.saveActions:
|
||||||
fpdb_simple.storeActions(cursor, hands_players_ids, action_types, allIns, action_amounts, actionNos)
|
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':
|
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.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:
|
if self.saveActions:
|
||||||
fpdb_simple.storeActions(cursor, hands_players_ids, action_types, allIns, action_amounts, actionNos)
|
fpdb_simple.storeActions(cursor, hands_players_ids, action_types, allIns, action_amounts, actionNos)
|
||||||
return hands_id
|
return hands_id
|
||||||
|
|
|
@ -30,12 +30,11 @@ import fpdb_db
|
||||||
import FpdbSQLQueries
|
import FpdbSQLQueries
|
||||||
|
|
||||||
class Filters(threading.Thread):
|
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
|
self.debug=debug
|
||||||
#print "start of GraphViewer constructor"
|
#print "start of GraphViewer constructor"
|
||||||
self.db=db
|
self.db=db
|
||||||
self.cursor=db.cursor
|
self.cursor=db.cursor
|
||||||
self.settings=settings
|
|
||||||
self.sql=qdict
|
self.sql=qdict
|
||||||
self.conf = config
|
self.conf = config
|
||||||
self.display = display
|
self.display = display
|
||||||
|
@ -235,7 +234,7 @@ class Filters(threading.Thread):
|
||||||
|
|
||||||
def __set_hero_name(self, w, site):
|
def __set_hero_name(self, w, site):
|
||||||
self.heroes[site] = w.get_text()
|
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):
|
def createSiteLine(self, hbox, site):
|
||||||
cb = gtk.CheckButton(site)
|
cb = gtk.CheckButton(site)
|
||||||
|
@ -556,23 +555,12 @@ def main(argv=None):
|
||||||
config = Configuration.Config()
|
config = Configuration.Config()
|
||||||
db = None
|
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 = fpdb_db.fpdb_db()
|
||||||
db.connect(settings['db-backend'],
|
db.do_connect(config)
|
||||||
settings['db-host'],
|
|
||||||
settings['db-databaseName'],
|
|
||||||
settings['db-user'],
|
|
||||||
settings['db-password'])
|
|
||||||
|
|
||||||
qdict = FpdbSQLQueries.FpdbSQLQueries(db.get_backend_name())
|
qdict = FpdbSQLQueries.FpdbSQLQueries(db.get_backend_name())
|
||||||
|
|
||||||
i = Filters(db, settings, config, qdict)
|
i = Filters(db, config, qdict)
|
||||||
main_window = gtk.Window()
|
main_window = gtk.Window()
|
||||||
main_window.connect('destroy', destroy)
|
main_window.connect('destroy', destroy)
|
||||||
main_window.add(i.get_vbox())
|
main_window.add(i.get_vbox())
|
||||||
|
|
|
@ -248,43 +248,6 @@ class FpdbSQLQueries:
|
||||||
self.query['createHandsTable'] = """ """
|
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
|
# Create TourneyTypes
|
||||||
################################
|
################################
|
||||||
|
@ -1550,136 +1513,6 @@ class FpdbSQLQueries:
|
||||||
elif(self.dbname == 'SQLite'):
|
elif(self.dbname == 'SQLite'):
|
||||||
self.query['playerStatsByPosition'] = """ """
|
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'):
|
if(self.dbname == 'MySQL InnoDB') or (self.dbname == 'PostgreSQL') or (self.dbname == 'SQLite'):
|
||||||
self.query['getGames'] = """SELECT DISTINCT category from Gametypes"""
|
self.query['getGames'] = """SELECT DISTINCT category from Gametypes"""
|
||||||
|
|
||||||
|
|
|
@ -43,14 +43,14 @@ import Filters
|
||||||
|
|
||||||
class GuiGraphViewer (threading.Thread):
|
class GuiGraphViewer (threading.Thread):
|
||||||
|
|
||||||
def __init__(self, db, settings, querylist, config, debug=True):
|
def __init__(self, querylist, config, debug=True):
|
||||||
"""Constructor for GraphViewer"""
|
"""Constructor for GraphViewer"""
|
||||||
self.debug=debug
|
self.debug=debug
|
||||||
#print "start of GraphViewer constructor"
|
#print "start of GraphViewer constructor"
|
||||||
self.db=db
|
self.db = fpdb_db.fpdb_db() # sets self.fdb.db self.fdb.cursor and self.fdb.sql
|
||||||
self.cursor=db.cursor
|
self.db.do_connect(config)
|
||||||
self.settings=settings
|
|
||||||
self.sql=querylist
|
self.sql = querylist
|
||||||
self.conf = config
|
self.conf = config
|
||||||
|
|
||||||
filters_display = { "Heroes" : True,
|
filters_display = { "Heroes" : True,
|
||||||
|
@ -63,7 +63,7 @@ class GuiGraphViewer (threading.Thread):
|
||||||
"Button2" : True
|
"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.registerButton1Name("Refresh Graph")
|
||||||
self.filters.registerButton1Callback(self.generateGraph)
|
self.filters.registerButton1Callback(self.generateGraph)
|
||||||
self.filters.registerButton2Name("Export to File")
|
self.filters.registerButton2Name("Export to File")
|
||||||
|
@ -146,7 +146,7 @@ class GuiGraphViewer (threading.Thread):
|
||||||
for site in sites:
|
for site in sites:
|
||||||
if sites[site] == True:
|
if sites[site] == True:
|
||||||
sitenos.append(siteids[site])
|
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()
|
result = self.db.cursor.fetchall()
|
||||||
if len(result) == 1:
|
if len(result) == 1:
|
||||||
playerids.append(result[0][0])
|
playerids.append(result[0][0])
|
||||||
|
@ -226,7 +226,7 @@ class GuiGraphViewer (threading.Thread):
|
||||||
|
|
||||||
#print "DEBUG: sql query:"
|
#print "DEBUG: sql query:"
|
||||||
#print tmp
|
#print tmp
|
||||||
self.cursor.execute(tmp)
|
self.db.cursor.execute(tmp)
|
||||||
#returns (HandId,Winnings,Costs,Profit)
|
#returns (HandId,Winnings,Costs,Profit)
|
||||||
winnings = self.db.cursor.fetchall()
|
winnings = self.db.cursor.fetchall()
|
||||||
self.db.db.rollback()
|
self.db.db.rollback()
|
||||||
|
|
|
@ -66,7 +66,7 @@ class GuiPlayerStats (threading.Thread):
|
||||||
"Button2" : True
|
"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.registerButton1Name("_Filters")
|
||||||
self.filters.registerButton1Callback(self.showDetailFilter)
|
self.filters.registerButton1Callback(self.showDetailFilter)
|
||||||
self.filters.registerButton2Name("_Refresh")
|
self.filters.registerButton2Name("_Refresh")
|
||||||
|
@ -227,11 +227,6 @@ class GuiPlayerStats (threading.Thread):
|
||||||
if not flags: holecards = False
|
if not flags: holecards = False
|
||||||
else: holecards = flags[0]
|
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.sql.query[query]
|
||||||
tmp = self.refineQuery(tmp, flags, playerids, sitenos, limits, seats, groups, dates)
|
tmp = self.refineQuery(tmp, flags, playerids, sitenos, limits, seats, groups, dates)
|
||||||
self.cursor.execute(tmp)
|
self.cursor.execute(tmp)
|
||||||
|
@ -279,10 +274,6 @@ class GuiPlayerStats (threading.Thread):
|
||||||
|
|
||||||
while sqlrow < rows:
|
while sqlrow < rows:
|
||||||
treerow = []
|
treerow = []
|
||||||
if(row%2 == 0):
|
|
||||||
bgcolor = "white"
|
|
||||||
else:
|
|
||||||
bgcolor = "lightgrey"
|
|
||||||
for col,column in enumerate(cols_to_show):
|
for col,column in enumerate(cols_to_show):
|
||||||
if column[colalias] in colnames:
|
if column[colalias] in colnames:
|
||||||
value = result[sqlrow][colnames.index(column[colalias])]
|
value = result[sqlrow][colnames.index(column[colalias])]
|
||||||
|
|
|
@ -20,6 +20,7 @@ import pygtk
|
||||||
pygtk.require('2.0')
|
pygtk.require('2.0')
|
||||||
import gtk
|
import gtk
|
||||||
import os
|
import os
|
||||||
|
from time import time, strftime
|
||||||
|
|
||||||
import fpdb_import
|
import fpdb_import
|
||||||
import fpdb_db
|
import fpdb_db
|
||||||
|
@ -58,21 +59,50 @@ class GuiPositionalStats (threading.Thread):
|
||||||
"Button2" : False
|
"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.registerButton1Name("Refresh")
|
||||||
self.filters.registerButton1Callback(self.refreshStats)
|
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.stat_table = None
|
||||||
self.stats_frame = None
|
self.stats_frame = None
|
||||||
|
self.stats_vbox = None
|
||||||
|
|
||||||
self.main_hbox = gtk.HBox(False, 0)
|
self.main_hbox = gtk.HBox(False, 0)
|
||||||
self.main_hbox.show()
|
self.main_hbox.show()
|
||||||
|
|
||||||
statsFrame = gtk.Frame("Stats:")
|
self.stats_frame = gtk.Frame()
|
||||||
statsFrame.set_label_align(0.0, 0.0)
|
self.stats_frame.set_label_align(0.0, 0.0)
|
||||||
statsFrame.show()
|
|
||||||
self.stats_frame = gtk.VBox(False, 0)
|
|
||||||
self.stats_frame.show()
|
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.
|
# 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
|
# 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"
|
, "PoFAFq", "Net($)", "bb/100", "$/hand", "Variance", "Hds"
|
||||||
)
|
)
|
||||||
|
|
||||||
self.fillStatsFrame(self.stats_frame)
|
self.fillStatsFrame(self.stats_vbox)
|
||||||
statsFrame.add(self.stats_frame)
|
self.stats_frame.add(self.stats_vbox)
|
||||||
|
|
||||||
self.main_hbox.pack_start(self.filters.get_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):
|
def get_vbox(self):
|
||||||
|
@ -107,9 +137,12 @@ class GuiPositionalStats (threading.Thread):
|
||||||
print "DEBUG: activesite set to %s" %(self.activesite)
|
print "DEBUG: activesite set to %s" %(self.activesite)
|
||||||
|
|
||||||
def refreshStats(self, widget, data):
|
def refreshStats(self, widget, data):
|
||||||
try: self.stats_table.destroy()
|
try: self.stats_vbox.destroy()
|
||||||
except AttributeError: pass
|
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):
|
def fillStatsFrame(self, vbox):
|
||||||
sites = self.filters.getSites()
|
sites = self.filters.getSites()
|
||||||
|
@ -144,66 +177,104 @@ class GuiPositionalStats (threading.Thread):
|
||||||
self.createStatsTable(vbox, playerids, sitenos, limits, seats, dates)
|
self.createStatsTable(vbox, playerids, sitenos, limits, seats, dates)
|
||||||
|
|
||||||
def createStatsTable(self, 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
|
row = 0
|
||||||
col = 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.sql.query['playerStatsByPosition']
|
||||||
tmp = self.refineQuery(tmp, playerids, sitenos, limits, seats, dates)
|
tmp = self.refineQuery(tmp, playerids, sitenos, limits, seats, dates)
|
||||||
self.cursor.execute(tmp)
|
self.cursor.execute(tmp)
|
||||||
result = self.cursor.fetchall()
|
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)
|
rows = len(result)
|
||||||
colnames = [desc[0].lower() for desc in self.cursor.description]
|
|
||||||
|
|
||||||
last_game,last_seats,sqlrow = "","",0
|
last_game,last_seats,sqlrow = "","",0
|
||||||
while sqlrow < rows:
|
while sqlrow < rows:
|
||||||
if(row%2 == 0):
|
|
||||||
bgcolor = "white"
|
|
||||||
else:
|
|
||||||
bgcolor = "lightgrey"
|
|
||||||
rowprinted=0
|
rowprinted=0
|
||||||
|
treerow = []
|
||||||
avgcol = colnames.index('avgseats')
|
avgcol = colnames.index('avgseats')
|
||||||
for col,colname in enumerate(self.posncols):
|
for col,colname in enumerate(self.posncols):
|
||||||
if colname in colnames:
|
if colname in colnames:
|
||||||
sqlcol = colnames.index(colname)
|
sqlcol = colnames.index(colname)
|
||||||
else:
|
else:
|
||||||
continue
|
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 result[sqlrow][sqlcol]:
|
||||||
if sqlrow == 0:
|
if sqlrow == 0:
|
||||||
l = gtk.Label(result[sqlrow][sqlcol])
|
value = result[sqlrow][sqlcol]
|
||||||
rowprinted=1
|
rowprinted=1
|
||||||
elif result[sqlrow][0] != last_game:
|
elif result[sqlrow][0] != last_game:
|
||||||
l = gtk.Label(' ')
|
value = ' '
|
||||||
elif 'show' in seats and seats['show'] and result[sqlrow][avgcol] != last_seats:
|
elif 'show' in seats and seats['show'] and result[sqlrow][avgcol] != last_seats:
|
||||||
l = gtk.Label(' ')
|
value = ' '
|
||||||
else:
|
else:
|
||||||
l = gtk.Label(result[sqlrow][sqlcol])
|
value = result[sqlrow][sqlcol]
|
||||||
rowprinted=1
|
rowprinted=1
|
||||||
else:
|
else:
|
||||||
l = gtk.Label(' ')
|
l = gtk.Label(' ')
|
||||||
if col == 0:
|
value = ' '
|
||||||
l.set_alignment(xalign=0.0, yalign=0.5)
|
if value and value != -999:
|
||||||
elif col == 1:
|
treerow.append(value)
|
||||||
l.set_alignment(xalign=0.5, yalign=0.5)
|
|
||||||
else:
|
else:
|
||||||
l.set_alignment(xalign=1.0, yalign=0.5)
|
treerow.append(' ')
|
||||||
eb.add(l)
|
iter = liststore.append(treerow)
|
||||||
self.stats_table.attach(eb, col, col+1, row+1, row+2, yoptions=gtk.SHRINK)
|
|
||||||
l.show()
|
|
||||||
eb.show()
|
|
||||||
last_game = result[sqlrow][0]
|
last_game = result[sqlrow][0]
|
||||||
last_seats = result[sqlrow][avgcol]
|
last_seats = result[sqlrow][avgcol]
|
||||||
if rowprinted:
|
if rowprinted:
|
||||||
|
@ -220,50 +291,36 @@ class GuiPositionalStats (threading.Thread):
|
||||||
|
|
||||||
# blank row between main stats and totals:
|
# blank row between main stats and totals:
|
||||||
col = 0
|
col = 0
|
||||||
if(row%2 == 0):
|
treerow = [' ' for x in self.posncols]
|
||||||
bgcolor = "white"
|
iter = liststore.append(treerow)
|
||||||
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()
|
|
||||||
row = row + 1
|
row = row + 1
|
||||||
|
|
||||||
for sqlrow in range(rows):
|
for sqlrow in range(rows):
|
||||||
if(row%2 == 0):
|
treerow = []
|
||||||
bgcolor = "white"
|
|
||||||
else:
|
|
||||||
bgcolor = "lightgrey"
|
|
||||||
for col,colname in enumerate(self.posncols):
|
for col,colname in enumerate(self.posncols):
|
||||||
if colname in colnames:
|
if colname in colnames:
|
||||||
sqlcol = colnames.index(colname)
|
sqlcol = colnames.index(colname)
|
||||||
elif colname != "plposition":
|
elif colname != "plposition":
|
||||||
continue
|
continue
|
||||||
eb = gtk.EventBox()
|
|
||||||
eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bgcolor))
|
|
||||||
if colname == 'plposition':
|
if colname == 'plposition':
|
||||||
l = gtk.Label('Totals')
|
l = gtk.Label('Totals')
|
||||||
|
value = 'Totals'
|
||||||
elif result[sqlrow][sqlcol]:
|
elif result[sqlrow][sqlcol]:
|
||||||
l = gtk.Label(result[sqlrow][sqlcol])
|
l = gtk.Label(result[sqlrow][sqlcol])
|
||||||
|
value = result[sqlrow][sqlcol]
|
||||||
else:
|
else:
|
||||||
l = gtk.Label(' ')
|
l = gtk.Label(' ')
|
||||||
if col == 0:
|
value = ' '
|
||||||
l.set_alignment(xalign=0.0, yalign=0.5)
|
if value and value != -999:
|
||||||
elif col == 1:
|
treerow.append(value)
|
||||||
l.set_alignment(xalign=0.5, yalign=0.5)
|
|
||||||
else:
|
else:
|
||||||
l.set_alignment(xalign=1.0, yalign=0.5)
|
treerow.append(' ')
|
||||||
eb.add(l)
|
iter = liststore.append(treerow)
|
||||||
self.stats_table.attach(eb, col, col+1, row+1, row+2, yoptions=gtk.SHRINK)
|
|
||||||
l.show()
|
|
||||||
eb.show()
|
|
||||||
row = row + 1
|
row = row + 1
|
||||||
|
vbox.show_all()
|
||||||
|
|
||||||
self.db.db.rollback()
|
self.db.db.rollback()
|
||||||
|
print "Positional Stats page displayed in %4.2f seconds" % (time() - starttime)
|
||||||
#end def fillStatsFrame(self, vbox):
|
#end def fillStatsFrame(self, vbox):
|
||||||
|
|
||||||
def refineQuery(self, query, playerids, sitenos, limits, seats, dates):
|
def refineQuery(self, query, playerids, sitenos, limits, seats, dates):
|
||||||
|
|
|
@ -34,10 +34,13 @@ import gobject
|
||||||
|
|
||||||
# FreePokerTools modules
|
# FreePokerTools modules
|
||||||
from Mucked import Aux_Window
|
from Mucked import Aux_Window
|
||||||
|
from Mucked import Seat_Window
|
||||||
|
from Mucked import Aux_Seats
|
||||||
|
|
||||||
class Hello(Aux_Window):
|
class Hello(Aux_Window):
|
||||||
"""A 'Hello World' Aux_Window demo."""
|
"""A 'Hello World' Aux_Window demo."""
|
||||||
def create(self):
|
def create(self):
|
||||||
|
print "creating Hello"
|
||||||
# This demo simply creates a label in a window.
|
# This demo simply creates a label in a window.
|
||||||
self.container = gtk.Window()
|
self.container = gtk.Window()
|
||||||
self.container.add(gtk.Label("Hello World"))
|
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.
|
# 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))
|
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):
|
class Hello_Seats(Aux_Seats):
|
||||||
"""A 'Hello World' Aux_Window demo."""
|
"""A 'Hello World' Seat_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()
|
|
||||||
|
|
||||||
def print_cards(self, *args):
|
def create_contents(self, container, i):
|
||||||
# callback for the menu item
|
container.label = gtk.Label("empty")
|
||||||
print "cards =", self.hud.cards
|
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)
|
Stats.do_tip(window.e_box[r][c], tip)
|
||||||
|
|
||||||
def topify_window(self, window):
|
def topify_window(self, window):
|
||||||
"""Set the specified gtk window to stayontop in MS Windows."""
|
# """Set the specified gtk window to stayontop in MS Windows."""
|
||||||
|
#
|
||||||
def windowEnumerationHandler(hwnd, resultList):
|
# def windowEnumerationHandler(hwnd, resultList):
|
||||||
'''Callback for win32gui.EnumWindows() to generate list of window handles.'''
|
# '''Callback for win32gui.EnumWindows() to generate list of window handles.'''
|
||||||
resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
|
# resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
|
||||||
|
# unique_name = 'unique name for finding this window'
|
||||||
unique_name = 'unique name for finding this window'
|
# real_name = window.get_title()
|
||||||
real_name = window.get_title()
|
# window.set_title(unique_name)
|
||||||
window.set_title(unique_name)
|
# tl_windows = []
|
||||||
tl_windows = []
|
# win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
|
||||||
win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
|
#
|
||||||
|
# for w in tl_windows:
|
||||||
for w in tl_windows:
|
# if w[1] == unique_name:
|
||||||
if w[1] == unique_name:
|
|
||||||
self.main_window.parentgdkhandle = gtk.gdk.window_foreign_new(long(self.table.number))
|
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)
|
self.main_window.gdkhandle.set_transient_for(self.main_window.parentgdkhandle)
|
||||||
|
|
||||||
style = win32gui.GetWindowLong(self.table.number, win32con.GWL_EXSTYLE)
|
style = win32gui.GetWindowLong(self.table.number, win32con.GWL_EXSTYLE)
|
||||||
style |= win32con.WS_CLIPCHILDREN
|
style |= win32con.WS_CLIPCHILDREN
|
||||||
win32gui.SetWindowLong(self.table.number, win32con.GWL_EXSTYLE, style)
|
win32gui.SetWindowLong(self.table.number, win32con.GWL_EXSTYLE, style)
|
||||||
break
|
# break
|
||||||
|
|
||||||
window.set_title(real_name)
|
# window.set_title(real_name)
|
||||||
|
|
||||||
class Stat_Window:
|
class Stat_Window:
|
||||||
|
|
||||||
|
@ -445,10 +445,10 @@ class Stat_Window:
|
||||||
|
|
||||||
Stats.do_tip(e_box[r][c], 'stuff')
|
Stats.do_tip(e_box[r][c], 'stuff')
|
||||||
if usegtkframes:
|
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])
|
self.frame[r][c].add(e_box[r][c])
|
||||||
else:
|
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') )
|
label[r].append( gtk.Label('xxx') )
|
||||||
|
|
||||||
if usegtkframes:
|
if usegtkframes:
|
||||||
|
@ -473,6 +473,7 @@ class Popup_window:
|
||||||
def __init__(self, parent, stat_window):
|
def __init__(self, parent, stat_window):
|
||||||
self.sb_click = 0
|
self.sb_click = 0
|
||||||
self.stat_window = stat_window
|
self.stat_window = stat_window
|
||||||
|
self.parent = parent
|
||||||
|
|
||||||
# create the popup window
|
# create the popup window
|
||||||
self.window = gtk.Window()
|
self.window = gtk.Window()
|
||||||
|
@ -532,11 +533,15 @@ class Popup_window:
|
||||||
# db_connection.close_connection()
|
# db_connection.close_connection()
|
||||||
stat_dict = stat_window.parent.stat_dict
|
stat_dict = stat_window.parent.stat_dict
|
||||||
pu_text = ""
|
pu_text = ""
|
||||||
|
mo_text = ""
|
||||||
for s in stat_list:
|
for s in stat_list:
|
||||||
number = Stats.do_stat(stat_dict, player = int(stat_window.player_id), stat = s)
|
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"
|
pu_text += number[3] + "\n"
|
||||||
|
|
||||||
|
|
||||||
self.lab.set_text(pu_text)
|
self.lab.set_text(pu_text)
|
||||||
|
Stats.do_tip(self.lab, mo_text)
|
||||||
self.window.show_all()
|
self.window.show_all()
|
||||||
|
|
||||||
self.window.set_transient_for(stat_window.window)
|
self.window.set_transient_for(stat_window.window)
|
||||||
|
@ -572,25 +577,25 @@ class Popup_window:
|
||||||
def topify_window(self, window):
|
def topify_window(self, window):
|
||||||
"""Set the specified gtk window to stayontop in MS Windows."""
|
"""Set the specified gtk window to stayontop in MS Windows."""
|
||||||
|
|
||||||
def windowEnumerationHandler(hwnd, resultList):
|
# def windowEnumerationHandler(hwnd, resultList):
|
||||||
'''Callback for win32gui.EnumWindows() to generate list of window handles.'''
|
# '''Callback for win32gui.EnumWindows() to generate list of window handles.'''
|
||||||
resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
|
# resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
|
||||||
|
|
||||||
unique_name = 'unique name for finding this window'
|
# unique_name = 'unique name for finding this window'
|
||||||
real_name = window.get_title()
|
# real_name = window.get_title()
|
||||||
window.set_title(unique_name)
|
# window.set_title(unique_name)
|
||||||
tl_windows = []
|
# tl_windows = []
|
||||||
win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
|
# win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
|
||||||
|
|
||||||
for w in tl_windows:
|
# for w in tl_windows:
|
||||||
if w[1] == unique_name:
|
# if w[1] == unique_name:
|
||||||
window.set_transient_for(self.parent.main_window)
|
window.set_transient_for(self.parent.main_window)
|
||||||
style = win32gui.GetWindowLong(self.table.number, win32con.GWL_EXSTYLE)
|
style = win32gui.GetWindowLong(self.table.number, win32con.GWL_EXSTYLE)
|
||||||
style |= win32con.WS_CLIPCHILDREN
|
style |= win32con.WS_CLIPCHILDREN
|
||||||
win32gui.SetWindowLong(self.table.number, win32con.GWL_EXSTYLE, style)
|
win32gui.SetWindowLong(self.table.number, win32con.GWL_EXSTYLE, style)
|
||||||
break
|
# break
|
||||||
|
|
||||||
window.set_title(real_name)
|
# window.set_title(real_name)
|
||||||
|
|
||||||
if __name__== "__main__":
|
if __name__== "__main__":
|
||||||
main_window = gtk.Window()
|
main_window = gtk.Window()
|
||||||
|
|
252
pyfpdb/Mucked.py
252
pyfpdb/Mucked.py
|
@ -37,27 +37,18 @@ import Configuration
|
||||||
import Database
|
import Database
|
||||||
import Card
|
import Card
|
||||||
|
|
||||||
class Aux_Window:
|
class Aux_Window(object):
|
||||||
def __init__(self, hud, params, config):
|
def __init__(self, hud, params, config):
|
||||||
self.hud = hud
|
self.hud = hud
|
||||||
self.params = params
|
self.params = params
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
def update_data(self, *args):
|
# Override these methods as needed
|
||||||
pass
|
def update_data(self, *args): pass
|
||||||
|
def update_gui(self, *args): pass
|
||||||
def update_gui(self, *args):
|
def create(self, *args): pass
|
||||||
pass
|
def relocate(self, *args): pass
|
||||||
|
def save_layout(self, *args): pass
|
||||||
def create(self, *args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def relocate(self, *args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def save_layout(self, *args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def destroy(self):
|
def destroy(self):
|
||||||
try:
|
try:
|
||||||
self.container.destroy()
|
self.container.destroy()
|
||||||
|
@ -89,15 +80,20 @@ class Aux_Window:
|
||||||
pb.copy_area(30*j, 42*i, 30, 42, temp_pb, 0, 0)
|
pb.copy_area(30*j, 42*i, 30, 42, temp_pb, 0, 0)
|
||||||
return temp_pb
|
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):
|
def has_cards(self, cards):
|
||||||
|
"""Returns the number of cards in the list."""
|
||||||
|
n = 0
|
||||||
for c in cards:
|
for c in cards:
|
||||||
if c in set('shdc'): return True
|
if c != None and c > 0: n = n + 1
|
||||||
return False
|
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):
|
class Stud_mucked(Aux_Window):
|
||||||
def __init__(self, hud, config, params):
|
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.seen_cards[(c, r)].set_from_pixbuf(self.card_images[0])
|
||||||
self.eb[(c, r)].set_tooltip_text('')
|
self.eb[(c, r)].set_tooltip_text('')
|
||||||
|
|
||||||
class Flop_Mucked(Aux_Window):
|
class Seat_Window(gtk.Window):
|
||||||
"""Aux_Window class for displaying mucked cards for flop games."""
|
"""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):
|
def __init__(self, hud, config, params):
|
||||||
self.hud = hud # hud object that this aux window supports
|
self.hud = hud # hud object that this aux window supports
|
||||||
self.config = config # configuration object for this aux window to use
|
self.config = config # configuration object for this aux window to use
|
||||||
self.params = params # dict aux params from config
|
self.params = params # dict aux params from config
|
||||||
self.positions = {} # dict of window positions
|
self.positions = {} # dict of window positions
|
||||||
# self.rel_positions = {} # dict of window positions, relative to the table origin
|
self.displayed = False # the seat windows are displayed
|
||||||
self.displayed_cards = False
|
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.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):
|
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))
|
loc = self.config.get_aux_locations(self.params['name'], int(self.hud.max))
|
||||||
|
|
||||||
self.m_windows = {} # windows to put the card images in
|
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']):
|
for i in (range(1, self.hud.max + 1) + ['common']):
|
||||||
if i == 'common':
|
if i == 'common':
|
||||||
(x, y) = self.params['layout'][self.hud.max].common
|
(x, y) = self.params['layout'][self.hud.max].common
|
||||||
else:
|
else:
|
||||||
(x, y) = loc[self.adj[i]]
|
(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_decorated(False)
|
||||||
self.m_windows[i].set_property("skip-taskbar-hint", True)
|
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_transient_for(self.hud.main_window)
|
||||||
self.m_windows[i].set_focus_on_map(False)
|
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].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.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])
|
self.m_windows[i].move(self.positions[i][0], self.positions[i][1])
|
||||||
self.m_windows[i].set_opacity(float(self.params['opacity']))
|
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()
|
self.m_windows[i].show_all()
|
||||||
self.m_windows[i].hide()
|
if self.uses_timer:
|
||||||
|
self.m_windows[i].hide()
|
||||||
|
|
||||||
|
def update_gui(self, new_hand_id):
|
||||||
|
"""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'])*n_cards,
|
||||||
|
int(self.params['card_ht']))
|
||||||
|
x = 0 # x coord where the next card starts in scratch
|
||||||
|
for card in cards:
|
||||||
|
# concatenate each card image to scratch
|
||||||
|
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'])
|
||||||
|
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'])
|
||||||
|
|
||||||
def update_gui(self, new_hand_id):
|
def update_gui(self, new_hand_id):
|
||||||
"""Prepare and show the mucked cards."""
|
"""Prepare and show the mucked cards."""
|
||||||
if self.displayed_cards:
|
if self.displayed: self.hide()
|
||||||
self.hide_mucked_cards()
|
|
||||||
self.displayed_cards = False
|
# See how many players showed a hand. Skip if only 1 shows (= hero)
|
||||||
|
n_sd = 0
|
||||||
for (i, cards) in self.hud.cards.iteritems():
|
for (i, cards) in self.hud.cards.iteritems():
|
||||||
if self.has_cards(cards):
|
n_cards = self.has_cards(cards)
|
||||||
# scratch is a working pixbuf, used to assemble the image
|
if n_cards > 0:
|
||||||
scratch = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8,
|
n_sd = n_sd + 1
|
||||||
int(self.params['card_wd'])*len(cards)/2,
|
if n_sd < 2:
|
||||||
int(self.params['card_ht']))
|
print "skipping, n_sd =", n_sd
|
||||||
x = 0 # x coord where the next card starts in scratch
|
return
|
||||||
for card in [cards[k:k+2] for k in xrange(0, len(cards), 2)]:
|
|
||||||
# concatenate each card image to scratch
|
|
||||||
self.card_images[self.split_cards(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
|
|
||||||
|
|
||||||
for stats in self.hud.stat_dict.itervalues():
|
super(Flop_Mucked, self).update_gui(new_hand_id)
|
||||||
self.eb[stats['seat']].set_tooltip_text(stats['screen_name'])
|
|
||||||
|
|
||||||
if self.displayed_cards and float(self.params['timeout']) > 0:
|
if self.displayed and float(self.params['timeout']) > 0:
|
||||||
self.timer_on = True
|
self.timer_on = True
|
||||||
gobject.timeout_add(int(1000*float(self.params['timeout'])), self.timed_out)
|
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):
|
def timed_out(self):
|
||||||
# this is the callback from the timeout
|
# this is the callback from the timeout
|
||||||
|
|
||||||
|
@ -418,15 +478,9 @@ class Flop_Mucked(Aux_Window):
|
||||||
if not self.timer_on:
|
if not self.timer_on:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
self.hide_mucked_cards()
|
self.hide()
|
||||||
return False
|
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):
|
def button_press_cb(self, widget, event, *args):
|
||||||
"""Handle button clicks in the event boxes."""
|
"""Handle button clicks in the event boxes."""
|
||||||
|
|
||||||
|
@ -444,58 +498,14 @@ class Flop_Mucked(Aux_Window):
|
||||||
self.timer_on = False
|
self.timer_on = False
|
||||||
else:
|
else:
|
||||||
self.timer_on = False
|
self.timer_on = False
|
||||||
self.hide_mucked_cards()
|
self.hide()
|
||||||
|
|
||||||
elif event.button == 1: # left button event
|
elif event.button == 1: # left button event
|
||||||
window = widget.get_parent()
|
window = widget.get_parent()
|
||||||
window.begin_move_drag(event.button, int(event.x_root), int(event.y_root), event.time)
|
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):
|
def expose_all(self):
|
||||||
for (i, cards) in self.hud.cards.iteritems():
|
for (i, cards) in self.hud.cards.iteritems():
|
||||||
self.m_windows[i].show()
|
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.m_windows[i].move(self.positions[i][0], self.positions[i][1]) # here is where I move back
|
||||||
self.displayed_cards = True
|
self.displayed = 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()
|
|
||||||
|
|
|
@ -541,19 +541,14 @@ class Sql:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.query['get_common_cards'] = """
|
self.query['get_common_cards'] = """
|
||||||
select
|
select
|
||||||
card1Value AS card1value,
|
boardcard1,
|
||||||
card1Suit AS card1suit,
|
boardcard2,
|
||||||
card2Value AS card2value,
|
boardcard3,
|
||||||
card2Suit AS card2suit,
|
boardcard4,
|
||||||
card3Value AS card3value,
|
boardcard5
|
||||||
card3Suit AS card3suit,
|
from Hands
|
||||||
card4Value AS card4value,
|
where Id = %s
|
||||||
card4Suit AS card4suit,
|
|
||||||
card5Value AS card5value,
|
|
||||||
card5Suit AS card5suit
|
|
||||||
from BoardCards
|
|
||||||
where handId = %s
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.query['get_action_from_hand'] = """
|
self.query['get_action_from_hand'] = """
|
||||||
|
|
|
@ -231,7 +231,7 @@ def discover_nt_by_name(c, tablename):
|
||||||
titles = {}
|
titles = {}
|
||||||
win32gui.EnumWindows(win_enum_handler, titles)
|
win32gui.EnumWindows(win_enum_handler, titles)
|
||||||
for hwnd in titles:
|
for hwnd in titles:
|
||||||
print "Tbales.py: tablename =", tablename, "title =", titles[hwnd]
|
#print "Tables.py: tablename =", tablename, "title =", titles[hwnd]
|
||||||
try:
|
try:
|
||||||
# this can blow up in XP on some windows, eg firefox displaying http://docs.python.org/tutorial/classes.html
|
# 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
|
if not tablename in titles[hwnd]: continue
|
||||||
|
@ -314,6 +314,10 @@ def get_site_from_exe(c, exe):
|
||||||
return params['site_name']
|
return params['site_name']
|
||||||
return None
|
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):
|
def pokerstars_decode_table(tw):
|
||||||
# Extract poker information from the window title. This is not needed for
|
# 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.
|
# 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()
|
print "game =", table.get_game()
|
||||||
|
|
||||||
fake = fake_hud(table)
|
fake = fake_hud(table)
|
||||||
|
print "fake =", fake
|
||||||
gobject.timeout_add(100, check_on_table, table, fake)
|
gobject.timeout_add(100, check_on_table, table, fake)
|
||||||
|
print "calling main"
|
||||||
gtk.main()
|
gtk.main()
|
||||||
|
|
||||||
|
|
|
@ -65,8 +65,11 @@ class Table(Table_Window):
|
||||||
print "x = %s y = %s width = %s height = %s" % (x, y, width, height)
|
print "x = %s y = %s width = %s height = %s" % (x, y, width, height)
|
||||||
self.x = int(x) + b_width
|
self.x = int(x) + b_width
|
||||||
self.y = int(y) + tb_height
|
self.y = int(y) + tb_height
|
||||||
self.height = int(height) - b_width - tb_height
|
self.width = width - x
|
||||||
self.width = int(width) - 2*b_width
|
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.exe = self.get_nt_exe(hwnd)
|
||||||
self.title = titles[hwnd]
|
self.title = titles[hwnd]
|
||||||
|
@ -76,12 +79,13 @@ class Table(Table_Window):
|
||||||
self.gdkhandle = gtk.gdk.window_foreign_new(long(self.window))
|
self.gdkhandle = gtk.gdk.window_foreign_new(long(self.window))
|
||||||
|
|
||||||
def get_geometry(self):
|
def get_geometry(self):
|
||||||
|
if not win32gui.IsWindow(self.number): # window closed
|
||||||
if not win32gui.IsWindow(self.window): # window closed
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
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,
|
return {'x' : int(x) + b_width,
|
||||||
'y' : int(y) + tb_height,
|
'y' : int(y) + tb_height,
|
||||||
'width' : int(height) - b_width - tb_height,
|
'width' : int(height) - b_width - tb_height,
|
||||||
|
@ -116,27 +120,32 @@ class Table(Table_Window):
|
||||||
def topify(self, hud):
|
def topify(self, hud):
|
||||||
"""Set the specified gtk window to stayontop in MS Windows."""
|
"""Set the specified gtk window to stayontop in MS Windows."""
|
||||||
|
|
||||||
def windowEnumerationHandler(hwnd, resultList):
|
# def windowEnumerationHandler(hwnd, resultList):
|
||||||
'''Callback for win32gui.EnumWindows() to generate list of window handles.'''
|
# '''Callback for win32gui.EnumWindows() to generate list of window handles.'''
|
||||||
resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
|
# resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
|
||||||
|
#
|
||||||
unique_name = 'unique name for finding this window'
|
# unique_name = 'unique name for finding this window'
|
||||||
real_name = hud.main_window.get_title()
|
# real_name = hud.main_window.get_title()
|
||||||
hud.main_window.set_title(unique_name)
|
# hud.main_window.set_title(unique_name)
|
||||||
tl_windows = []
|
# tl_windows = []
|
||||||
win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
|
# win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
|
||||||
|
#
|
||||||
for w in tl_windows:
|
# for w in tl_windows:
|
||||||
if w[1] == unique_name:
|
# if w[1] == unique_name:
|
||||||
hud.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0])
|
# hud.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0])
|
||||||
hud.main_window.gdkhandle.set_transient_for(self.gdkhandle)
|
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 = win32gui.GetWindowLong(self.number, win32con.GWL_EXSTYLE)
|
||||||
# style |= win32con.WS_CLIPCHILDREN
|
# style |= win32con.WS_CLIPCHILDREN
|
||||||
# win32gui.SetWindowLong(self.number, win32con.GWL_EXSTYLE, style)
|
# 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):
|
def win_enum_handler(hwnd, titles):
|
||||||
titles[hwnd] = win32gui.GetWindowText(hwnd)
|
titles[hwnd] = win32gui.GetWindowText(hwnd)
|
||||||
|
|
|
@ -32,7 +32,7 @@ import pygtk
|
||||||
pygtk.require('2.0')
|
pygtk.require('2.0')
|
||||||
import gtk
|
import gtk
|
||||||
|
|
||||||
import fpdb_db
|
|
||||||
import fpdb_simple
|
import fpdb_simple
|
||||||
import GuiBulkImport
|
import GuiBulkImport
|
||||||
import GuiPlayerStats
|
import GuiPlayerStats
|
||||||
|
@ -41,6 +41,8 @@ import GuiTableViewer
|
||||||
import GuiAutoImport
|
import GuiAutoImport
|
||||||
import GuiGraphViewer
|
import GuiGraphViewer
|
||||||
import GuiSessionViewer
|
import GuiSessionViewer
|
||||||
|
import SQL
|
||||||
|
import Database
|
||||||
import FpdbSQLQueries
|
import FpdbSQLQueries
|
||||||
import Configuration
|
import Configuration
|
||||||
|
|
||||||
|
@ -178,20 +180,21 @@ class fpdb:
|
||||||
def dia_load_profile(self, widget, data=None):
|
def dia_load_profile(self, widget, data=None):
|
||||||
"""Dialogue to select a file to load a profile from"""
|
"""Dialogue to select a file to load a profile from"""
|
||||||
if self.obtain_global_lock() == 0: # returns 0 if successful
|
if self.obtain_global_lock() == 0: # returns 0 if successful
|
||||||
try:
|
#try:
|
||||||
chooser = gtk.FileChooserDialog(title="Please select a profile file to load",
|
# chooser = gtk.FileChooserDialog(title="Please select a profile file to load",
|
||||||
action=gtk.FILE_CHOOSER_ACTION_OPEN,
|
# action=gtk.FILE_CHOOSER_ACTION_OPEN,
|
||||||
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
|
# buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
|
||||||
chooser.set_filename(self.profile)
|
# chooser.set_filename(self.profile)
|
||||||
|
|
||||||
response = chooser.run()
|
# response = chooser.run()
|
||||||
chooser.destroy()
|
# chooser.destroy()
|
||||||
if response == gtk.RESPONSE_OK:
|
# if response == gtk.RESPONSE_OK:
|
||||||
self.load_profile(chooser.get_filename())
|
# self.load_profile(chooser.get_filename())
|
||||||
elif response == gtk.RESPONSE_CANCEL:
|
# elif response == gtk.RESPONSE_CANCEL:
|
||||||
print 'User cancelled loading profile'
|
# print 'User cancelled loading profile'
|
||||||
except:
|
#except:
|
||||||
pass
|
# pass
|
||||||
|
self.load_profile()
|
||||||
self.release_global_lock()
|
self.release_global_lock()
|
||||||
#end def dia_load_profile
|
#end def dia_load_profile
|
||||||
|
|
||||||
|
@ -203,22 +206,23 @@ class fpdb:
|
||||||
try:
|
try:
|
||||||
dia_confirm = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING,
|
dia_confirm = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING,
|
||||||
buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm deleting and recreating tables")
|
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
|
dia_confirm.format_secondary_text(diastring)#todo: make above string with bold for db, host and deleted
|
||||||
|
|
||||||
response = dia_confirm.run()
|
response = dia_confirm.run()
|
||||||
dia_confirm.destroy()
|
dia_confirm.destroy()
|
||||||
if response == gtk.RESPONSE_YES:
|
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
|
# mysql requires locks on all tables or none - easier to release this lock
|
||||||
# than lock all the other tables
|
# than lock all the other tables
|
||||||
# ToDo: lock all other tables so that lock doesn't have to be released
|
# ToDo: lock all other tables so that lock doesn't have to be released
|
||||||
self.release_global_lock()
|
self.release_global_lock()
|
||||||
lock_released = True
|
lock_released = True
|
||||||
self.db.recreate_tables()
|
self.db.fdb.recreate_tables()
|
||||||
else:
|
else:
|
||||||
# for other dbs use same connection as holds global lock
|
# 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:
|
elif response == gtk.RESPONSE_NO:
|
||||||
print 'User cancelled recreating tables'
|
print 'User cancelled recreating tables'
|
||||||
except:
|
except:
|
||||||
|
@ -346,6 +350,7 @@ class fpdb:
|
||||||
|
|
||||||
def load_profile(self):
|
def load_profile(self):
|
||||||
"""Loads profile from the provided path name."""
|
"""Loads profile from the provided path name."""
|
||||||
|
self.config = Configuration.Config(file=options.config, dbname=options.dbname)
|
||||||
self.settings = {}
|
self.settings = {}
|
||||||
if (os.sep=="/"):
|
if (os.sep=="/"):
|
||||||
self.settings['os']="linuxmac"
|
self.settings['os']="linuxmac"
|
||||||
|
@ -358,17 +363,13 @@ class fpdb:
|
||||||
self.settings.update(self.config.get_import_parameters())
|
self.settings.update(self.config.get_import_parameters())
|
||||||
self.settings.update(self.config.get_default_paths())
|
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.disconnect()
|
||||||
|
|
||||||
self.db = fpdb_db.fpdb_db()
|
self.sql = SQL.Sql(type = self.settings['db-type'], db_server = self.settings['db-server'])
|
||||||
#print "end of fpdb.load_profile, databaseName:",self.settings['db-databaseName']
|
self.db = Database.Database(self.config, sql = self.sql)
|
||||||
self.db.connect(self.settings['db-backend'],
|
|
||||||
self.settings['db-host'],
|
if self.db.fdb.wrongDbVersion:
|
||||||
self.settings['db-databaseName'],
|
|
||||||
self.settings['db-user'],
|
|
||||||
self.settings['db-password'])
|
|
||||||
if self.db.wrongDbVersion:
|
|
||||||
diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
|
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.")
|
label = gtk.Label("An invalid DB version or missing tables have been detected.")
|
||||||
|
@ -386,9 +387,16 @@ class fpdb:
|
||||||
response = diaDbVersionWarning.run()
|
response = diaDbVersionWarning.run()
|
||||||
diaDbVersionWarning.destroy()
|
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
|
# Database connected to successfully, load queries to pass on to other classes
|
||||||
self.querydict = FpdbSQLQueries.FpdbSQLQueries(self.db.get_backend_name())
|
self.querydict = FpdbSQLQueries.FpdbSQLQueries(self.db.get_backend_name())
|
||||||
self.db.db.rollback()
|
self.db.connection.rollback()
|
||||||
#end def load_profile
|
#end def load_profile
|
||||||
|
|
||||||
def not_implemented(self, widget, data=None):
|
def not_implemented(self, widget, data=None):
|
||||||
|
@ -397,13 +405,9 @@ class fpdb:
|
||||||
|
|
||||||
def obtain_global_lock(self):
|
def obtain_global_lock(self):
|
||||||
print "\nTaking global lock ..."
|
print "\nTaking global lock ..."
|
||||||
self.fdb_lock = fpdb_db.fpdb_db()
|
self.fdb_lock = Database.Database(self.config, sql = self.sql)
|
||||||
self.fdb_lock.connect(self.settings['db-backend'],
|
self.fdb_lock.do_connect(self.config)
|
||||||
self.settings['db-host'],
|
return self.fdb_lock.fdb.get_global_lock()
|
||||||
self.settings['db-databaseName'],
|
|
||||||
self.settings['db-user'],
|
|
||||||
self.settings['db-password'])
|
|
||||||
return self.fdb_lock.get_global_lock()
|
|
||||||
#end def obtain_global_lock
|
#end def obtain_global_lock
|
||||||
|
|
||||||
def quit(self, widget, data=None):
|
def quit(self, widget, data=None):
|
||||||
|
@ -414,9 +418,9 @@ class fpdb:
|
||||||
#end def quit_cliecked
|
#end def quit_cliecked
|
||||||
|
|
||||||
def release_global_lock(self):
|
def release_global_lock(self):
|
||||||
self.fdb_lock.db.rollback()
|
self.fdb_lock.fdb.db.rollback()
|
||||||
self.fdb_lock.disconnect()
|
self.fdb_lock.fdb.disconnect()
|
||||||
print "Global lock released."
|
print "Global lock released.\n"
|
||||||
#end def release_global_lock
|
#end def release_global_lock
|
||||||
|
|
||||||
def tab_abbreviations(self, widget, data=None):
|
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):
|
def tab_table_viewer(self, widget, data=None):
|
||||||
"""opens a table viewer tab"""
|
"""opens a table viewer tab"""
|
||||||
#print "start of tab_table_viewer"
|
#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)
|
self.threads.append(new_tv_thread)
|
||||||
tv_tab=new_tv_thread.get_vbox()
|
tv_tab=new_tv_thread.get_vbox()
|
||||||
self.add_and_display_tab(tv_tab, "Table Viewer")
|
self.add_and_display_tab(tv_tab, "Table Viewer")
|
||||||
|
@ -474,17 +478,16 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||||
def tabGraphViewer(self, widget, data=None):
|
def tabGraphViewer(self, widget, data=None):
|
||||||
"""opens a graph viewer tab"""
|
"""opens a graph viewer tab"""
|
||||||
#print "start of tabGraphViewer"
|
#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)
|
self.threads.append(new_gv_thread)
|
||||||
gv_tab=new_gv_thread.get_vbox()
|
gv_tab=new_gv_thread.get_vbox()
|
||||||
self.add_and_display_tab(gv_tab, "Graphs")
|
self.add_and_display_tab(gv_tab, "Graphs")
|
||||||
#end def tabGraphViewer
|
#end def tabGraphViewer
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.threads=[]
|
self.threads = []
|
||||||
self.db=None
|
self.db = None
|
||||||
self.config = Configuration.Config(file=options.config, dbname=options.dbname)
|
self.status_bar = None
|
||||||
self.load_profile()
|
|
||||||
|
|
||||||
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||||
self.window.connect("delete_event", self.delete_event)
|
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.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.window.show()
|
||||||
|
self.load_profile()
|
||||||
sys.stderr.write("fpdb starting ...")
|
sys.stderr.write("fpdb starting ...")
|
||||||
#end def __init__
|
#end def __init__
|
||||||
|
|
||||||
|
|
|
@ -243,7 +243,6 @@ class fpdb_db:
|
||||||
self.cursor.execute(self.sql.query['createPlayersTable'])
|
self.cursor.execute(self.sql.query['createPlayersTable'])
|
||||||
self.cursor.execute(self.sql.query['createAutoratesTable'])
|
self.cursor.execute(self.sql.query['createAutoratesTable'])
|
||||||
self.cursor.execute(self.sql.query['createHandsTable'])
|
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['createTourneyTypesTable'])
|
||||||
self.cursor.execute(self.sql.query['createTourneysTable'])
|
self.cursor.execute(self.sql.query['createTourneysTable'])
|
||||||
self.cursor.execute(self.sql.query['createTourneysPlayersTable'])
|
self.cursor.execute(self.sql.query['createTourneysPlayersTable'])
|
||||||
|
@ -568,17 +567,18 @@ class fpdb_db:
|
||||||
print "analyze took", atime, "seconds"
|
print "analyze took", atime, "seconds"
|
||||||
#end def analyzeDB
|
#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
|
# Return values are Unix style, 0 for success, positive integers for errors
|
||||||
# 1 = generic error
|
# 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):
|
def get_global_lock(self):
|
||||||
if self.backend == self.MYSQL_INNODB:
|
if self.backend == self.MYSQL_INNODB:
|
||||||
try:
|
try:
|
||||||
self.cursor.execute( "lock tables Hands write" )
|
self.cursor.execute( "lock tables Players write" )
|
||||||
except:
|
except:
|
||||||
# Table 'fpdb.hands' doesn't exist
|
# Table 'fpdb.players' doesn't exist
|
||||||
if str(sys.exc_value).find(".Hands' doesn't exist") >= 0:
|
if str(sys.exc_value).find(".Players' doesn't exist") >= 0:
|
||||||
return(2)
|
return(2)
|
||||||
print "Error! failed to obtain global lock. Close all programs accessing " \
|
print "Error! failed to obtain global lock. Close all programs accessing " \
|
||||||
+ "database (including fpdb) and try again (%s)." \
|
+ "database (including fpdb) and try again (%s)." \
|
||||||
|
@ -586,11 +586,11 @@ class fpdb_db:
|
||||||
return(1)
|
return(1)
|
||||||
elif self.backend == self.PGSQL:
|
elif self.backend == self.PGSQL:
|
||||||
try:
|
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
|
#print "... after lock table, status =", self.cursor.statusmessage
|
||||||
except:
|
except:
|
||||||
# relation "hands" does not exist
|
# relation "players" does not exist
|
||||||
if str(sys.exc_value).find('relation "hands" does not exist') >= 0:
|
if str(sys.exc_value).find('relation "players" does not exist') >= 0:
|
||||||
return(2)
|
return(2)
|
||||||
print "Error! failed to obtain global lock. Close all programs accessing " \
|
print "Error! failed to obtain global lock. Close all programs accessing " \
|
||||||
+ "database (including fpdb) and try again (%s)." \
|
+ "database (including fpdb) and try again (%s)." \
|
||||||
|
|
|
@ -31,6 +31,7 @@ import re
|
||||||
|
|
||||||
import fpdb_simple
|
import fpdb_simple
|
||||||
import fpdb_db
|
import fpdb_db
|
||||||
|
import Database
|
||||||
import fpdb_parse_logic
|
import fpdb_parse_logic
|
||||||
import Configuration
|
import Configuration
|
||||||
|
|
||||||
|
@ -57,7 +58,8 @@ class Importer:
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
self.caller = caller
|
self.caller = caller
|
||||||
self.config = config
|
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.cursor = None
|
||||||
self.filelist = {}
|
self.filelist = {}
|
||||||
self.dirlist = {}
|
self.dirlist = {}
|
||||||
|
@ -75,6 +77,7 @@ class Importer:
|
||||||
self.settings.setdefault("minPrint", 30)
|
self.settings.setdefault("minPrint", 30)
|
||||||
self.settings.setdefault("handCount", 0)
|
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 = fpdb_db.fpdb_db() # sets self.fdb.db self.fdb.cursor and self.fdb.sql
|
||||||
self.fdb.do_connect(self.config)
|
self.fdb.do_connect(self.config)
|
||||||
self.fdb.db.rollback()
|
self.fdb.db.rollback()
|
||||||
|
@ -392,8 +395,9 @@ class Importer:
|
||||||
self.hand=hand
|
self.hand=hand
|
||||||
|
|
||||||
try:
|
try:
|
||||||
handsId = fpdb_parse_logic.mainParser(self.settings, self.fdb
|
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()
|
self.fdb.db.commit()
|
||||||
|
|
||||||
stored += 1
|
stored += 1
|
||||||
|
|
|
@ -21,10 +21,13 @@ import fpdb_simple
|
||||||
import Database
|
import Database
|
||||||
|
|
||||||
#parses a holdem hand
|
#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']
|
backend = settings['db-backend']
|
||||||
#This is redundant - hopefully fdb will be a Database object in an interation soon
|
if db == None:
|
||||||
db = Database.Database(config, 'fpdb', '')
|
#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])
|
category = fpdb_simple.recogniseCategory(hand[0])
|
||||||
|
|
||||||
base = "hold" if category == "holdem" or category == "omahahi" or category == "omahahilo" else "stud"
|
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)
|
cursor.executemany("INSERT INTO HandsActions (handsPlayerId, street, actionNo, action, allIn, amount) VALUES (%s, %s, %s, %s, %s, %s)", inserts)
|
||||||
#end def storeActions
|
#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
|
def storeHands(backend, conn, cursor, site_hand_no, gametype_id
|
||||||
,hand_start_time, names, tableName, maxSeats, hudCache,
|
,hand_start_time, names, tableName, maxSeats, hudCache,
|
||||||
board_values, board_suits):
|
board_values, board_suits):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user