Merge branch 'carl'

This commit is contained in:
steffen123 2010-10-02 13:40:13 +02:00
commit 4bd5f3c23e
29 changed files with 14817 additions and 14741 deletions

View File

@ -37,7 +37,7 @@ class Betfair(HandHistoryConverter):
# Static regexes # Static regexes
re_GameInfo = re.compile("^(?P<LIMIT>NL|PL|) (?P<CURRENCY>\$|)?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) (?P<GAME>(Texas Hold\'em|Omaha Hi|Omaha|Razz))", re.MULTILINE) re_GameInfo = re.compile("^(?P<LIMIT>NL|PL|) (?P<CURRENCY>\$|)?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) (?P<GAME>(Texas Hold\'em|Omaha Hi|Omaha|Razz))", re.MULTILINE)
re_SplitHands = re.compile(r'\n\n+') re_SplitHands = re.compile(r'\n\n+')
re_HandInfo = re.compile("\*\*\*\*\* Betfair Poker Hand History for Game (?P<HID>[0-9]+) \*\*\*\*\*\n(?P<LIMIT>NL|PL|) (?P<CURRENCY>\$|)?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) (?P<GAMETYPE>(Texas Hold\'em|Omaha Hi|Razz)) - (?P<DATETIME>[a-zA-Z]+, [a-zA-Z]+ \d+, \d\d:\d\d:\d\d GMT \d\d\d\d)\nTable (?P<TABLE>[ a-zA-Z0-9]+) \d-max \(Real Money\)\nSeat (?P<BUTTON>[0-9]+)", re.MULTILINE) re_HandInfo = re.compile("\*\*\*\*\* Betfair Poker Hand History for Game (?P<HID>[0-9]+) \*\*\*\*\*\n(?P<LIMIT>NL|PL|) (?P<CURRENCY>\$|)?(?P<SB>[.0-9]+)/\$?(?P<BB>[.0-9]+) (?P<GAMETYPE>(Texas Hold\'em|Omaha|Razz)) - (?P<DATETIME>[a-zA-Z]+, [a-zA-Z]+ \d+, \d\d:\d\d:\d\d GMT \d\d\d\d)\nTable (?P<TABLE>[ a-zA-Z0-9]+) \d-max \(Real Money\)\nSeat (?P<BUTTON>[0-9]+)", re.MULTILINE)
re_Button = re.compile(ur"^Seat (?P<BUTTON>\d+) is the button", re.MULTILINE) re_Button = re.compile(ur"^Seat (?P<BUTTON>\d+) is the button", re.MULTILINE)
re_PlayerInfo = re.compile("Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*)\s\(\s(\$(?P<CASH>[.0-9]+)) \)") re_PlayerInfo = re.compile("Seat (?P<SEAT>[0-9]+): (?P<PNAME>.*)\s\(\s(\$(?P<CASH>[.0-9]+)) \)")
re_Board = re.compile(ur"\[ (?P<CARDS>.+) \]") re_Board = re.compile(ur"\[ (?P<CARDS>.+) \]")
@ -107,7 +107,6 @@ class Betfair(HandHistoryConverter):
if(m == None): if(m == None):
log.error(_("Didn't match re_HandInfo")) log.error(_("Didn't match re_HandInfo"))
raise FpdbParseError(_("No match in readHandInfo.")) raise FpdbParseError(_("No match in readHandInfo."))
print "DEBUG: got this far!"
logging.debug("HID %s, Table %s" % (m.group('HID'), m.group('TABLE'))) logging.debug("HID %s, Table %s" % (m.group('HID'), m.group('TABLE')))
hand.handid = m.group('HID') hand.handid = m.group('HID')
hand.tablename = m.group('TABLE') hand.tablename = m.group('TABLE')

View File

@ -126,6 +126,7 @@ class Database:
, {'tab':'Hands', 'col':'gametypeId', 'drop':0} # mct 22/3/09 , {'tab':'Hands', 'col':'gametypeId', 'drop':0} # mct 22/3/09
#, {'tab':'Hands', 'col':'siteHandNo', 'drop':0} unique indexes not dropped #, {'tab':'Hands', 'col':'siteHandNo', 'drop':0} unique indexes not dropped
, {'tab':'HandsActions', 'col':'handsPlayerId', 'drop':0} , {'tab':'HandsActions', 'col':'handsPlayerId', 'drop':0}
, {'tab':'HandsActions', 'col':'actionId', 'drop':1}
, {'tab':'HandsPlayers', 'col':'handId', 'drop':1} , {'tab':'HandsPlayers', 'col':'handId', 'drop':1}
, {'tab':'HandsPlayers', 'col':'playerId', 'drop':1} , {'tab':'HandsPlayers', 'col':'playerId', 'drop':1}
, {'tab':'HandsPlayers', 'col':'tourneysPlayersId', 'drop':0} , {'tab':'HandsPlayers', 'col':'tourneysPlayersId', 'drop':0}
@ -149,6 +150,8 @@ class Database:
, {'tab':'HandsPlayers', 'col':'handId', 'drop':0} , {'tab':'HandsPlayers', 'col':'handId', 'drop':0}
, {'tab':'HandsPlayers', 'col':'playerId', 'drop':0} , {'tab':'HandsPlayers', 'col':'playerId', 'drop':0}
, {'tab':'HandsPlayers', 'col':'tourneysPlayersId', 'drop':0} , {'tab':'HandsPlayers', 'col':'tourneysPlayersId', 'drop':0}
, {'tab':'HandsActions', 'col':'handsPlayerId', 'drop':0}
, {'tab':'HandsActions', 'col':'actionId', 'drop':1}
, {'tab':'HudCache', 'col':'gametypeId', 'drop':1} , {'tab':'HudCache', 'col':'gametypeId', 'drop':1}
, {'tab':'HudCache', 'col':'playerId', 'drop':0} , {'tab':'HudCache', 'col':'playerId', 'drop':0}
, {'tab':'HudCache', 'col':'tourneyTypeId', 'drop':0} , {'tab':'HudCache', 'col':'tourneyTypeId', 'drop':0}
@ -172,6 +175,7 @@ class Database:
, {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1}
, {'fktab':'HandsPlayers', 'fkcol':'tourneysPlayersId','rtab':'TourneysPlayers','rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'tourneysPlayersId','rtab':'TourneysPlayers','rcol':'id', 'drop':1}
, {'fktab':'HandsActions', 'fkcol':'handsPlayerId', 'rtab':'HandsPlayers', 'rcol':'id', 'drop':1} , {'fktab':'HandsActions', 'fkcol':'handsPlayerId', 'rtab':'HandsPlayers', 'rcol':'id', 'drop':1}
, {'fktab':'HandsActions', 'fkcol':'actionId', 'rtab':'Actions', 'rcol':'id', 'drop':1}
, {'fktab':'HudCache', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1} , {'fktab':'HudCache', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
, {'fktab':'HudCache', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':0} , {'fktab':'HudCache', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':0}
, {'fktab':'HudCache', 'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes', 'rcol':'id', 'drop':1} , {'fktab':'HudCache', 'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes', 'rcol':'id', 'drop':1}
@ -181,6 +185,7 @@ class Database:
, {'fktab':'HandsPlayers', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1}
, {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1}
, {'fktab':'HandsActions', 'fkcol':'handsPlayerId', 'rtab':'HandsPlayers', 'rcol':'id', 'drop':1} , {'fktab':'HandsActions', 'fkcol':'handsPlayerId', 'rtab':'HandsPlayers', 'rcol':'id', 'drop':1}
, {'fktab':'HandsActions', 'fkcol':'actionId', 'rtab':'Actions', 'rcol':'id', 'drop':1}
, {'fktab':'HudCache', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1} , {'fktab':'HudCache', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
, {'fktab':'HudCache', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':0} , {'fktab':'HudCache', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':0}
, {'fktab':'HudCache', 'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes', 'rcol':'id', 'drop':1} , {'fktab':'HudCache', 'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes', 'rcol':'id', 'drop':1}
@ -302,7 +307,7 @@ class Database:
tables=self.cursor.execute(self.sql.query['list_tables']) tables=self.cursor.execute(self.sql.query['list_tables'])
tables=self.cursor.fetchall() tables=self.cursor.fetchall()
for table in (u'Autorates', u'Backings', u'Gametypes', u'Hands', u'HandsActions', u'HandsPlayers', u'HudCache', u'Players', u'RawHands', u'RawTourneys', u'Settings', u'Sites', u'TourneyTypes', u'Tourneys', u'TourneysPlayers'): for table in (u'Actions', u'Autorates', u'Backings', u'Gametypes', u'Hands', u'HandsActions', u'HandsPlayers', u'HudCache', u'Players', u'RawHands', u'RawTourneys', u'Settings', u'Sites', u'TourneyTypes', u'Tourneys', u'TourneysPlayers'):
print "table:", table print "table:", table
result+="###################\nTable "+table+"\n###################\n" result+="###################\nTable "+table+"\n###################\n"
rows=self.cursor.execute(self.sql.query['get'+table]) rows=self.cursor.execute(self.sql.query['get'+table])
@ -1151,6 +1156,7 @@ class Database:
c.execute(self.sql.query['createSettingsTable']) c.execute(self.sql.query['createSettingsTable'])
log.debug("Creating tables") log.debug("Creating tables")
c.execute(self.sql.query['createActionsTable'])
c.execute(self.sql.query['createSitesTable']) c.execute(self.sql.query['createSitesTable'])
c.execute(self.sql.query['createGametypesTable']) c.execute(self.sql.query['createGametypesTable'])
c.execute(self.sql.query['createPlayersTable']) c.execute(self.sql.query['createPlayersTable'])
@ -1422,6 +1428,7 @@ class Database:
def fillDefaultData(self): def fillDefaultData(self):
c = self.get_cursor() c = self.get_cursor()
c.execute("INSERT INTO Settings (version) VALUES (%s);" % (DB_VERSION)) c.execute("INSERT INTO Settings (version) VALUES (%s);" % (DB_VERSION))
#Fill Sites
c.execute("INSERT INTO Sites (name,code) VALUES ('Full Tilt Poker', 'FT')") c.execute("INSERT INTO Sites (name,code) VALUES ('Full Tilt Poker', 'FT')")
c.execute("INSERT INTO Sites (name,code) VALUES ('PokerStars', 'PS')") c.execute("INSERT INTO Sites (name,code) VALUES ('PokerStars', 'PS')")
c.execute("INSERT INTO Sites (name,code) VALUES ('Everleaf', 'EV')") c.execute("INSERT INTO Sites (name,code) VALUES ('Everleaf', 'EV')")
@ -1436,6 +1443,22 @@ class Database:
c.execute("INSERT INTO Sites (name,code) VALUES ('PKR', 'PK')") c.execute("INSERT INTO Sites (name,code) VALUES ('PKR', 'PK')")
c.execute("INSERT INTO Sites (name,code) VALUES ('iPoker', 'IP')") c.execute("INSERT INTO Sites (name,code) VALUES ('iPoker', 'IP')")
c.execute("INSERT INTO Sites (name,code) VALUES ('Winamax', 'WM')") c.execute("INSERT INTO Sites (name,code) VALUES ('Winamax', 'WM')")
#Fill Actions
c.execute("INSERT INTO Actions (name,code) VALUES ('ante', 'A')")
c.execute("INSERT INTO Actions (name,code) VALUES ('small blind', 'SB')")
c.execute("INSERT INTO Actions (name,code) VALUES ('secondsb', 'SSB')")
c.execute("INSERT INTO Actions (name,code) VALUES ('big blind', 'BB')")
c.execute("INSERT INTO Actions (name,code) VALUES ('both', 'SBBB')")
c.execute("INSERT INTO Actions (name,code) VALUES ('calls', 'C')")
c.execute("INSERT INTO Actions (name,code) VALUES ('raises', 'R')")
c.execute("INSERT INTO Actions (name,code) VALUES ('bets', 'B')")
c.execute("INSERT INTO Actions (name,code) VALUES ('stands pat', 'S')")
c.execute("INSERT INTO Actions (name,code) VALUES ('folds', 'F')")
c.execute("INSERT INTO Actions (name,code) VALUES ('checks', 'K')")
c.execute("INSERT INTO Actions (name,code) VALUES ('discards', 'D')")
c.execute("INSERT INTO Actions (name,code) VALUES ('bringin', 'I')")
c.execute("INSERT INTO Actions (name,code) VALUES ('completes', 'P')")
#end def fillDefaultData #end def fillDefaultData
def rebuild_indexes(self, start=None): def rebuild_indexes(self, start=None):
@ -1563,7 +1586,7 @@ class Database:
self.connection.set_isolation_level(1) # go back to normal isolation level self.connection.set_isolation_level(1) # go back to normal isolation level
self.commit() self.commit()
atime = time() - stime atime = time() - stime
print _("Analyze took %.1f seconds") % (atime,) log.info(_("Analyze took %.1f seconds") % (atime,))
#end def analyzeDB #end def analyzeDB
def vacuumDB(self): def vacuumDB(self):
@ -1653,6 +1676,7 @@ class Database:
pp.pprint(pdata) pp.pprint(pdata)
inserts = [] inserts = []
hpid = {}
for p in pdata: for p in pdata:
inserts.append( (hid, inserts.append( (hid,
pids[p], pids[p],
@ -1757,39 +1781,44 @@ class Database:
#print "DEBUG: inserts: %s" %inserts #print "DEBUG: inserts: %s" %inserts
#print "DEBUG: q: %s" % q #print "DEBUG: q: %s" % q
c = self.get_cursor() c = self.get_cursor()
if self.import_options['saveActions']:
for r in inserts:
c.execute(q, r)
hpid[(r[0], r[1])] = self.get_last_insert_id(c)
else:
c.executemany(q, inserts) c.executemany(q, inserts)
def storeHandsActions(self, hid, pids, adata, printdata = False): return hpid
def storeHandsActions(self, hid, pids, hpid, adata, printdata = False):
#print "DEBUG: %s %s %s" %(hid, pids, adata) #print "DEBUG: %s %s %s" %(hid, pids, adata)
if printdata: if printdata:
import pprint import pprint
pp = pprint.PrettyPrinter(indent=4) pp = pprint.PrettyPrinter(indent=4)
pp.pprint(adata) pp.pprint(adata)
#inserts = [] inserts = []
#for p in pdata: for a in adata:
# inserts.append( (hid, inserts.append( (hpid[(hid, pids[adata[a]['player']])],
# pids[p], #self.getHandsPlayerId(self.hid, pids[adata[a]['player']]),
# adata[p]['startCash'], adata[a]['street'],
# adata[p]['seatNo'], adata[a]['actionNo'],
# adata[p]['sitout'], adata[a]['streetActionNo'],
# adata[p]['card1'], adata[a]['actionId'],
adata[a]['amount'],
#handsPlayerId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handsPlayerId) REFERENCES HandsPlayers(id), adata[a]['raiseTo'],
#street SMALLINT NOT NULL, adata[a]['amountCalled'],
#actionNo SMALLINT NOT NULL, adata[a]['numDiscarded'],
#action CHAR(5) NOT NULL, adata[a]['cardsDiscarded'],
#allIn BOOLEAN NOT NULL, adata[a]['allIn']
#amount INT NOT NULL, ) )
q = self.sql.query['store_hands_actions'] q = self.sql.query['store_hands_actions']
#q = q.replace('%s', self.sql.query['placeholder']) q = q.replace('%s', self.sql.query['placeholder'])
#print "DEBUG: inserts: %s" %inserts c = self.get_cursor()
#print "DEBUG: q: %s" % q c.executemany(q, inserts)
#c = self.get_cursor()
#c.executemany(q, inserts)
def storeHudCache(self, gid, pids, starttime, pdata): def storeHudCache(self, gid, pids, starttime, pdata):
"""Update cached statistics. If update fails because no record exists, do an insert.""" """Update cached statistics. If update fails because no record exists, do an insert."""

View File

@ -23,13 +23,6 @@ import logging
# logging has been set up in fpdb.py or HUD_main.py, use their settings: # logging has been set up in fpdb.py or HUD_main.py, use their settings:
log = logging.getLogger("parser") log = logging.getLogger("parser")
DEBUG = False
if DEBUG:
import pprint
pp = pprint.PrettyPrinter(indent=4)
class DerivedStats(): class DerivedStats():
def __init__(self, hand): def __init__(self, hand):
self.hand = hand self.hand = hand
@ -93,17 +86,9 @@ class DerivedStats():
self.assembleHands(self.hand) self.assembleHands(self.hand)
self.assembleHandsPlayers(self.hand) self.assembleHandsPlayers(self.hand)
if DEBUG: if self.hand.saveActions:
self.assembleHandsActions(self.hand) self.assembleHandsActions(self.hand)
if DEBUG:
#print "Hands:"
#pp.pprint(self.hands)
#print "HandsPlayers:"
#pp.pprint(self.handsplayers)
print "HandsActions:"
pp.pprint(self.handsactions)
def getHands(self): def getHands(self):
return self.hands return self.hands
@ -216,9 +201,35 @@ class DerivedStats():
# Squeeze, Ratchet? # Squeeze, Ratchet?
def assembleHandsActions(self, hand): def assembleHandsActions(self, hand):
print "DEBUG: hand.actions" k = 0
pp.pprint(hand.actions) for i, street in enumerate(hand.actionStreets):
pass for j, act in enumerate(hand.actions[street]):
k += 1
self.handsactions[k] = {}
#default values
self.handsactions[k]['amount'] = 0
self.handsactions[k]['raiseTo'] = 0
self.handsactions[k]['amountCalled'] = 0
self.handsactions[k]['numDiscarded'] = 0
self.handsactions[k]['cardsDiscarded'] = None
self.handsactions[k]['allIn'] = False
#Insert values from hand.actions
self.handsactions[k]['player'] = act[0]
self.handsactions[k]['street'] = i-1
self.handsactions[k]['actionNo'] = k
self.handsactions[k]['streetActionNo'] = (j+1)
self.handsactions[k]['actionId'] = hand.ACTION[act[1]]
if act[1] not in ('discards') and len(act) > 2:
self.handsactions[k]['amount'] = int(100 * act[2])
if act[1] in ('raises', 'completes'):
self.handsactions[k]['raiseTo'] = int(100 * act[3])
self.handsactions[k]['amountCalled'] = int(100 * act[4])
if act[1] in ('discards'):
self.handsactions[k]['numDiscarded'] = int(act[2])
if act[1] in ('discards') and len(act) > 3:
self.handsactions[k]['cardsDiscarded'] = act[3]
if len(act) > 3 and act[1] not in ('discards'):
self.handsactions[k]['allIn'] = act[-1]
def setPositions(self, hand): def setPositions(self, hand):
"""Sets the position for each player in HandsPlayers """Sets the position for each player in HandsPlayers
@ -251,8 +262,8 @@ class DerivedStats():
else: else:
# set blinds first, then others from pfbao list, avoids problem if bb # set blinds first, then others from pfbao list, avoids problem if bb
# is missing from pfbao list or if there is no small blind # is missing from pfbao list or if there is no small blind
bb = [x[0] for x in hand.actions[hand.actionStreets[0]] if x[2] == 'big blind'] bb = [x[0] for x in hand.actions[hand.actionStreets[0]] if x[1] == 'big blind']
sb = [x[0] for x in hand.actions[hand.actionStreets[0]] if x[2] == 'small blind'] sb = [x[0] for x in hand.actions[hand.actionStreets[0]] if x[1] == 'small blind']
# if there are > 1 sb or bb only the first is used! # if there are > 1 sb or bb only the first is used!
if bb: if bb:
self.handsplayers[bb[0]]['position'] = 'B' self.handsplayers[bb[0]]['position'] = 'B'

View File

@ -23,6 +23,10 @@
Main for FreePokerTools HUD. Main for FreePokerTools HUD.
""" """
import L10n
_ = L10n.get_translation()
# TODO allow window resizing # TODO allow window resizing
# TODO hud to echo, but ignore non numbers # TODO hud to echo, but ignore non numbers
# TODO no stat window for hero # TODO no stat window for hero
@ -60,21 +64,6 @@ elif os.name == 'nt':
#import Tables #import Tables
import Hud import Hud
import locale
lang = locale.getdefaultlocale()[0][0:2]
print "lang:", lang
if lang == "en":
def _(string):
return string
else:
import gettext
try:
trans = gettext.translation("fpdb", localedir="locale", languages=[lang])
trans.install()
except IOError:
def _(string):
return string
# get config and set up logger # get config and set up logger
c = Configuration.Config(file=options.config, dbname=options.dbname) c = Configuration.Config(file=options.config, dbname=options.dbname)
log = Configuration.get_logger("logging.conf", "hud", log_dir=c.dir_log, log_file='HUD-log.txt') log = Configuration.get_logger("logging.conf", "hud", log_dir=c.dir_log, log_file='HUD-log.txt')

View File

@ -49,11 +49,14 @@ 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'$', 'GBP': '$', 'T$': '', 'play': ''} SYMBOL = {'USD': '$', 'EUR': u'$', 'GBP': '$', 'T$': '', 'play': ''}
MS = {'horse' : 'HORSE', '8game' : '8-Game', 'hose' : 'HOSE', 'ha': 'HA'} MS = {'horse' : 'HORSE', '8game' : '8-Game', 'hose' : 'HOSE', 'ha': 'HA'}
ACTION = {'ante': 1, 'small blind': 2, 'secondsb': 3, 'big blind': 4, 'both': 5, 'calls': 6, 'raises': 7,
'bets': 8, 'stands pat': 9, 'folds': 10, 'checks': 11, 'discards': 12, 'bringin': 13, 'completes': 14}
def __init__(self, config, sitename, gametype, handText, builtFrom = "HHC"): def __init__(self, config, sitename, gametype, handText, builtFrom = "HHC"):
#log.debug( _("Hand.init(): handText is ") + str(handText) ) #log.debug( _("Hand.init(): handText is ") + str(handText) )
self.config = config self.config = config
self.saveActions = self.config.get_import_parameters().get('saveActions')
#log = Configuration.get_logger("logging.conf", "db", log_dir=self.config.dir_log) #log = Configuration.get_logger("logging.conf", "db", log_dir=self.config.dir_log)
self.sitename = sitename self.sitename = sitename
self.siteId = self.config.get_site_id(sitename) self.siteId = self.config.get_site_id(sitename)
@ -65,6 +68,7 @@ class Hand(object):
self.cancelled = False self.cancelled = False
self.dbid_hands = 0 self.dbid_hands = 0
self.dbid_pids = None self.dbid_pids = None
self.dbid_hpid = None
self.dbid_gt = 0 self.dbid_gt = 0
self.tablename = "" self.tablename = ""
self.hero = "" self.hero = ""
@ -262,10 +266,11 @@ db: a connected Database object"""
hh['seats'] = len(self.dbid_pids) hh['seats'] = len(self.dbid_pids)
self.dbid_hands = db.storeHand(hh) self.dbid_hands = db.storeHand(hh)
db.storeHandsPlayers(self.dbid_hands, self.dbid_pids, self.stats.getHandsPlayers(), printdata = printtest) self.dbid_hpid = db.storeHandsPlayers(self.dbid_hands, self.dbid_pids,
# TODO HandsActions - all actions for all players for all streets - self.actions self.stats.getHandsPlayers(), printdata = printtest)
# HudCache data can be generated from HandsActions (HandsPlayers?) if self.saveActions:
#db.storeHandsActions(self.dbid_hands, self.dbid_pids, self.stats.getHandsActions(), printdata = printtest) db.storeHandsActions(self.dbid_hands, self.dbid_pids, self.dbid_hpid,
self.stats.getHandsActions(), printdata = printtest)
else: else:
log.info(_("Hand.insert(): hid #: %s is a duplicate") % hh['siteHandNo']) log.info(_("Hand.insert(): hid #: %s is a duplicate") % hh['siteHandNo'])
self.is_duplicate = True # i.e. don't update hudcache self.is_duplicate = True # i.e. don't update hudcache
@ -350,7 +355,7 @@ For sites (currently only Carbon Poker) which record "all in" as a special actio
ante = re.sub(u',', u'', ante) #some sites have commas ante = re.sub(u',', u'', ante) #some sites have commas
self.bets['BLINDSANTES'][player].append(Decimal(ante)) self.bets['BLINDSANTES'][player].append(Decimal(ante))
self.stacks[player] -= Decimal(ante) self.stacks[player] -= Decimal(ante)
act = (player, 'posts', "ante", ante, self.stacks[player]==0) act = (player, 'ante', Decimal(ante), self.stacks[player]==0)
self.actions['BLINDSANTES'].append(act) self.actions['BLINDSANTES'].append(act)
# self.pot.addMoney(player, Decimal(ante)) # self.pot.addMoney(player, Decimal(ante))
self.pot.addCommonMoney(player, Decimal(ante)) self.pot.addCommonMoney(player, Decimal(ante))
@ -369,7 +374,7 @@ For sites (currently only Carbon Poker) which record "all in" as a special actio
if player is not None: if player is not None:
amount = re.sub(u',', u'', amount) #some sites have commas amount = re.sub(u',', u'', amount) #some sites have commas
self.stacks[player] -= Decimal(amount) self.stacks[player] -= Decimal(amount)
act = (player, 'posts', blindtype, amount, self.stacks[player]==0) act = (player, blindtype, Decimal(amount), self.stacks[player]==0)
self.actions['BLINDSANTES'].append(act) self.actions['BLINDSANTES'].append(act)
if blindtype == 'both': if blindtype == 'both':
@ -402,7 +407,7 @@ For sites (currently only Carbon Poker) which record "all in" as a special actio
#self.lastBet[street] = Decimal(amount) #self.lastBet[street] = Decimal(amount)
self.stacks[player] -= Decimal(amount) self.stacks[player] -= Decimal(amount)
#print "DEBUG %s calls %s, stack %s" % (player, amount, self.stacks[player]) #print "DEBUG %s calls %s, stack %s" % (player, amount, self.stacks[player])
act = (player, 'calls', amount, self.stacks[player]==0) act = (player, 'calls', Decimal(amount), self.stacks[player]==0)
self.actions[street].append(act) self.actions[street].append(act)
self.pot.addMoney(player, Decimal(amount)) self.pot.addMoney(player, Decimal(amount))
@ -463,11 +468,11 @@ Add a raise on [street] by [player] to [amountTo]
Rb = Rt - C - Bc Rb = Rt - C - Bc
self._addRaise(street, player, C, Rb, Rt) self._addRaise(street, player, C, Rb, Rt)
def _addRaise(self, street, player, C, Rb, Rt): def _addRaise(self, street, player, C, Rb, Rt, action = 'raises'):
log.debug(_("%s %s raise %s") %(street, player, Rt)) log.debug(_("%s %s raise %s") %(street, player, Rt))
self.bets[street][player].append(C + Rb) self.bets[street][player].append(C + Rb)
self.stacks[player] -= (C + Rb) self.stacks[player] -= (C + Rb)
act = (player, 'raises', Rb, Rt, C, self.stacks[player]==0) act = (player, action, Rb, Rt, C, self.stacks[player]==0)
self.actions[street].append(act) self.actions[street].append(act)
self.lastBet[street] = Rt # TODO check this is correct self.lastBet[street] = Rt # TODO check this is correct
self.pot.addMoney(player, C+Rb) self.pot.addMoney(player, C+Rb)
@ -481,7 +486,7 @@ Add a raise on [street] by [player] to [amountTo]
self.bets[street][player].append(Decimal(amount)) self.bets[street][player].append(Decimal(amount))
self.stacks[player] -= Decimal(amount) self.stacks[player] -= Decimal(amount)
#print "DEBUG %s bets %s, stack %s" % (player, amount, self.stacks[player]) #print "DEBUG %s bets %s, stack %s" % (player, amount, self.stacks[player])
act = (player, 'bets', amount, self.stacks[player]==0) act = (player, 'bets', Decimal(amount), self.stacks[player]==0)
self.actions[street].append(act) self.actions[street].append(act)
self.lastBet[street] = Decimal(amount) self.lastBet[street] = Decimal(amount)
self.pot.addMoney(player, Decimal(amount)) self.pot.addMoney(player, Decimal(amount))
@ -1020,7 +1025,7 @@ class DrawHand(Hand):
self.bets['DEAL'][player].append(Decimal(amount)) self.bets['DEAL'][player].append(Decimal(amount))
self.stacks[player] -= Decimal(amount) self.stacks[player] -= Decimal(amount)
#print "DEBUG %s posts, stack %s" % (player, self.stacks[player]) #print "DEBUG %s posts, stack %s" % (player, self.stacks[player])
act = (player, 'posts', blindtype, amount, self.stacks[player]==0) act = (player, blindtype, Decimal(amount), self.stacks[player]==0)
self.actions['BLINDSANTES'].append(act) self.actions['BLINDSANTES'].append(act)
self.pot.addMoney(player, Decimal(amount)) self.pot.addMoney(player, Decimal(amount))
if blindtype == 'big blind': if blindtype == 'big blind':
@ -1050,10 +1055,10 @@ class DrawHand(Hand):
def addDiscard(self, street, player, num, cards): def addDiscard(self, street, player, num, cards):
self.checkPlayerExists(player) self.checkPlayerExists(player)
if cards: if cards:
act = (player, 'discards', num, cards) act = (player, 'discards', Decimal(num), cards)
self.discardDrawHoleCards(cards, player, street) self.discardDrawHoleCards(cards, player, street)
else: else:
act = (player, 'discards', num) act = (player, 'discards', Decimal(num))
self.actions[street].append(act) self.actions[street].append(act)
def holecardsAsSet(self, street, player): def holecardsAsSet(self, street, player):
@ -1246,7 +1251,7 @@ Add a complete on [street] by [player] to [amountTo]
Rt = Decimal(amountTo) Rt = Decimal(amountTo)
C = Bp - Bc C = Bp - Bc
Rb = Rt - C Rb = Rt - C
self._addRaise(street, player, C, Rb, Rt) self._addRaise(street, player, C, Rb, Rt, 'completes')
#~ self.bets[street][player].append(C + Rb) #~ self.bets[street][player].append(C + Rb)
#~ self.stacks[player] -= (C + Rb) #~ self.stacks[player] -= (C + Rb)
#~ act = (player, 'raises', Rb, Rt, C, self.stacks[player]==0) #~ act = (player, 'raises', Rb, Rt, C, self.stacks[player]==0)
@ -1259,7 +1264,7 @@ Add a complete on [street] by [player] to [amountTo]
log.debug(_("Bringin: %s, %s") % (player , bringin)) log.debug(_("Bringin: %s, %s") % (player , bringin))
self.bets['THIRD'][player].append(Decimal(bringin)) self.bets['THIRD'][player].append(Decimal(bringin))
self.stacks[player] -= Decimal(bringin) self.stacks[player] -= Decimal(bringin)
act = (player, 'bringin', bringin, self.stacks[player]==0) act = (player, 'bringin', Decimal(bringin), self.stacks[player]==0)
self.actions['THIRD'].append(act) self.actions['THIRD'].append(act)
self.lastBet['THIRD'] = Decimal(bringin) self.lastBet['THIRD'] = Decimal(bringin)
self.pot.addMoney(player, Decimal(bringin)) self.pot.addMoney(player, Decimal(bringin))

View File

@ -262,9 +262,16 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
self.obs = m.sub('', self.obs) self.obs = m.sub('', self.obs)
if self.obs is None or self.obs == "": if self.obs is None or self.obs == "":
log.info(_("Read no hands.")) log.error(_("Read no hands."))
return [] return []
return re.split(self.re_SplitHands, self.obs) handlist = re.split(self.re_SplitHands, self.obs)
# Some HH formats leave dangling text after the split
# ie. </game> (split) </session>EOL
# Remove this dangler if less than 50 characters and warn in the log
if len(handlist[-1]) <= 50:
handlist.pop()
log.warn(_("Removing text < 50 characters"))
return handlist
def processHand(self, handText): def processHand(self, handText):
gametype = self.determineGameType(handText) gametype = self.determineGameType(handText)

View File

@ -52,15 +52,15 @@ class OnGame(HandHistoryConverter):
games = { # base, category games = { # base, category
"TEXAS_HOLDEM" : ('hold','holdem'), "TEXAS_HOLDEM" : ('hold','holdem'),
# 'Omaha' : ('hold','omahahi'), 'OMAHA_HI' : ('hold','omahahi'),
# 'Omaha Hi/Lo' : ('hold','omahahilo'), # 'Omaha Hi/Lo' : ('hold','omahahilo'),
# 'Razz' : ('stud','razz'), # 'Razz' : ('stud','razz'),
# 'RAZZ' : ('stud','razz'), # 'RAZZ' : ('stud','razz'),
# '7 Card Stud' : ('stud','studhi'), 'SEVEN_CARD_STUD' : ('stud','studhi'),
'SEVEN_CARD_STUD_HI_LO' : ('stud','studhilo'), 'SEVEN_CARD_STUD_HI_LO' : ('stud','studhilo'),
# 'Badugi' : ('draw','badugi'), # 'Badugi' : ('draw','badugi'),
# 'Triple Draw 2-7 Lowball' : ('draw','27_3draw'), # 'Triple Draw 2-7 Lowball' : ('draw','27_3draw'),
# '5 Card Draw' : ('draw','fivedraw') 'FIVE_CARD_DRAW' : ('draw','fivedraw')
} }
# Static regexes # Static regexes
@ -88,7 +88,7 @@ class OnGame(HandHistoryConverter):
Table:\s(?P<TABLE>[\'\w\s]+)\s\[\d+\]\s\( Table:\s(?P<TABLE>[\'\w\s]+)\s\[\d+\]\s\(
( (
(?P<LIMIT>NO_LIMIT|Limit|LIMIT|Pot\sLimit)\s (?P<LIMIT>NO_LIMIT|Limit|LIMIT|Pot\sLimit)\s
(?P<GAME>TEXAS_HOLDEM|RAZZ)\s (?P<GAME>TEXAS_HOLDEM|OMAHA_HI|SEVEN_CARD_STUD|SEVEN_CARD_STUD_HI_LO|RAZZ|FIVE_CARD_DRAW)\s
(%(LS)s)?(?P<SB>[.0-9]+)/ (%(LS)s)?(?P<SB>[.0-9]+)/
(%(LS)s)?(?P<BB>[.0-9]+) (%(LS)s)?(?P<BB>[.0-9]+)
)? )?
@ -156,6 +156,7 @@ class OnGame(HandHistoryConverter):
["ring", "hold", "fl"], ["ring", "hold", "fl"],
["ring", "hold", "nl"], ["ring", "hold", "nl"],
["ring", "stud", "fl"], ["ring", "stud", "fl"],
["ring", "draw", "fl"],
] ]
def determineGameType(self, handText): def determineGameType(self, handText):
@ -239,18 +240,24 @@ class OnGame(HandHistoryConverter):
hand.addPlayer(int(a.group('SEAT')), a.group('PNAME'), a.group('CASH')) hand.addPlayer(int(a.group('SEAT')), a.group('PNAME'), a.group('CASH'))
def markStreets(self, hand): def markStreets(self, hand):
# PREFLOP = ** Dealing down cards ** if hand.gametype['base'] in ("hold"):
# This re fails if, say, river is missing; then we don't get the ** that starts the river.
#m = re.search('(\*\* Dealing down cards \*\*\n)(?P<PREFLOP>.*?\n\*\*)?( Dealing Flop \*\* \[ (?P<FLOP1>\S\S), (?P<FLOP2>\S\S), (?P<FLOP3>\S\S) \])?(?P<FLOP>.*?\*\*)?( Dealing Turn \*\* \[ (?P<TURN1>\S\S) \])?(?P<TURN>.*?\*\*)?( Dealing River \*\* \[ (?P<RIVER1>\S\S) \])?(?P<RIVER>.*)', hand.string,re.DOTALL)
#if hand.gametype['base'] in ("hold"):
#elif hand.gametype['base'] in ("stud"):
#elif hand.gametype['base'] in ("draw"):
# only holdem so far:
m = re.search(r"pocket cards(?P<PREFLOP>.+(?= Dealing flop )|.+(?=Summary))" m = re.search(r"pocket cards(?P<PREFLOP>.+(?= Dealing flop )|.+(?=Summary))"
r"( Dealing flop (?P<FLOP>\[\S\S, \S\S, \S\S\].+(?= Dealing turn)|.+(?=Summary)))?" r"( Dealing flop (?P<FLOP>\[\S\S, \S\S, \S\S\].+(?= Dealing turn)|.+(?=Summary)))?"
r"( Dealing turn (?P<TURN>\[\S\S\].+(?= Dealing river)|.+(?=Summary)))?" r"( Dealing turn (?P<TURN>\[\S\S\].+(?= Dealing river)|.+(?=Summary)))?"
r"( Dealing river (?P<RIVER>\[\S\S\].+(?=Summary)))?", hand.handText, re.DOTALL) r"( Dealing river (?P<RIVER>\[\S\S\].+(?=Summary)))?", hand.handText, re.DOTALL)
elif hand.gametype['base'] in ("stud"):
m = re.search(r"(?P<ANTES>.+(?=Dealing pocket cards)|.+)"
r"(Dealing pocket cards(?P<THIRD>.+(?=Dealing 4th street)|.+))?"
r"(Dealing 4th street(?P<FOURTH>.+(?=Dealing 5th street)|.+))?"
r"(Dealing 5th street(?P<FIFTH>.+(?=Dealing 6th street)|.+))?"
r"(Dealing 6th street(?P<SIXTH>.+(?=Dealing river)|.+))?"
r"(Dealing river(?P<SEVENTH>.+))?", hand.handText,re.DOTALL)
elif hand.gametype['base'] in ("draw"):
m = re.search(r"(?P<PREDEAL>.+(?=Dealing pocket cards)|.+)"
r"(Dealing pocket cards(?P<DEAL>.+(?=\*\*\* FIRST DRAW \*\*\*)|.+))?"
r"(\*\*\* FIRST DRAW \*\*\*(?P<DRAWONE>.+(?=\*\*\* SECOND DRAW \*\*\*)|.+))?"
r"(\*\*\* SECOND DRAW \*\*\*(?P<DRAWTWO>.+(?=\*\*\* THIRD DRAW \*\*\*)|.+))?"
r"(\*\*\* THIRD DRAW \*\*\*(?P<DRAWTHREE>.+))?", hand.handText,re.DOTALL)
hand.addStreets(m) hand.addStreets(m)

View File

@ -52,7 +52,7 @@ class PartyPoker(HandHistoryConverter):
re_GameInfoRing = re.compile(""" re_GameInfoRing = re.compile("""
(?P<CURRENCY>\$|)\s*(?P<RINGLIMIT>[.,0-9]+)([.,0-9/$]+)?\s*(?:USD)?\s* (?P<CURRENCY>\$|)\s*(?P<RINGLIMIT>[.,0-9]+)([.,0-9/$]+)?\s*(?:USD)?\s*
(?P<LIMIT>(NL|PL|))\s* (?P<LIMIT>(NL|PL|))\s*
(?P<GAME>(Texas\ Hold\'em|Omaha)) (?P<GAME>(Texas\ Hold\'em|Omaha|7 Card Stud Hi-Lo))
\s*\-\s* \s*\-\s*
(?P<DATETIME>.+) (?P<DATETIME>.+)
""", re.VERBOSE) """, re.VERBOSE)
@ -202,6 +202,7 @@ class PartyPoker(HandHistoryConverter):
games = { # base, category games = { # base, category
"Texas Hold'em" : ('hold','holdem'), "Texas Hold'em" : ('hold','holdem'),
'Omaha' : ('hold','omahahi'), 'Omaha' : ('hold','omahahi'),
"7 Card Stud Hi-Lo" : ('stud','studhi'),
} }
currencies = { '$':'USD', '':'T$' } currencies = { '$':'USD', '':'T$' }

View File

@ -154,6 +154,27 @@ class Sql:
rawTourney TEXT NOT NULL, rawTourney TEXT NOT NULL,
complain BOOLEAN NOT NULL DEFAULT FALSE)""" complain BOOLEAN NOT NULL DEFAULT FALSE)"""
################################
# Create Actions
################################
if db_server == 'mysql':
self.query['createActionsTable'] = """CREATE TABLE Actions (
id SMALLINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
name varchar(32) NOT NULL,
code char(4) NOT NULL)
ENGINE=INNODB"""
elif db_server == 'postgresql':
self.query['createActionsTable'] = """CREATE TABLE Actions (
id SERIAL, PRIMARY KEY (id),
name varchar(32),
code char(4))"""
elif db_server == 'sqlite':
self.query['createActionsTable'] = """CREATE TABLE Actions (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
code TEXT NOT NULL)"""
################################ ################################
# Create Sites # Create Sites
################################ ################################
@ -989,11 +1010,14 @@ class Sql:
handsPlayerId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handsPlayerId) REFERENCES HandsPlayers(id), handsPlayerId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handsPlayerId) REFERENCES HandsPlayers(id),
street SMALLINT NOT NULL, street SMALLINT NOT NULL,
actionNo SMALLINT NOT NULL, actionNo SMALLINT NOT NULL,
action CHAR(5) NOT NULL, streetActionNo SMALLINT NOT NULL,
allIn BOOLEAN NOT NULL, actionId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (actionId) REFERENCES Actions(id),
amount INT NOT NULL, amount INT NOT NULL,
comment TEXT, raiseTo INT NOT NULL,
commentTs DATETIME) amountCalled INT NOT NULL,
numDiscarded SMALLINT NOT NULL,
cardsDiscarded varchar(14),
allIn BOOLEAN NOT NULL)
ENGINE=INNODB""" ENGINE=INNODB"""
elif db_server == 'postgresql': elif db_server == 'postgresql':
self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions ( self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions (
@ -1001,23 +1025,30 @@ class Sql:
handsPlayerId BIGINT, FOREIGN KEY (handsPlayerId) REFERENCES HandsPlayers(id), handsPlayerId BIGINT, FOREIGN KEY (handsPlayerId) REFERENCES HandsPlayers(id),
street SMALLINT, street SMALLINT,
actionNo SMALLINT, actionNo SMALLINT,
action CHAR(5), streetActionNo SMALLINT,
allIn BOOLEAN, actionId SMALLINT, FOREIGN KEY (actionId) REFERENCES Actions(id),
amount INT, amount INT,
comment TEXT, raiseTo INT,
commentTs timestamp without time zone)""" amountCalled INT,
numDiscarded SMALLINT,
cardsDiscarded varchar(14),
allIn BOOLEAN)"""
elif db_server == 'sqlite': elif db_server == 'sqlite':
self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions ( self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
handsPlayerId BIGINT, handsPlayerId BIGINT,
street SMALLINT, street SMALLINT,
actionNo SMALLINT, actionNo SMALLINT,
action CHAR(5), streetActionNo SMALLINT,
allIn INT, actionId SMALLINT,
amount INT, amount INT,
comment TEXT, raiseTo INT,
commentTs timestamp without time zone, amountCalled INT,
FOREIGN KEY (handsPlayerId) REFERENCES HandsPlayers(id) numDiscarded SMALLINT,
cardsDiscarded TEXT,
allIn BOOLEAN,
FOREIGN KEY (handsPlayerId) REFERENCES HandsPlayers(id),
FOREIGN KEY (actionId) REFERENCES Actions(id) ON DELETE CASCADE
)""" )"""
@ -4251,11 +4282,17 @@ class Sql:
handsPlayerId, handsPlayerId,
street, street,
actionNo, actionNo,
action, streetActionNo,
allIn, actionId,
amount amount,
raiseTo,
amountCalled,
numDiscarded,
cardsDiscarded,
allIn
) )
VALUES ( VALUES (
%s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s %s
)""" )"""

View File

@ -18,6 +18,9 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
######################################################################## ########################################################################
import L10n
_ = L10n.get_translation()
import sys import sys
import exceptions import exceptions
@ -28,18 +31,6 @@ import Configuration
from HandHistoryConverter import * from HandHistoryConverter import *
from decimal import Decimal from decimal import Decimal
import time import time
import locale
lang=locale.getdefaultlocale()[0][0:2]
if lang=="en":
def _(string): return string
else:
import gettext
try:
trans = gettext.translation("fpdb", localedir="locale", languages=[lang])
trans.install()
except IOError:
def _(string): return string
# Winamax HH Format # Winamax HH Format
@ -58,7 +49,7 @@ class Winamax(HandHistoryConverter):
siteName = "Winamax" siteName = "Winamax"
filetype = "text" filetype = "text"
codepage = ("utf8", "cp1252") codepage = ("utf8", "cp1252")
siteId = 5 # Needs to match id entry in Sites database siteId = 14 # Needs to match id entry in Sites database
mixes = { } # Legal mixed games mixes = { } # Legal mixed games
sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\xe2\x82\xac", "GBP": "\xa3"} # ADD Euro, Sterling, etc HERE sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\xe2\x82\xac", "GBP": "\xa3"} # ADD Euro, Sterling, etc HERE

View File

@ -239,7 +239,7 @@ class Importer:
if self.settings['dropIndexes'] == 'drop': if self.settings['dropIndexes'] == 'drop':
self.database.prepareBulkImport() self.database.prepareBulkImport()
else: else:
log.debug(_("No need to drop indexes.")) log.info(_("No need to drop indexes."))
#print "dropInd =", self.settings['dropIndexes'], " dropHudCache =", self.settings['dropHudCache'] #print "dropInd =", self.settings['dropIndexes'], " dropHudCache =", self.settings['dropHudCache']
if self.settings['threads'] <= 0: if self.settings['threads'] <= 0:
@ -277,11 +277,11 @@ class Importer:
if self.settings['dropIndexes'] == 'drop': if self.settings['dropIndexes'] == 'drop':
self.database.afterBulkImport() self.database.afterBulkImport()
else: else:
print _("No need to rebuild indexes.") log.info (_("No need to rebuild indexes."))
if 'dropHudCache' in self.settings and self.settings['dropHudCache'] == 'drop': if 'dropHudCache' in self.settings and self.settings['dropHudCache'] == 'drop':
self.database.rebuild_hudcache() self.database.rebuild_hudcache()
else: else:
print _("No need to rebuild hudcache.") log.info (_("No need to rebuild hudcache."))
self.database.analyzeDB() self.database.analyzeDB()
endtime = time() endtime = time()
return (totstored, totdups, totpartial, toterrors, endtime-starttime) return (totstored, totdups, totpartial, toterrors, endtime-starttime)