Merge branch 'chaz'

This commit is contained in:
Steffen Schaumburg 2011-04-09 19:46:45 +02:00
commit 00c3c114a8
9 changed files with 409 additions and 137 deletions

View File

@ -73,7 +73,7 @@ except ImportError:
use_numpy = False use_numpy = False
DB_VERSION = 152 DB_VERSION = 156
# Variance created as sqlite has a bunch of undefined aggregate functions. # Variance created as sqlite has a bunch of undefined aggregate functions.
@ -124,10 +124,12 @@ class Database:
, [ # indexes for postgres (list index 3) , [ # indexes for postgres (list index 3)
{'tab':'Gametypes', 'col':'siteId', 'drop':0} {'tab':'Gametypes', 'col':'siteId', 'drop':0}
, {'tab':'Hands', 'col':'gametypeId', 'drop':0} # mct 22/3/09 , {'tab':'Hands', 'col':'gametypeId', 'drop':0} # mct 22/3/09
, {'tab':'Hands', 'col':'fileId', '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':'handId', 'drop':1} , {'tab':'HandsActions', 'col':'handId', 'drop':1}
, {'tab':'HandsActions', 'col':'playerId', 'drop':1} , {'tab':'HandsActions', 'col':'playerId', 'drop':1}
, {'tab':'HandsActions', 'col':'actionId', 'drop':1} , {'tab':'HandsActions', 'col':'actionId', 'drop':1}
, {'tab':'Boards', 'col':'handId', '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}
@ -151,6 +153,8 @@ class Database:
] ]
, [ # indexes for sqlite (list index 4) , [ # indexes for sqlite (list index 4)
{'tab':'Hands', 'col':'gametypeId', 'drop':0} {'tab':'Hands', 'col':'gametypeId', 'drop':0}
, {'tab':'Hands', 'col':'fileId', 'drop':0}
, {'tab':'Boards', 'col':'handId', 'drop':0}
, {'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}
@ -179,6 +183,8 @@ class Database:
, [ ] # no db with index 1 , [ ] # no db with index 1
, [ # foreign keys for mysql (index 2) , [ # foreign keys for mysql (index 2)
{'fktab':'Hands', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1} {'fktab':'Hands', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
, {'fktab':'Hands', 'fkcol':'fileId', 'rtab':'Files', 'rcol':'id', 'drop':1}
, {'fktab':'Boards', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1}
, {'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':'HandsPlayers', 'fkcol':'tourneysPlayersId','rtab':'TourneysPlayers','rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'tourneysPlayersId','rtab':'TourneysPlayers','rcol':'id', 'drop':1}
@ -194,6 +200,8 @@ class Database:
] ]
, [ # foreign keys for postgres (index 3) , [ # foreign keys for postgres (index 3)
{'fktab':'Hands', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1} {'fktab':'Hands', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
, {'fktab':'Hands', 'fkcol':'fileId', 'rtab':'Files', 'rcol':'id', 'drop':1}
, {'fktab':'Boards', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1}
, {'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':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1} , {'fktab':'HandsActions', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1}
@ -332,7 +340,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'Actions', u'Autorates', u'Backings', u'Gametypes', u'Hands', u'HandsActions', u'HandsPlayers', u'HudCache', u'SessionsCache', 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'Boards', u'HandsActions', u'HandsPlayers', u'Files', u'HudCache', u'SessionsCache', 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])
@ -515,12 +523,12 @@ class Database:
except:# _mysql_exceptions.ProgrammingError: except:# _mysql_exceptions.ProgrammingError:
if database != ":memory:": if database != ":memory:":
if create: if create:
print (_("Failed to read settings table.") + " - " + _("Recreating tables.")) #print (_("Failed to read settings table.") + " - " + _("Recreating tables."))
log.info(_("Failed to read settings table.") + " - " + _("Recreating tables.")) log.info(_("Failed to read settings table.") + " - " + _("Recreating tables."))
self.recreate_tables() self.recreate_tables()
self.check_version(database=database, create=False) self.check_version(database=database, create=False)
else: else:
print (_("Failed to read settings table.") + " - " + _("Please recreate tables.")) #print (_("Failed to read settings table.") + " - " + _("Please recreate tables."))
log.info(_("Failed to read settings table.") + " - " + _("Please recreate tables.")) log.info(_("Failed to read settings table.") + " - " + _("Please recreate tables."))
self.wrongDbVersion = True self.wrongDbVersion = True
else: else:
@ -1241,7 +1249,7 @@ class Database:
self.createAllIndexes() self.createAllIndexes()
self.commit() self.commit()
self.get_sites() self.get_sites()
print _("Finished recreating tables") #print _("Finished recreating tables")
log.info(_("Finished recreating tables")) log.info(_("Finished recreating tables"))
#end def recreate_tables #end def recreate_tables
@ -1256,9 +1264,11 @@ class Database:
c.execute(self.sql.query['createActionsTable']) 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['createFilesTable'])
c.execute(self.sql.query['createPlayersTable']) c.execute(self.sql.query['createPlayersTable'])
c.execute(self.sql.query['createAutoratesTable']) c.execute(self.sql.query['createAutoratesTable'])
c.execute(self.sql.query['createHandsTable']) c.execute(self.sql.query['createHandsTable'])
c.execute(self.sql.query['createBoardsTable'])
c.execute(self.sql.query['createTourneyTypesTable']) c.execute(self.sql.query['createTourneyTypesTable'])
c.execute(self.sql.query['createTourneysTable']) c.execute(self.sql.query['createTourneysTable'])
c.execute(self.sql.query['createTourneysPlayersTable']) c.execute(self.sql.query['createTourneysPlayersTable'])
@ -1857,6 +1867,7 @@ class Database:
hdata['gametypeId'], hdata['gametypeId'],
hdata['sessionId'], hdata['sessionId'],
hdata['gameSessionId'], hdata['gameSessionId'],
hdata['fileId'],
hdata['startTime'], hdata['startTime'],
datetime.utcnow(), #importtime datetime.utcnow(), #importtime
hdata['seats'], hdata['seats'],
@ -1868,6 +1879,7 @@ class Database:
hdata['boardcard3'], hdata['boardcard3'],
hdata['boardcard4'], hdata['boardcard4'],
hdata['boardcard5'], hdata['boardcard5'],
hdata['runIt'],
hdata['playersAtStreet1'], hdata['playersAtStreet1'],
hdata['playersAtStreet2'], hdata['playersAtStreet2'],
hdata['playersAtStreet3'], hdata['playersAtStreet3'],
@ -1883,19 +1895,28 @@ class Database:
hdata['street3Pot'], hdata['street3Pot'],
hdata['street4Pot'], hdata['street4Pot'],
hdata['showdownPot'], hdata['showdownPot'],
hdata['boards'],
hdata['id'] hdata['id']
]) ])
if doinsert: if doinsert:
bbulk = []
for h in hbulk: for h in hbulk:
id = h.pop() id = h.pop()
if hdata['sc'] and hdata['gsc']: if hdata['sc'] and hdata['gsc']:
h[4] = hdata['sc'][id]['id'] h[4] = hdata['sc'][id]['id']
h[5] = hdata['gsc'][id]['id'] h[5] = hdata['gsc'][id]['id']
boards = h.pop()
for b in boards:
bbulk += [[id] + b]
q = self.sql.query['store_hand'] q = self.sql.query['store_hand']
q = q.replace('%s', self.sql.query['placeholder']) q = q.replace('%s', self.sql.query['placeholder'])
c = self.get_cursor() c = self.get_cursor()
c.executemany(q, hbulk) c.executemany(q, hbulk)
q = self.sql.query['store_boards']
q = q.replace('%s', self.sql.query['placeholder'])
c = self.get_cursor()
c.executemany(q, bbulk)
self.commit() self.commit()
return hbulk return hbulk
@ -1941,6 +1962,7 @@ class Database:
pdata[p]['street3Seen'], pdata[p]['street3Seen'],
pdata[p]['street4Seen'], pdata[p]['street4Seen'],
pdata[p]['sawShowdown'], pdata[p]['sawShowdown'],
pdata[p]['showed'],
pdata[p]['wonAtSD'], pdata[p]['wonAtSD'],
pdata[p]['street0Aggr'], pdata[p]['street0Aggr'],
pdata[p]['street1Aggr'], pdata[p]['street1Aggr'],
@ -2087,6 +2109,7 @@ class Database:
insert_hudcache = insert_hudcache.replace('%s', self.sql.query['placeholder']) insert_hudcache = insert_hudcache.replace('%s', self.sql.query['placeholder'])
#print "DEBUG: %s %s %s" %(hid, pids, pdata) #print "DEBUG: %s %s %s" %(hid, pids, pdata)
hcs = []
for p in pdata: for p in pdata:
#NOTE: Insert new stats at right place because SQL needs strict order #NOTE: Insert new stats at right place because SQL needs strict order
line = [] line = []
@ -2179,7 +2202,7 @@ class Database:
line.append(pdata[p]['street3Raises']) line.append(pdata[p]['street3Raises'])
line.append(pdata[p]['street4Raises']) line.append(pdata[p]['street4Raises'])
hc, hcs = {}, [] hc = {}
hc['gametypeId'] = gid hc['gametypeId'] = gid
hc['playerId'] = pids[p] hc['playerId'] = pids[p]
hc['activeSeats'] = len(pids) hc['activeSeats'] = len(pids)
@ -2187,6 +2210,9 @@ class Database:
hc['position'] = pos[pdata[p]['position']] hc['position'] = pos[pdata[p]['position']]
hc['tourneyTypeId'] = pdata[p]['tourneyTypeId'] hc['tourneyTypeId'] = pdata[p]['tourneyTypeId']
hc['styleKey'] = styleKey hc['styleKey'] = styleKey
for i in range(len(line)):
if line[i]: line[i] = 1
else: line[i] = 0
hc['line'] = line hc['line'] = line
hc['game'] = [hc['gametypeId'] hc['game'] = [hc['gametypeId']
,hc['playerId'] ,hc['playerId']
@ -2199,6 +2225,7 @@ class Database:
for h in hcs: for h in hcs:
match = False match = False
for b in hcbulk: for b in hcbulk:
#print h['game']==b['game'], h['game'], b['game']
if h['game']==b['game']: if h['game']==b['game']:
b['line'] = [sum(l) for l in zip(b['line'], h['line'])] b['line'] = [sum(l) for l in zip(b['line'], h['line'])]
match = True match = True
@ -2206,14 +2233,9 @@ class Database:
if doinsert: if doinsert:
inserts = [] inserts = []
exists = [] c = self.get_cursor()
updates = []
for hc in hcbulk: for hc in hcbulk:
row = hc['line'] + hc['game'] row = hc['line'] + hc['game']
if hc['game'] in exists:
updates.append(row)
continue
c = self.get_cursor()
num = c.execute(update_hudcache, row) num = c.execute(update_hudcache, row)
# Try to do the update first. Do insert it did not work # Try to do the update first. Do insert it did not work
if ((self.backend == self.PGSQL and c.statusmessage != "UPDATE 1") if ((self.backend == self.PGSQL and c.statusmessage != "UPDATE 1")
@ -2224,10 +2246,10 @@ class Database:
#num = c.execute(insert_hudcache, row) #num = c.execute(insert_hudcache, row)
#print "DEBUG: Successfully(?: %s) updated HudCacho using INSERT" % num #print "DEBUG: Successfully(?: %s) updated HudCacho using INSERT" % num
else: else:
exists.append(hc['game'])
#print "DEBUG: Successfully updated HudCacho using UPDATE" #print "DEBUG: Successfully updated HudCacho using UPDATE"
if inserts: c.executemany(insert_hudcache, inserts) pass
if updates: c.executemany(update_hudcache, updates) if inserts:
c.executemany(insert_hudcache, inserts)
return hcbulk return hcbulk
@ -2500,6 +2522,52 @@ class Database:
return gsc return gsc
def getGameTypeId(self, siteid, game, printdata = False):
c = self.get_cursor()
#FIXME: Fixed for NL at the moment
c.execute(self.sql.query['getGametypeNL'], (siteid, game['type'], game['category'], game['limitType'], game['currency'],
game['mix'], int(Decimal(game['sb'])*100), int(Decimal(game['bb'])*100)))
tmp = c.fetchone()
if (tmp == None):
hilo = "h"
if game['category'] in ['studhilo', 'omahahilo']:
hilo = "s"
elif game['category'] in ['razz','27_3draw','badugi', '27_1draw']:
hilo = "l"
#FIXME: recognise currency
#TODO: this wont work for non-standard structures
tmp = self.insertGameTypes( (siteid, game['currency'], game['type'], game['base'], game['category'], game['limitType'], hilo,
game['mix'], int(Decimal(game['sb'])*100), int(Decimal(game['bb'])*100),
int(Decimal(game['bb'])*100), int(Decimal(game['bb'])*200)), printdata = printdata)
return tmp[0]
def insertGameTypes(self, row, printdata = False):
if printdata:
print _("######## Gametype ##########")
import pprint
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(row)
print _("###### End Gametype ########")
c = self.get_cursor()
c.execute( self.sql.query['insertGameTypes'], row )
return [self.get_last_insert_id(c)]
def storeFile(self, fdata):
q = self.sql.query['store_file']
q = q.replace('%s', self.sql.query['placeholder'])
c = self.get_cursor()
c.execute(q, fdata)
id = self.get_last_insert_id(c)
return id
def updateFile(self, fdata):
q = self.sql.query['update_file']
q = q.replace('%s', self.sql.query['placeholder'])
c = self.get_cursor()
c.execute(q, fdata)
def getHeroIds(self, pids, sitename): def getHeroIds(self, pids, sitename):
#Grab playerIds using hero names in HUD_Config.xml #Grab playerIds using hero names in HUD_Config.xml
try: try:
@ -2549,40 +2617,6 @@ class Database:
dup = True dup = True
return dup return dup
def getGameTypeId(self, siteid, game, printdata = False):
c = self.get_cursor()
#FIXME: Fixed for NL at the moment
c.execute(self.sql.query['getGametypeNL'], (siteid, game['type'], game['category'], game['limitType'], game['currency'],
int(Decimal(game['sb'])*100), int(Decimal(game['bb'])*100)))
tmp = c.fetchone()
if (tmp == None):
hilo = "h"
if game['category'] in ['studhilo', 'omahahilo']:
hilo = "s"
elif game['category'] in ['razz','27_3draw','badugi', '27_1draw']:
hilo = "l"
#FIXME: recognise currency
#TODO: this wont work for non-standard structures
tmp = self.insertGameTypes( (siteid, game['currency'], game['type'], game['base'], game['category'], game['limitType'], hilo,
int(Decimal(game['sb'])*100), int(Decimal(game['bb'])*100),
int(Decimal(game['bb'])*100), int(Decimal(game['bb'])*200)), printdata = printdata)
return tmp[0]
def insertGameTypes(self, row, printdata = False):
if printdata:
print _("######## Gametype ##########")
import pprint
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(row)
print _("###### End Gametype ########")
c = self.get_cursor()
c.execute( self.sql.query['insertGameTypes'], row )
return [self.get_last_insert_id(c)]
################################# #################################
# Finish of NEWIMPORT CODE # Finish of NEWIMPORT CODE
################################# #################################

View File

@ -43,6 +43,7 @@ class DerivedStats():
init['street4Aggr'] = False init['street4Aggr'] = False
init['wonWhenSeenStreet1'] = 0.0 init['wonWhenSeenStreet1'] = 0.0
init['sawShowdown'] = False init['sawShowdown'] = False
init['showed'] = False
init['wonAtSD'] = 0.0 init['wonAtSD'] = 0.0
init['startCards'] = 0 init['startCards'] = 0
init['position'] = 2 init['position'] = 2
@ -144,6 +145,20 @@ class DerivedStats():
self.hands['boardcard4'] = cards[3] self.hands['boardcard4'] = cards[3]
self.hands['boardcard5'] = cards[4] self.hands['boardcard5'] = cards[4]
self.hands['boards'] = []
self.hands['runIt'] = False
for i in range(hand.runItTimes):
self.hands['runIt'] = True
boardcards = []
for street in hand.communityStreets:
boardId = i+1
street_i = street + str(boardId)
if street_i in hand.board:
boardcards += hand.board[street_i]
boardcards = [u'0x', u'0x', u'0x', u'0x', u'0x'] + boardcards
cards = [Card.encodeCard(c) for c in boardcards[-5:]]
self.hands['boards'] += [[boardId] + cards]
#print "DEBUG: self.getStreetTotals = (%s, %s, %s, %s, %s)" % hand.getStreetTotals() #print "DEBUG: self.getStreetTotals = (%s, %s, %s, %s, %s)" % hand.getStreetTotals()
totals = hand.getStreetTotals() totals = hand.getStreetTotals()
totals = [int(100*i) for i in totals] totals = [int(100*i) for i in totals]
@ -173,6 +188,8 @@ class DerivedStats():
self.handsplayers[player[1]]['tourneysPlayersIds'] = hand.tourneysPlayersIds[player[1]] self.handsplayers[player[1]]['tourneysPlayersIds'] = hand.tourneysPlayersIds[player[1]]
else: else:
self.handsplayers[player[1]]['tourneysPlayersIds'] = None self.handsplayers[player[1]]['tourneysPlayersIds'] = None
if player[1] in hand.shown:
self.handsplayers[player[1]]['showed'] = True
#### seen now processed in playersAtStreetX() #### seen now processed in playersAtStreetX()
# XXX: enumerate(list, start=x) is python 2.6 syntax; 'start' # XXX: enumerate(list, start=x) is python 2.6 syntax; 'start'

View File

@ -148,17 +148,11 @@ class Fulltilt(HandHistoryConverter):
##Total Prize Pool: 1,500 Play Chips ##Total Prize Pool: 1,500 Play Chips
# These regexes are for FTP only # These regexes are for FTP only
re_Mixed = re.compile(r'\s\-\s(?P<MIXED>HA|HORSE|HOSE)\s\-\s', re.VERBOSE) re_Mixed = re.compile(r'\s\-\s(?P<MIXED>7\-Game|8\-Game|9\-Game|10\-Game|HA|HEROS|HO|HOE|HORSE|HOSE|OA|OE|SE)\s\-\s', re.VERBOSE)
re_Max = re.compile("(?P<MAX>\d+)( max)?", re.MULTILINE) re_Max = re.compile("(?P<MAX>\d+)( max)?", re.MULTILINE)
# NB: if we ever match "Full Tilt Poker" we should also match "FullTiltPoker", which PT Stud erroneously exports. # NB: if we ever match "Full Tilt Poker" we should also match "FullTiltPoker", which PT Stud erroneously exports.
re_DateTime = re.compile("""((?P<H>[0-9]+):(?P<MIN>[0-9]+):(?P<S>[0-9]+)\s(?P<TZ>\w+)\s-\s(?P<Y>[0-9]{4})\/(?P<M>[0-9]{2})\/(?P<D>[0-9]{2})|(?P<H2>[0-9]+):(?P<MIN2>[0-9]+)\s(?P<TZ2>\w+)\s-\s\w+\,\s(?P<M2>\w+)\s(?P<D2>\d+)\,\s(?P<Y2>[0-9]{4}))(?P<PARTIAL>\s\(partial\))?""", re.MULTILINE) re_DateTime = re.compile("""((?P<H>[0-9]+):(?P<MIN>[0-9]+):(?P<S>[0-9]+)\s(?P<TZ>\w+)\s-\s(?P<Y>[0-9]{4})\/(?P<M>[0-9]{2})\/(?P<D>[0-9]{2})|(?P<H2>[0-9]+):(?P<MIN2>[0-9]+)\s(?P<TZ2>\w+)\s-\s\w+\,\s(?P<M2>\w+)\s(?P<D2>\d+)\,\s(?P<Y2>[0-9]{4}))(?P<PARTIAL>\s\(partial\))?""", re.MULTILINE)
mixes = { 'HORSE': 'horse', '7-Game': '7game', 'HOSE': 'hose', 'HA': 'ha'}
def compilePlayerRegexs(self, hand): def compilePlayerRegexs(self, hand):
players = set([player[1] for player in hand.players]) players = set([player[1] for player in hand.players])
if not players <= self.compiledPlayers: # x <= y means 'x is subset of y' if not players <= self.compiledPlayers: # x <= y means 'x is subset of y'
@ -180,7 +174,7 @@ class Fulltilt(HandHistoryConverter):
self.re_ShowdownAction = re.compile(r"^%s shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE) self.re_ShowdownAction = re.compile(r"^%s shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
self.re_CollectPot = re.compile(r"^Seat (?P<SEAT>[0-9]+): %(PLAYERS)s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \([%(LS)s]?(?P<POT>[%(NUM)s]+)\)(, mucked| with.*)?" % self.substitutions, re.MULTILINE) self.re_CollectPot = re.compile(r"^Seat (?P<SEAT>[0-9]+): %(PLAYERS)s (\(button\) |\(small blind\) |\(big blind\) )?(collected|showed \[.*\] and won) \([%(LS)s]?(?P<POT>[%(NUM)s]+)\)(, mucked| with.*)?" % self.substitutions, re.MULTILINE)
self.re_SitsOut = re.compile(r"^%s sits out" % player_re, re.MULTILINE) self.re_SitsOut = re.compile(r"^%s sits out" % player_re, re.MULTILINE)
self.re_ShownCards = re.compile(r"^Seat (?P<SEAT>[0-9]+): %s (\(button\) |\(small blind\) |\(big blind\) )?(?P<ACT>showed|mucked) \[(?P<CARDS>.*)\].*" % player_re, re.MULTILINE) self.re_ShownCards = re.compile(r"^Seat (?P<SEAT>[0-9]+): %s (\(button\) |\(small blind\) |\(big blind\) )?(?P<SHOWED>showed|mucked) \[(?P<CARDS>.*)\](( and won \(.*\) with | and lost with | \- )(?P<STRING>.*))?" % player_re, re.MULTILINE)
def readSupportedGames(self): def readSupportedGames(self):
return [["ring", "hold", "nl"], return [["ring", "hold", "nl"],
@ -233,6 +227,21 @@ class Fulltilt(HandHistoryConverter):
'Badugi' : ('draw','badugi'), 'Badugi' : ('draw','badugi'),
'2-7 Single Draw' : ('draw','27_1draw') '2-7 Single Draw' : ('draw','27_1draw')
} }
mixes = {
'7-Game' : '7game',
'8-Game' : '8game',
'9-Game' : '9game',
'10-Game' : '10game',
'HA' : 'ha',
'HEROS' : 'heros',
'HO' : 'ho',
'HOE' : 'hoe',
'HORSE' : 'horse',
'HOSE' : 'hose',
'OA' : 'oa',
'OE' : 'oe',
'SE' : 'se'
}
currencies = { u'':'EUR', '$':'USD', '':'T$' } currencies = { u'':'EUR', '$':'USD', '':'T$' }
if 'SB' in mg: if 'SB' in mg:
@ -264,6 +273,9 @@ class Fulltilt(HandHistoryConverter):
if mg['CURRENCY'] is not None: if mg['CURRENCY'] is not None:
info['currency'] = currencies[mg['CURRENCY']] info['currency'] = currencies[mg['CURRENCY']]
# NB: SB, BB must be interpreted as blinds or bets depending on limit type. # NB: SB, BB must be interpreted as blinds or bets depending on limit type.
m = self.re_Mixed.search(self.in_path)
if m: info['mix'] = mixes[m.groupdict()['MIXED']]
return info return info
def readHandInfo(self, hand): def readHandInfo(self, hand):
@ -380,10 +392,16 @@ class Fulltilt(HandHistoryConverter):
def markStreets(self, hand): def markStreets(self, hand):
if hand.gametype['base'] == 'hold': if hand.gametype['base'] == 'hold':
m = re.search(r"\*\*\* HOLE CARDS \*\*\*(?P<PREFLOP>.+(?=\*\*\* FLOP \*\*\*)|.+)" m = re.search(r"\*\*\* HOLE CARDS \*\*\*(?P<PREFLOP>.+(?=\*\*\* FLOP (1\s)?\*\*\*)|.+)"
r"(\*\*\* FLOP \*\*\*(?P<FLOP> \[\S\S \S\S \S\S\].+(?=\*\*\* TURN \*\*\*)|.+))?" r"(\*\*\* FLOP \*\*\*(?P<FLOP> \[\S\S \S\S \S\S\].+(?=\*\*\* TURN (1\s)?\*\*\*)|.+))?"
r"(\*\*\* TURN \*\*\* \[\S\S \S\S \S\S] (?P<TURN>\[\S\S\].+(?=\*\*\* RIVER \*\*\*)|.+))?" r"(\*\*\* TURN \*\*\* \[\S\S \S\S \S\S] (?P<TURN>\[\S\S\].+(?=\*\*\* RIVER (1\s)?\*\*\*)|.+))?"
r"(\*\*\* RIVER \*\*\* \[\S\S \S\S \S\S \S\S] (?P<RIVER>\[\S\S\].+))?", hand.handText,re.DOTALL) r"(\*\*\* RIVER \*\*\* \[\S\S \S\S \S\S \S\S] (?P<RIVER>\[\S\S\].+))?"
r"(\*\*\* FLOP 1 \*\*\*(?P<FLOP1> \[\S\S \S\S \S\S\].+(?=\*\*\* TURN 1 \*\*\*)|.+))?"
r"(\*\*\* TURN 1 \*\*\* \[\S\S \S\S \S\S] (?P<TURN1>\[\S\S\].+(?=\*\*\* RIVER 1 \*\*\*)|.+))?"
r"(\*\*\* RIVER 1 \*\*\* \[\S\S \S\S \S\S \S\S] (?P<RIVER1>\[\S\S\].))?"
r"(\*\*\* FLOP 2 \*\*\*(?P<FLOP2> \[\S\S \S\S \S\S\].+(?=\*\*\* TURN 2 \*\*\*)|.+))?"
r"(\*\*\* TURN 2 \*\*\* \[\S\S \S\S \S\S] (?P<TURN2>\[\S\S\].+(?=\*\*\* RIVER 2 \*\*\*)|.+))?"
r"(\*\*\* RIVER 2 \*\*\* \[\S\S \S\S \S\S \S\S] (?P<RIVER2>\[\S\S\].+))?", hand.handText,re.DOTALL)
elif hand.gametype['base'] == "stud": elif hand.gametype['base'] == "stud":
m = re.search(r"(?P<ANTES>.+(?=\*\*\* 3RD STREET \*\*\*)|.+)" m = re.search(r"(?P<ANTES>.+(?=\*\*\* 3RD STREET \*\*\*)|.+)"
r"(\*\*\* 3RD STREET \*\*\*(?P<THIRD>.+(?=\*\*\* 4TH STREET \*\*\*)|.+))?" r"(\*\*\* 3RD STREET \*\*\*(?P<THIRD>.+(?=\*\*\* 4TH STREET \*\*\*)|.+))?"
@ -402,10 +420,13 @@ class Fulltilt(HandHistoryConverter):
def readCommunityCards(self, hand, street): # street has been matched by markStreets, so exists in this hand def readCommunityCards(self, hand, street): # street has been matched by markStreets, so exists in this hand
if street in ('FLOP','TURN','RIVER'): # a list of streets which get dealt community cards (i.e. all but PREFLOP) if street in ('FLOP','TURN','RIVER'): # a list of streets which get dealt community cards (i.e. all but PREFLOP)
#print "DEBUG readCommunityCards:", street, hand.streets.group(street) #print "DEBUG readCommunityCards:", street, hand.streets[street]
m = self.re_Board.search(hand.streets[street]) m = self.re_Board.search(hand.streets[street])
hand.setCommunityCards(street, m.group('CARDS').split(' ')) hand.setCommunityCards(street, m.group('CARDS').split(' '))
if street in ('FLOP1', 'TURN1', 'RIVER1', 'FLOP2', 'TURN2', 'RIVER2'):
m = self.re_Board.search(hand.streets[street])
hand.setCommunityCards(street, m.group('CARDS').split(' '))
hand.runItTimes = 2
def readBlinds(self, hand): def readBlinds(self, hand):
try: try:
@ -520,10 +541,16 @@ class Fulltilt(HandHistoryConverter):
def readShownCards(self,hand): def readShownCards(self,hand):
for m in self.re_ShownCards.finditer(hand.handText): for m in self.re_ShownCards.finditer(hand.handText):
if m.group('CARDS') is not None: if m.group('CARDS') is not None:
if m.group('ACT'): cards = m.group('CARDS')
hand.addShownCards(cards=m.group('CARDS').split(' '), player=m.group('PNAME'), shown = False, mucked = True) cards = cards.split(' ') # needs to be a list, not a set--stud needs the order
else: string = m.group('STRING')
hand.addShownCards(cards=m.group('CARDS').split(' '), player=m.group('PNAME'), shown = True, mucked = False)
(shown, mucked) = (False, False)
if m.group('SHOWED') == "showed": shown = True
elif m.group('SHOWED') == "mucked": mucked = True
#print "DEBUG: hand.addShownCards(%s, %s, %s, %s)" %(cards, m.group('PNAME'), shown, mucked)
hand.addShownCards(cards=cards, player=m.group('PNAME'), shown=shown, mucked=mucked, string=string)
def guessMaxSeats(self, hand): def guessMaxSeats(self, hand):
"""Return a guess at max_seats when not specified in HH.""" """Return a guess at max_seats when not specified in HH."""
@ -543,13 +570,6 @@ class Fulltilt(HandHistoryConverter):
if mo <= 6: return 6 if mo <= 6: return 6
return 9 return 9
def readOther(self, hand):
m = self.re_Mixed.search(self.in_path)
if m is None:
hand.mixed = None
else:
hand.mixed = self.mixes[m.groupdict()['MIXED']]
def readSummaryInfo(self, summaryInfoList): def readSummaryInfo(self, summaryInfoList):
self.status = True self.status = True

View File

@ -77,6 +77,7 @@ class Hand(object):
self.maxseats = None self.maxseats = None
self.counted_seats = 0 self.counted_seats = 0
self.buttonpos = 0 self.buttonpos = 0
self.runItTimes = 0
#tourney stuff #tourney stuff
self.tourNo = None self.tourNo = None
@ -112,6 +113,7 @@ class Hand(object):
self.board = {} # dict from street names to community cards self.board = {} # dict from street names to community cards
self.holecards = {} self.holecards = {}
self.discards = {} self.discards = {}
self.showdownStrings = {}
for street in self.allStreets: for street in self.allStreets:
self.streets[street] = "" # portions of the handText, filled by markStreets() self.streets[street] = "" # portions of the handText, filled by markStreets()
self.actions[street] = [] self.actions[street] = []
@ -273,12 +275,13 @@ dealt whether they were seen in a 'dealt to' line
next = id +1 next = id +1
return next return next
def insertHands(self, db, hbulk, doinsert = False, printtest = False): def insertHands(self, db, hbulk, fileId, doinsert = False, printtest = False):
""" Function to insert Hand into database """ Function to insert Hand into database
Should not commit, and do minimal selects. Callers may want to cache commits Should not commit, and do minimal selects. Callers may want to cache commits
db: a connected Database object""" db: a connected Database object"""
self.hands['gametypeId'] = self.dbid_gt self.hands['gametypeId'] = self.dbid_gt
self.hands['seats'] = len(self.dbid_pids) self.hands['seats'] = len(self.dbid_pids)
self.hands['fileId'] = fileId
hbulk = db.storeHand(self.hands, hbulk, doinsert, printtest) hbulk = db.storeHand(self.hands, hbulk, doinsert, printtest)
return hbulk return hbulk
@ -709,7 +712,7 @@ Add a raise on [street] by [player] to [amountTo]
self.collectees[player] += Decimal(pot) self.collectees[player] += Decimal(pot)
def addShownCards(self, cards, player, holeandboard=None, shown=True, mucked=False): def addShownCards(self, cards, player, holeandboard=None, shown=True, mucked=False, string=None):
"""\ """\
For when a player shows cards for any reason (for showdown or out of choice). For when a player shows cards for any reason (for showdown or out of choice).
Card ranks will be uppercased Card ranks will be uppercased
@ -717,6 +720,8 @@ Card ranks will be uppercased
log.debug(_("addShownCards %s hole=%s all=%s") % (player, cards, holeandboard)) log.debug(_("addShownCards %s hole=%s all=%s") % (player, cards, holeandboard))
if cards is not None: if cards is not None:
self.addHoleCards(cards,player,shown, mucked) self.addHoleCards(cards,player,shown, mucked)
if string is not None:
self.showdownStrings[player] = string
elif holeandboard is not None: elif holeandboard is not None:
holeandboard = set([self.card(c) for c in holeandboard]) holeandboard = set([self.card(c) for c in holeandboard])
board = set([c for s in self.board.values() for c in s]) board = set([c for s in self.board.values() for c in s])
@ -886,9 +891,8 @@ class HoldemOmahaHand(Hand):
hhc.readHeroCards(self) hhc.readHeroCards(self)
hhc.readShowdownActions(self) hhc.readShowdownActions(self)
# Read actions in street order # Read actions in street order
for street in self.communityStreets: for street, text in self.streets.iteritems():
if self.streets[street]: if text: hhc.readCommunityCards(self, street)
hhc.readCommunityCards(self, street)
for street in self.actionStreets: for street in self.actionStreets:
if self.streets[street]: if self.streets[street]:
hhc.readAction(self, street) hhc.readAction(self, street)
@ -912,7 +916,7 @@ class HoldemOmahaHand(Hand):
pass pass
def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False): def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False, string=None):
if player == self.hero: # we have hero's cards just update shown/mucked if player == self.hero: # we have hero's cards just update shown/mucked
if shown: self.shown.add(player) if shown: self.shown.add(player)
if mucked: self.mucked.add(player) if mucked: self.mucked.add(player)
@ -925,6 +929,8 @@ class HoldemOmahaHand(Hand):
diff = filter( lambda x: x not in self.board['FLOP']+self.board['TURN']+self.board['RIVER'], cards ) diff = filter( lambda x: x not in self.board['FLOP']+self.board['TURN']+self.board['RIVER'], cards )
if len(diff) == 2 and self.gametype['category'] in ('holdem'): if len(diff) == 2 and self.gametype['category'] in ('holdem'):
self.addHoleCards('PREFLOP', player, open=[], closed=diff, shown=shown, mucked=mucked, dealt=dealt) self.addHoleCards('PREFLOP', player, open=[], closed=diff, shown=shown, mucked=mucked, dealt=dealt)
if string is not None:
self.showdownStrings[player] = string
def getStreetTotals(self): def getStreetTotals(self):
# street1Pot INT, /* pot size at flop/street4 */ # street1Pot INT, /* pot size at flop/street4 */
@ -1200,13 +1206,15 @@ class DrawHand(Hand):
elif builtFrom == "DB": elif builtFrom == "DB":
self.select("dummy") # Will need a handId self.select("dummy") # Will need a handId
def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False): def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False, string=None):
if player == self.hero: # we have hero's cards just update shown/mucked if player == self.hero: # we have hero's cards just update shown/mucked
if shown: self.shown.add(player) if shown: self.shown.add(player)
if mucked: self.mucked.add(player) if mucked: self.mucked.add(player)
else: else:
# TODO: Probably better to find the last street with action and add the hole cards to that street # TODO: Probably better to find the last street with action and add the hole cards to that street
self.addHoleCards('DRAWTHREE', player, open=[], closed=cards, shown=shown, mucked=mucked, dealt=dealt) self.addHoleCards('DRAWTHREE', player, open=[], closed=cards, shown=shown, mucked=mucked, dealt=dealt)
if string is not None:
self.showdownStrings[player] = string
def discardDrawHoleCards(self, cards, player, street): def discardDrawHoleCards(self, cards, player, street):
@ -1378,7 +1386,7 @@ class StudHand(Hand):
elif builtFrom == "DB": elif builtFrom == "DB":
self.select("dummy") # Will need a handId self.select("dummy") # Will need a handId
def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False): def addShownCards(self, cards, player, shown=True, mucked=False, dealt=False, string=None):
if player == self.hero: # we have hero's cards just update shown/mucked if player == self.hero: # we have hero's cards just update shown/mucked
if shown: self.shown.add(player) if shown: self.shown.add(player)
if mucked: self.mucked.add(player) if mucked: self.mucked.add(player)
@ -1389,6 +1397,8 @@ class StudHand(Hand):
self.addHoleCards('SIXTH', player, open=[cards[5]], closed=cards[2:5], shown=shown, mucked=mucked) self.addHoleCards('SIXTH', player, open=[cards[5]], closed=cards[2:5], shown=shown, mucked=mucked)
if len(cards) > 6: if len(cards) > 6:
self.addHoleCards('SEVENTH', player, open=[], closed=[cards[6]], shown=shown, mucked=mucked) self.addHoleCards('SEVENTH', player, open=[], closed=[cards[6]], shown=shown, mucked=mucked)
if string is not None:
self.showdownStrings[player] = string
def addPlayerCards(self, player, street, open=[], closed=[]): def addPlayerCards(self, player, street, open=[], closed=[]):

View File

@ -68,7 +68,7 @@ class HandHistoryConverter():
# maybe archive params should be one archive param, then call method in specific converter. if archive: convert_archive() # maybe archive params should be one archive param, then call method in specific converter. if archive: convert_archive()
def __init__( self, config, in_path = '-', out_path = '-', follow=False, index=0 def __init__( self, config, in_path = '-', out_path = '-', follow=False, index=0
, autostart=True, starsArchive=False, ftpArchive=False, sitename="PokerStars" ): , autostart=True, starsArchive=False, ftpArchive=False, sitename="PokerStars"):
"""\ """\
in_path (default '-' = sys.stdin) in_path (default '-' = sys.stdin)
out_path (default '-' = sys.stdout) out_path (default '-' = sys.stdout)
@ -289,6 +289,7 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
self.numErrors += 1 self.numErrors += 1
else: else:
# See if gametype is supported. # See if gametype is supported.
if 'mix' not in gametype: gametype['mix'] = 'none'
type = gametype['type'] type = gametype['type']
base = gametype['base'] base = gametype['base']
limit = gametype['limitType'] limit = gametype['limitType']
@ -332,6 +333,7 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
'base' in ('hold', 'stud', 'draw') 'base' in ('hold', 'stud', 'draw')
'category' in ('holdem', 'omahahi', omahahilo', 'razz', 'studhi', 'studhilo', 'fivedraw', '27_1draw', '27_3draw', 'badugi') 'category' in ('holdem', 'omahahi', omahahilo', 'razz', 'studhi', 'studhilo', 'fivedraw', '27_1draw', '27_3draw', 'badugi')
'hilo' in ('h','l','s') 'hilo' in ('h','l','s')
'mix' in (site specific, or 'none')
'smallBlind' int? 'smallBlind' int?
'bigBlind' int? 'bigBlind' int?
'smallBet' 'smallBet'
@ -446,6 +448,7 @@ or None if we fail to get the info """
def readCollectPot(self, hand): abstract def readCollectPot(self, hand): abstract
def readShownCards(self, hand): abstract def readShownCards(self, hand): abstract
# EDIT: readOther is depreciated
# Some sites do odd stuff that doesn't fall in to the normal HH parsing. # Some sites do odd stuff that doesn't fall in to the normal HH parsing.
# e.g., FTP doesn't put mixed game info in the HH, but puts in in the # e.g., FTP doesn't put mixed game info in the HH, but puts in in the
# file name. Use readOther() to clean up those messes. # file name. Use readOther() to clean up those messes.

View File

@ -37,8 +37,6 @@ class PokerStars(HandHistoryConverter):
filetype = "text" filetype = "text"
codepage = ("utf8", "cp1252") codepage = ("utf8", "cp1252")
siteId = 2 # Needs to match id entry in Sites database siteId = 2 # Needs to match id entry in Sites database
mixes = { 'HORSE': 'horse', '8-Game': '8game', 'HOSE': 'hose', 'Mixed Hold\'em': 'mholdem'} # Legal mixed games
sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\xe2\x82\xac", "GBP": "\xa3", "play": ""} # ADD Euro, Sterling, etc HERE sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\xe2\x82\xac", "GBP": "\xa3", "play": ""} # ADD Euro, Sterling, etc HERE
substitutions = { substitutions = {
'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes 'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes
@ -80,6 +78,15 @@ class PokerStars(HandHistoryConverter):
'Single Draw 2-7 Lowball' : ('draw','27_1draw'), 'Single Draw 2-7 Lowball' : ('draw','27_1draw'),
'5 Card Draw' : ('draw','fivedraw') '5 Card Draw' : ('draw','fivedraw')
} }
mixes = {
'HORSE': 'horse',
'8-Game': '8game',
'HOSE': 'hose',
'Mixed PLH/PLO': 'plh_plo',
'Mixed Omaha H/L': 'plo_lo',
'Mixed Hold\'em': 'mholdem',
'Triple Stud': '3stud'
} # Legal mixed games
currencies = { u'':'EUR', '$':'USD', '':'T$' } currencies = { u'':'EUR', '$':'USD', '':'T$' }
# Static regexes # Static regexes
@ -90,7 +97,7 @@ class PokerStars(HandHistoryConverter):
# here's how I plan to use LS # here's how I plan to use LS
(?P<BUYIN>(?P<BIAMT>[%(LS)s\d\.]+)?\+?(?P<BIRAKE>[%(LS)s\d\.]+)?\+?(?P<BOUNTY>[%(LS)s\d\.]+)?\s?(?P<TOUR_ISO>%(LEGAL_ISO)s)?|Freeroll)\s+)? (?P<BUYIN>(?P<BIAMT>[%(LS)s\d\.]+)?\+?(?P<BIRAKE>[%(LS)s\d\.]+)?\+?(?P<BOUNTY>[%(LS)s\d\.]+)?\s?(?P<TOUR_ISO>%(LEGAL_ISO)s)?|Freeroll)\s+)?
# close paren of tournament info # close paren of tournament info
(?P<MIXED>HORSE|8\-Game|HOSE|Mixed\sPLH/PLO|Mixed\sHold\'em)?\s?\(? (?P<MIXED>HORSE|8\-Game|HOSE|Mixed\sOmaha\sH/L|Mixed\sHold\'em|Mixed\sPLH/PLO|Triple\sStud)?\s?\(?
(?P<GAME>Hold\'em|Razz|RAZZ|7\sCard\sStud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball|Single\sDraw\s2\-7\sLowball|5\sCard\sDraw)\s (?P<GAME>Hold\'em|Razz|RAZZ|7\sCard\sStud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball|Single\sDraw\s2\-7\sLowball|5\sCard\sDraw)\s
(?P<LIMIT>No\sLimit|Limit|LIMIT|Pot\sLimit)\)?,?\s (?P<LIMIT>No\sLimit|Limit|LIMIT|Pot\sLimit)\)?,?\s
(-\s)? (-\s)?
@ -150,7 +157,7 @@ class PokerStars(HandHistoryConverter):
% short_subst, re.MULTILINE|re.VERBOSE) % short_subst, re.MULTILINE|re.VERBOSE)
re_ShowdownAction = re.compile(r"^%s: shows \[(?P<CARDS>.*)\]" % short_subst['PLYR'], re.MULTILINE) re_ShowdownAction = re.compile(r"^%s: shows \[(?P<CARDS>.*)\]" % short_subst['PLYR'], re.MULTILINE)
re_sitsOut = re.compile("^%s sits out" % short_subst['PLYR'], re.MULTILINE) re_sitsOut = re.compile("^%s sits out" % short_subst['PLYR'], re.MULTILINE)
re_ShownCards = re.compile("^Seat (?P<SEAT>[0-9]+): %s (\(.*\) )?(?P<SHOWED>showed|mucked) \[(?P<CARDS>.*)\].*" % short_subst['PLYR'], re.MULTILINE) re_ShownCards = re.compile("^Seat (?P<SEAT>[0-9]+): %s (\(.*\) )?(?P<SHOWED>showed|mucked) \[(?P<CARDS>.*)\]( and won \([.\d]+\) with (?P<STRING>.*))?" % short_subst['PLYR'], re.MULTILINE)
re_CollectPot = re.compile(r"Seat (?P<SEAT>[0-9]+): %(PLYR)s (\(button\) |\(small blind\) |\(big blind\) |\(button\) \(small blind\) |\(button\) \(big blind\) )?(collected|showed \[.*\] and won) \(%(CUR)s(?P<POT>[.\d]+)\)(, mucked| with.*|)" % short_subst, re.MULTILINE) re_CollectPot = re.compile(r"Seat (?P<SEAT>[0-9]+): %(PLYR)s (\(button\) |\(small blind\) |\(big blind\) |\(button\) \(small blind\) |\(button\) \(big blind\) )?(collected|showed \[.*\] and won) \(%(CUR)s(?P<POT>[.\d]+)\)(, mucked| with.*|)" % short_subst, re.MULTILINE)
def compilePlayerRegexs(self, hand): def compilePlayerRegexs(self, hand):
@ -198,6 +205,8 @@ class PokerStars(HandHistoryConverter):
info['bb'] = mg['BB'] info['bb'] = mg['BB']
if 'CURRENCY' in mg: if 'CURRENCY' in mg:
info['currency'] = self.currencies[mg['CURRENCY']] info['currency'] = self.currencies[mg['CURRENCY']]
if 'MIXED' in mg:
if mg['MIXED'] is not None: info['mix'] = self.mixes[mg['MIXED']]
if 'TOURNO' in mg and mg['TOURNO'] is None: if 'TOURNO' in mg and mg['TOURNO'] is None:
info['type'] = 'ring' info['type'] = 'ring'
@ -299,8 +308,6 @@ class PokerStars(HandHistoryConverter):
if key == 'MAX' and info[key] != None: if key == 'MAX' and info[key] != None:
hand.maxseats = int(info[key]) hand.maxseats = int(info[key])
if key == 'MIXED':
hand.mixed = self.mixes[info[key]] if info[key] is not None else None
if key == 'PLAY' and info['PLAY'] is not None: if key == 'PLAY' and info['PLAY'] is not None:
# hand.currency = 'play' # overrides previously set value # hand.currency = 'play' # overrides previously set value
hand.gametype['currency'] = 'play' hand.gametype['currency'] = 'play'
@ -455,13 +462,14 @@ class PokerStars(HandHistoryConverter):
if m.group('CARDS') is not None: if m.group('CARDS') is not None:
cards = m.group('CARDS') cards = m.group('CARDS')
cards = cards.split(' ') # needs to be a list, not a set--stud needs the order cards = cards.split(' ') # needs to be a list, not a set--stud needs the order
string = m.group('STRING')
(shown, mucked) = (False, False) (shown, mucked) = (False, False)
if m.group('SHOWED') == "showed": shown = True if m.group('SHOWED') == "showed": shown = True
elif m.group('SHOWED') == "mucked": mucked = True elif m.group('SHOWED') == "mucked": mucked = True
#print "DEBUG: hand.addShownCards(%s, %s, %s, %s)" %(cards, m.group('PNAME'), shown, mucked) #print "DEBUG: hand.addShownCards(%s, %s, %s, %s)" %(cards, m.group('PNAME'), shown, mucked)
hand.addShownCards(cards=cards, player=m.group('PNAME'), shown=shown, mucked=mucked) hand.addShownCards(cards=cards, player=m.group('PNAME'), shown=shown, mucked=mucked, string=string)
if __name__ == "__main__": if __name__ == "__main__":
parser = OptionParser() parser = OptionParser()

View File

@ -245,6 +245,7 @@ class Sql:
category varchar(9) NOT NULL, category varchar(9) NOT NULL,
limitType char(2) NOT NULL, limitType char(2) NOT NULL,
hiLo char(1) NOT NULL, hiLo char(1) NOT NULL,
mix varchar(9) NOT NULL,
smallBlind int, smallBlind int,
bigBlind int, bigBlind int,
smallBet int NOT NULL, smallBet int NOT NULL,
@ -252,32 +253,34 @@ class Sql:
ENGINE=INNODB""" ENGINE=INNODB"""
elif db_server == 'postgresql': elif db_server == 'postgresql':
self.query['createGametypesTable'] = """CREATE TABLE Gametypes ( self.query['createGametypesTable'] = """CREATE TABLE Gametypes (
id SERIAL, PRIMARY KEY (id), id SERIAL NOT NULL, PRIMARY KEY (id),
siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id), siteId INTEGER NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
currency varchar(4), currency varchar(4) NOT NULL,
type char(4), type char(4) NOT NULL,
base char(4), base char(4) NOT NULL,
category varchar(9), category varchar(9) NOT NULL,
limitType char(2), limitType char(2) NOT NULL,
hiLo char(1), hiLo char(1) NOT NULL,
mix char(9) NOT NULL,
smallBlind int, smallBlind int,
bigBlind int, bigBlind int,
smallBet int, smallBet int NOT NULL,
bigBet int)""" bigBet int NOT NULL)"""
elif db_server == 'sqlite': elif db_server == 'sqlite':
self.query['createGametypesTable'] = """CREATE TABLE Gametypes ( self.query['createGametypesTable'] = """CREATE TABLE Gametypes (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY NOT NULL,
siteId INTEGER, siteId INTEGER NOT NULL,
currency TEXT, currency TEXT NOT NULL,
type TEXT, type TEXT NOT NULL,
base TEXT, base TEXT NOT NULL,
category TEXT, category TEXT NOT NULL,
limitType TEXT, limitType TEXT NOT NULL,
hiLo TEXT, hiLo TEXT NOT NULL,
mix TEXT NOT NULL,
smallBlind INTEGER, smallBlind INTEGER,
bigBlind INTEGER, bigBlind INTEGER,
smallBet INTEGER, smallBet INTEGER NOT NULL,
bigBet INTEGER, bigBet INTEGER NOT NULL,
FOREIGN KEY(siteId) REFERENCES Sites(id) ON DELETE CASCADE)""" FOREIGN KEY(siteId) REFERENCES Sites(id) ON DELETE CASCADE)"""
@ -357,6 +360,7 @@ class Sql:
gametypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id), gametypeId SMALLINT UNSIGNED NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
sessionId INT UNSIGNED, sessionId INT UNSIGNED,
gameSessionId INT UNSIGNED, gameSessionId INT UNSIGNED,
fileId INT(10) UNSIGNED NOT NULL, FOREIGN KEY (fileId) REFERENCES Files(id),
startTime DATETIME NOT NULL, startTime DATETIME NOT NULL,
importTime DATETIME NOT NULL, importTime DATETIME NOT NULL,
seats TINYINT NOT NULL, seats TINYINT NOT NULL,
@ -368,6 +372,7 @@ class Sql:
boardcard4 smallint, boardcard4 smallint,
boardcard5 smallint, boardcard5 smallint,
texture smallint, texture smallint,
runIt BOOLEAN,
playersVpi SMALLINT NOT NULL, /* num of players vpi */ playersVpi SMALLINT NOT NULL, /* num of players vpi */
playersAtStreet1 SMALLINT NOT NULL, /* num of players seeing flop/street4 */ playersAtStreet1 SMALLINT NOT NULL, /* num of players seeing flop/street4 */
playersAtStreet2 SMALLINT NOT NULL, playersAtStreet2 SMALLINT NOT NULL,
@ -396,6 +401,7 @@ class Sql:
gametypeId INT NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id), gametypeId INT NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
sessionId INT, sessionId INT,
gameSessionId INT, gameSessionId INT,
fileId BIGINT NOT NULL, FOREIGN KEY (fileId) REFERENCES Files(id),
startTime timestamp without time zone NOT NULL, startTime timestamp without time zone NOT NULL,
importTime timestamp without time zone NOT NULL, importTime timestamp without time zone NOT NULL,
seats SMALLINT NOT NULL, seats SMALLINT NOT NULL,
@ -407,6 +413,7 @@ class Sql:
boardcard4 smallint, boardcard4 smallint,
boardcard5 smallint, boardcard5 smallint,
texture smallint, texture smallint,
runIt BOOLEAN,
playersVpi SMALLINT NOT NULL, /* num of players vpi */ playersVpi SMALLINT NOT NULL, /* num of players vpi */
playersAtStreet1 SMALLINT NOT NULL, /* num of players seeing flop/street4 */ playersAtStreet1 SMALLINT NOT NULL, /* num of players seeing flop/street4 */
playersAtStreet2 SMALLINT NOT NULL, playersAtStreet2 SMALLINT NOT NULL,
@ -434,6 +441,7 @@ class Sql:
gametypeId INT NOT NULL, gametypeId INT NOT NULL,
sessionId INT, sessionId INT,
gameSessionId INT, gameSessionId INT,
fileId INT NOT NULL,
startTime REAL NOT NULL, startTime REAL NOT NULL,
importTime REAL NOT NULL, importTime REAL NOT NULL,
seats INT NOT NULL, seats INT NOT NULL,
@ -445,6 +453,7 @@ class Sql:
boardcard4 INT, boardcard4 INT,
boardcard5 INT, boardcard5 INT,
texture INT, texture INT,
runIt BOOLEAN,
playersVpi INT NOT NULL, /* num of players vpi */ playersVpi INT NOT NULL, /* num of players vpi */
playersAtStreet1 INT NOT NULL, /* num of players seeing flop/street4 */ playersAtStreet1 INT NOT NULL, /* num of players seeing flop/street4 */
playersAtStreet2 INT NOT NULL, playersAtStreet2 INT NOT NULL,
@ -464,6 +473,42 @@ class Sql:
comment TEXT, comment TEXT,
commentTs REAL)""" commentTs REAL)"""
################################
# Create Hands
################################
if db_server == 'mysql':
self.query['createBoardsTable'] = """CREATE TABLE Boards (
id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
handId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handId) REFERENCES Hands(id),
boardId smallint,
boardcard1 smallint, /* 0=none, 1-13=2-Ah 14-26=2-Ad 27-39=2-Ac 40-52=2-As */
boardcard2 smallint,
boardcard3 smallint,
boardcard4 smallint,
boardcard5 smallint)
ENGINE=INNODB"""
elif db_server == 'postgresql':
self.query['createBoardsTable'] = """CREATE TABLE Boards (
id BIGSERIAL, PRIMARY KEY (id),
handId BIGINT NOT NULL, FOREIGN KEY (handId) REFERENCES Hands(id),
boardId smallint,
boardcard1 smallint, /* 0=none, 1-13=2-Ah 14-26=2-Ad 27-39=2-Ac 40-52=2-As */
boardcard2 smallint,
boardcard3 smallint,
boardcard4 smallint,
boardcard5 smallint)"""
elif db_server == 'sqlite':
self.query['createBoardsTable'] = """CREATE TABLE Boards (
id INTEGER PRIMARY KEY,
handId INT NOT NULL,
boardId INT,
boardcard1 INT, /* 0=none, 1-13=2-Ah 14-26=2-Ad 27-39=2-Ac 40-52=2-As */
boardcard2 INT,
boardcard3 INT,
boardcard4 INT,
boardcard5 INT)"""
################################ ################################
# Create TourneyTypes # Create TourneyTypes
@ -686,6 +731,7 @@ class Sql:
street3Seen BOOLEAN, street3Seen BOOLEAN,
street4Seen BOOLEAN, street4Seen BOOLEAN,
sawShowdown BOOLEAN, sawShowdown BOOLEAN,
showed BOOLEAN,
street1Aggr BOOLEAN, street1Aggr BOOLEAN,
street2Aggr BOOLEAN, street2Aggr BOOLEAN,
@ -826,6 +872,7 @@ class Sql:
street3Seen BOOLEAN, street3Seen BOOLEAN,
street4Seen BOOLEAN, street4Seen BOOLEAN,
sawShowdown BOOLEAN, sawShowdown BOOLEAN,
showed BOOLEAN,
street1Aggr BOOLEAN, street1Aggr BOOLEAN,
street2Aggr BOOLEAN, street2Aggr BOOLEAN,
@ -965,6 +1012,7 @@ class Sql:
street3Seen INT, street3Seen INT,
street4Seen INT, street4Seen INT,
sawShowdown INT, sawShowdown INT,
showed INT,
street1Aggr INT, street1Aggr INT,
street2Aggr INT, street2Aggr INT,
@ -1136,6 +1184,60 @@ class Sql:
allIn BOOLEAN allIn BOOLEAN
)""" )"""
################################
# Create Files
################################
if db_server == 'mysql':
self.query['createFilesTable'] = """CREATE TABLE Files (
id INT(10) UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id),
file text NOT NULL,
site VARCHAR(32),
type VARCHAR(7),
startTime DATETIME NOT NULL,
lastUpdate DATETIME NOT NULL,
endTime DATETIME,
hands INT,
stored INT,
dups INT,
partial INT,
errs INT,
ttime100 INT,
finished BOOLEAN)
ENGINE=INNODB"""
elif db_server == 'postgresql':
self.query['createFilesTable'] = """CREATE TABLE Files (
id BIGSERIAL, PRIMARY KEY (id),
file TEXT NOT NULL,
site VARCHAR(32),
type VARCHAR(7),
startTime timestamp without time zone NOT NULL,
lastUpdate timestamp without time zone NOT NULL,
endTime timestamp without time zone,
hands INT,
stored INT,
dups INT,
partial INT,
errs INT,
ttime100 INT,
finished BOOLEAN)"""
elif db_server == 'sqlite':
self.query['createFilesTable'] = """CREATE TABLE Files (
id INTEGER PRIMARY KEY,
file TEXT NOT NULL,
site VARCHAR(32),
type VARCHAR(7),
startTime timestamp NOT NULL,
lastUpdate timestamp NOT NULL,
endTime timestamp,
hands INT,
stored INT,
dups INT,
partial INT,
errs INT,
ttime100 INT,
finished BOOLEAN
)"""
################################ ################################
# Create HudCache # Create HudCache
@ -1498,10 +1600,10 @@ class Sql:
elif db_server == 'postgresql': elif db_server == 'postgresql':
self.query['createSessionsCacheTable'] = """CREATE TABLE SessionsCache ( self.query['createSessionsCacheTable'] = """CREATE TABLE SessionsCache (
id BIGSERIAL, PRIMARY KEY (id), id BIGSERIAL, PRIMARY KEY (id),
sessionStart REAL NOT NULL, sessionStart timestamp without time zone NOT NULL,
sessionEnd REAL NOT NULL, sessionEnd timestamp without time zone NOT NULL,
gameStart REAL NOT NULL, gameStart timestamp without time zone NOT NULL,
gameEnd REAL NOT NULL, gameEnd timestamp without time zone NOT NULL,
sessionId INT, sessionId INT,
date CHAR(7) NOT NULL, /* 1st char is style (A/T/H/S), other 6 are the key */ date CHAR(7) NOT NULL, /* 1st char is style (A/T/H/S), other 6 are the key */
type char(7), type char(7),
@ -3481,7 +3583,7 @@ class Sql:
<limit_test> <limit_test>
<game_test> <game_test>
AND hp.tourneysPlayersId IS NULL AND hp.tourneysPlayersId IS NULL
GROUP BY h.startTime, hp.handId, hp.sawShowdown, ( hp.totalProfit / ( gt.bigBlind * 2 ) ) * 100 GROUP BY h.startTime, hp.handId, hp.sawShowdown, hp.totalProfit
ORDER BY h.startTime""" ORDER BY h.startTime"""
self.query['getRingProfitAllHandsPlayerIdSiteInDollars'] = """ self.query['getRingProfitAllHandsPlayerIdSiteInDollars'] = """
@ -4645,14 +4747,15 @@ class Sql:
AND category=%s AND category=%s
AND limitType=%s AND limitType=%s
AND currency=%s AND currency=%s
AND mix=%s
AND smallBlind=%s AND smallBlind=%s
AND bigBlind=%s AND bigBlind=%s
""" """
self.query['insertGameTypes'] = """INSERT INTO Gametypes self.query['insertGameTypes'] = """INSERT INTO Gametypes
(siteId, currency, type, base, category, limitType (siteId, currency, type, base, category, limitType
,hiLo, smallBlind, bigBlind, smallBet, bigBet) ,hiLo, mix, smallBlind, bigBlind, smallBet, bigBet)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""" VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
self.query['isAlreadyInDB'] = """SELECT id FROM Hands self.query['isAlreadyInDB'] = """SELECT id FROM Hands
WHERE gametypeId=%s AND siteHandNo=%s WHERE gametypeId=%s AND siteHandNo=%s
@ -4792,6 +4895,7 @@ class Sql:
gametypeid, gametypeid,
sessionId, sessionId,
gameSessionId, gameSessionId,
fileId,
startTime, startTime,
importtime, importtime,
seats, seats,
@ -4803,6 +4907,7 @@ class Sql:
boardcard3, boardcard3,
boardcard4, boardcard4,
boardcard5, boardcard5,
runIt,
playersAtStreet1, playersAtStreet1,
playersAtStreet2, playersAtStreet2,
playersAtStreet3, playersAtStreet3,
@ -4822,7 +4927,8 @@ class Sql:
values values
(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""" %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s)"""
self.query['store_hands_players'] = """insert into HandsPlayers ( self.query['store_hands_players'] = """insert into HandsPlayers (
@ -4860,6 +4966,7 @@ class Sql:
street3Seen, street3Seen,
street4Seen, street4Seen,
sawShowdown, sawShowdown,
showed,
wonAtSD, wonAtSD,
street0Aggr, street0Aggr,
street1Aggr, street1Aggr,
@ -4968,7 +5075,7 @@ class Sql:
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s %s, %s, %s
)""" )"""
self.query['store_hands_actions'] = """insert into HandsActions ( self.query['store_hands_actions'] = """insert into HandsActions (
@ -4991,6 +5098,56 @@ class Sql:
%s, %s %s, %s
)""" )"""
self.query['store_boards'] = """insert into Boards (
handId,
boardId,
boardcard1,
boardcard2,
boardcard3,
boardcard4,
boardcard5
)
values (
%s, %s, %s, %s, %s,
%s, %s
)"""
################################
# queries for Files Table
################################
self.query['store_file'] = """ insert into Files (
file,
site,
startTime,
lastUpdate,
hands,
stored,
dups,
partial,
errs,
ttime100,
finished)
values (
%s, %s, %s, %s, %s,
%s, %s, %s, %s, %s,
%s
)"""
self.query['update_file'] = """
UPDATE Files SET
type=%s,
lastUpdate=%s,
endTime=%s,
hands=hands+%s,
stored=stored+%s,
dups=dups+%s,
partial=partial+%s,
errs=errs+%s,
ttime100=ttime100+%s,
finished=%s
WHERE id=%s"""
################################ ################################
# Counts for DB stats window # Counts for DB stats window
################################ ################################

View File

@ -127,7 +127,7 @@ def compare_handsplayers_file(filename, importer, errors):
# The stats match - continue # The stats match - continue
pass pass
else: else:
if stat == 'tourneyTypeId' or stat == 'tourneysPlayersIds': if stat == 'tourneyTypeId' or stat == 'tourneysPlayersIds' or stat == 'showed':
# Not and error # Not and error
pass pass
else: else:
@ -153,6 +153,7 @@ def compare_hands_file(filename, importer, errors):
del ghash['gsc'] del ghash['gsc']
del ghash['sc'] del ghash['sc']
del ghash['id'] del ghash['id']
del ghash['board']
for datum in ghash: for datum in ghash:
#print "DEBUG: hand: '%s'" % datum #print "DEBUG: hand: '%s'" % datum
try: try:
@ -161,7 +162,12 @@ def compare_hands_file(filename, importer, errors):
pass pass
else: else:
# Stats don't match. # Stats don't match.
if datum == "gametypeId" or datum == 'sessionId' or datum == 'tourneyId' or datum == 'gameSessionId': if (datum == "gametypeId"
or datum == 'sessionId'
or datum == 'tourneyId'
or datum == 'gameSessionId'
or datum == 'fileId'
or datum == 'runIt'):
# Not an error. gametypeIds are dependent on the order added to the db. # Not an error. gametypeIds are dependent on the order added to the db.
#print "DEBUG: Skipping mismatched gamtypeId" #print "DEBUG: Skipping mismatched gamtypeId"
pass pass

View File

@ -166,6 +166,19 @@ class Importer:
for i in xrange(len(self.writerdbs)): for i in xrange(len(self.writerdbs)):
self.writerdbs[i].disconnect() self.writerdbs[i].disconnect()
def logImport(self, type, file, stored, dups, partial, errs, ttime, id):
hands = stored + dups + partial + errs
now = datetime.datetime.utcnow()
ttime100 = ttime * 100
self.database.updateFile([type, now, now, hands, stored, dups, partial, errs, ttime100, True, id])
def addFileToList(self, file, site, filter):
now = datetime.datetime.utcnow()
file = os.path.splitext(os.path.basename(file))[0]
id = self.database.storeFile([file, site, now, now, 0, 0, 0, 0, 0, 0, False])
self.database.commit()
return [site] + [filter] + [id]
#Add an individual file to filelist #Add an individual file to filelist
def addImportFile(self, filename, site = "default", filter = "passthrough"): def addImportFile(self, filename, site = "default", filter = "passthrough"):
#TODO: test it is a valid file -> put that in config!! #TODO: test it is a valid file -> put that in config!!
@ -173,7 +186,7 @@ class Importer:
# filename not guaranteed to be unicode # filename not guaranteed to be unicode
if filename in self.filelist or not os.path.exists(filename): if filename in self.filelist or not os.path.exists(filename):
return return
self.filelist[filename] = [site] + [filter] self.filelist[filename] = self.addFileToList(filename, site, filter)
if site not in self.siteIds: if site not in self.siteIds:
# Get id from Sites table in DB # Get id from Sites table in DB
result = self.database.get_site_id(site) result = self.database.get_site_id(site)
@ -303,13 +316,15 @@ class Importer:
ProgressDialog.progress_update() ProgressDialog.progress_update()
(stored, duplicates, partial, errors, ttime) = self.import_file_dict(file (stored, duplicates, partial, errors, ttime) = self.import_file_dict(file, self.filelist[file][0]
,self.filelist[file][0], self.filelist[file][1], q) ,self.filelist[file][1], self.filelist[file][2], q)
totstored += stored totstored += stored
totdups += duplicates totdups += duplicates
totpartial += partial totpartial += partial
toterrors += errors toterrors += errors
self.logImport('bulk', file, stored, duplicates, partial, errors, ttime, self.filelist[file][2])
self.database.commit()
del ProgressDialog del ProgressDialog
for i in xrange( self.settings['threads'] ): for i in xrange( self.settings['threads'] ):
@ -394,7 +409,9 @@ class Importer:
self.caller.addText("\n"+os.path.basename(file)) self.caller.addText("\n"+os.path.basename(file))
except KeyError: # TODO: What error happens here? except KeyError: # TODO: What error happens here?
pass pass
(stored, duplicates, partial, errors, ttime) = self.import_file_dict(file, self.filelist[file][0], self.filelist[file][1], None) (stored, duplicates, partial, errors, ttime) = self.import_file_dict(file, self.filelist[file][0]
,self.filelist[file][1], self.filelist[file][2], None)
self.logImport('auto', file, stored, duplicates, partial, errors, ttime, self.filelist[file][2])
try: try:
if not os.path.isdir(file): # Note: This assumes that whatever calls us has an "addText" func if not os.path.isdir(file): # Note: This assumes that whatever calls us has an "addText" func
self.caller.addText(" %d stored, %d duplicates, %d partial, %d errors (time = %f)" % (stored, duplicates, partial, errors, ttime)) self.caller.addText(" %d stored, %d duplicates, %d partial, %d errors (time = %f)" % (stored, duplicates, partial, errors, ttime))
@ -425,7 +442,7 @@ class Importer:
#rulog.close() #rulog.close()
# This is now an internal function that should not be called directly. # This is now an internal function that should not be called directly.
def import_file_dict(self, file, site, filter, q=None): def import_file_dict(self, file, site, filter, fileId, q=None):
if os.path.isdir(file): if os.path.isdir(file):
self.addToDirList[file] = [site] + [filter] self.addToDirList[file] = [site] + [filter]
@ -449,7 +466,7 @@ class Importer:
hhc = obj( self.config, in_path = file, index = idx hhc = obj( self.config, in_path = file, index = idx
,starsArchive = self.settings['starsArchive'] ,starsArchive = self.settings['starsArchive']
,ftpArchive = self.settings['ftpArchive'] ,ftpArchive = self.settings['ftpArchive']
,sitename = site ) ,sitename = site)
if hhc.getStatus(): if hhc.getStatus():
if self.caller: hhc.progressNotify() if self.caller: hhc.progressNotify()
@ -476,10 +493,10 @@ class Importer:
try: try:
id = hand.getHandId(self.database, id) id = hand.getHandId(self.database, id)
sc, gsc = hand.updateSessionsCache(self.database, sc, gsc, None, doinsert) sc, gsc = hand.updateSessionsCache(self.database, sc, gsc, None, doinsert)
hbulk = hand.insertHands(self.database, hbulk, doinsert, self.settings['testData']) hbulk = hand.insertHands(self.database, hbulk, fileId, doinsert, self.settings['testData'])
hcbulk = hand.updateHudCache(self.database, hcbulk, doinsert) hcbulk = hand.updateHudCache(self.database, hcbulk, doinsert)
ihands.append(hand) ihands.append(hand)
to_hud.append(id) to_hud.append(hand.dbid_hands)
except Exceptions.FpdbHandDuplicate: except Exceptions.FpdbHandDuplicate:
duplicates += 1 duplicates += 1
self.database.commit() self.database.commit()
@ -496,7 +513,7 @@ class Importer:
if self.callHud: if self.callHud:
for hid in to_hud: for hid in to_hud:
try: try:
print _("fpdb_import: sending hand to hud"), hand.dbid_hands, "pipe =", self.caller.pipe_to_hud print _("fpdb_import: sending hand to hud"), hid, "pipe =", self.caller.pipe_to_hud
self.caller.pipe_to_hud.stdin.write("%s" % (hid) + os.linesep) self.caller.pipe_to_hud.stdin.write("%s" % (hid) + os.linesep)
except IOError, e: except IOError, e:
log.error(_("Failed to send hand to HUD: %s") % e) log.error(_("Failed to send hand to HUD: %s") % e)