Merge from ray, minor conflicts
This commit is contained in:
commit
79ca83c95a
|
@ -88,12 +88,32 @@ class Site:
|
||||||
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():
|
||||||
|
@ -633,6 +661,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,
|
||||||
|
@ -683,9 +713,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,6 +87,8 @@ 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()
|
||||||
|
@ -88,6 +96,19 @@ class Database:
|
||||||
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):
|
||||||
|
@ -285,7 +302,8 @@ class Database:
|
||||||
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
|
fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits)
|
||||||
|
|
||||||
hands_id = fpdb_simple.storeHands(self.backend, db, cursor, site_hand_no, gametype_id
|
hands_id = fpdb_simple.storeHands(self.backend, db, cursor, site_hand_no, gametype_id
|
||||||
,hand_start_time, names, tableName, maxSeats, hudImportData)
|
,hand_start_time, names, tableName, maxSeats, hudImportData
|
||||||
|
,(None, None, None, None, None), (None, None, None, None, None))
|
||||||
|
|
||||||
#print "before calling store_hands_players_stud, antes:", antes
|
#print "before calling store_hands_players_stud, antes:", antes
|
||||||
hands_players_ids = fpdb_simple.store_hands_players_stud(self.backend, db, cursor, hands_id, player_ids
|
hands_players_ids = fpdb_simple.store_hands_players_stud(self.backend, db, cursor, hands_id, player_ids
|
||||||
|
@ -326,7 +344,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 +378,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())
|
||||||
|
|
|
@ -282,43 +282,6 @@ class FpdbSQLQueries:
|
||||||
FOREIGN KEY(gametypeId) REFERENCES Gametypes(id) ON DELETE CASCADE)"""
|
FOREIGN KEY(gametypeId) REFERENCES Gametypes(id) ON DELETE CASCADE)"""
|
||||||
|
|
||||||
|
|
||||||
################################
|
|
||||||
# Create BoardCards
|
|
||||||
################################
|
|
||||||
|
|
||||||
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
|
||||||
################################
|
################################
|
||||||
|
@ -1598,136 +1561,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,13 +43,13 @@ 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
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
|
412
pyfpdb/Hand.py
412
pyfpdb/Hand.py
|
@ -15,6 +15,8 @@
|
||||||
#In the "official" distribution you can find the license in
|
#In the "official" distribution you can find the license in
|
||||||
#agpl-3.0.txt in the docs folder of the package.
|
#agpl-3.0.txt in the docs folder of the package.
|
||||||
|
|
||||||
|
# TODO: get writehand() encoding correct
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
@ -26,12 +28,20 @@ import operator
|
||||||
import time,datetime
|
import time,datetime
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from Exceptions import *
|
from Exceptions import *
|
||||||
|
import pprint
|
||||||
import DerivedStats
|
import DerivedStats
|
||||||
import Card
|
import Card
|
||||||
|
|
||||||
class Hand:
|
class Hand:
|
||||||
|
|
||||||
|
###############################################################3
|
||||||
|
# Class Variables
|
||||||
UPS = {'a':'A', 't':'T', 'j':'J', 'q':'Q', 'k':'K', 'S':'s', 'C':'c', 'H':'h', 'D':'d'}
|
UPS = {'a':'A', 't':'T', 'j':'J', 'q':'Q', 'k':'K', 'S':'s', 'C':'c', 'H':'h', 'D':'d'}
|
||||||
LCS = {'H':'h', 'D':'d', 'C':'c', 'S':'s'}
|
LCS = {'H':'h', 'D':'d', 'C':'c', 'S':'s'}
|
||||||
|
SYMBOL = {'USD': '$', 'EUR': u'E', 'T$': '', 'play': ''}
|
||||||
|
MS = {'horse' : 'HORSE', '8game' : '8-Game', 'hose' : 'HOSE'}
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, sitename, gametype, handText, builtFrom = "HHC"):
|
def __init__(self, sitename, gametype, handText, builtFrom = "HHC"):
|
||||||
self.sitename = sitename
|
self.sitename = sitename
|
||||||
self.stats = DerivedStats.DerivedStats(self)
|
self.stats = DerivedStats.DerivedStats(self)
|
||||||
|
@ -44,6 +54,10 @@ class Hand:
|
||||||
self.maxseats = 10
|
self.maxseats = 10
|
||||||
self.counted_seats = 0
|
self.counted_seats = 0
|
||||||
self.buttonpos = 0
|
self.buttonpos = 0
|
||||||
|
self.tourNo = None
|
||||||
|
self.buyin = None
|
||||||
|
self.level = None
|
||||||
|
self.mixed = None
|
||||||
self.seating = []
|
self.seating = []
|
||||||
self.players = []
|
self.players = []
|
||||||
self.posted = []
|
self.posted = []
|
||||||
|
@ -55,17 +69,19 @@ class Hand:
|
||||||
self.actions = {} # [['mct','bets','$10'],['mika','folds'],['carlg','raises','$20']]
|
self.actions = {} # [['mct','bets','$10'],['mika','folds'],['carlg','raises','$20']]
|
||||||
self.board = {} # dict from street names to community cards
|
self.board = {} # dict from street names to community cards
|
||||||
self.holecards = {}
|
self.holecards = {}
|
||||||
|
self.discards = {}
|
||||||
for street in self.allStreets:
|
for street in self.allStreets:
|
||||||
self.streets[street] = "" # portions of the handText, filled by markStreets()
|
self.streets[street] = "" # portions of the handText, filled by markStreets()
|
||||||
|
self.actions[street] = []
|
||||||
|
for street in self.actionStreets:
|
||||||
self.bets[street] = {}
|
self.bets[street] = {}
|
||||||
self.lastBet[street] = 0
|
self.lastBet[street] = 0
|
||||||
self.actions[street] = []
|
|
||||||
self.board[street] = []
|
self.board[street] = []
|
||||||
|
for street in self.holeStreets:
|
||||||
self.holecards[street] = {} # dict from player names to holecards
|
self.holecards[street] = {} # dict from player names to holecards
|
||||||
|
self.discards[street] = {} # dict from player names to dicts by street ... of tuples ... of discarded holecards
|
||||||
# Collections indexed by player names
|
# Collections indexed by player names
|
||||||
# self.holecards = {} # dict from player names to dicts by street ... of tuples ... of holecards
|
# self.holecards = {} # dict from player names to dicts by street ... of tuples ... of holecards
|
||||||
self.discards = {} # dict from player names to dicts by street ... of tuples ... of discarded holecards
|
|
||||||
self.stacks = {}
|
self.stacks = {}
|
||||||
self.collected = [] #list of ?
|
self.collected = [] #list of ?
|
||||||
self.collectees = {} # dict from player names to amounts collected (?)
|
self.collectees = {} # dict from player names to amounts collected (?)
|
||||||
|
@ -74,6 +90,7 @@ class Hand:
|
||||||
self.folded = set()
|
self.folded = set()
|
||||||
self.dealt = set() # 'dealt to' line to be printed
|
self.dealt = set() # 'dealt to' line to be printed
|
||||||
self.shown = set() # cards were shown
|
self.shown = set() # cards were shown
|
||||||
|
self.mucked = set() # cards were mucked at showdown
|
||||||
|
|
||||||
# self.action = []
|
# self.action = []
|
||||||
# Things to do with money
|
# Things to do with money
|
||||||
|
@ -83,10 +100,77 @@ class Hand:
|
||||||
self.rake = None
|
self.rake = None
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
vars = ( ("BB", self.bb),
|
||||||
|
("SB", self.sb),
|
||||||
|
("BUTTONPOS", self.buttonpos),
|
||||||
|
("HAND NO.", self.handid),
|
||||||
|
("SITE", self.sitename),
|
||||||
|
("TABLE NAME", self.tablename),
|
||||||
|
("HERO", self.hero),
|
||||||
|
("MAXSEATS", self.maxseats),
|
||||||
|
("TOURNAMENT NO", self.tourNo),
|
||||||
|
("BUYIN", self.buyin),
|
||||||
|
("LEVEL", self.level),
|
||||||
|
("MIXED", self.mixed),
|
||||||
|
("LASTBET", self.lastBet),
|
||||||
|
("ACTION STREETS", self.actionStreets),
|
||||||
|
("STREETS", self.streets),
|
||||||
|
("ALL STREETS", self.allStreets),
|
||||||
|
("COMMUNITY STREETS", self.communityStreets),
|
||||||
|
("HOLE STREETS", self.holeStreets),
|
||||||
|
("COUNTED SEATS", self.counted_seats),
|
||||||
|
("DEALT", self.dealt),
|
||||||
|
("SHOWN", self.shown),
|
||||||
|
("MUCKED", self.mucked),
|
||||||
|
("TOTAL POT", self.totalpot),
|
||||||
|
("TOTAL COLLECTED", self.totalcollected),
|
||||||
|
("RAKE", self.rake),
|
||||||
|
("START TIME", self.starttime),
|
||||||
|
)
|
||||||
|
|
||||||
|
structs = ( ("PLAYERS", self.players),
|
||||||
|
("STACKS", self.stacks),
|
||||||
|
("POSTED", self.posted),
|
||||||
|
("POT", self.pot),
|
||||||
|
("SEATING", self.seating),
|
||||||
|
("GAMETYPE", self.gametype),
|
||||||
|
("ACTION", self.actions),
|
||||||
|
("COLLECTEES", self.collectees),
|
||||||
|
("BETS", self.bets),
|
||||||
|
("BOARD", self.board),
|
||||||
|
("DISCARDS", self.discards),
|
||||||
|
("HOLECARDS", self.holecards),
|
||||||
|
)
|
||||||
str = ''
|
str = ''
|
||||||
str = str + "Hand Object for %s at %s" % (self.handid, self.sitename)
|
for (name, var) in vars:
|
||||||
|
str = str + "\n%s = " % name + pprint.pformat(var)
|
||||||
|
|
||||||
|
for (name, struct) in structs:
|
||||||
|
str = str + "\n%s =\n" % name + pprint.pformat(struct, 4)
|
||||||
return str
|
return str
|
||||||
|
|
||||||
|
def addHoleCards(self, street, player, open=[], closed=[], shown=False, mucked=False, dealt=False):
|
||||||
|
"""\
|
||||||
|
Assigns observed holecards to a player.
|
||||||
|
cards list of card bigrams e.g. ['2h','Jc']
|
||||||
|
player (string) name of player
|
||||||
|
shown whether they were revealed at showdown
|
||||||
|
mucked whether they were mucked at showdown
|
||||||
|
dealt whether they were seen in a 'dealt to' line
|
||||||
|
"""
|
||||||
|
# logging.debug("addHoleCards %s %s" % (open + closed, player))
|
||||||
|
try:
|
||||||
|
self.checkPlayerExists(player)
|
||||||
|
except FpdbParseError, e:
|
||||||
|
print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
||||||
|
return
|
||||||
|
|
||||||
|
if dealt: self.dealt.add(player)
|
||||||
|
if shown: self.shown.add(player)
|
||||||
|
if mucked: self.mucked.add(player)
|
||||||
|
|
||||||
|
self.holecards[street][player] = [open, closed]
|
||||||
|
|
||||||
def insert(self, db):
|
def insert(self, db):
|
||||||
""" Function to insert Hand into database
|
""" Function to insert Hand into database
|
||||||
Should not commit, and do minimal selects. Callers may want to cache commits
|
Should not commit, and do minimal selects. Callers may want to cache commits
|
||||||
|
@ -178,10 +262,10 @@ If a player has None chips he won't be added."""
|
||||||
self.players.append([seat, name, chips])
|
self.players.append([seat, name, chips])
|
||||||
self.stacks[name] = Decimal(chips)
|
self.stacks[name] = Decimal(chips)
|
||||||
self.pot.addPlayer(name)
|
self.pot.addPlayer(name)
|
||||||
for street in self.allStreets:
|
for street in self.actionStreets:
|
||||||
self.bets[street][name] = []
|
self.bets[street][name] = []
|
||||||
#self.holecards[name] = {} # dict from street names.
|
#self.holecards[name] = {} # dict from street names.
|
||||||
self.discards[name] = {} # dict from street names.
|
#self.discards[name] = {} # dict from street names.
|
||||||
|
|
||||||
|
|
||||||
def addStreets(self, match):
|
def addStreets(self, match):
|
||||||
|
@ -202,7 +286,7 @@ If a player has None chips he won't be added."""
|
||||||
def setCommunityCards(self, street, cards):
|
def setCommunityCards(self, street, cards):
|
||||||
logging.debug("setCommunityCards %s %s" %(street, cards))
|
logging.debug("setCommunityCards %s %s" %(street, cards))
|
||||||
self.board[street] = [self.card(c) for c in cards]
|
self.board[street] = [self.card(c) for c in cards]
|
||||||
print "DEBUG: self.board: %s" % self.board
|
# print "DEBUG: self.board: %s" % self.board
|
||||||
|
|
||||||
def card(self,c):
|
def card(self,c):
|
||||||
"""upper case the ranks but not suits, 'atjqk' => 'ATJQK'"""
|
"""upper case the ranks but not suits, 'atjqk' => 'ATJQK'"""
|
||||||
|
@ -367,6 +451,20 @@ Add a raise on [street] by [player] to [amountTo]
|
||||||
self.collectees[player] += Decimal(pot)
|
self.collectees[player] += Decimal(pot)
|
||||||
|
|
||||||
|
|
||||||
|
def addShownCards(self, cards, player, holeandboard=None, shown=True, mucked=False):
|
||||||
|
"""\
|
||||||
|
For when a player shows cards for any reason (for showdown or out of choice).
|
||||||
|
Card ranks will be uppercased
|
||||||
|
"""
|
||||||
|
logging.debug("addShownCards %s hole=%s all=%s" % (player, cards, holeandboard))
|
||||||
|
if cards is not None:
|
||||||
|
self.addHoleCards(cards,player,shown, mucked)
|
||||||
|
elif holeandboard is not None:
|
||||||
|
holeandboard = set([self.card(c) for c in holeandboard])
|
||||||
|
board = set([c for s in self.board.values() for c in s])
|
||||||
|
self.addHoleCards(holeandboard.difference(board),player,shown, mucked)
|
||||||
|
|
||||||
|
|
||||||
def totalPot(self):
|
def totalPot(self):
|
||||||
"""If all bets and blinds have been added, totals up the total pot size"""
|
"""If all bets and blinds have been added, totals up the total pot size"""
|
||||||
|
|
||||||
|
@ -410,7 +508,6 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
||||||
|
|
||||||
logging.debug("gametype: %s" %(self.gametype))
|
logging.debug("gametype: %s" %(self.gametype))
|
||||||
retstring = "%s %s" %(gs[self.gametype['category']], ls[self.gametype['limitType']])
|
retstring = "%s %s" %(gs[self.gametype['category']], ls[self.gametype['limitType']])
|
||||||
|
|
||||||
return retstring
|
return retstring
|
||||||
|
|
||||||
|
|
||||||
|
@ -447,6 +544,33 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
||||||
elif act[1] == 'stands pat':
|
elif act[1] == 'stands pat':
|
||||||
return ("%s: stands pat" %(act[0]))
|
return ("%s: stands pat" %(act[0]))
|
||||||
|
|
||||||
|
def getStakesAsString(self):
|
||||||
|
retstring = "%s%s/%s%s" % (self.SYMBOL[self.gametype['currency']], self.sb, self.SYMBOL[self.gametype['currency']], self.bb)
|
||||||
|
return retstring
|
||||||
|
|
||||||
|
def writeGameLine(self):
|
||||||
|
# print >>fh, ("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, datetime.datetime.strftime(self.starttime,'%Y/%m/%d - %H:%M:%S ET')))
|
||||||
|
game_string = "PokerStars Game #%s: " % self.handid
|
||||||
|
if self.tourNo != None:
|
||||||
|
game_string = game_string + "Tournament #%s, %s %s - Level %s (%s) - " % (self.tourNo,
|
||||||
|
self.buyin, self.getGameTypeAsString(), self.level, self.getStakesAsString())
|
||||||
|
elif self.mixed != None:
|
||||||
|
game_string = game_string + " %s (%s, %s) - " % (self.MS[self.mixed],
|
||||||
|
self.getGameTypeAsString(), self.getStakesAsString())
|
||||||
|
else:
|
||||||
|
game_string = game_string + " %s (%s) - " % (self.getGameTypeAsString(), self.getStakesAsString())
|
||||||
|
game_string = game_string + datetime.datetime.strftime(self.starttime,'%Y/%m/%d %H:%M:%S ET')
|
||||||
|
return game_string
|
||||||
|
|
||||||
|
|
||||||
|
def writeTableLine(self):
|
||||||
|
table_string = "Table \'%s\' %s-max" % (self.tablename, self.maxseats)
|
||||||
|
if self.gametype['currency'] == 'play':
|
||||||
|
table_string = table_string + " (Play Money)"
|
||||||
|
if self.buttonpos != None:
|
||||||
|
table_string = table_string + " Seat #%s is the button" % self.buttonpos
|
||||||
|
return table_string
|
||||||
|
|
||||||
|
|
||||||
class HoldemOmahaHand(Hand):
|
class HoldemOmahaHand(Hand):
|
||||||
def __init__(self, hhc, sitename, gametype, handText, builtFrom = "HHC", handid=None):
|
def __init__(self, hhc, sitename, gametype, handText, builtFrom = "HHC", handid=None):
|
||||||
|
@ -494,45 +618,12 @@ class HoldemOmahaHand(Hand):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def addHoleCards(self, cards, player, shown=False, dealt=False):
|
def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False):
|
||||||
"""\
|
if player == self.hero: # we have hero's cards just update shown/mucked
|
||||||
Assigns observed holecards to a player.
|
if shown: self.shown.add(player)
|
||||||
cards list of card bigrams e.g. ['2h','Jc']
|
if mucked: self.mucked.add(player)
|
||||||
player (string) name of player
|
|
||||||
shown whether they were revealed at showdown
|
|
||||||
dealt whether they were seen in a 'dealt to' line
|
|
||||||
"""
|
|
||||||
logging.debug("addHoleCards %s %s" % (cards, player))
|
|
||||||
try:
|
|
||||||
self.checkPlayerExists(player)
|
|
||||||
except FpdbParseError, e:
|
|
||||||
print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
|
||||||
return
|
|
||||||
|
|
||||||
cardset = set((self.card(c) for c in cards))
|
|
||||||
if len(cardset) == 0:
|
|
||||||
return
|
|
||||||
if dealt:
|
|
||||||
self.dealt.add(player)
|
|
||||||
if shown:
|
|
||||||
self.shown.add(player)
|
|
||||||
if player in self.holecards['PREFLOP']:
|
|
||||||
self.holecards['PREFLOP'][player].update(cardset)
|
|
||||||
else:
|
else:
|
||||||
self.holecards['PREFLOP'][player] = cardset
|
self.addHoleCards('PREFLOP', player, open=[], closed=cards, shown=shown, mucked=mucked, dealt=dealt)
|
||||||
|
|
||||||
def addShownCards(self, cards, player, holeandboard=None):
|
|
||||||
"""\
|
|
||||||
For when a player shows cards for any reason (for showdown or out of choice).
|
|
||||||
Card ranks will be uppercased
|
|
||||||
"""
|
|
||||||
logging.debug("addShownCards %s hole=%s all=%s" % (player, cards, holeandboard))
|
|
||||||
if cards is not None:
|
|
||||||
self.addHoleCards(cards,player,shown=True)
|
|
||||||
elif holeandboard is not None:
|
|
||||||
holeandboard = set([self.card(c) for c in holeandboard])
|
|
||||||
board = set([c for s in self.board.values() for c in s])
|
|
||||||
self.addHoleCards(holeandboard.difference(board),player,shown=True)
|
|
||||||
|
|
||||||
|
|
||||||
def writeHTMLHand(self, fh=sys.__stdout__):
|
def writeHTMLHand(self, fh=sys.__stdout__):
|
||||||
|
@ -632,8 +723,11 @@ Card ranks will be uppercased
|
||||||
|
|
||||||
def writeHand(self, fh=sys.__stdout__):
|
def writeHand(self, fh=sys.__stdout__):
|
||||||
# PokerStars format.
|
# PokerStars format.
|
||||||
print >>fh, ("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, datetime.datetime.strftime(self.starttime,'%Y/%m/%d - %H:%M:%S ET')))
|
# print >>fh, ("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, datetime.datetime.strftime(self.starttime,'%Y/%m/%d - %H:%M:%S ET')))
|
||||||
print >>fh, ("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
print >>fh, self.writeGameLine()
|
||||||
|
print >>fh, self.writeTableLine()
|
||||||
|
|
||||||
|
# print >>fh, ("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
||||||
|
|
||||||
players_who_act_preflop = set(([x[0] for x in self.actions['PREFLOP']]+[x[0] for x in self.actions['BLINDSANTES']]))
|
players_who_act_preflop = set(([x[0] for x in self.actions['PREFLOP']]+[x[0] for x in self.actions['BLINDSANTES']]))
|
||||||
logging.debug(self.actions['PREFLOP'])
|
logging.debug(self.actions['PREFLOP'])
|
||||||
|
@ -647,10 +741,10 @@ Card ranks will be uppercased
|
||||||
|
|
||||||
print >>fh, ("*** HOLE CARDS ***")
|
print >>fh, ("*** HOLE CARDS ***")
|
||||||
for player in self.dealt:
|
for player in self.dealt:
|
||||||
print >>fh, ("Dealt to %s [%s]" %(player, " ".join(self.holecards['PREFLOP'][player])))
|
print >>fh, ("Dealt to %s [%s]" %(player, " ".join(self.holecards['PREFLOP'][player][1])))
|
||||||
if self.hero == "":
|
if self.hero == "":
|
||||||
for player in self.shown.difference(self.dealt):
|
for player in self.shown.difference(self.dealt):
|
||||||
print >>fh, ("Dealt to %s [%s]" %(player, " ".join(self.holecards['PREFLOP'][player])))
|
print >>fh, ("Dealt to %s [%s]" %(player, " ".join(self.holecards['PREFLOP'][player][1])))
|
||||||
|
|
||||||
if self.actions['PREFLOP']:
|
if self.actions['PREFLOP']:
|
||||||
for act in self.actions['PREFLOP']:
|
for act in self.actions['PREFLOP']:
|
||||||
|
@ -689,7 +783,7 @@ Card ranks will be uppercased
|
||||||
elif self.gametype['category'] in ('holdem'):
|
elif self.gametype['category'] in ('holdem'):
|
||||||
numOfHoleCardsNeeded = 2
|
numOfHoleCardsNeeded = 2
|
||||||
if len(self.holecards['PREFLOP'][name]) == numOfHoleCardsNeeded:
|
if len(self.holecards['PREFLOP'][name]) == numOfHoleCardsNeeded:
|
||||||
print >>fh, ("%s shows [%s] (a hand...)" % (name, " ".join(self.holecards['PREFLOP'][name])))
|
print >>fh, ("%s shows [%s] (a hand...)" % (name, " ".join(self.holecards['PREFLOP'][name][1])))
|
||||||
|
|
||||||
# Current PS format has the lines:
|
# Current PS format has the lines:
|
||||||
# Uncalled bet ($111.25) returned to s0rrow
|
# Uncalled bet ($111.25) returned to s0rrow
|
||||||
|
@ -716,7 +810,7 @@ Card ranks will be uppercased
|
||||||
seatnum = player[0]
|
seatnum = player[0]
|
||||||
name = player[1]
|
name = player[1]
|
||||||
if name in self.collectees and name in self.shown:
|
if name in self.collectees and name in self.shown:
|
||||||
print >>fh, ("Seat %d: %s showed [%s] and won ($%s)" % (seatnum, name, " ".join(self.holecards['PREFLOP'][name]), self.collectees[name]))
|
print >>fh, ("Seat %d: %s showed [%s] and won ($%s)" % (seatnum, name, " ".join(self.holecards['PREFLOP'][name][1]), self.collectees[name]))
|
||||||
elif name in self.collectees:
|
elif name in self.collectees:
|
||||||
print >>fh, ("Seat %d: %s collected ($%s)" % (seatnum, name, self.collectees[name]))
|
print >>fh, ("Seat %d: %s collected ($%s)" % (seatnum, name, self.collectees[name]))
|
||||||
#~ elif name in self.shown:
|
#~ elif name in self.shown:
|
||||||
|
@ -725,7 +819,9 @@ Card ranks will be uppercased
|
||||||
print >>fh, ("Seat %d: %s folded" % (seatnum, name))
|
print >>fh, ("Seat %d: %s folded" % (seatnum, name))
|
||||||
else:
|
else:
|
||||||
if name in self.shown:
|
if name in self.shown:
|
||||||
print >>fh, ("Seat %d: %s showed [%s] and lost with..." % (seatnum, name, " ".join(self.holecards['PREFLOP'][name])))
|
print >>fh, ("Seat %d: %s showed [%s] and lost with..." % (seatnum, name, " ".join(self.holecards['PREFLOP'][name][1])))
|
||||||
|
elif name in self.mucked:
|
||||||
|
print >>fh, ("Seat %d: %s mucked [%s] " % (seatnum, name, " ".join(self.holecards['PREFLOP'][name][1])))
|
||||||
else:
|
else:
|
||||||
print >>fh, ("Seat %d: %s mucked" % (seatnum, name))
|
print >>fh, ("Seat %d: %s mucked" % (seatnum, name))
|
||||||
|
|
||||||
|
@ -736,8 +832,10 @@ class DrawHand(Hand):
|
||||||
if gametype['base'] != 'draw':
|
if gametype['base'] != 'draw':
|
||||||
pass # or indeed don't pass and complain instead
|
pass # or indeed don't pass and complain instead
|
||||||
self.streetList = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
self.streetList = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
||||||
|
self.allStreets = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
||||||
self.holeStreets = ['DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
self.holeStreets = ['DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
||||||
self.actionStreets = ['PREDEAL', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
self.actionStreets = ['PREDEAL', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
||||||
|
self.communityStreets = []
|
||||||
Hand.__init__(self, sitename, gametype, handText)
|
Hand.__init__(self, sitename, gametype, handText)
|
||||||
self.sb = gametype['sb']
|
self.sb = gametype['sb']
|
||||||
self.bb = gametype['bb']
|
self.bb = gametype['bb']
|
||||||
|
@ -749,12 +847,13 @@ class DrawHand(Hand):
|
||||||
hhc.markStreets(self)
|
hhc.markStreets(self)
|
||||||
hhc.readBlinds(self)
|
hhc.readBlinds(self)
|
||||||
hhc.readButton(self)
|
hhc.readButton(self)
|
||||||
|
hhc.readHeroCards(self)
|
||||||
hhc.readShowdownActions(self)
|
hhc.readShowdownActions(self)
|
||||||
# Read actions in street order
|
# Read actions in street order
|
||||||
for street in self.streetList:
|
for street in self.streetList:
|
||||||
if self.streets[street]:
|
if self.streets[street]:
|
||||||
# hhc.readCommunityCards(self, street)
|
# hhc.readCommunityCards(self, street)
|
||||||
hhc.readDrawCards(self, street)
|
# hhc.readDrawCards(self, street)
|
||||||
hhc.readAction(self, street)
|
hhc.readAction(self, street)
|
||||||
hhc.readCollectPot(self)
|
hhc.readCollectPot(self)
|
||||||
hhc.readShownCards(self)
|
hhc.readShownCards(self)
|
||||||
|
@ -790,25 +889,33 @@ class DrawHand(Hand):
|
||||||
#print "DEBUG: self.posted: %s" %(self.posted)
|
#print "DEBUG: self.posted: %s" %(self.posted)
|
||||||
|
|
||||||
|
|
||||||
|
def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False):
|
||||||
|
if player == self.hero: # we have hero's cards just update shown/mucked
|
||||||
|
if shown: self.shown.add(player)
|
||||||
|
if mucked: self.mucked.add(player)
|
||||||
|
else:
|
||||||
|
# TODO: Probably better to find the last street with action and add the hole cards to that street
|
||||||
|
self.addHoleCards('DRAWTHREE', player, open=[], closed=cards, shown=shown, mucked=mucked, dealt=dealt)
|
||||||
|
|
||||||
def addDrawHoleCards(self, newcards, oldcards, player, street, shown=False):
|
|
||||||
"""\
|
# def addDrawHoleCards(self, newcards, oldcards, player, street, shown=False):
|
||||||
Assigns observed holecards to a player.
|
# """\
|
||||||
cards list of card bigrams e.g. ['2h','Jc']
|
#Assigns observed holecards to a player.
|
||||||
player (string) name of player
|
#cards list of card bigrams e.g. ['2h','Jc']
|
||||||
"""
|
#player (string) name of player
|
||||||
try:
|
#"""
|
||||||
self.checkPlayerExists(player)
|
# try:
|
||||||
# if shown and len(cardset) > 0:
|
# self.checkPlayerExists(player)
|
||||||
# self.shown.add(player)
|
## if shown and len(cardset) > 0:
|
||||||
self.holecards[player][street] = (newcards,oldcards)
|
## self.shown.add(player)
|
||||||
except FpdbParseError, e:
|
# self.holecards[street][player] = (newcards,oldcards)
|
||||||
print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
# except FpdbParseError, e:
|
||||||
|
# print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
||||||
|
|
||||||
|
|
||||||
def discardDrawHoleCards(self, cards, player, street):
|
def discardDrawHoleCards(self, cards, player, street):
|
||||||
logging.debug("discardDrawHoleCards '%s' '%s' '%s'" % (cards, player, street))
|
logging.debug("discardDrawHoleCards '%s' '%s' '%s'" % (cards, player, street))
|
||||||
self.discards[player][street] = set([cards])
|
self.discards[street][player] = set([cards])
|
||||||
|
|
||||||
|
|
||||||
def addDiscard(self, street, player, num, cards):
|
def addDiscard(self, street, player, num, cards):
|
||||||
|
@ -821,12 +928,12 @@ player (string) name of player
|
||||||
self.actions[street].append(act)
|
self.actions[street].append(act)
|
||||||
|
|
||||||
|
|
||||||
def addShownCards(self, cards, player, holeandboard=None):
|
# def addShownCards(self, cards, player, holeandboard=None, shown=False, mucked=False):
|
||||||
"""\
|
# """\
|
||||||
For when a player shows cards for any reason (for showdown or out of choice).
|
#For when a player shows cards for any reason (for showdown or out of choice).
|
||||||
Card ranks will be uppercased
|
#Card ranks will be uppercased
|
||||||
"""
|
#"""
|
||||||
logging.debug("addShownCards %s hole=%s all=%s" % (player, cards, holeandboard))
|
# logging.debug("addShownCards %s hole=%s all=%s" % (player, cards, holeandboard))
|
||||||
# if cards is not None:
|
# if cards is not None:
|
||||||
# self.shown.add(player)
|
# self.shown.add(player)
|
||||||
# self.addHoleCards(cards,player)
|
# self.addHoleCards(cards,player)
|
||||||
|
@ -836,10 +943,39 @@ Card ranks will be uppercased
|
||||||
# self.addHoleCards(holeandboard.difference(board),player,shown=True)
|
# self.addHoleCards(holeandboard.difference(board),player,shown=True)
|
||||||
|
|
||||||
|
|
||||||
|
# def addHoleCards(self, cards, player, shown, mucked, dealt=False):
|
||||||
|
# """\
|
||||||
|
#Assigns observed holecards to a player.
|
||||||
|
#cards list of card bigrams e.g. ['2h','Jc']
|
||||||
|
#player (string) name of player
|
||||||
|
#shown whether they were revealed at showdown
|
||||||
|
#mucked whether they were mucked at showdown
|
||||||
|
#dealt whether they were seen in a 'dealt to' line
|
||||||
|
#"""
|
||||||
|
## I think this only gets called for shown cards.
|
||||||
|
# logging.debug("addHoleCards %s %s" % (cards, player))
|
||||||
|
# try:
|
||||||
|
# self.checkPlayerExists(player)
|
||||||
|
# except FpdbParseError, e:
|
||||||
|
# print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
# if dealt:
|
||||||
|
# self.dealt.add(player)
|
||||||
|
# if shown:
|
||||||
|
# self.shown.add(player)
|
||||||
|
# if mucked:
|
||||||
|
# self.mucked.add(player)
|
||||||
|
# if player != self.hero: #skip hero, we know his cards
|
||||||
|
# print "player, cards =", player, cards
|
||||||
|
# self.holecards[self.holeStreets[-1]][player] = (cards, set([]))
|
||||||
|
|
||||||
def writeHand(self, fh=sys.__stdout__):
|
def writeHand(self, fh=sys.__stdout__):
|
||||||
# PokerStars format.
|
# PokerStars format.
|
||||||
print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, time.strftime('%Y/%m/%d %H:%M:%S ET', self.starttime)))
|
# print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, time.strftime('%Y/%m/%d %H:%M:%S ET', self.starttime)))
|
||||||
print >>fh, _("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
print >>fh, self.writeGameLine()
|
||||||
|
# print >>fh, _("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
||||||
|
print >>fh, self.writeTableLine()
|
||||||
|
|
||||||
players_who_act_ondeal = set(([x[0] for x in self.actions['DEAL']]+[x[0] for x in self.actions['BLINDSANTES']]))
|
players_who_act_ondeal = set(([x[0] for x in self.actions['DEAL']]+[x[0] for x in self.actions['BLINDSANTES']]))
|
||||||
|
|
||||||
|
@ -865,8 +1001,8 @@ Card ranks will be uppercased
|
||||||
for act in self.actions['DRAWONE']:
|
for act in self.actions['DRAWONE']:
|
||||||
print >>fh, self.actionString(act)
|
print >>fh, self.actionString(act)
|
||||||
if act[0] == self.hero and act[1] == 'discards':
|
if act[0] == self.hero and act[1] == 'discards':
|
||||||
(nc,oc) = self.holecards[act[0]]['DRAWONE']
|
(nc,oc) = self.holecards['DRAWONE'][act[0]]
|
||||||
dc = self.discards[act[0]]['DRAWONE']
|
dc = self.discards['DRAWONE'][act[0]]
|
||||||
kc = oc - dc
|
kc = oc - dc
|
||||||
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
||||||
|
|
||||||
|
@ -875,8 +1011,8 @@ Card ranks will be uppercased
|
||||||
for act in self.actions['DRAWTWO']:
|
for act in self.actions['DRAWTWO']:
|
||||||
print >>fh, self.actionString(act)
|
print >>fh, self.actionString(act)
|
||||||
if act[0] == self.hero and act[1] == 'discards':
|
if act[0] == self.hero and act[1] == 'discards':
|
||||||
(nc,oc) = self.holecards[act[0]]['DRAWTWO']
|
(nc,oc) = self.holecards['DRAWTWO'][act[0]]
|
||||||
dc = self.discards[act[0]]['DRAWTWO']
|
dc = self.discards['DRAWTWO'][act[0]]
|
||||||
kc = oc - dc
|
kc = oc - dc
|
||||||
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
||||||
|
|
||||||
|
@ -885,8 +1021,8 @@ Card ranks will be uppercased
|
||||||
for act in self.actions['DRAWTHREE']:
|
for act in self.actions['DRAWTHREE']:
|
||||||
print >>fh, self.actionString(act)
|
print >>fh, self.actionString(act)
|
||||||
if act[0] == self.hero and act[1] == 'discards':
|
if act[0] == self.hero and act[1] == 'discards':
|
||||||
(nc,oc) = self.holecards[act[0]]['DRAWTHREE']
|
(nc,oc) = self.holecards['DRAWTHREE'][act[0]]
|
||||||
dc = self.discards[act[0]]['DRAWTHREE']
|
dc = self.discards['DRAWTHREE'][act[0]]
|
||||||
kc = oc - dc
|
kc = oc - dc
|
||||||
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
||||||
|
|
||||||
|
@ -916,6 +1052,11 @@ class StudHand(Hand):
|
||||||
def __init__(self, hhc, sitename, gametype, handText, builtFrom = "HHC"):
|
def __init__(self, hhc, sitename, gametype, handText, builtFrom = "HHC"):
|
||||||
if gametype['base'] != 'stud':
|
if gametype['base'] != 'stud':
|
||||||
pass # or indeed don't pass and complain instead
|
pass # or indeed don't pass and complain instead
|
||||||
|
|
||||||
|
self.allStreets = ['ANTES','THIRD','FOURTH','FIFTH','SIXTH','SEVENTH']
|
||||||
|
self.communityStreets = []
|
||||||
|
self.actionStreets = ['ANTES','THIRD','FOURTH','FIFTH','SIXTH','SEVENTH']
|
||||||
|
|
||||||
self.streetList = ['ANTES','THIRD','FOURTH','FIFTH','SIXTH','SEVENTH'] # a list of the observed street names in order
|
self.streetList = ['ANTES','THIRD','FOURTH','FIFTH','SIXTH','SEVENTH'] # a list of the observed street names in order
|
||||||
self.holeStreets = ['ANTES','THIRD','FOURTH','FIFTH','SIXTH','SEVENTH']
|
self.holeStreets = ['ANTES','THIRD','FOURTH','FIFTH','SIXTH','SEVENTH']
|
||||||
Hand.__init__(self, sitename, gametype, handText)
|
Hand.__init__(self, sitename, gametype, handText)
|
||||||
|
@ -931,21 +1072,35 @@ class StudHand(Hand):
|
||||||
hhc.markStreets(self)
|
hhc.markStreets(self)
|
||||||
hhc.readAntes(self)
|
hhc.readAntes(self)
|
||||||
hhc.readBringIn(self)
|
hhc.readBringIn(self)
|
||||||
|
hhc.readHeroCards(self)
|
||||||
#hhc.readShowdownActions(self) # not done yet
|
#hhc.readShowdownActions(self) # not done yet
|
||||||
# Read actions in street order
|
# Read actions in street order
|
||||||
for street in self.streetList:
|
for street in self.streetList:
|
||||||
if self.streets[street]:
|
if self.streets[street]:
|
||||||
logging.debug(street)
|
logging.debug(street)
|
||||||
logging.debug(self.streets[street])
|
logging.debug(self.streets[street])
|
||||||
hhc.readStudPlayerCards(self, street)
|
# hhc.readStudPlayerCards(self, street)
|
||||||
hhc.readAction(self, street)
|
hhc.readAction(self, street)
|
||||||
hhc.readCollectPot(self)
|
hhc.readCollectPot(self)
|
||||||
#hhc.readShownCards(self) # not done yet
|
hhc.readShownCards(self) # not done yet
|
||||||
self.totalPot() # finalise it (total the pot)
|
self.totalPot() # finalise it (total the pot)
|
||||||
hhc.getRake(self)
|
hhc.getRake(self)
|
||||||
elif builtFrom == "DB":
|
elif builtFrom == "DB":
|
||||||
self.select("dummy") # Will need a handId
|
self.select("dummy") # Will need a handId
|
||||||
|
|
||||||
|
def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False):
|
||||||
|
if player == self.hero: # we have hero's cards just update shown/mucked
|
||||||
|
if shown: self.shown.add(player)
|
||||||
|
if mucked: self.mucked.add(player)
|
||||||
|
else:
|
||||||
|
# self.addHoleCards('PREFLOP', player, open=[], closed=cards, shown=shown, mucked=mucked, dealt=dealt)
|
||||||
|
self.addHoleCards('THIRD', player, open=[cards[2]], closed=cards[0:2], shown=shown, mucked=mucked)
|
||||||
|
self.addHoleCards('FOURTH', player, open=[cards[3]], closed=[], shown=shown, mucked=mucked)
|
||||||
|
self.addHoleCards('FIFTH', player, open=[cards[4]], closed=[], shown=shown, mucked=mucked)
|
||||||
|
self.addHoleCards('SIXTH', player, open=[cards[5]], closed=[], shown=shown, mucked=mucked)
|
||||||
|
self.addHoleCards('SEVENTH', player, open=[], closed=[cards[6]], shown=shown, mucked=mucked)
|
||||||
|
|
||||||
|
|
||||||
def addPlayerCards(self, player, street, open=[], closed=[]):
|
def addPlayerCards(self, player, street, open=[], closed=[]):
|
||||||
"""\
|
"""\
|
||||||
Assigns observed cards to a player.
|
Assigns observed cards to a player.
|
||||||
|
@ -957,12 +1112,47 @@ closed likewise, but known only to player
|
||||||
logging.debug("addPlayerCards %s, o%s x%s" % (player, open, closed))
|
logging.debug("addPlayerCards %s, o%s x%s" % (player, open, closed))
|
||||||
try:
|
try:
|
||||||
self.checkPlayerExists(player)
|
self.checkPlayerExists(player)
|
||||||
self.holecards[player][street] = (open, closed)
|
self.holecards[street][player] = (open, closed)
|
||||||
# cards = set([self.card(c) for c in cards])
|
# cards = set([self.card(c) for c in cards])
|
||||||
# self.holecards[player].update(cards)
|
# self.holecards[player].update(cards)
|
||||||
except FpdbParseError, e:
|
except FpdbParseError, e:
|
||||||
print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
||||||
|
|
||||||
|
# def addHoleCards(self, cards, player, shown, mucked, dealt=False):
|
||||||
|
# """\
|
||||||
|
#Assigns observed holecards to a player.
|
||||||
|
#cards list of card bigrams e.g. ['2h','Jc']
|
||||||
|
#player (string) name of player
|
||||||
|
#shown whether they were revealed at showdown
|
||||||
|
#mucked whether they were mucked at showdown
|
||||||
|
#dealt whether they were seen in a 'dealt to' line
|
||||||
|
#"""
|
||||||
|
##
|
||||||
|
## For stud games we just need to do the routine setting of shown/mucked/etc
|
||||||
|
## and then update the cards 'THIRD' and 'SEVENTH'
|
||||||
|
# logging.debug("addHoleCards %s %s" % (cards, player))
|
||||||
|
# try:
|
||||||
|
# self.checkPlayerExists(player)
|
||||||
|
# except FpdbParseError, e:
|
||||||
|
# print "[ERROR] Tried to add holecards for unknown player: %s" % (player,)
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
# if dealt:
|
||||||
|
# self.dealt.add(player)
|
||||||
|
# if shown:
|
||||||
|
# self.shown.add(player)
|
||||||
|
# if mucked:
|
||||||
|
# self.mucked.add(player)
|
||||||
|
# if player == self.hero:
|
||||||
|
# if len(cards) > 2:
|
||||||
|
# self.holecards['THIRD'][player] = ([cards[0:3]], [])
|
||||||
|
# if len(cards) > 6:
|
||||||
|
# self.holecards['SEVENTH'][player] = ([cards[6]], [])
|
||||||
|
# else:
|
||||||
|
# if len(cards) > 2:
|
||||||
|
# self.holecards['THIRD'][player] = ([cards[0]], cards[1:3])
|
||||||
|
# if len(cards) > 6:
|
||||||
|
# self.holecards['SEVENTH'][player] = ([], [cards[6]])
|
||||||
# TODO: def addComplete(self, player, amount):
|
# TODO: def addComplete(self, player, amount):
|
||||||
def addComplete(self, street, player, amountTo):
|
def addComplete(self, street, player, amountTo):
|
||||||
# assert street=='THIRD'
|
# assert street=='THIRD'
|
||||||
|
@ -995,11 +1185,19 @@ Add a complete on [street] by [player] to [amountTo]
|
||||||
self.lastBet['THIRD'] = Decimal(bringin)
|
self.lastBet['THIRD'] = Decimal(bringin)
|
||||||
self.pot.addMoney(player, Decimal(bringin))
|
self.pot.addMoney(player, Decimal(bringin))
|
||||||
|
|
||||||
|
|
||||||
def writeHand(self, fh=sys.__stdout__):
|
def writeHand(self, fh=sys.__stdout__):
|
||||||
# PokerStars format.
|
# PokerStars format.
|
||||||
# print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, time.strftime('%Y/%m/%d - %H:%M:%S (ET)', self.starttime)))
|
# print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, time.strftime('%Y/%m/%d - %H:%M:%S (ET)', self.starttime)))
|
||||||
print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, datetime.datetime.strftime(self.starttime,'%Y/%m/%d - %H:%M:%S ET')))
|
|
||||||
print >>fh, _("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
# TODO:
|
||||||
|
# Hole cards are not currently correctly written. Currently the down cards for non-heros
|
||||||
|
# are shown in the "dealt to" lines. They should be hidden in those lines. I tried to fix
|
||||||
|
# but mind got boggled, will try again.
|
||||||
|
# print >>fh, _("%s Game #%s: %s ($%s/$%s) - %s" %("PokerStars", self.handid, self.getGameTypeAsString(), self.sb, self.bb, datetime.datetime.strftime(self.starttime,'%Y/%m/%d - %H:%M:%S ET')))
|
||||||
|
print >>fh, self.writeGameLine()
|
||||||
|
print >>fh, self.writeTableLine()
|
||||||
|
# print >>fh, _("Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos))
|
||||||
|
|
||||||
players_who_post_antes = set([x[0] for x in self.actions['ANTES']])
|
players_who_post_antes = set([x[0] for x in self.actions['ANTES']])
|
||||||
|
|
||||||
|
@ -1015,8 +1213,8 @@ Add a complete on [street] by [player] to [amountTo]
|
||||||
dealt = 0
|
dealt = 0
|
||||||
#~ print >>fh, _("*** 3RD STREET ***")
|
#~ print >>fh, _("*** 3RD STREET ***")
|
||||||
for player in [x[1] for x in self.players if x[1] in players_who_post_antes]:
|
for player in [x[1] for x in self.players if x[1] in players_who_post_antes]:
|
||||||
if 'THIRD' in self.holecards[player]:
|
if self.holecards['THIRD'].has_key(player):
|
||||||
(open, closed) = self.holecards[player]['THIRD']
|
(open, closed) = self.holecards['THIRD'][player]
|
||||||
dealt+=1
|
dealt+=1
|
||||||
if dealt==1:
|
if dealt==1:
|
||||||
print >>fh, _("*** 3RD STREET ***")
|
print >>fh, _("*** 3RD STREET ***")
|
||||||
|
@ -1029,12 +1227,12 @@ Add a complete on [street] by [player] to [amountTo]
|
||||||
dealt = 0
|
dealt = 0
|
||||||
#~ print >>fh, _("*** 4TH STREET ***")
|
#~ print >>fh, _("*** 4TH STREET ***")
|
||||||
for player in [x[1] for x in self.players if x[1] in players_who_post_antes]:
|
for player in [x[1] for x in self.players if x[1] in players_who_post_antes]:
|
||||||
if 'FOURTH' in self.holecards[player]:
|
if player in self.holecards['FOURTH']:
|
||||||
old = []
|
old = []
|
||||||
(o,c) = self.holecards[player]['THIRD']
|
(o,c) = self.holecards['THIRD'][player]
|
||||||
if o:old.extend(o)
|
if o:old.extend(o)
|
||||||
if c:old.extend(c)
|
if c:old.extend(c)
|
||||||
new = self.holecards[player]['FOURTH'][0]
|
new = self.holecards['FOURTH'][player][0]
|
||||||
dealt+=1
|
dealt+=1
|
||||||
if dealt==1:
|
if dealt==1:
|
||||||
print >>fh, _("*** 4TH STREET ***")
|
print >>fh, _("*** 4TH STREET ***")
|
||||||
|
@ -1046,13 +1244,13 @@ Add a complete on [street] by [player] to [amountTo]
|
||||||
dealt = 0
|
dealt = 0
|
||||||
#~ print >>fh, _("*** 5TH STREET ***")
|
#~ print >>fh, _("*** 5TH STREET ***")
|
||||||
for player in [x[1] for x in self.players if x[1] in players_who_post_antes]:
|
for player in [x[1] for x in self.players if x[1] in players_who_post_antes]:
|
||||||
if 'FIFTH' in self.holecards[player]:
|
if self.holecards['FIFTH'].has_key(player):
|
||||||
old = []
|
old = []
|
||||||
for street in ('THIRD','FOURTH'):
|
for street in ('THIRD','FOURTH'):
|
||||||
(o,c) = self.holecards[player][street]
|
(o,c) = self.holecards[street][player]
|
||||||
if o:old.extend(o)
|
if o:old.extend(o)
|
||||||
if c:old.extend(c)
|
if c:old.extend(c)
|
||||||
new = self.holecards[player]['FIFTH'][0]
|
new = self.holecards['FIFTH'][player][0]
|
||||||
dealt+=1
|
dealt+=1
|
||||||
if dealt==1:
|
if dealt==1:
|
||||||
print >>fh, _("*** 5TH STREET ***")
|
print >>fh, _("*** 5TH STREET ***")
|
||||||
|
@ -1064,13 +1262,13 @@ Add a complete on [street] by [player] to [amountTo]
|
||||||
dealt = 0
|
dealt = 0
|
||||||
#~ print >>fh, _("*** 6TH STREET ***")
|
#~ print >>fh, _("*** 6TH STREET ***")
|
||||||
for player in [x[1] for x in self.players if x[1] in players_who_post_antes]:
|
for player in [x[1] for x in self.players if x[1] in players_who_post_antes]:
|
||||||
if 'SIXTH' in self.holecards[player]:
|
if self.holecards['SIXTH'].has_key(player):
|
||||||
old = []
|
old = []
|
||||||
for street in ('THIRD','FOURTH','FIFTH'):
|
for street in ('THIRD','FOURTH','FIFTH'):
|
||||||
(o,c) = self.holecards[player][street]
|
(o,c) = self.holecards[street][player]
|
||||||
if o:old.extend(o)
|
if o:old.extend(o)
|
||||||
if c:old.extend(c)
|
if c:old.extend(c)
|
||||||
new = self.holecards[player]['SIXTH'][0]
|
new = self.holecards['SIXTH'][player][0]
|
||||||
dealt += 1
|
dealt += 1
|
||||||
if dealt == 1:
|
if dealt == 1:
|
||||||
print >>fh, _("*** 6TH STREET ***")
|
print >>fh, _("*** 6TH STREET ***")
|
||||||
|
@ -1085,13 +1283,13 @@ Add a complete on [street] by [player] to [amountTo]
|
||||||
# i.e. are all but one players folded; is there an allin showdown; and all that.
|
# i.e. are all but one players folded; is there an allin showdown; and all that.
|
||||||
print >>fh, _("*** 7TH STREET ***")
|
print >>fh, _("*** 7TH STREET ***")
|
||||||
for player in [x[1] for x in self.players if x[1] in players_who_post_antes]:
|
for player in [x[1] for x in self.players if x[1] in players_who_post_antes]:
|
||||||
if 'SEVENTH' in self.holecards[player]:
|
if self.holecards['SEVENTH'].has_key(player):
|
||||||
old = []
|
old = []
|
||||||
for street in ('THIRD','FOURTH','FIFTH','SIXTH'):
|
for street in ('THIRD','FOURTH','FIFTH','SIXTH'):
|
||||||
(o,c) = self.holecards[player][street]
|
(o,c) = self.holecards[street][player]
|
||||||
if o:old.extend(o)
|
if o:old.extend(o)
|
||||||
if c:old.extend(c)
|
if c:old.extend(c)
|
||||||
new = self.holecards[player]['SEVENTH'][0]
|
new = self.holecards['SEVENTH'][player][0]
|
||||||
if new:
|
if new:
|
||||||
print >>fh, _("Dealt to %s:%s%s") % (player, " [" + " ".join(old) + "] " if old else " ", "[" + " ".join(new) + "]" if new else "")
|
print >>fh, _("Dealt to %s:%s%s") % (player, " [" + " ".join(old) + "] " if old else " ", "[" + " ".join(new) + "]" if new else "")
|
||||||
for act in self.actions['SEVENTH']:
|
for act in self.actions['SEVENTH']:
|
||||||
|
@ -1130,11 +1328,13 @@ Add a complete on [street] by [player] to [amountTo]
|
||||||
seatnum = player[0]
|
seatnum = player[0]
|
||||||
name = player[1]
|
name = player[1]
|
||||||
if name in self.collectees and name in self.shown:
|
if name in self.collectees and name in self.shown:
|
||||||
print >>fh, _("Seat %d: %s showed [%s] and won ($%s)" % (seatnum, name, " ".join(self.holecards[name]), self.collectees[name]))
|
print >>fh, _("Seat %d: %s showed [%s] and won ($%s)" % (seatnum, name, self.join_holecards(name), self.collectees[name]))
|
||||||
elif name in self.collectees:
|
elif name in self.collectees:
|
||||||
print >>fh, _("Seat %d: %s collected ($%s)" % (seatnum, name, self.collectees[name]))
|
print >>fh, _("Seat %d: %s collected ($%s)" % (seatnum, name, self.collectees[name]))
|
||||||
elif name in self.shown:
|
elif name in self.shown:
|
||||||
print >>fh, _("Seat %d: %s showed [%s]" % (seatnum, name, " ".join(self.holecards[name])))
|
print >>fh, _("Seat %d: %s showed [%s]" % (seatnum, name, self.join_holecards(name)))
|
||||||
|
elif name in self.mucked:
|
||||||
|
print >>fh, _("Seat %d: %s mucked [%s]" % (seatnum, name, self.join_holecards(name)))
|
||||||
elif name in self.folded:
|
elif name in self.folded:
|
||||||
print >>fh, _("Seat %d: %s folded" % (seatnum, name))
|
print >>fh, _("Seat %d: %s folded" % (seatnum, name))
|
||||||
else:
|
else:
|
||||||
|
@ -1143,6 +1343,12 @@ Add a complete on [street] by [player] to [amountTo]
|
||||||
print >>fh, "\n\n"
|
print >>fh, "\n\n"
|
||||||
|
|
||||||
|
|
||||||
|
def join_holecards(self, player):
|
||||||
|
holecards = []
|
||||||
|
for street in self.holeStreets:
|
||||||
|
if self.holecards[street].has_key(player):
|
||||||
|
holecards = holecards + self.holecards[street][player][0]
|
||||||
|
return " ".join(holecards)
|
||||||
|
|
||||||
class Pot(object):
|
class Pot(object):
|
||||||
|
|
||||||
|
|
|
@ -197,6 +197,7 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
|
||||||
logging.info("Unsupported game type: %s" % gametype)
|
logging.info("Unsupported game type: %s" % gametype)
|
||||||
|
|
||||||
if hand:
|
if hand:
|
||||||
|
# print hand
|
||||||
hand.writeHand(self.out_fh)
|
hand.writeHand(self.out_fh)
|
||||||
else:
|
else:
|
||||||
logging.info("Unsupported game type: %s" % gametype)
|
logging.info("Unsupported game type: %s" % gametype)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
237
pyfpdb/Mucked.py
237
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,14 +80,19 @@ 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,152 @@ 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])
|
||||||
|
if self.params.has_key('opacity'):
|
||||||
self.m_windows[i].set_opacity(float(self.params['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()
|
||||||
|
if self.uses_timer:
|
||||||
self.m_windows[i].hide()
|
self.m_windows[i].hide()
|
||||||
|
|
||||||
def update_gui(self, new_hand_id):
|
def update_gui(self, new_hand_id):
|
||||||
"""Prepare and show the mucked cards."""
|
"""Update the gui, LDO."""
|
||||||
if self.displayed_cards:
|
for i in self.m_windows.keys():
|
||||||
self.hide_mucked_cards()
|
self.update_contents(self.m_windows[i], i)
|
||||||
self.displayed_cards = False
|
|
||||||
for (i, cards) in self.hud.cards.iteritems():
|
# Methods likely to be of use for any Seat_Window implementation
|
||||||
if self.has_cards(cards):
|
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 is a working pixbuf, used to assemble the image
|
||||||
scratch = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8,
|
scratch = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8,
|
||||||
int(self.params['card_wd'])*len(cards)/2,
|
int(self.params['card_wd'])*n_cards,
|
||||||
int(self.params['card_ht']))
|
int(self.params['card_ht']))
|
||||||
x = 0 # x coord where the next card starts in scratch
|
x = 0 # x coord where the next card starts in scratch
|
||||||
for card in [cards[k:k+2] for k in xrange(0, len(cards), 2)]:
|
for card in cards:
|
||||||
# concatenate each card image to scratch
|
# concatenate each card image to scratch
|
||||||
self.card_images[self.split_cards(card)].copy_area(0, 0,
|
if card == None or card ==0:
|
||||||
|
break
|
||||||
|
self.card_images[card].copy_area(0, 0,
|
||||||
int(self.params['card_wd']), int(self.params['card_ht']),
|
int(self.params['card_wd']), int(self.params['card_ht']),
|
||||||
scratch, x, 0)
|
scratch, x, 0)
|
||||||
x = x + int(self.params['card_wd'])
|
x = x + int(self.params['card_wd'])
|
||||||
self.seen_cards[i].set_from_pixbuf(scratch)
|
container.seen_cards.set_from_pixbuf(scratch)
|
||||||
# self.m_windows[i].show_all()
|
container.resize(1,1)
|
||||||
self.m_windows[i].resize(1,1)
|
container.show()
|
||||||
self.m_windows[i].show()
|
container.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 = True
|
||||||
self.displayed_cards = True
|
if i != "common":
|
||||||
|
id = self.get_id_from_seat(i)
|
||||||
|
self.m_windows[i].eb.set_tooltip_text(self.hud.stat_dict[id]['screen_name'])
|
||||||
|
|
||||||
for stats in self.hud.stat_dict.itervalues():
|
def update_gui(self, new_hand_id):
|
||||||
self.eb[stats['seat']].set_tooltip_text(stats['screen_name'])
|
"""Prepare and show the mucked cards."""
|
||||||
|
if self.displayed: self.hide()
|
||||||
|
|
||||||
if self.displayed_cards and float(self.params['timeout']) > 0:
|
# See how many players showed a hand. Skip if only 1 shows (= hero)
|
||||||
|
n_sd = 0
|
||||||
|
for (i, cards) in self.hud.cards.iteritems():
|
||||||
|
n_cards = self.has_cards(cards)
|
||||||
|
if n_cards > 0 and i != 'common':
|
||||||
|
n_sd = n_sd + 1
|
||||||
|
if n_sd < 2:
|
||||||
|
print "skipping, n_sd =", n_sd
|
||||||
|
return
|
||||||
|
|
||||||
|
super(Flop_Mucked, self).update_gui(new_hand_id)
|
||||||
|
|
||||||
|
if self.displayed and float(self.params['timeout']) > 0:
|
||||||
self.timer_on = True
|
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 +479,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 +499,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()
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
|
# TODO: straighten out discards for draw games
|
||||||
import sys
|
import sys
|
||||||
from HandHistoryConverter import *
|
from HandHistoryConverter import *
|
||||||
|
|
||||||
|
@ -25,16 +26,35 @@ from HandHistoryConverter import *
|
||||||
|
|
||||||
class PokerStars(HandHistoryConverter):
|
class PokerStars(HandHistoryConverter):
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# Class Variables
|
||||||
|
|
||||||
# Static regexes
|
# Static regexes
|
||||||
re_GameInfo = re.compile("PokerStars Game #(?P<HID>[0-9]+):\s+(HORSE)? \(?(?P<GAME>Hold\'em|Razz|7 Card Stud|7 Card Stud Hi/Lo|Omaha|Omaha Hi/Lo|Badugi) (?P<LIMIT>No Limit|Limit|Pot Limit),? \(?(?P<CURRENCY>\$|)?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+)\) - (?P<DATETIME>.*$)", re.MULTILINE)
|
re_GameInfo = re.compile("""PokerStars\sGame\s\#(?P<HID>[0-9]+):\s+
|
||||||
|
(Tournament\s\#(?P<TOURNO>\d+),\s(?P<BUYIN>[\$\+\d\.]+)\s)?
|
||||||
|
(?P<MIXED>HORSE|8\-Game|HOSE)?\s?\(?
|
||||||
|
(?P<GAME>Hold\'em|Razz|7\sCard\sStud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball)\s
|
||||||
|
(?P<LIMIT>No\sLimit|Limit|Pot\sLimit)\)?,?\s
|
||||||
|
(-\sLevel\s(?P<LEVEL>[IVXLC]+)\s)?\(?
|
||||||
|
(?P<CURRENCY>\$|)?
|
||||||
|
(?P<SB>[.0-9]+)/\$?
|
||||||
|
(?P<BB>[.0-9]+)\)\s-\s
|
||||||
|
(?P<DATETIME>.*$)""",
|
||||||
|
re.MULTILINE|re.VERBOSE)
|
||||||
re_SplitHands = re.compile('\n\n+')
|
re_SplitHands = re.compile('\n\n+')
|
||||||
re_TailSplitHands = re.compile('(\n\n\n+)')
|
re_TailSplitHands = re.compile('(\n\n\n+)')
|
||||||
re_HandInfo = re.compile("^Table \'(?P<TABLE>[- a-zA-Z]+)\'(?P<TABLEATTRIBUTES>.+?$)?", re.MULTILINE)
|
re_HandInfo = re.compile("""^Table\s\'(?P<TABLE>[-\ a-zA-Z\d]+)\'\s
|
||||||
|
((?P<MAX>\d+)-max\s)?
|
||||||
|
(?P<PLAY>\(Play\sMoney\)\s)?
|
||||||
|
(Seat\s\#(?P<BUTTON>\d+)\sis\sthe\sbutton)?""",
|
||||||
|
re.MULTILINE|re.VERBOSE)
|
||||||
re_Button = re.compile('Seat #(?P<BUTTON>\d+) is the button', re.MULTILINE)
|
re_Button = re.compile('Seat #(?P<BUTTON>\d+) is the button', re.MULTILINE)
|
||||||
re_PlayerInfo = re.compile('^Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\$?(?P<CASH>[.0-9]+) in chips\)', re.MULTILINE)
|
re_PlayerInfo = re.compile('^Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*) \(\$?(?P<CASH>[.0-9]+) in chips\)', re.MULTILINE)
|
||||||
re_Board = re.compile(r"\[(?P<CARDS>.+)\]")
|
re_Board = re.compile(r"\[(?P<CARDS>.+)\]")
|
||||||
# self.re_setHandInfoRegex('.*#(?P<HID>[0-9]+): Table (?P<TABLE>[ a-zA-Z]+) - \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) - (?P<GAMETYPE>.*) - (?P<HR>[0-9]+):(?P<MIN>[0-9]+) ET - (?P<YEAR>[0-9]+)/(?P<MON>[0-9]+)/(?P<DAY>[0-9]+)Table (?P<TABLE>[ a-zA-Z]+)\nSeat (?P<BUTTON>[0-9]+)')
|
# self.re_setHandInfoRegex('.*#(?P<HID>[0-9]+): Table (?P<TABLE>[ a-zA-Z]+) - \$?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) - (?P<GAMETYPE>.*) - (?P<HR>[0-9]+):(?P<MIN>[0-9]+) ET - (?P<YEAR>[0-9]+)/(?P<MON>[0-9]+)/(?P<DAY>[0-9]+)Table (?P<TABLE>[ a-zA-Z]+)\nSeat (?P<BUTTON>[0-9]+)')
|
||||||
|
|
||||||
|
mixes = { 'HORSE': 'horse', '8-Game': '8game', 'HOSE': 'hose'}
|
||||||
|
|
||||||
def __init__(self, in_path = '-', out_path = '-', follow = False, autostart=True):
|
def __init__(self, in_path = '-', out_path = '-', follow = False, autostart=True):
|
||||||
"""\
|
"""\
|
||||||
in_path (default '-' = sys.stdin)
|
in_path (default '-' = sys.stdin)
|
||||||
|
@ -53,6 +73,9 @@ follow : whether to tail -f the input"""
|
||||||
players = set([player[1] for player in hand.players])
|
players = set([player[1] for player in hand.players])
|
||||||
if not players <= self.compiledPlayers: # x <= y means 'x is subset of y'
|
if not players <= self.compiledPlayers: # x <= y means 'x is subset of y'
|
||||||
# we need to recompile the player regexs.
|
# we need to recompile the player regexs.
|
||||||
|
# TODO: should probably rename re_HeroCards and corresponding method,
|
||||||
|
# since they are used to find all cards on lines starting with "Dealt to:"
|
||||||
|
# They still identify the hero.
|
||||||
self.compiledPlayers = players
|
self.compiledPlayers = players
|
||||||
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
|
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
|
||||||
logging.debug("player_re: " + player_re)
|
logging.debug("player_re: " + player_re)
|
||||||
|
@ -62,32 +85,43 @@ follow : whether to tail -f the input"""
|
||||||
self.re_BringIn = re.compile(r"^%s: brings[- ]in( low|) for \$?(?P<BRINGIN>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_BringIn = re.compile(r"^%s: brings[- ]in( low|) for \$?(?P<BRINGIN>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.re_PostBoth = re.compile(r"^%s: posts small \& big blinds \[\$? (?P<SBBB>[.0-9]+)" % player_re, re.MULTILINE)
|
self.re_PostBoth = re.compile(r"^%s: posts small \& big blinds \[\$? (?P<SBBB>[.0-9]+)" % player_re, re.MULTILINE)
|
||||||
self.re_HeroCards = re.compile(r"^Dealt to %s(?: \[(?P<OLDCARDS>.+?)\])?( \[(?P<NEWCARDS>.+?)\])" % player_re, re.MULTILINE)
|
self.re_HeroCards = re.compile(r"^Dealt to %s(?: \[(?P<OLDCARDS>.+?)\])?( \[(?P<NEWCARDS>.+?)\])" % player_re, re.MULTILINE)
|
||||||
self.re_Action = re.compile(r"^%s:(?P<ATYPE> bets| checks| raises| calls| folds| discards| stands pat)( \$(?P<BET>[.\d]+))?( to \$(?P<BETTO>[.\d]+))?( (?P<NODISCARDED>\d) cards?( \[(?P<DISCARDED>.+?)\])?)?" % player_re, re.MULTILINE)
|
self.re_Action = re.compile(r"""^%s:(?P<ATYPE>\sbets|\schecks|\sraises|\scalls|\sfolds|\sdiscards|\sstands\spat)
|
||||||
|
(\s\$?(?P<BET>[.\d]+))?(\sto\s\$?(?P<BETTO>[.\d]+))? # the number discarded goes in <BET>
|
||||||
|
(\scards?(\s\[(?P<DISCARDED>.+?)\])?)?"""
|
||||||
|
% player_re, re.MULTILINE|re.VERBOSE)
|
||||||
self.re_ShowdownAction = re.compile(r"^%s: shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
|
self.re_ShowdownAction = re.compile(r"^%s: shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
|
||||||
self.re_CollectPot = re.compile(r"Seat (?P<SEAT>[0-9]+): %s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \(\$(?P<POT>[.\d]+)\)(, mucked| with.*|)" % player_re, re.MULTILINE)
|
self.re_CollectPot = re.compile(r"Seat (?P<SEAT>[0-9]+): %s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \(\$?(?P<POT>[.\d]+)\)(, mucked| with.*|)" % player_re, re.MULTILINE)
|
||||||
self.re_sitsOut = re.compile("^%s sits out" % player_re, re.MULTILINE)
|
self.re_sitsOut = re.compile("^%s sits out" % player_re, re.MULTILINE)
|
||||||
self.re_ShownCards = re.compile("^Seat (?P<SEAT>[0-9]+): %s \(.*\) showed \[(?P<CARDS>.*)\].*" % player_re, re.MULTILINE)
|
self.re_ShownCards = re.compile("^Seat (?P<SEAT>[0-9]+): %s (\(.*\) )?(?P<SHOWED>showed|mucked) \[(?P<CARDS>.*)\].*" % player_re, re.MULTILINE)
|
||||||
|
|
||||||
|
|
||||||
def readSupportedGames(self):
|
def readSupportedGames(self):
|
||||||
return [["ring", "hold", "nl"],
|
return [["ring", "hold", "nl"],
|
||||||
["ring", "hold", "pl"],
|
["ring", "hold", "pl"],
|
||||||
["ring", "hold", "fl"],
|
["ring", "hold", "fl"],
|
||||||
|
|
||||||
["ring", "stud", "fl"],
|
["ring", "stud", "fl"],
|
||||||
#["ring", "draw", "fl"],
|
|
||||||
["ring", "omaha", "pl"]
|
["ring", "draw", "fl"],
|
||||||
|
|
||||||
|
["tour", "hold", "nl"],
|
||||||
|
["tour", "hold", "pl"],
|
||||||
|
["tour", "hold", "fl"],
|
||||||
|
|
||||||
|
["tour", "stud", "fl"],
|
||||||
]
|
]
|
||||||
|
|
||||||
def determineGameType(self, handText):
|
def determineGameType(self, handText):
|
||||||
info = {'type':'ring'}
|
# inspect the handText and return the gametype dict
|
||||||
|
# gametype dict is:
|
||||||
|
# {'limitType': xxx, 'base': xxx, 'category': xxx}
|
||||||
|
|
||||||
|
info = {}
|
||||||
m = self.re_GameInfo.search(handText)
|
m = self.re_GameInfo.search(handText)
|
||||||
if not m:
|
if not m:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
mg = m.groupdict()
|
mg = m.groupdict()
|
||||||
|
# translations from captured groups to fpdb info strings
|
||||||
# translations from captured groups to our info strings
|
|
||||||
limits = { 'No Limit':'nl', 'Pot Limit':'pl', 'Limit':'fl' }
|
limits = { 'No Limit':'nl', 'Pot Limit':'pl', 'Limit':'fl' }
|
||||||
games = { # base, category
|
games = { # base, category
|
||||||
"Hold'em" : ('hold','holdem'),
|
"Hold'em" : ('hold','holdem'),
|
||||||
|
@ -96,9 +130,14 @@ follow : whether to tail -f the input"""
|
||||||
'Razz' : ('stud','razz'),
|
'Razz' : ('stud','razz'),
|
||||||
'7 Card Stud' : ('stud','studhi'),
|
'7 Card Stud' : ('stud','studhi'),
|
||||||
'7 Card Stud Hi/Lo' : ('stud','studhilo'),
|
'7 Card Stud Hi/Lo' : ('stud','studhilo'),
|
||||||
'Badugi' : ('draw','badugi')
|
'Badugi' : ('draw','badugi'),
|
||||||
|
'Triple Draw 2-7 Lowball' : ('draw','27_3draw'),
|
||||||
}
|
}
|
||||||
currencies = { u'€':'EUR', '$':'USD', '':'T$' }
|
currencies = { u'€':'EUR', '$':'USD', '':'T$' }
|
||||||
|
# I don't think this is doing what we think. mg will always have all
|
||||||
|
# the expected keys, but the ones that didn't match in the regex will
|
||||||
|
# have a value of None. It is OK if it throws an exception when it
|
||||||
|
# runs across an unknown game or limit or whatever.
|
||||||
if 'LIMIT' in mg:
|
if 'LIMIT' in mg:
|
||||||
info['limitType'] = limits[mg['LIMIT']]
|
info['limitType'] = limits[mg['LIMIT']]
|
||||||
if 'GAME' in mg:
|
if 'GAME' in mg:
|
||||||
|
@ -109,8 +148,13 @@ follow : whether to tail -f the input"""
|
||||||
info['bb'] = mg['BB']
|
info['bb'] = mg['BB']
|
||||||
if 'CURRENCY' in mg:
|
if 'CURRENCY' in mg:
|
||||||
info['currency'] = currencies[mg['CURRENCY']]
|
info['currency'] = currencies[mg['CURRENCY']]
|
||||||
# NB: SB, BB must be interpreted as blinds or bets depending on limit type.
|
|
||||||
|
|
||||||
|
if 'TOURNO' in mg and mg['TOURNO'] == None:
|
||||||
|
info['type'] = 'ring'
|
||||||
|
else:
|
||||||
|
info['type'] = 'tour'
|
||||||
|
|
||||||
|
# NB: SB, BB must be interpreted as blinds or bets depending on limit type.
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,14 +163,13 @@ follow : whether to tail -f the input"""
|
||||||
m = self.re_HandInfo.search(hand.handText,re.DOTALL)
|
m = self.re_HandInfo.search(hand.handText,re.DOTALL)
|
||||||
if m:
|
if m:
|
||||||
info.update(m.groupdict())
|
info.update(m.groupdict())
|
||||||
# TODO: Be less lazy and parse maxseats from the HandInfo regex
|
# hand.maxseats = int(m2.group(1))
|
||||||
if m.group('TABLEATTRIBUTES'):
|
else:
|
||||||
m2 = re.search("\s*(\d+)-max", m.group('TABLEATTRIBUTES'))
|
pass # throw an exception here, eh?
|
||||||
hand.maxseats = int(m2.group(1))
|
|
||||||
m = self.re_GameInfo.search(hand.handText)
|
m = self.re_GameInfo.search(hand.handText)
|
||||||
if m: info.update(m.groupdict())
|
if m: info.update(m.groupdict())
|
||||||
m = self.re_Button.search(hand.handText)
|
# m = self.re_Button.search(hand.handText)
|
||||||
if m: info.update(m.groupdict())
|
# if m: info.update(m.groupdict())
|
||||||
# TODO : I rather like the idea of just having this dict as hand.info
|
# TODO : I rather like the idea of just having this dict as hand.info
|
||||||
logging.debug("readHandInfo: %s" % info)
|
logging.debug("readHandInfo: %s" % info)
|
||||||
for key in info:
|
for key in info:
|
||||||
|
@ -143,6 +186,22 @@ follow : whether to tail -f the input"""
|
||||||
hand.tablename = info[key]
|
hand.tablename = info[key]
|
||||||
if key == 'BUTTON':
|
if key == 'BUTTON':
|
||||||
hand.buttonpos = info[key]
|
hand.buttonpos = info[key]
|
||||||
|
if key == 'MAX':
|
||||||
|
hand.maxseats = int(info[key])
|
||||||
|
|
||||||
|
if key == 'MIXED':
|
||||||
|
if info[key] == None: hand.mixed = None
|
||||||
|
else: hand.mixed = self.mixes[info[key]]
|
||||||
|
|
||||||
|
if key == 'TOURNO':
|
||||||
|
hand.tourNo = info[key]
|
||||||
|
if key == 'BUYIN':
|
||||||
|
hand.buyin = info[key]
|
||||||
|
if key == 'LEVEL':
|
||||||
|
hand.level = info[key]
|
||||||
|
if key == 'PLAY' and info['PLAY'] != None:
|
||||||
|
# hand.currency = 'play' # overrides previously set value
|
||||||
|
hand.gametype['currency'] = 'play'
|
||||||
|
|
||||||
def readButton(self, hand):
|
def readButton(self, hand):
|
||||||
m = self.re_Button.search(hand.handText)
|
m = self.re_Button.search(hand.handText)
|
||||||
|
@ -211,78 +270,115 @@ follow : whether to tail -f the input"""
|
||||||
for a in self.re_PostBoth.finditer(hand.handText):
|
for a in self.re_PostBoth.finditer(hand.handText):
|
||||||
hand.addBlind(a.group('PNAME'), 'both', a.group('SBBB'))
|
hand.addBlind(a.group('PNAME'), 'both', a.group('SBBB'))
|
||||||
|
|
||||||
|
# def readHeroCards(self, hand):
|
||||||
|
# m = self.re_HeroCards.search(hand.handText)
|
||||||
|
# if(m == None):
|
||||||
|
# #Not involved in hand
|
||||||
|
# hand.involved = False
|
||||||
|
# else:
|
||||||
|
# hand.hero = m.group('PNAME')
|
||||||
|
# # "2c, qh" -> set(["2c","qc"])
|
||||||
|
# # Also works with Omaha hands.
|
||||||
|
# cards = m.group('NEWCARDS')
|
||||||
|
# cards = set(cards.split(' '))
|
||||||
|
# hand.addHoleCards(cards, m.group('PNAME'), shown=False, mucked=False, dealt=True)
|
||||||
|
|
||||||
def readHeroCards(self, hand):
|
def readHeroCards(self, hand):
|
||||||
m = self.re_HeroCards.search(hand.handText)
|
# streets PREFLOP, PREDRAW, and THIRD are special cases beacause
|
||||||
if(m == None):
|
# we need to grab hero's cards
|
||||||
#Not involved in hand
|
for street in ('PREFLOP', 'DEAL'):
|
||||||
hand.involved = False
|
if street in hand.streets.keys():
|
||||||
else:
|
|
||||||
hand.hero = m.group('PNAME')
|
|
||||||
# "2c, qh" -> set(["2c","qc"])
|
|
||||||
# Also works with Omaha hands.
|
|
||||||
cards = m.group('NEWCARDS')
|
|
||||||
cards = set(cards.split(' '))
|
|
||||||
hand.addHoleCards(cards, m.group('PNAME'))
|
|
||||||
|
|
||||||
def readDrawCards(self, hand, street):
|
|
||||||
logging.debug("readDrawCards")
|
|
||||||
m = self.re_HeroCards.finditer(hand.streets[street])
|
m = self.re_HeroCards.finditer(hand.streets[street])
|
||||||
if m == None:
|
for found in m:
|
||||||
hand.involved = False
|
# if m == None:
|
||||||
else:
|
# hand.involved = False
|
||||||
for player in m:
|
# else:
|
||||||
hand.hero = player.group('PNAME') # Only really need to do this once
|
hand.hero = found.group('PNAME')
|
||||||
newcards = player.group('NEWCARDS')
|
newcards = found.group('NEWCARDS').split(' ')
|
||||||
oldcards = player.group('OLDCARDS')
|
hand.addHoleCards(street, hand.hero, closed=newcards, shown=False, mucked=False, dealt=True)
|
||||||
if newcards == None:
|
|
||||||
newcards = set()
|
|
||||||
else:
|
|
||||||
newcards = set(newcards.split(' '))
|
|
||||||
if oldcards == None:
|
|
||||||
oldcards = set()
|
|
||||||
else:
|
|
||||||
oldcards = set(oldcards.split(' '))
|
|
||||||
hand.addDrawHoleCards(newcards, oldcards, player.group('PNAME'), street)
|
|
||||||
|
|
||||||
|
for street, text in hand.streets.iteritems():
|
||||||
def readStudPlayerCards(self, hand, street):
|
if street in ('PREFLOP', 'DEAL'): continue # already done these
|
||||||
# See comments of reference implementation in FullTiltToFpdb.py
|
|
||||||
logging.debug("readStudPlayerCards")
|
|
||||||
m = self.re_HeroCards.finditer(hand.streets[street])
|
m = self.re_HeroCards.finditer(hand.streets[street])
|
||||||
for player in m:
|
for found in m:
|
||||||
#~ logging.debug(player.groupdict())
|
player = found.group('PNAME')
|
||||||
(pname, oldcards, newcards) = (player.group('PNAME'), player.group('OLDCARDS'), player.group('NEWCARDS'))
|
if found.group('NEWCARDS') == None:
|
||||||
if oldcards:
|
newcards = []
|
||||||
oldcards = [c.strip() for c in oldcards.split(' ')]
|
else:
|
||||||
if newcards:
|
newcards = found.group('NEWCARDS').split(' ')
|
||||||
newcards = [c.strip() for c in newcards.split(' ')]
|
if found.group('OLDCARDS') == None:
|
||||||
if street=='ANTES':
|
oldcards = []
|
||||||
return
|
else:
|
||||||
elif street=='THIRD':
|
oldcards = found.group('OLDCARDS').split(' ')
|
||||||
# we'll have observed hero holecards in CARDS and thirdstreet open cards in 'NEWCARDS'
|
|
||||||
# hero: [xx][o]
|
if street == 'THIRD' and len(newcards) == 3: # hero in stud game
|
||||||
# others: [o]
|
hand.hero = player
|
||||||
hand.addPlayerCards(player = player.group('PNAME'), street = street, closed = oldcards, open = newcards)
|
hand.dealt.add(player) # need this for stud??
|
||||||
elif street in ('FOURTH', 'FIFTH', 'SIXTH'):
|
hand.addHoleCards(street, player, closed=newcards[0:2], open=[newcards[2]], shown=False, mucked=False, dealt=False)
|
||||||
# 4th:
|
else:
|
||||||
# hero: [xxo] [o]
|
hand.addHoleCards(street, player, open=newcards, closed=oldcards, shown=False, mucked=False, dealt=False)
|
||||||
# others: [o] [o]
|
|
||||||
# 5th:
|
|
||||||
# hero: [xxoo] [o]
|
# def readDrawCards(self, hand, street):
|
||||||
# others: [oo] [o]
|
# logging.debug("readDrawCards")
|
||||||
# 6th:
|
# m = self.re_HeroCards.finditer(hand.streets[street])
|
||||||
# hero: [xxooo] [o]
|
# if m == None:
|
||||||
# others: [ooo] [o]
|
# hand.involved = False
|
||||||
hand.addPlayerCards(player = player.group('PNAME'), street = street, open = newcards)
|
# else:
|
||||||
# we may additionally want to check the earlier streets tally with what we have but lets trust it for now.
|
# for player in m:
|
||||||
elif street=='SEVENTH' and newcards:
|
# hand.hero = player.group('PNAME') # Only really need to do this once
|
||||||
# hero: [xxoooo] [x]
|
# newcards = player.group('NEWCARDS')
|
||||||
# others: not reported.
|
# oldcards = player.group('OLDCARDS')
|
||||||
hand.addPlayerCards(player = player.group('PNAME'), street = street, closed = newcards)
|
# if newcards == None:
|
||||||
|
# newcards = set()
|
||||||
|
# else:
|
||||||
|
# newcards = set(newcards.split(' '))
|
||||||
|
# if oldcards == None:
|
||||||
|
# oldcards = set()
|
||||||
|
# else:
|
||||||
|
# oldcards = set(oldcards.split(' '))
|
||||||
|
# hand.addDrawHoleCards(newcards, oldcards, player.group('PNAME'), street)
|
||||||
|
|
||||||
|
|
||||||
|
# def readStudPlayerCards(self, hand, street):
|
||||||
|
# # See comments of reference implementation in FullTiltToFpdb.py
|
||||||
|
# logging.debug("readStudPlayerCards")
|
||||||
|
# m = self.re_HeroCards.finditer(hand.streets[street])
|
||||||
|
# for player in m:
|
||||||
|
# #~ logging.debug(player.groupdict())
|
||||||
|
# (pname, oldcards, newcards) = (player.group('PNAME'), player.group('OLDCARDS'), player.group('NEWCARDS'))
|
||||||
|
# if oldcards:
|
||||||
|
# oldcards = [c.strip() for c in oldcards.split(' ')]
|
||||||
|
# if newcards:
|
||||||
|
# newcards = [c.strip() for c in newcards.split(' ')]
|
||||||
|
# if street=='ANTES':
|
||||||
|
# return
|
||||||
|
# elif street=='THIRD':
|
||||||
|
# # we'll have observed hero holecards in CARDS and thirdstreet open cards in 'NEWCARDS'
|
||||||
|
# # hero: [xx][o]
|
||||||
|
# # others: [o]
|
||||||
|
# hand.addPlayerCards(player = player.group('PNAME'), street = street, closed = oldcards, open = newcards)
|
||||||
|
# elif street in ('FOURTH', 'FIFTH', 'SIXTH'):
|
||||||
|
# # 4th:
|
||||||
|
# # hero: [xxo] [o]
|
||||||
|
# # others: [o] [o]
|
||||||
|
# # 5th:
|
||||||
|
# # hero: [xxoo] [o]
|
||||||
|
# # others: [oo] [o]
|
||||||
|
# # 6th:
|
||||||
|
# # hero: [xxooo] [o]
|
||||||
|
# # others: [ooo] [o]
|
||||||
|
# hand.addPlayerCards(player = player.group('PNAME'), street = street, open = newcards)
|
||||||
|
# # we may additionally want to check the earlier streets tally with what we have but lets trust it for now.
|
||||||
|
# elif street=='SEVENTH' and newcards:
|
||||||
|
# # hero: [xxoooo] [x]
|
||||||
|
# # others: not reported.
|
||||||
|
# hand.addPlayerCards(player = player.group('PNAME'), street = street, closed = newcards)
|
||||||
|
|
||||||
def readAction(self, hand, street):
|
def readAction(self, hand, street):
|
||||||
m = self.re_Action.finditer(hand.streets[street])
|
m = self.re_Action.finditer(hand.streets[street])
|
||||||
for action in m:
|
for action in m:
|
||||||
|
acts = action.groupdict()
|
||||||
if action.group('ATYPE') == ' raises':
|
if action.group('ATYPE') == ' raises':
|
||||||
hand.addRaiseBy( street, action.group('PNAME'), action.group('BET') )
|
hand.addRaiseBy( street, action.group('PNAME'), action.group('BET') )
|
||||||
elif action.group('ATYPE') == ' calls':
|
elif action.group('ATYPE') == ' calls':
|
||||||
|
@ -294,7 +390,7 @@ follow : whether to tail -f the input"""
|
||||||
elif action.group('ATYPE') == ' checks':
|
elif action.group('ATYPE') == ' checks':
|
||||||
hand.addCheck( street, action.group('PNAME'))
|
hand.addCheck( street, action.group('PNAME'))
|
||||||
elif action.group('ATYPE') == ' discards':
|
elif action.group('ATYPE') == ' discards':
|
||||||
hand.addDiscard(street, action.group('PNAME'), action.group('NODISCARDED'), action.group('DISCARDED'))
|
hand.addDiscard(street, action.group('PNAME'), action.group('BET'), action.group('DISCARDED'))
|
||||||
elif action.group('ATYPE') == ' stands pat':
|
elif action.group('ATYPE') == ' stands pat':
|
||||||
hand.addStandsPat( street, action.group('PNAME'))
|
hand.addStandsPat( street, action.group('PNAME'))
|
||||||
else:
|
else:
|
||||||
|
@ -302,9 +398,9 @@ follow : whether to tail -f the input"""
|
||||||
|
|
||||||
|
|
||||||
def readShowdownActions(self, hand):
|
def readShowdownActions(self, hand):
|
||||||
|
# TODO: pick up mucks also
|
||||||
for shows in self.re_ShowdownAction.finditer(hand.handText):
|
for shows in self.re_ShowdownAction.finditer(hand.handText):
|
||||||
cards = shows.group('CARDS')
|
cards = shows.group('CARDS').split(' ')
|
||||||
cards = set(cards.split(' '))
|
|
||||||
hand.addShownCards(cards, shows.group('PNAME'))
|
hand.addShownCards(cards, shows.group('PNAME'))
|
||||||
|
|
||||||
def readCollectPot(self,hand):
|
def readCollectPot(self,hand):
|
||||||
|
@ -315,8 +411,13 @@ follow : whether to tail -f the input"""
|
||||||
for m in self.re_ShownCards.finditer(hand.handText):
|
for m in self.re_ShownCards.finditer(hand.handText):
|
||||||
if m.group('CARDS') is not None:
|
if m.group('CARDS') is not None:
|
||||||
cards = m.group('CARDS')
|
cards = m.group('CARDS')
|
||||||
cards = set(cards.split(' '))
|
cards = cards.split(' ') # needs to be a list, not a set--stud needs the order
|
||||||
hand.addShownCards(cards=cards, player=m.group('PNAME'))
|
|
||||||
|
(shown, mucked) = (False, False)
|
||||||
|
if m.group('SHOWED') == "showed": shown = True
|
||||||
|
elif m.group('SHOWED') == "mucked": mucked = True
|
||||||
|
|
||||||
|
hand.addShownCards(cards=cards, player=m.group('PNAME'), shown=shown, mucked=mucked)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
|
|
|
@ -542,18 +542,13 @@ 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.
|
||||||
|
@ -365,7 +369,7 @@ def clean_title(name):
|
||||||
for pattern in [' \(6 max\)', ' \(heads up\)', ' \(deep\)',
|
for pattern in [' \(6 max\)', ' \(heads up\)', ' \(deep\)',
|
||||||
' \(deep hu\)', ' \(deep 6\)', ' \(2\)',
|
' \(deep hu\)', ' \(deep 6\)', ' \(2\)',
|
||||||
' \(edu\)', ' \(edu, 6 max\)', ' \(6\)',
|
' \(edu\)', ' \(edu, 6 max\)', ' \(6\)',
|
||||||
' \(speed\)',
|
' \(speed\)', 'special', 'newVPP',
|
||||||
' no all-in', ' fast', ',', ' 50BB min', '50bb min', '\s+$']:
|
' no all-in', ' fast', ',', ' 50BB min', '50bb min', '\s+$']:
|
||||||
name = re.sub(pattern, '', name)
|
name = re.sub(pattern, '', name)
|
||||||
name = name.rstrip()
|
name = name.rstrip()
|
||||||
|
|
|
@ -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 = hud.main_window.window
|
||||||
hud.main_window.gdkhandle.set_transient_for(self.gdkhandle)
|
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)
|
||||||
|
|
|
@ -33,7 +33,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
|
||||||
|
@ -42,6 +42,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
|
||||||
|
|
||||||
|
@ -179,20 +181,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
|
||||||
|
|
||||||
|
@ -204,22 +207,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:
|
||||||
|
@ -347,6 +351,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"
|
||||||
|
@ -359,17 +364,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.")
|
||||||
|
@ -387,9 +388,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):
|
||||||
|
@ -398,13 +406,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):
|
||||||
|
@ -415,9 +419,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):
|
||||||
|
@ -466,7 +470,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")
|
||||||
|
@ -475,22 +479,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):
|
||||||
LOG_FILENAME = './logging.out'
|
|
||||||
LOG_FORMAT = "%(asctime)-15s %(levelname)-8s %(message)s"
|
|
||||||
logging.basicConfig(filename=LOG_FILENAME,level=10,format=LOG_FORMAT)
|
|
||||||
logging.info("Fpdb started")
|
|
||||||
|
|
||||||
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)
|
||||||
|
@ -525,11 +523,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__
|
||||||
|
|
||||||
|
|
|
@ -255,7 +255,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'])
|
||||||
|
@ -587,17 +586,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)." \
|
||||||
|
@ -605,11 +605,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)." \
|
||||||
|
|
|
@ -32,6 +32,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
|
||||||
|
|
||||||
|
@ -58,7 +59,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 = {}
|
||||||
|
@ -76,6 +78,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()
|
||||||
|
@ -394,7 +397,8 @@ class Importer:
|
||||||
|
|
||||||
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