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