Merge branch 'master' of git://git.assembla.com/fpdb-sql

This commit is contained in:
Ray 2009-08-03 13:13:18 -04:00
commit a6d1a41752
8 changed files with 260 additions and 155 deletions

View File

@ -182,57 +182,23 @@ class Database:
else: else:
self.sql = sql self.sql = sql
self.pcache = None # PlayerId cache
self.cachemiss = 0 # Delete me later - using to count player cache misses
# config while trying out new hudcache mechanism # config while trying out new hudcache mechanism
self.use_date_in_hudcache = True self.use_date_in_hudcache = True
# To add to config: #self.hud_hero_style = 'T' # Duplicate set of vars just for hero - not used yet.
self.hud_session_gap = 30 # Gap (minutes) between hands that indicates a change of session #self.hud_hero_hands = 2000 # Idea is that you might want all-time stats for others
# (hands every 2 mins for 1 hour = one session, if followed #self.hud_hero_days = 30 # but last T days or last H hands for yourself
# by a 40 minute gap and then more hands on same table that is
# a new session)
self.hud_style = 'T' # 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 # vars for hand ids or dates fetched according to above config:
self.hud_hero_hands = 2000 self.hand_1day_ago = 0 # max hand id more than 24 hrs earlier than now
self.hud_hero_days = 30 self.date_ndays_ago = 'd000000' # date N days ago ('d' + YYMMDD)
self.date_nhands_ago = {} # dates N hands ago per player - not used yet
self.cursor = self.fdb.cursor self.cursor = self.fdb.cursor
if self.fdb.wrongDbVersion == False:
# self.hand_1day_ago used to fetch stats for current session (i.e. if hud_style = 'S')
self.hand_1day_ago = 0
self.cursor.execute(self.sql.query['get_hand_1day_ago'])
row = self.cursor.fetchone()
if row and row[0]:
self.hand_1day_ago = row[0]
#print "hand 1day ago =", self.hand_1day_ago
# self.date_ndays_ago used if hud_style = 'T'
d = timedelta(days=self.hud_days)
now = datetime.utcnow() - d
self.date_ndays_ago = "d%02d%02d%02d" % (now.year-2000, now.month, now.day)
# self.hand_nhands_ago is used for fetching stats for last n hands (hud_style = 'H')
# This option not used yet
self.hand_nhands_ago = 0
# should use aggregated version of query if appropriate
self.cursor.execute(self.sql.query['get_hand_nhands_ago'], (self.hud_hands,self.hud_hands))
row = self.cursor.fetchone()
if row and row[0]:
self.hand_nhands_ago = row[0]
print "hand n hands ago =", self.hand_nhands_ago
#self.cursor.execute(self.sql.query['get_table_name'], (hand_id, ))
#row = self.cursor.fetchone()
else:
print "Bailing on DB query, not sure it exists yet"
self.saveActions = False if self.import_options['saveActions'] == False else True self.saveActions = False if self.import_options['saveActions'] == False else True
self.connection.rollback() # make sure any locks taken so far are released self.connection.rollback() # make sure any locks taken so far are released
@ -365,22 +331,67 @@ class Database:
winners[row[0]] = row[1] winners[row[0]] = row[1]
return winners return winners
def get_stats_from_hand(self, hand, aggregate = False): def init_hud_stat_vars(self, hud_days):
if self.hud_style == 'S': """Initialise variables used by Hud to fetch stats."""
return( self.get_stats_from_hand_session(hand) )
else: # self.hud_style == A
if aggregate:
query = 'get_stats_from_hand_aggregated'
else:
query = 'get_stats_from_hand'
if self.hud_style == 'T': try:
# self.hand_1day_ago used to fetch stats for current session (i.e. if hud_style = 'S')
self.hand_1day_ago = 1
c = self.get_cursor()
c.execute(self.sql.query['get_hand_1day_ago'])
row = c.fetchone()
if row and row[0]:
self.hand_1day_ago = row[0]
#print "hand 1day ago =", self.hand_1day_ago
# self.date_ndays_ago used if hud_style = 'T'
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:
err = traceback.extract_tb(sys.exc_info()[2])[-1]
print "***Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
def init_player_hud_stat_vars(self, playerid):
# not sure if this is workable, to be continued ...
try:
# self.date_nhands_ago is used for fetching stats for last n hands (hud_style = 'H')
# This option not used yet - needs to be called for each player :-(
self.date_nhands_ago[str(playerid)] = 'd000000'
# should use aggregated version of query if appropriate
c.execute(self.sql.query['get_date_nhands_ago'], (self.hud_hands, playerid))
row = c.fetchone()
if row and row[0]:
self.date_nhands_ago[str(playerid)] = row[0]
c.close()
print "date n hands ago = " + self.date_nhands_ago[str(playerid)] + "(playerid "+str(playerid)+")"
except:
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, hud_style = 'A', agg_bb_mult = 100):
if hud_style == 'S':
return( self.get_stats_from_hand_session(hand) )
else: # hud_style == A
if hud_style == 'T':
stylekey = self.date_ndays_ago stylekey = self.date_ndays_ago
#elif hud_style == 'H':
# stylekey = date_nhands_ago needs array by player here ...
else: # assume A (all-time) else: # assume A (all-time)
stylekey = '0000000' # all stylekey values should be higher than this stylekey = '0000000' # all stylekey values should be higher than this
subs = (hand, hand, stylekey) if aggregate:
#print "get stats: hud style =", self.hud_style, "subs =", subs query = 'get_stats_from_hand_aggregated'
subs = (hand, stylekey, agg_bb_mult, agg_bb_mult)
else:
query = 'get_stats_from_hand'
subs = (hand, stylekey)
#print "get stats: hud style =", hud_style, "query =", query, "subs =", subs
c = self.connection.cursor() c = self.connection.cursor()
# now get the stats # now get the stats
@ -399,17 +410,14 @@ class Database:
# uses query on handsplayers instead of hudcache to get stats on just this session # uses query on handsplayers instead of hudcache to get stats on just this session
def get_stats_from_hand_session(self, hand): def get_stats_from_hand_session(self, hand):
if self.hud_style == 'S':
query = self.sql.query['get_stats_from_hand_session'] query = self.sql.query['get_stats_from_hand_session']
if self.db_server == 'mysql': if self.db_server == 'mysql':
query = query.replace("<signed>", 'signed ') query = query.replace("<signed>", 'signed ')
else: else:
query = query.replace("<signed>", '') query = query.replace("<signed>", '')
else: # self.hud_style == A
return None
subs = (self.hand_1day_ago, hand) subs = (self.hand_1day_ago, hand)
c = self.connection.cursor() c = self.get_cursor()
# now get the stats # now get the stats
#print "sess_stats: subs =", subs, "subs[0] =", subs[0] #print "sess_stats: subs =", subs, "subs[0] =", subs[0]
@ -725,8 +733,8 @@ class Database:
if self.backend == self.MYSQL_INNODB: if self.backend == self.MYSQL_INNODB:
print "creating mysql index ", idx['tab'], idx['col'] print "creating mysql index ", idx['tab'], idx['col']
try: try:
c.execute( "alter table %s add index %s(%s)" s = "alter table %s add index %s(%s)" % (idx['tab'],idx['col'],idx['col'])
, (idx['tab'],idx['col'],idx['col']) ) c.execute(s)
except: except:
print " create fk failed: " + str(sys.exc_info()) print " create fk failed: " + str(sys.exc_info())
elif self.backend == self.PGSQL: elif self.backend == self.PGSQL:
@ -734,9 +742,8 @@ class Database:
# mod to use tab_col for index name? # mod to use tab_col for index name?
print "creating pg index ", idx['tab'], idx['col'] print "creating pg index ", idx['tab'], idx['col']
try: try:
print "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( "create index %s_%s_idx on %s(%s)" c.execute(s)
% (idx['tab'], idx['col'], idx['tab'], idx['col']) )
except: except:
print " create index failed: " + str(sys.exc_info()) print " create index failed: " + str(sys.exc_info())
else: else:
@ -851,20 +858,18 @@ class Database:
if self.backend == self.MYSQL_INNODB: if self.backend == self.MYSQL_INNODB:
print "creating mysql index ", idx['tab'], idx['col'] print "creating mysql index ", idx['tab'], idx['col']
try: try:
self.get_cursor().execute( "alter table %s add index %s(%s)" s = "create index %s on %s(%s)" % (idx['col'],idx['tab'],idx['col'])
, (idx['tab'],idx['col'],idx['col']) ) self.get_cursor().execute(s)
except: except:
pass print " create idx failed: " + str(sys.exc_info())
elif self.backend == self.PGSQL: elif self.backend == self.PGSQL:
# mod to use tab_col for index name? # mod to use tab_col for index name?
print "creating pg index ", idx['tab'], idx['col'] print "creating pg index ", idx['tab'], idx['col']
try: try:
print "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( "create index %s_%s_idx on %s(%s)" self.get_cursor().execute(s)
% (idx['tab'], idx['col'], idx['tab'], idx['col']) )
except: except:
print " ERROR! :-(" print " create idx failed: " + str(sys.exc_info())
pass
else: else:
print "Only MySQL and Postgres supported so far" print "Only MySQL and Postgres supported so far"
return -1 return -1
@ -964,6 +969,30 @@ class Database:
print "Error during fdb.lock_for_insert:", str(sys.exc_value) print "Error during fdb.lock_for_insert:", str(sys.exc_value)
#end def lock_for_insert #end def lock_for_insert
def getSqlPlayerIDs(self, pnames, siteid):
result = {}
if(self.pcache == None):
self.pcache = LambdaDict(lambda key:self.insertPlayer(key, siteid))
for player in pnames:
result[player] = self.pcache[player]
return result
def insertPlayer(self, name, site_id):
self.cachemiss += 1
result = None
c = self.get_cursor()
c.execute ("SELECT id FROM Players WHERE name=%s", (name,))
tmp=c.fetchall()
if (len(tmp)==0): #new player
c.execute ("INSERT INTO Players (name, siteId) VALUES (%s, %s)", (name, site_id))
c.execute ("SELECT id FROM Players WHERE name=%s", (name,))
tmp=c.fetchall()
#print "recognisePlayerIDs, names[i]:",names[i],"tmp:",tmp
print "DEBUG: cache misses: %s" %self.cachemiss
return tmp[0][0]
def store_the_hand(self, h): def store_the_hand(self, h):
"""Take a HandToWrite object and store it in the db""" """Take a HandToWrite object and store it in the db"""
@ -1780,3 +1809,17 @@ if __name__=="__main__":
print "press enter to continue" print "press enter to continue"
sys.stdin.readline() sys.stdin.readline()
#Code borrowed from http://push.cx/2008/caching-dictionaries-in-python-vs-ruby
class LambdaDict(dict):
def __init__(self, l):
super(LambdaDict, self).__init__()
self.l = l
def __getitem__(self, key):
if key in self:
return self.get(key)
else:
self.__setitem__(key, self.l(key))
return self.get(key)

View File

@ -31,10 +31,11 @@ import Configuration
import string import string
class GuiAutoImport (threading.Thread): class GuiAutoImport (threading.Thread):
def __init__(self, settings, config): def __init__(self, settings, config, sql):
"""Constructor for GuiAutoImport""" """Constructor for GuiAutoImport"""
self.settings=settings self.settings=settings
self.config=config self.config=config
self.sql = sql
imp = self.config.get_import_parameters() imp = self.config.get_import_parameters()
@ -44,7 +45,7 @@ class GuiAutoImport (threading.Thread):
self.input_settings = {} self.input_settings = {}
self.pipe_to_hud = None self.pipe_to_hud = None
self.importer = fpdb_import.Importer(self,self.settings, self.config) self.importer = fpdb_import.Importer(self, self.settings, self.config, self.sql)
self.importer.setCallHud(True) self.importer.setCallHud(True)
self.importer.setMinPrint(settings['minPrint']) self.importer.setMinPrint(settings['minPrint'])
self.importer.setQuiet(False) self.importer.setQuiet(False)

View File

@ -210,7 +210,7 @@
<game cols="3" db="fpdb" game_name="holdem" rows="2" aux="mucked"> <game cols="3" db="fpdb" game_name="holdem" rows="2" aux="mucked">
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat> <stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat> <stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat> <stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat> <stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat> <stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat> <stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
@ -219,7 +219,7 @@
<game cols="3" db="fpdb" game_name="razz" rows="2" aux="stud_mucked"> <game cols="3" db="fpdb" game_name="razz" rows="2" aux="stud_mucked">
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat> <stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat> <stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat> <stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat> <stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat> <stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat> <stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
@ -228,7 +228,7 @@
<game cols="3" db="fpdb" game_name="omahahi" rows="2" aux="mucked"> <game cols="3" db="fpdb" game_name="omahahi" rows="2" aux="mucked">
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat> <stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat> <stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat> <stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat> <stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat> <stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat> <stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
@ -237,7 +237,7 @@
<game cols="3" db="fpdb" game_name="omahahilo" rows="2" aux="mucked"> <game cols="3" db="fpdb" game_name="omahahilo" rows="2" aux="mucked">
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat> <stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat> <stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat> <stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat> <stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat> <stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat> <stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
@ -246,7 +246,7 @@
<game cols="3" db="fpdb" game_name="studhi" rows="2" aux="stud_mucked"> <game cols="3" db="fpdb" game_name="studhi" rows="2" aux="stud_mucked">
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat> <stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat> <stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat> <stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat> <stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat> <stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat> <stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
@ -255,7 +255,7 @@
<game cols="3" db="fpdb" game_name="studhilo" rows="2" aux="stud_mucked"> <game cols="3" db="fpdb" game_name="studhilo" rows="2" aux="stud_mucked">
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat> <stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat> <stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq_1" tip="tip1"> </stat> <stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat> <stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat> <stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat> <stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
@ -274,18 +274,18 @@
<pu_stat pu_stat_name="wmsd"> </pu_stat> <pu_stat pu_stat_name="wmsd"> </pu_stat>
<pu_stat pu_stat_name="wtsd"> </pu_stat> <pu_stat pu_stat_name="wtsd"> </pu_stat>
<pu_stat pu_stat_name="WMsF"> </pu_stat> <pu_stat pu_stat_name="WMsF"> </pu_stat>
<pu_stat pu_stat_name="a_freq_1"> </pu_stat> <pu_stat pu_stat_name="a_freq1"> </pu_stat>
<pu_stat pu_stat_name="a_freq_2"> </pu_stat> <pu_stat pu_stat_name="a_freq2"> </pu_stat>
<pu_stat pu_stat_name="a_freq_3"> </pu_stat> <pu_stat pu_stat_name="a_freq3"> </pu_stat>
<pu_stat pu_stat_name="a_freq_4"> </pu_stat> <pu_stat pu_stat_name="a_freq4"> </pu_stat>
<pu_stat pu_stat_name="cb_1"> </pu_stat> <pu_stat pu_stat_name="cb1"> </pu_stat>
<pu_stat pu_stat_name="cb_2"> </pu_stat> <pu_stat pu_stat_name="cb2"> </pu_stat>
<pu_stat pu_stat_name="cb_3"> </pu_stat> <pu_stat pu_stat_name="cb3"> </pu_stat>
<pu_stat pu_stat_name="cb_4"> </pu_stat> <pu_stat pu_stat_name="cb4"> </pu_stat>
<pu_stat pu_stat_name="ffreq_1"> </pu_stat> <pu_stat pu_stat_name="ffreq1"> </pu_stat>
<pu_stat pu_stat_name="ffreq_2"> </pu_stat> <pu_stat pu_stat_name="ffreq2"> </pu_stat>
<pu_stat pu_stat_name="ffreq_3"> </pu_stat> <pu_stat pu_stat_name="ffreq3"> </pu_stat>
<pu_stat pu_stat_name="ffreq_4"> </pu_stat> <pu_stat pu_stat_name="ffreq4"> </pu_stat>
</pu> </pu>
</popup_windows> </popup_windows>

View File

@ -31,6 +31,7 @@ Main for FreePokerTools HUD.
import sys import sys
import os import os
import Options import Options
import traceback
(options, sys.argv) = Options.fpdb_options() (options, sys.argv) = Options.fpdb_options()
@ -55,7 +56,23 @@ import Database
import Tables import Tables
import Hud import Hud
aggregate_stats = {"ring": False, "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): class HUD_main(object):
"""A main() object to own both the read_stdin thread and the gui.""" """A main() object to own both the read_stdin thread and the gui."""
@ -144,6 +161,7 @@ class HUD_main(object):
# need their own access to the database, but should open their own # need their own access to the database, but should open their own
# if it is required. # if it is required.
self.db_connection = Database.Database(self.config, self.db_name, 'temp') self.db_connection = Database.Database(self.config, self.db_name, 'temp')
self.db_connection.init_hud_stat_vars(hud_days)
tourny_finder = re.compile('(\d+) (\d+)') tourny_finder = re.compile('(\d+) (\d+)')
while 1: # wait for a new hand number on stdin while 1: # wait for a new hand number on stdin
@ -156,13 +174,16 @@ class HUD_main(object):
# if there is a db error, complain, skip hand, and proceed # if there is a db error, complain, skip hand, and proceed
try: try:
(table_name, max, poker_game, type) = self.db_connection.get_table_name(new_hand_id) (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) cards = self.db_connection.get_cards(new_hand_id)
comm_cards = self.db_connection.get_common_cards(new_hand_id) comm_cards = self.db_connection.get_common_cards(new_hand_id)
if comm_cards != {}: # stud! if comm_cards != {}: # stud!
cards['common'] = comm_cards['common'] cards['common'] = comm_cards['common']
except Exception, err: except Exception, err:
print "db error: skipping ", new_hand_id, err err = traceback.extract_tb(sys.exc_info()[2])[-1]
print "db error: skipping "+str(new_hand_id)+" "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
if new_hand_id: # new_hand_id is none if we had an error prior to the store if new_hand_id: # new_hand_id is none if we had an error prior to the store
sys.stderr.write("Database error %s in hand %d. Skipping.\n" % (err, int(new_hand_id))) sys.stderr.write("Database error %s in hand %d. Skipping.\n" % (err, int(new_hand_id)))
continue continue

View File

@ -40,10 +40,12 @@ class Hand(object):
LCS = {'H':'h', 'D':'d', 'C':'c', 'S':'s'} LCS = {'H':'h', 'D':'d', 'C':'c', 'S':'s'}
SYMBOL = {'USD': '$', 'EUR': u'$', 'T$': '', 'play': ''} SYMBOL = {'USD': '$', 'EUR': u'$', 'T$': '', 'play': ''}
MS = {'horse' : 'HORSE', '8game' : '8-Game', 'hose' : 'HOSE', 'ha': 'HA'} MS = {'horse' : 'HORSE', '8game' : '8-Game', 'hose' : 'HOSE', 'ha': 'HA'}
SITEIDS = {'Fulltilt':1, 'PokerStars':2, 'Everleaf':3, 'Win2day':4, 'OnGame':5, 'UltimateBet':6, 'Betfair':7}
def __init__(self, sitename, gametype, handText, builtFrom = "HHC"): def __init__(self, sitename, gametype, handText, builtFrom = "HHC"):
self.sitename = sitename self.sitename = sitename
self.siteId = self.SITEIDS[sitename]
self.stats = DerivedStats.DerivedStats(self) self.stats = DerivedStats.DerivedStats(self)
self.gametype = gametype self.gametype = gametype
self.starttime = 0 self.starttime = 0

View File

@ -167,9 +167,9 @@ class Sql:
################################ ################################
if db_server == 'mysql': if db_server == 'mysql':
self.query['list_tables'] = """SHOW TABLES""" self.query['list_tables'] = """SHOW TABLES"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['list_tables'] = """SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'""" self.query['list_tables'] = """SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"""
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['list_tables'] = """SELECT name FROM sqlite_master self.query['list_tables'] = """SELECT name FROM sqlite_master
WHERE type='table' WHERE type='table'
ORDER BY name;""" ORDER BY name;"""
@ -188,10 +188,10 @@ class Sql:
self.query['createSettingsTable'] = """CREATE TABLE Settings ( self.query['createSettingsTable'] = """CREATE TABLE Settings (
version SMALLINT NOT NULL) version SMALLINT NOT NULL)
ENGINE=INNODB""" ENGINE=INNODB"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['createSettingsTable'] = """CREATE TABLE Settings (version SMALLINT)""" self.query['createSettingsTable'] = """CREATE TABLE Settings (version SMALLINT)"""
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['createSettingsTable'] = """CREATE TABLE Settings self.query['createSettingsTable'] = """CREATE TABLE Settings
(version INTEGER) """ (version INTEGER) """
@ -206,12 +206,12 @@ class Sql:
name varchar(32) NOT NULL, name varchar(32) NOT NULL,
currency char(3) NOT NULL) currency char(3) NOT NULL)
ENGINE=INNODB""" ENGINE=INNODB"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['createSitesTable'] = """CREATE TABLE Sites ( self.query['createSitesTable'] = """CREATE TABLE Sites (
id SERIAL, PRIMARY KEY (id), id SERIAL, PRIMARY KEY (id),
name varchar(32), name varchar(32),
currency char(3))""" currency char(3))"""
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['createSitesTable'] = """CREATE TABLE Sites ( self.query['createSitesTable'] = """CREATE TABLE Sites (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
name TEXT NOT NULL, name TEXT NOT NULL,
@ -236,7 +236,7 @@ class Sql:
smallBet int NOT NULL, smallBet int NOT NULL,
bigBet int NOT NULL) bigBet int NOT NULL)
ENGINE=INNODB""" ENGINE=INNODB"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['createGametypesTable'] = """CREATE TABLE Gametypes ( self.query['createGametypesTable'] = """CREATE TABLE Gametypes (
id SERIAL, PRIMARY KEY (id), id SERIAL, PRIMARY KEY (id),
siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id), siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id),
@ -249,7 +249,7 @@ class Sql:
bigBlind int, bigBlind int,
smallBet int, smallBet int,
bigBet int)""" bigBet int)"""
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['createGametypesTable'] = """CREATE TABLE GameTypes ( self.query['createGametypesTable'] = """CREATE TABLE GameTypes (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
siteId INTEGER, siteId INTEGER,
@ -277,14 +277,14 @@ class Sql:
comment text, comment text,
commentTs DATETIME) commentTs DATETIME)
ENGINE=INNODB""" ENGINE=INNODB"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['createPlayersTable'] = """CREATE TABLE Players ( self.query['createPlayersTable'] = """CREATE TABLE Players (
id SERIAL, PRIMARY KEY (id), id SERIAL, PRIMARY KEY (id),
name VARCHAR(32), name VARCHAR(32),
siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id), siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id),
comment text, comment text,
commentTs timestamp without time zone)""" commentTs timestamp without time zone)"""
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['createPlayersTable'] = """CREATE TABLE Players ( self.query['createPlayersTable'] = """CREATE TABLE Players (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
name TEXT, name TEXT,
@ -308,7 +308,7 @@ class Sql:
ratingTime DATETIME NOT NULL, ratingTime DATETIME NOT NULL,
handCount int NOT NULL) handCount int NOT NULL)
ENGINE=INNODB""" ENGINE=INNODB"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['createAutoratesTable'] = """CREATE TABLE Autorates ( self.query['createAutoratesTable'] = """CREATE TABLE Autorates (
id BIGSERIAL, PRIMARY KEY (id), id BIGSERIAL, PRIMARY KEY (id),
playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id), playerId INT, FOREIGN KEY (playerId) REFERENCES Players(id),
@ -317,7 +317,7 @@ class Sql:
shortDesc char(8), shortDesc char(8),
ratingTime timestamp without time zone, ratingTime timestamp without time zone,
handCount int)""" handCount int)"""
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['createAutoratesTable'] = """ """ self.query['createAutoratesTable'] = """ """
@ -360,7 +360,7 @@ class Sql:
comment TEXT, comment TEXT,
commentTs DATETIME) commentTs DATETIME)
ENGINE=INNODB""" ENGINE=INNODB"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['createHandsTable'] = """CREATE TABLE Hands ( self.query['createHandsTable'] = """CREATE TABLE Hands (
id BIGSERIAL, PRIMARY KEY (id), id BIGSERIAL, PRIMARY KEY (id),
tableName VARCHAR(20) NOT NULL, tableName VARCHAR(20) NOT NULL,
@ -394,7 +394,7 @@ class Sql:
showdownPot INT, /* pot size at sd/street7 */ showdownPot INT, /* pot size at sd/street7 */
comment TEXT, comment TEXT,
commentTs timestamp without time zone)""" commentTs timestamp without time zone)"""
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['createHandsTable'] = """CREATE TABLE Hands ( self.query['createHandsTable'] = """CREATE TABLE Hands (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
tableName TEXT(20), tableName TEXT(20),
@ -422,7 +422,7 @@ class Sql:
knockout INT NOT NULL, knockout INT NOT NULL,
rebuyOrAddon BOOLEAN NOT NULL) rebuyOrAddon BOOLEAN NOT NULL)
ENGINE=INNODB""" ENGINE=INNODB"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes ( self.query['createTourneyTypesTable'] = """CREATE TABLE TourneyTypes (
id SERIAL, PRIMARY KEY (id), id SERIAL, PRIMARY KEY (id),
siteId INT, FOREIGN KEY (siteId) REFERENCES Sites(id), siteId INT, FOREIGN KEY (siteId) REFERENCES Sites(id),
@ -430,7 +430,7 @@ class Sql:
fee INT, fee INT,
knockout INT, knockout INT,
rebuyOrAddon BOOLEAN)""" rebuyOrAddon BOOLEAN)"""
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['createTourneyTypesTable'] = """ """ self.query['createTourneyTypesTable'] = """ """
@ -449,7 +449,7 @@ class Sql:
comment TEXT, comment TEXT,
commentTs DATETIME) commentTs DATETIME)
ENGINE=INNODB""" ENGINE=INNODB"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['createTourneysTable'] = """CREATE TABLE Tourneys ( self.query['createTourneysTable'] = """CREATE TABLE Tourneys (
id SERIAL, PRIMARY KEY (id), id SERIAL, PRIMARY KEY (id),
tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id), tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
@ -459,7 +459,7 @@ class Sql:
startTime timestamp without time zone, startTime timestamp without time zone,
comment TEXT, comment TEXT,
commentTs timestamp without time zone)""" commentTs timestamp without time zone)"""
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['createTourneysTable'] = """CREATE TABLE TourneyTypes ( self.query['createTourneysTable'] = """CREATE TABLE TourneyTypes (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
siteId INTEGER, siteId INTEGER,
@ -591,7 +591,7 @@ class Sql:
FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id)) FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id))
ENGINE=INNODB""" ENGINE=INNODB"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['createHandsPlayersTable'] = """CREATE TABLE HandsPlayers ( self.query['createHandsPlayersTable'] = """CREATE TABLE HandsPlayers (
id BIGSERIAL, PRIMARY KEY (id), id BIGSERIAL, PRIMARY KEY (id),
handId BIGINT NOT NULL, FOREIGN KEY (handId) REFERENCES Hands(id), handId BIGINT NOT NULL, FOREIGN KEY (handId) REFERENCES Hands(id),
@ -708,7 +708,7 @@ class Sql:
actionString VARCHAR(15), actionString VARCHAR(15),
FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id))""" FOREIGN KEY (tourneysPlayersId) REFERENCES TourneysPlayers(id))"""
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['createHandsPlayersTable'] = """ """ self.query['createHandsPlayersTable'] = """ """
@ -727,7 +727,7 @@ class Sql:
comment TEXT, comment TEXT,
commentTs DATETIME) commentTs DATETIME)
ENGINE=INNODB""" ENGINE=INNODB"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['createTourneysPlayersTable'] = """CREATE TABLE TourneysPlayers ( self.query['createTourneysPlayersTable'] = """CREATE TABLE TourneysPlayers (
id BIGSERIAL, PRIMARY KEY (id), id BIGSERIAL, PRIMARY KEY (id),
tourneyId INT, FOREIGN KEY (tourneyId) REFERENCES Tourneys(id), tourneyId INT, FOREIGN KEY (tourneyId) REFERENCES Tourneys(id),
@ -737,7 +737,7 @@ class Sql:
winnings INT, winnings INT,
comment TEXT, comment TEXT,
commentTs timestamp without time zone)""" commentTs timestamp without time zone)"""
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['createTourneysPlayersTable'] = """ """ self.query['createTourneysPlayersTable'] = """ """
@ -757,7 +757,7 @@ class Sql:
comment TEXT, comment TEXT,
commentTs DATETIME) commentTs DATETIME)
ENGINE=INNODB""" ENGINE=INNODB"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions ( self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions (
id BIGSERIAL, PRIMARY KEY (id), id BIGSERIAL, PRIMARY KEY (id),
handsPlayerId BIGINT, FOREIGN KEY (handsPlayerId) REFERENCES HandsPlayers(id), handsPlayerId BIGINT, FOREIGN KEY (handsPlayerId) REFERENCES HandsPlayers(id),
@ -768,7 +768,7 @@ class Sql:
amount INT, amount INT,
comment TEXT, comment TEXT,
commentTs timestamp without time zone)""" commentTs timestamp without time zone)"""
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['createHandsActionsTable'] = """ """ self.query['createHandsActionsTable'] = """ """
@ -877,7 +877,7 @@ class Sql:
street4Raises INT) street4Raises INT)
ENGINE=INNODB""" ENGINE=INNODB"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['createHudCacheTable'] = """CREATE TABLE HudCache ( self.query['createHudCacheTable'] = """CREATE TABLE HudCache (
id BIGSERIAL, PRIMARY KEY (id), id BIGSERIAL, PRIMARY KEY (id),
gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id), gametypeId INT, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
@ -976,28 +976,28 @@ class Sql:
street3Raises INT, street3Raises INT,
street4Raises INT) street4Raises INT)
""" """
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['createHudCacheTable'] = """ """ self.query['createHudCacheTable'] = """ """
if db_server == 'mysql': if db_server == 'mysql':
self.query['addTourneyIndex'] = """ALTER TABLE Tourneys ADD INDEX siteTourneyNo(siteTourneyNo)""" self.query['addTourneyIndex'] = """ALTER TABLE Tourneys ADD INDEX siteTourneyNo(siteTourneyNo)"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['addTourneyIndex'] = """CREATE INDEX siteTourneyNo ON Tourneys (siteTourneyNo)""" self.query['addTourneyIndex'] = """CREATE INDEX siteTourneyNo ON Tourneys (siteTourneyNo)"""
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['addHandsIndex'] = """ """ self.query['addHandsIndex'] = """ """
if db_server == 'mysql': if db_server == 'mysql':
self.query['addHandsIndex'] = """ALTER TABLE Hands ADD INDEX siteHandNo(siteHandNo)""" self.query['addHandsIndex'] = """ALTER TABLE Hands ADD INDEX siteHandNo(siteHandNo)"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['addHandsIndex'] = """CREATE INDEX siteHandNo ON Hands (siteHandNo)""" self.query['addHandsIndex'] = """CREATE INDEX siteHandNo ON Hands (siteHandNo)"""
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['addHandsIndex'] = """ """ self.query['addHandsIndex'] = """ """
if db_server == 'mysql': if db_server == 'mysql':
self.query['addPlayersIndex'] = """ALTER TABLE Players ADD INDEX name(name)""" self.query['addPlayersIndex'] = """ALTER TABLE Players ADD INDEX name(name)"""
elif db_server == 'postgresql': # what is the correct value here? elif db_server == 'postgresql':
self.query['addPlayersIndex'] = """CREATE INDEX name ON Players (name)""" self.query['addPlayersIndex'] = """CREATE INDEX name ON Players (name)"""
elif db_server == 'sqlite': # what is the correct value here? elif db_server == 'sqlite':
self.query['addPlayersIndex'] = """ """ self.query['addPlayersIndex'] = """ """
@ -1073,7 +1073,7 @@ class Sql:
sum(hc.street4CheckCallRaiseChance) AS ccr_opp_4, sum(hc.street4CheckCallRaiseChance) AS ccr_opp_4,
sum(hc.street4CheckCallRaiseDone) AS ccr_4 sum(hc.street4CheckCallRaiseDone) AS ccr_4
FROM Hands h FROM Hands h
INNER JOIN HandsPlayers hp ON (hp.handId = %s) INNER JOIN HandsPlayers hp ON (hp.handId = h.id)
INNER JOIN HudCache hc ON ( hc.PlayerId = hp.PlayerId+0 INNER JOIN HudCache hc ON ( hc.PlayerId = hp.PlayerId+0
AND hc.gametypeId+0 = h.gametypeId+0) AND hc.gametypeId+0 = h.gametypeId+0)
INNER JOIN Players p ON (p.id = hp.PlayerId+0) INNER JOIN Players p ON (p.id = hp.PlayerId+0)
@ -1155,27 +1155,31 @@ class Sql:
sum(hc.street4CheckCallRaiseChance) AS ccr_opp_4, sum(hc.street4CheckCallRaiseChance) AS ccr_opp_4,
sum(hc.street4CheckCallRaiseDone) AS ccr_4 sum(hc.street4CheckCallRaiseDone) AS ccr_4
FROM Hands h FROM Hands h
INNER JOIN HandsPlayers hp ON (hp.handId = %s) INNER JOIN HandsPlayers hp ON (hp.handId = h.id)
INNER JOIN HudCache hc ON (hc.playerId = hp.playerId) INNER JOIN HudCache hc ON (hc.playerId = hp.playerId)
INNER JOIN Players p ON (p.id = hc.playerId) INNER JOIN Players p ON (p.id = hc.playerId)
WHERE h.id = %s WHERE h.id = %s
AND hc.styleKey > %s AND hc.styleKey > %s
/* styleKey is currently 'd' (for date) followed by a yyyymmdd /* styleKey is currently 'd' (for date) followed by a yyyymmdd
date key. Set it to 0000000 or similar to get all records */ date key. Set it to 0000000 or similar to get all records */
/* also check activeseats here? even if only 3 groups eg 2-3/4-6/7+ ?? /* Note: s means the placeholder 'percent's but we can't include that
in comments. (db api thinks they are actual arguments)
Could also check activeseats here? even if only 3 groups eg 2-3/4-6/7+ ??
e.g. could use a multiplier: e.g. could use a multiplier:
AND h.seats > %s / 1.25 and hp.seats < %s * 1.25 AND h.seats > s / 1.25 and hp.seats < s * 1.25
where %s is the number of active players at the current table (and where s is the number of active players at the current table (and
1.25 would be a config value so user could change it) 1.25 would be a config value so user could change it)
*/ */
AND hc.gametypeId+0 in AND hc.gametypeId+0 in
(SELECT gt1.id from Gametypes gt1, Gametypes gt2 (SELECT gt1.id from Gametypes gt1, Gametypes gt2
WHERE gt1.siteid = gt2.siteid WHERE gt1.siteid = gt2.siteid /* find gametypes where these match: */
AND gt1.type = gt2.type AND gt1.type = gt2.type /* ring/tourney */
AND gt1.category = gt2.category AND gt1.category = gt2.category /* holdem/stud*/
AND gt1.limittype = gt2.limittype 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) AND gt2.id = h.gametypeId)
GROUP BY hc.PlayerId, p.name, hc.styleKey GROUP BY hc.PlayerId, p.name
""" """
if db_server == 'mysql': if db_server == 'mysql':
@ -1406,16 +1410,50 @@ class Sql:
select coalesce(max(id),0) select coalesce(max(id),0)
from Hands from Hands
where handStart < date_sub(utc_timestamp(), interval '1' day)""" where handStart < date_sub(utc_timestamp(), interval '1' day)"""
else: # assume postgresql elif db_server == 'postgresql':
self.query['get_hand_1day_ago'] = """ self.query['get_hand_1day_ago'] = """
select coalesce(max(id),0) select coalesce(max(id),0)
from Hands from Hands
where handStart < now() at time zone 'UTC' - interval '1 day'""" where handStart < now() at time zone 'UTC' - interval '1 day'"""
#if db_server == 'mysql': # not used yet ...
self.query['get_hand_nhands_ago'] = """ # gets a date, would need to use handsplayers (not hudcache) to get exact hand Id
select coalesce(greatest(max(id),%s)-%s,0) if db_server == 'mysql':
from Hands""" self.query['get_date_nhands_ago'] = """
select concat( 'd', date_format(max(h.handStart), '%Y%m%d') )
from (select hp.playerId
,coalesce(greatest(max(hp.handId)-%s,1),1) as maxminusx
from HandsPlayers hp
where hp.playerId = %s
group by hp.playerId) hp2
inner join HandsPlayers hp3 on ( hp3.handId <= hp2.maxminusx
and hp3.playerId = hp2.playerId)
inner join Hands h on (h.id = hp3.handId)
"""
elif db_server == 'postgresql':
self.query['get_date_nhands_ago'] = """
select 'd' || to_char(max(h3.handStart), 'YYMMDD')
from (select hp.playerId
,coalesce(greatest(max(hp.handId)-%s,1),1) as maxminusx
from HandsPlayers hp
where hp.playerId = %s
group by hp.playerId) hp2
inner join HandsPlayers hp3 on ( hp3.handId <= hp2.maxminusx
and hp3.playerId = hp2.playerId)
inner join Hands h on (h.id = hp3.handId)
"""
elif db_server == 'sqlite': # untested guess at query:
self.query['get_date_nhands_ago'] = """
select 'd' || strftime(max(h3.handStart), 'YYMMDD')
from (select hp.playerId
,coalesce(greatest(max(hp.handId)-%s,1),1) as maxminusx
from HandsPlayers hp
where hp.playerId = %s
group by hp.playerId) hp2
inner join HandsPlayers hp3 on ( hp3.handId <= hp2.maxminusx
and hp3.playerId = hp2.playerId)
inner join Hands h on (h.id = hp3.handId)
"""
# used in GuiPlayerStats: # used in GuiPlayerStats:
self.query['getPlayerId'] = """SELECT id from Players where name = %s""" self.query['getPlayerId'] = """SELECT id from Players where name = %s"""
@ -1586,7 +1624,7 @@ class Sql:
,upper(gt.limitType) ,upper(gt.limitType)
,s.name ,s.name
""" """
#elif db_server == 'sqlite': # what is the correct value here? #elif db_server == 'sqlite':
# self.query['playerDetailedStats'] = """ """ # self.query['playerDetailedStats'] = """ """
if db_server == 'mysql': if db_server == 'mysql':
@ -1798,7 +1836,7 @@ class Sql:
) hprof2 ) hprof2
on hprof2.gtId = stats.gtId on hprof2.gtId = stats.gtId
order by stats.base, stats.limittype, stats.bigBlindDesc desc <orderbyseats>""" order by stats.base, stats.limittype, stats.bigBlindDesc desc <orderbyseats>"""
#elif db_server == 'sqlite': # what is the correct value here? #elif db_server == 'sqlite':
# self.query['playerStats'] = """ """ # self.query['playerStats'] = """ """
if db_server == 'mysql': if db_server == 'mysql':
@ -2073,7 +2111,7 @@ class Sql:
order by stats.category, stats.limitType, stats.bigBlindDesc desc order by stats.category, stats.limitType, stats.bigBlindDesc desc
<orderbyseats>, cast(stats.PlPosition as smallint) <orderbyseats>, cast(stats.PlPosition as smallint)
""" """
#elif db_server == 'sqlite': # what is the correct value here? #elif db_server == 'sqlite':
# self.query['playerStatsByPosition'] = """ """ # self.query['playerStatsByPosition'] = """ """
self.query['getRingProfitAllHandsPlayerIdSite'] = """ self.query['getRingProfitAllHandsPlayerIdSite'] = """

View File

@ -491,7 +491,7 @@ class fpdb:
def tab_auto_import(self, widget, data=None): def tab_auto_import(self, widget, data=None):
"""opens the auto import tab""" """opens the auto import tab"""
new_aimp_thread=GuiAutoImport.GuiAutoImport(self.settings, self.config) new_aimp_thread=GuiAutoImport.GuiAutoImport(self.settings, self.config, self.sql)
self.threads.append(new_aimp_thread) self.threads.append(new_aimp_thread)
aimp_tab=new_aimp_thread.get_vbox() aimp_tab=new_aimp_thread.get_vbox()
self.add_and_display_tab(aimp_tab, "Auto Import") self.add_and_display_tab(aimp_tab, "Auto Import")

View File

@ -392,17 +392,17 @@ class Importer:
mod = __import__(filter) mod = __import__(filter)
obj = getattr(mod, filter_name, None) obj = getattr(mod, filter_name, None)
if callable(obj): if callable(obj):
conv = obj(in_path = file, out_path = out_path, index = 0) # Index into file 0 until changeover hhc = obj(in_path = file, out_path = out_path, index = 0) # Index into file 0 until changeover
if(conv.getStatus() and self.NEWIMPORT == False): if(hhc.getStatus() and self.NEWIMPORT == False):
(stored, duplicates, partial, errors, ttime) = self.import_fpdb_file(db, out_path, site, q) (stored, duplicates, partial, errors, ttime) = self.import_fpdb_file(db, out_path, site, q)
elif (conv.getStatus() and self.NEWIMPORT == True): elif (hhc.getStatus() and self.NEWIMPORT == True):
#This code doesn't do anything yet #This code doesn't do anything yet
handlist = hhc.getProcessedHands() handlist = hhc.getProcessedHands()
self.pos_in_file[file] = hhc.getLastCharacterRead() self.pos_in_file[file] = hhc.getLastCharacterRead()
for hand in handlist: for hand in handlist:
hand.prepInsert() #hand.prepInsert()
hand.insert() hand.insert(self.database)
else: else:
# conversion didn't work # conversion didn't work
# TODO: appropriate response? # TODO: appropriate response?