diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index d40f37f9..728ffd5c 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -672,38 +672,50 @@ class Config: except: hui['label'] = default_text + try: hui['hud_style'] = self.ui.hud_style + except: hui['hud_style'] = 'A' # default is show stats for All-time, also S(session) and T(ime) + + try: hui['hud_days'] = int(self.ui.hud_days) + except: hui['hud_days'] = 90 + try: hui['aggregate_ring'] = self.ui.aggregate_ring except: hui['aggregate_ring'] = False try: hui['aggregate_tour'] = self.ui.aggregate_tour except: hui['aggregate_tour'] = True - try: hui['hud_style'] = self.ui.hud_style - except: hui['hud_style'] = 'A' - - try: hui['hud_days'] = int(self.ui.hud_days) - except: hui['hud_days'] = 90 - try: hui['agg_bb_mult'] = self.ui.agg_bb_mult except: hui['agg_bb_mult'] = 1 + try: hui['seats_style'] = self.ui.seats_style + except: hui['seats_style'] = 'C' # A / C / E, use A(ll) / C(ustom) / E(xact) seat numbers + + try: hui['seats_cust_nums'] = self.ui.seats_cust_nums + except: hui['seats_cust_nums'] = ['n/a', 'n/a', (2,2), (3,4), (3,5), (4,6), (5,7), (6,8), (7,9), (8,10), (8,10)] + # Hero specific - try: hui['h_aggregate_ring'] = self.ui.h_aggregate_ring - except: hui['h_aggregate_ring'] = False - - try: hui['h_aggregate_tour'] = self.ui.h_aggregate_tour - except: hui['h_aggregate_tour'] = True - try: hui['h_hud_style'] = self.ui.h_hud_style except: hui['h_hud_style'] = 'S' try: hui['h_hud_days'] = int(self.ui.h_hud_days) except: hui['h_hud_days'] = 30 + try: hui['h_aggregate_ring'] = self.ui.h_aggregate_ring + except: hui['h_aggregate_ring'] = False + + try: hui['h_aggregate_tour'] = self.ui.h_aggregate_tour + except: hui['h_aggregate_tour'] = True + try: hui['h_agg_bb_mult'] = self.ui.h_agg_bb_mult except: hui['h_agg_bb_mult'] = 1 + try: hui['h_seats_style'] = self.ui.h_seats_style + except: hui['h_seats_style'] = 'E' # A / C / E, use A(ll) / C(ustom) / E(xact) seat numbers + + try: hui['h_seats_cust_nums'] = self.ui.h_seats_cust_nums + except: hui['h_seats_cust_nums'] = ['n/a', 'n/a', (2,2), (3,4), (3,5), (4,6), (5,7), (6,8), (7,9), (8,10), (8,10)] + return hui diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 9f214aeb..20d4d639 100755 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -433,17 +433,50 @@ class Database: def get_stats_from_hand( self, hand, type # type is "ring" or "tour" , hud_params = {'hud_style':'A', 'agg_bb_mult':1000 - ,'h_hud_style':'S', 'h_agg_bb_mult':1000} + ,'seats_style':'A', 'seats_cust_nums':['n/a', 'n/a', (2,2), (3,4), (3,5), (4,6), (5,7), (6,8), (7,9), (8,10), (8,10)] + ,'h_hud_style':'S', 'h_agg_bb_mult':1000 + ,'h_seats_style':'A', 'h_seats_cust_nums':['n/a', 'n/a', (2,2), (3,4), (3,5), (4,6), (5,7), (6,8), (7,9), (8,10), (8,10)] + } , hero_id = -1 + , num_seats = 6 ): hud_style = hud_params['hud_style'] agg_bb_mult = hud_params['agg_bb_mult'] + seats_style = hud_params['seats_style'] + seats_cust_nums = hud_params['seats_cust_nums'] h_hud_style = hud_params['h_hud_style'] h_agg_bb_mult = hud_params['h_agg_bb_mult'] + h_seats_style = hud_params['h_seats_style'] + h_seats_cust_nums = hud_params['h_seats_cust_nums'] + stat_dict = {} + if seats_style == 'A': + seats_min, seats_max = 2, 10 + elif seats_style == 'C': + seats_min, seats_max = seats_cust_nums[num_seats][0], seats_cust_nums[num_seats][1] + elif seats_style == 'E': + seats_min, seats_max = num_seats, num_seats + else: + seats_min, seats_max = 2, 10 + print "bad seats_style value:", seats_style + + if h_seats_style == 'A': + h_seats_min, h_seats_max = 2, 10 + elif h_seats_style == 'C': + h_seats_min, h_seats_max = h_seats_cust_nums[num_seats][0], h_seats_cust_nums[num_seats][1] + elif h_seats_style == 'E': + h_seats_min, h_seats_max = num_seats, num_seats + else: + h_seats_min, h_seats_max = 2, 10 + print "bad h_seats_style value:", h_seats_style + print "opp seats style", seats_style, "hero seats style", h_seats_style + print "opp seats:", seats_min, seats_max, " hero seats:", h_seats_min, h_seats_max + if hud_style == 'S' or h_hud_style == 'S': - self.get_stats_from_hand_session(hand, stat_dict, hero_id, hud_style, h_hud_style) + self.get_stats_from_hand_session(hand, stat_dict, hero_id + ,hud_style, seats_min, seats_max + ,h_hud_style, h_seats_min, h_seats_max) if hud_style == 'S' and h_hud_style == 'S': return stat_dict @@ -475,7 +508,9 @@ class Database: # h_stylekey = date_nhands_ago needs array by player here ... query = 'get_stats_from_hand_aggregated' - subs = (hand, hero_id, stylekey, agg_bb_mult, agg_bb_mult, hero_id, h_stylekey, h_agg_bb_mult, h_agg_bb_mult) + subs = (hand + ,hero_id, stylekey, agg_bb_mult, agg_bb_mult, seats_min, seats_max # hero params + ,hero_id, h_stylekey, h_agg_bb_mult, h_agg_bb_mult, h_seats_min, h_seats_max) # villain params #print "get stats: hud style =", hud_style, "query =", query, "subs =", subs c = self.connection.cursor() @@ -495,12 +530,15 @@ class Database: return stat_dict # uses query on handsplayers instead of hudcache to get stats on just this session - def get_stats_from_hand_session(self, hand, stat_dict, hero_id, hud_style, h_hud_style): + def get_stats_from_hand_session(self, hand, stat_dict, hero_id + ,hud_style, seats_min, seats_max + ,h_hud_style, h_seats_min, h_seats_max): """Get stats for just this session (currently defined as any play in the last 24 hours - to be improved at some point ...) h_hud_style and hud_style params indicate whether to get stats for hero and/or others - only fetch heros stats if h_hud_style == 'S', and only fetch others stats if hud_style == 'S' + seats_min/max params give seats limits, only include stats if between these values """ query = self.sql.query['get_stats_from_hand_session'] @@ -509,7 +547,8 @@ class Database: else: query = query.replace("", '') - subs = (self.hand_1day_ago, hand) + subs = (self.hand_1day_ago, hand, hero_id, seats_min, seats_max + , hero_id, h_seats_min, h_seats_max) c = self.get_cursor() # now get the stats @@ -524,6 +563,7 @@ class Database: # Loop through stats adding them to appropriate stat_dict: while row: playerid = row[0] + seats = row[1] if (playerid == hero_id and h_hud_style == 'S') or (playerid != hero_id and hud_style == 'S'): for name, val in zip(colnames, row): if not playerid in stat_dict: @@ -535,7 +575,7 @@ class Database: stat_dict[playerid][name.lower()] += val n += 1 if n >= 10000: break # todo: don't think this is needed so set nice and high - # for now - comment out or remove? + # prevents infinite loop so leave for now - comment out or remove? row = c.fetchone() else: log.error("ERROR: query %s result does not have player_id as first column" % (query,)) @@ -2721,7 +2761,9 @@ if __name__=="__main__": # db_connection = Database(c, 'PTrackSv2', 'razz') # mysql razz # db_connection = Database(c, 'ptracks', 'razz') # postgres print "database connection object = ", db_connection.connection - db_connection.recreate_tables() + # db_connection.recreate_tables() + db_connection.dropAllIndexes() + db_connection.createAllIndexes() h = db_connection.get_last_hand() print "last hand = ", h diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py index 7965f0b5..becaaa76 100755 --- a/pyfpdb/HUD_main.py +++ b/pyfpdb/HUD_main.py @@ -196,7 +196,7 @@ class HUD_main(object): # get basic info about the new hand from the db # if there is a db error, complain, skip hand, and proceed try: - (table_name, max, poker_game, type, site_id, site_name, tour_number, tab_number) = \ + (table_name, max, poker_game, type, site_id, site_name, num_seats, tour_number, tab_number) = \ self.db_connection.get_table_info(new_hand_id) except Exception, err: print "db error: skipping %s" % new_hand_id @@ -213,7 +213,8 @@ class HUD_main(object): # get stats using hud's specific params and get cards self.db_connection.init_hud_stat_vars( self.hud_dict[temp_key].hud_params['hud_days'] , self.hud_dict[temp_key].hud_params['h_hud_days']) - stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_dict[temp_key].hud_params, self.hero_ids[site_id]) + stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_dict[temp_key].hud_params + ,self.hero_ids[site_id], num_seats) self.hud_dict[temp_key].stat_dict = stat_dict cards = self.db_connection.get_cards(new_hand_id) comm_cards = self.db_connection.get_common_cards(new_hand_id) @@ -227,7 +228,8 @@ class HUD_main(object): else: # get stats using default params--also get cards self.db_connection.init_hud_stat_vars( self.hud_params['hud_days'], self.hud_params['h_hud_days'] ) - stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_params, self.hero_ids[site_id]) + stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_params + ,self.hero_ids[site_id], num_seats) cards = self.db_connection.get_cards(new_hand_id) comm_cards = self.db_connection.get_common_cards(new_hand_id) if comm_cards != {}: # stud! diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 9c74e1f1..d98d9fbe 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -1402,6 +1402,7 @@ class Sql: AND gt1.bigblind <= gt2.bigblind * %s /* bigblind similar size */ AND gt1.bigblind >= gt2.bigblind / %s AND gt2.id = h.gametypeId) + AND hc.activeSeats between %s and %s ) OR ( hp.playerId = %s @@ -1415,6 +1416,7 @@ class Sql: AND gt1.bigblind <= gt2.bigblind * %s /* bigblind similar size */ AND gt1.bigblind >= gt2.bigblind / %s AND gt2.id = h.gametypeId) + AND hc.activeSeats between %s and %s ) ) GROUP BY hc.PlayerId, p.name @@ -1432,11 +1434,11 @@ class Sql: if db_server == 'mysql': self.query['get_stats_from_hand_session'] = """ - SELECT hp.playerId AS player_id, + SELECT hp.playerId AS player_id, /* playerId and seats must */ + h.seats AS seats, /* be first and second field */ hp.handId AS hand_id, hp.seatNo AS seat, p.name AS screen_name, - h.seats AS seats, 1 AS n, cast(hp2.street0VPI as integer) AS vpip, cast(hp2.street0Aggr as integer) AS pfr, @@ -1494,21 +1496,30 @@ class Sql: cast(hp2.street4CheckCallRaiseChance as integer) AS ccr_opp_4, cast(hp2.street4CheckCallRaiseDone as integer) AS ccr_4 FROM - Hands h /* players in this hand */ + Hands h INNER JOIN Hands h2 ON (h2.id > %s AND h2.tableName = h.tableName) - INNER JOIN HandsPlayers hp ON (h.id = hp.handId) + INNER JOIN HandsPlayers hp ON (h.id = hp.handId) /* players in this hand */ INNER JOIN HandsPlayers hp2 ON (hp2.playerId+0 = hp.playerId+0 AND (hp2.handId = h2.id+0)) /* other hands by these players */ INNER JOIN Players p ON (p.id = hp2.PlayerId+0) WHERE hp.handId = %s /* check activeseats once this data returned (don't want to do that here as it might assume a session ended just because the number of seats dipped for a few hands) */ + AND ( /* 2 separate parts for hero and opponents */ + ( hp2.playerId != %s + AND h2.seats between %s and %s + ) + OR + ( hp2.playerId = %s + AND h2.seats between %s and %s + ) + ) ORDER BY h.handStart desc, hp2.PlayerId /* order rows by handstart descending so that we can stop reading rows when there's a gap over X minutes between hands (ie. when we get back to start of the session */ """ - else: # assume postgresql + elif db_server == 'postgresql': self.query['get_stats_from_hand_session'] = """ SELECT hp.playerId AS player_id, hp.handId AS hand_id, @@ -1582,6 +1593,103 @@ class Sql: /* check activeseats once this data returned (don't want to do that here as it might assume a session ended just because the number of seats dipped for a few hands) */ + AND ( /* 2 separate parts for hero and opponents */ + ( hp2.playerId != %s + AND h2.seats between %s and %s + ) + OR + ( hp2.playerId = %s + AND h2.seats between %s and %s + ) + ) + ORDER BY h.handStart desc, hp2.PlayerId + /* order rows by handstart descending so that we can stop reading rows when + there's a gap over X minutes between hands (ie. when we get back to start of + the session */ + """ + elif db_server == 'sqlite': + self.query['get_stats_from_hand_session'] = """ + SELECT hp.playerId AS player_id, + hp.handId AS hand_id, + hp.seatNo AS seat, + p.name AS screen_name, + h.seats AS seats, + 1 AS n, + cast(hp2.street0VPI as integer) AS vpip, + cast(hp2.street0Aggr as integer) AS pfr, + cast(hp2.street0_3BChance as integer) AS TB_opp_0, + cast(hp2.street0_3BDone as integer) AS TB_0, + cast(hp2.street1Seen as integer) AS saw_f, + cast(hp2.street1Seen as integer) AS saw_1, + cast(hp2.street2Seen as integer) AS saw_2, + cast(hp2.street3Seen as integer) AS saw_3, + cast(hp2.street4Seen as integer) AS saw_4, + cast(hp2.sawShowdown as integer) AS sd, + cast(hp2.street1Aggr as integer) AS aggr_1, + cast(hp2.street2Aggr as integer) AS aggr_2, + cast(hp2.street3Aggr as integer) AS aggr_3, + cast(hp2.street4Aggr as integer) AS aggr_4, + cast(hp2.otherRaisedStreet1 as integer) AS was_raised_1, + cast(hp2.otherRaisedStreet2 as integer) AS was_raised_2, + cast(hp2.otherRaisedStreet3 as integer) AS was_raised_3, + cast(hp2.otherRaisedStreet4 as integer) AS was_raised_4, + cast(hp2.foldToOtherRaisedStreet1 as integer) AS f_freq_1, + cast(hp2.foldToOtherRaisedStreet2 as integer) AS f_freq_2, + cast(hp2.foldToOtherRaisedStreet3 as integer) AS f_freq_3, + cast(hp2.foldToOtherRaisedStreet4 as integer) AS f_freq_4, + cast(hp2.wonWhenSeenStreet1 as integer) AS w_w_s_1, + cast(hp2.wonAtSD as integer) AS wmsd, + cast(hp2.stealAttemptChance as integer) AS steal_opp, + cast(hp2.stealAttempted as integer) AS steal, + cast(hp2.foldSbToStealChance as integer) AS SBstolen, + cast(hp2.foldedSbToSteal as integer) AS SBnotDef, + cast(hp2.foldBbToStealChance as integer) AS BBstolen, + cast(hp2.foldedBbToSteal as integer) AS BBnotDef, + cast(hp2.street1CBChance as integer) AS CB_opp_1, + cast(hp2.street1CBDone as integer) AS CB_1, + cast(hp2.street2CBChance as integer) AS CB_opp_2, + cast(hp2.street2CBDone as integer) AS CB_2, + cast(hp2.street3CBChance as integer) AS CB_opp_3, + cast(hp2.street3CBDone as integer) AS CB_3, + cast(hp2.street4CBChance as integer) AS CB_opp_4, + cast(hp2.street4CBDone as integer) AS CB_4, + cast(hp2.foldToStreet1CBChance as integer) AS f_cb_opp_1, + cast(hp2.foldToStreet1CBDone as integer) AS f_cb_1, + cast(hp2.foldToStreet2CBChance as integer) AS f_cb_opp_2, + cast(hp2.foldToStreet2CBDone as integer) AS f_cb_2, + cast(hp2.foldToStreet3CBChance as integer) AS f_cb_opp_3, + cast(hp2.foldToStreet3CBDone as integer) AS f_cb_3, + cast(hp2.foldToStreet4CBChance as integer) AS f_cb_opp_4, + cast(hp2.foldToStreet4CBDone as integer) AS f_cb_4, + cast(hp2.totalProfit as integer) AS net, + cast(hp2.street1CheckCallRaiseChance as integer) AS ccr_opp_1, + cast(hp2.street1CheckCallRaiseDone as integer) AS ccr_1, + cast(hp2.street2CheckCallRaiseChance as integer) AS ccr_opp_2, + cast(hp2.street2CheckCallRaiseDone as integer) AS ccr_2, + cast(hp2.street3CheckCallRaiseChance as integer) AS ccr_opp_3, + cast(hp2.street3CheckCallRaiseDone as integer) AS ccr_3, + cast(hp2.street4CheckCallRaiseChance as integer) AS ccr_opp_4, + cast(hp2.street4CheckCallRaiseDone as integer) AS ccr_4 + FROM Hands h /* this hand */ + INNER JOIN Hands h2 ON ( h2.id > %s /* other hands */ + AND h2.tableName = h.tableName) + INNER JOIN HandsPlayers hp ON (h.id = hp.handId) /* players in this hand */ + INNER JOIN HandsPlayers hp2 ON ( hp2.playerId+0 = hp.playerId+0 + AND hp2.handId = h2.id) /* other hands by these players */ + INNER JOIN Players p ON (p.id = hp2.PlayerId+0) + WHERE h.id = %s + /* check activeseats once this data returned (don't want to do that here as it might + assume a session ended just because the number of seats dipped for a few hands) + */ + AND ( /* 2 separate parts for hero and opponents */ + ( hp2.playerId != %s + AND h2.seats between %s and %s + ) + OR + ( hp2.playerId = %s + AND h2.seats between %s and %s + ) + ) ORDER BY h.handStart desc, hp2.PlayerId /* order rows by handstart descending so that we can stop reading rows when there's a gap over X minutes between hands (ie. when we get back to start of @@ -1605,10 +1713,13 @@ class Sql: self.query['get_table_name'] = """ SELECT h.tableName, h.maxSeats, gt.category, gt.type, s.id, s.name - FROM Hands h, Gametypes gt, Sites s + , count(1) as numseats + FROM Hands h, Gametypes gt, Sites s, HandsPlayers hp WHERE h.id = %s AND gt.id = h.gametypeId AND s.id = gt.siteID + AND hp.handId = h.id + GROUP BY h.tableName, h.maxSeats, gt.category, gt.type, s.id, s.name """ self.query['get_actual_seat'] = """ diff --git a/pyfpdb/TournamentTracker.py b/pyfpdb/TournamentTracker.py index 72be8494..e2dc724c 100644 --- a/pyfpdb/TournamentTracker.py +++ b/pyfpdb/TournamentTracker.py @@ -248,7 +248,7 @@ class ttracker_main(object): # get basic info about the new hand from the db # if there is a db error, complain, skip hand, and proceed try: - (table_name, max, poker_game, type, site_id) = self.db_connection.get_table_name(new_hand_id) + (table_name, max, poker_game, type, site_id, numseats) = self.db_connection.get_table_name(new_hand_id) stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, aggregate_stats[type] ,hud_style, agg_bb_mult)