From 8e0519708e1fa080b69c1c3825cea588459e4386 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Sun, 2 Aug 2009 13:00:55 +0100 Subject: [PATCH 1/4] fix bugs and move hud stat config to HUD_main.py so that GUI can set it --- pyfpdb/Database.py | 58 ++++++++++++++++++---------------------------- pyfpdb/HUD_main.py | 24 ++++++++++++++++--- pyfpdb/SQL.py | 12 ++++++---- 3 files changed, 51 insertions(+), 43 deletions(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index f9ebea39..841d96d4 100755 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -185,19 +185,6 @@ class Database: # config while trying out new hudcache mechanism self.use_date_in_hudcache = True - # To add to config: - self.hud_session_gap = 30 # Gap (minutes) between hands that indicates a change of session - # (hands every 2 mins for 1 hour = one session, if followed - # by a 40 minute gap and then more hands on same table that is - # a new session) - self.hud_style = 'A' # A=All-time - # S=Session - # T=timed (last n days) - # Future values may also include: - # H=Hands (last n hands) - self.hud_hands = 2000 # Max number of hands from each player to use for hud stats - self.hud_days = 30 # Max number of days from each player to use for hud stats - #self.hud_hero_style = 'T' # Duplicate set of vars just for hero - not used yet. #self.hud_hero_hands = 2000 # Idea is that you might want all-time stats for others #self.hud_hero_days = 30 # but last T days or last H hands for yourself @@ -341,7 +328,7 @@ class Database: winners[row[0]] = row[1] return winners - def init_hud_stat_vars(self): + def init_hud_stat_vars(self, hud_days): """Initialise variables used by Hud to fetch stats.""" try: @@ -355,7 +342,7 @@ class Database: #print "hand 1day ago =", self.hand_1day_ago # self.date_ndays_ago used if hud_style = 'T' - d = timedelta(days=self.hud_days) + d = timedelta(days=hud_days) now = datetime.utcnow() - d self.date_ndays_ago = "d%02d%02d%02d" % (now.year-2000, now.month, now.day) except: @@ -380,24 +367,28 @@ class Database: err = traceback.extract_tb(sys.exc_info()[2])[-1] print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) - def get_stats_from_hand(self, hand, aggregate = False): - if self.hud_style == 'S': + def get_stats_from_hand(self, hand, aggregate = False, hud_style = 'A', agg_bb_mult = 100): + if hud_style == 'S': + return( self.get_stats_from_hand_session(hand) ) - else: # self.hud_style == A + + else: # hud_style == A + + if hud_style == 'T': + stylekey = self.date_ndays_ago + #elif hud_style == 'H': + # stylekey = date_nhands_ago needs array by player here ... + else: # assume A (all-time) + stylekey = '0000000' # all stylekey values should be higher than this + if aggregate: query = 'get_stats_from_hand_aggregated' + subs = (hand, stylekey, agg_bb_mult, agg_bb_mult) else: query = 'get_stats_from_hand' - - if self.hud_style == 'T': - stylekey = self.date_ndays_ago - #elif self.hud_style == 'H': - # stylekey = self.date_nhands_ago needs array by player here ... - else: # assume A (all-time) - stylekey = '0000000' # all stylekey values should be higher than this + subs = (hand, stylekey) - subs = (hand, stylekey) - #print "get stats: hud style =", self.hud_style, "query =", query, "subs =", subs + #print "get stats: hud style =", hud_style, "query =", query, "subs =", subs c = self.connection.cursor() # now get the stats @@ -416,14 +407,11 @@ class Database: # uses query on handsplayers instead of hudcache to get stats on just this session def get_stats_from_hand_session(self, hand): - if self.hud_style == 'S': - query = self.sql.query['get_stats_from_hand_session'] - if self.db_server == 'mysql': - query = query.replace("", 'signed ') - else: - query = query.replace("", '') - else: # self.hud_style == A - return None + query = self.sql.query['get_stats_from_hand_session'] + if self.db_server == 'mysql': + query = query.replace("", 'signed ') + else: + query = query.replace("", '') subs = (self.hand_1day_ago, hand) c = self.get_cursor() diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py index b65a73b1..b240b64c 100755 --- a/pyfpdb/HUD_main.py +++ b/pyfpdb/HUD_main.py @@ -56,7 +56,23 @@ import Database import Tables import Hud -aggregate_stats = {"ring": True, "tour": False} # config file! +# To add to config: +aggregate_stats = {"ring": False, "tour": False} # uses agg_bb_mult +hud_style = 'A' # A=All-time + # S=Session + # T=timed (last n days - set hud_days to required value) + # Future values may also include: + # H=Hands (last n hands) +hud_days = 90 # Max number of days from each player to use for hud stats +agg_bb_mult = 100 # 1 = no aggregation. When aggregating stats across levels larger blinds + # must be < (agg_bb_mult * smaller blinds) to be aggregated + # ie. 100 will aggregate almost everything, 2 will probably agg just the + # next higher and lower levels into the current one, try 3/10/30/100 +hud_session_gap = 30 # Gap (minutes) between hands that indicates a change of session + # (hands every 2 mins for 1 hour = one session, if followed + # by a 40 minute gap and then more hands on same table that is + # a new session) +#hud_hands = 0 # Max number of hands from each player to use for hud stats (not used) class HUD_main(object): """A main() object to own both the read_stdin thread and the gui.""" @@ -145,7 +161,7 @@ class HUD_main(object): # need their own access to the database, but should open their own # if it is required. self.db_connection = Database.Database(self.config, self.db_name, 'temp') - self.db_connection.init_hud_stat_vars() + self.db_connection.init_hud_stat_vars(hud_days) tourny_finder = re.compile('(\d+) (\d+)') while 1: # wait for a new hand number on stdin @@ -158,7 +174,9 @@ class HUD_main(object): # if there is a db error, complain, skip hand, and proceed try: (table_name, max, poker_game, type) = self.db_connection.get_table_name(new_hand_id) - stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, aggregate = aggregate_stats[type]) + stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, aggregate_stats[type] + ,hud_style, agg_bb_mult) + 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 87242a8b..1f109475 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -1172,12 +1172,14 @@ class Sql: */ AND hc.gametypeId+0 in (SELECT gt1.id from Gametypes gt1, Gametypes gt2 - WHERE gt1.siteid = gt2.siteid - AND gt1.type = gt2.type - AND gt1.category = gt2.category - AND gt1.limittype = gt2.limittype + WHERE gt1.siteid = gt2.siteid /* find gametypes where these match: */ + AND gt1.type = gt2.type /* ring/tourney */ + AND gt1.category = gt2.category /* holdem/stud*/ + AND gt1.limittype = gt2.limittype /* fl/nl */ + AND gt1.bigblind < gt2.bigblind * %s /* bigblind similar size */ + AND gt1.bigblind > gt2.bigblind / %s AND gt2.id = h.gametypeId) - GROUP BY hc.PlayerId, p.name, hc.styleKey + GROUP BY hc.PlayerId, p.name """ if db_server == 'mysql': From 745baf139f7d8b968dae0e2a02603608abab6d4c Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Mon, 3 Aug 2009 01:30:51 +0100 Subject: [PATCH 2/4] Sorry guys. Added some error checking and discovered a bug in the mysql index creation - I've fixed it and imports don't degrade anything like they used to now. I've just imported 15K hands at 20+/second when it used to be down at 5/sec after 10K hands or so. --- pyfpdb/Database.py | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 15c59c16..a7be2e10 100755 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -733,8 +733,8 @@ class Database: if self.backend == self.MYSQL_INNODB: print "creating mysql index ", idx['tab'], idx['col'] try: - c.execute( "alter table %s add index %s(%s)" - , (idx['tab'],idx['col'],idx['col']) ) + s = "alter table %s add index %s(%s)" % (idx['tab'],idx['col'],idx['col']) + c.execute(s) except: print " create fk failed: " + str(sys.exc_info()) elif self.backend == self.PGSQL: @@ -742,9 +742,8 @@ class Database: # mod to use tab_col for index name? print "creating pg index ", idx['tab'], idx['col'] try: - print "create index %s_%s_idx on %s(%s)" % (idx['tab'], idx['col'], idx['tab'], idx['col']) - c.execute( "create index %s_%s_idx on %s(%s)" - % (idx['tab'], idx['col'], idx['tab'], idx['col']) ) + s = "create index %s_%s_idx on %s(%s)" % (idx['tab'], idx['col'], idx['tab'], idx['col']) + c.execute(s) except: print " create index failed: " + str(sys.exc_info()) else: @@ -859,20 +858,18 @@ class Database: if self.backend == self.MYSQL_INNODB: print "creating mysql index ", idx['tab'], idx['col'] try: - self.get_cursor().execute( "alter table %s add index %s(%s)" - , (idx['tab'],idx['col'],idx['col']) ) + s = "create index %s on %s(%s)" % (idx['col'],idx['tab'],idx['col']) + self.get_cursor().execute(s) except: - pass + print " create idx failed: " + str(sys.exc_info()) elif self.backend == self.PGSQL: # mod to use tab_col for index name? print "creating pg index ", idx['tab'], idx['col'] try: - print "create index %s_%s_idx on %s(%s)" % (idx['tab'], idx['col'], idx['tab'], idx['col']) - self.get_cursor().execute( "create index %s_%s_idx on %s(%s)" - % (idx['tab'], idx['col'], idx['tab'], idx['col']) ) + s = "create index %s_%s_idx on %s(%s)" % (idx['tab'], idx['col'], idx['tab'], idx['col']) + self.get_cursor().execute(s) except: - print " ERROR! :-(" - pass + print " create idx failed: " + str(sys.exc_info()) else: print "Only MySQL and Postgres supported so far" return -1 From bbf02c7ee3ae4ccb44fd70aab52a4cb3e7e29c68 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 2 Aug 2009 23:50:44 -0400 Subject: [PATCH 3/4] Added correct cp1252 symbols for Euros and GBP. --- pyfpdb/PokerStarsToFpdb.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyfpdb/PokerStarsToFpdb.py b/pyfpdb/PokerStarsToFpdb.py index 7f746e9e..fcfecb84 100755 --- a/pyfpdb/PokerStarsToFpdb.py +++ b/pyfpdb/PokerStarsToFpdb.py @@ -30,10 +30,10 @@ class PokerStars(HandHistoryConverter): # Class Variables mixes = { 'HORSE': 'horse', '8-Game': '8game', 'HOSE': 'hose'} # Legal mixed games - sym = {'USD': "\$", 'CAD': "\$", 'T$': ""} # ADD Euro, Sterling, etc HERE + sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\x80", "GBP": "\xa3"} # ADD Euro, Sterling, etc HERE substitutions = { 'LEGAL_ISO' : "USD|EUR|GBP|CAD", # legal ISO currency codes - 'LS' : "\$" # legal currency symbols ADD Euro, Sterling, etc HERE + 'LS' : "\$|\x80|\xa3" # legal currency symbols ADD Euro, Sterling, etc HERE } # Static regexes @@ -50,7 +50,7 @@ class PokerStars(HandHistoryConverter): (-\sLevel\s(?P[IVXLC]+)\s)? \(? # open paren of the stakes (?P%(LS)s|)? - (?P[.0-9]+)/%(LS)s? + (?P[.0-9]+)/(%(LS)s)? (?P[.0-9]+) \s?(?P%(LEGAL_ISO)s)? \)\s-\s # close paren of the stakes @@ -60,7 +60,7 @@ class PokerStars(HandHistoryConverter): re_PlayerInfo = re.compile(""" ^Seat\s(?P[0-9]+):\s (?P.*)\s - \(%(LS)s?(?P[.0-9]+)\sin\schips\)""" % substitutions, + \((%(LS)s)?(?P[.0-9]+)\sin\schips\)""" % substitutions, re.MULTILINE|re.VERBOSE) re_HandInfo = re.compile(""" From 5a94f16d16abe9b6dd6c9916dffeeb4b58d0d5e8 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Mon, 3 Aug 2009 19:15:36 +0100 Subject: [PATCH 4/4] fix typo in column name --- pyfpdb/Database.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index a7be2e10..bf3e20dd 100755 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -68,7 +68,7 @@ class Database: , {'tab':'Hands', 'col':'gametypeId', 'drop':0} # mct 22/3/09 , {'tab':'HandsPlayers', 'col':'handId', 'drop':0} # not needed, handled by fk , {'tab':'HandsPlayers', 'col':'playerId', 'drop':0} # not needed, handled by fk - , {'tab':'HandsPlayers', 'col':'tourneysTypeId', 'drop':0} + , {'tab':'HandsPlayers', 'col':'tourneyTypeId', 'drop':0} , {'tab':'HandsPlayers', 'col':'tourneysPlayersId', 'drop':0} , {'tab':'Tourneys', 'col':'siteTourneyNo', 'drop':0} ]