Merge branch 'chaz'
This commit is contained in:
commit
00c3c114a8
|
@ -73,7 +73,7 @@ except ImportError:
|
|||
use_numpy = False
|
||||
|
||||
|
||||
DB_VERSION = 152
|
||||
DB_VERSION = 156
|
||||
|
||||
|
||||
# Variance created as sqlite has a bunch of undefined aggregate functions.
|
||||
|
@ -124,10 +124,12 @@ class Database:
|
|||
, [ # indexes for postgres (list index 3)
|
||||
{'tab':'Gametypes', 'col':'siteId', 'drop':0}
|
||||
, {'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':'HandsActions', 'col':'handId', 'drop':1}
|
||||
, {'tab':'HandsActions', 'col':'playerId', 'drop':1}
|
||||
, {'tab':'HandsActions', 'col':'actionId', 'drop':1}
|
||||
, {'tab':'Boards', 'col':'handId', 'drop':1}
|
||||
, {'tab':'HandsPlayers', 'col':'handId', 'drop':1}
|
||||
, {'tab':'HandsPlayers', 'col':'playerId', 'drop':1}
|
||||
, {'tab':'HandsPlayers', 'col':'tourneysPlayersId', 'drop':0}
|
||||
|
@ -151,6 +153,8 @@ class Database:
|
|||
]
|
||||
, [ # indexes for sqlite (list index 4)
|
||||
{'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':'playerId', 'drop':0}
|
||||
, {'tab':'HandsPlayers', 'col':'tourneysPlayersId', 'drop':0}
|
||||
|
@ -179,6 +183,8 @@ class Database:
|
|||
, [ ] # no db with index 1
|
||||
, [ # foreign keys for mysql (index 2)
|
||||
{'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':'playerId', 'rtab':'Players', '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)
|
||||
{'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':'playerId', 'rtab':'Players', '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.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
|
||||
result+="###################\nTable "+table+"\n###################\n"
|
||||
rows=self.cursor.execute(self.sql.query['get'+table])
|
||||
|
@ -515,12 +523,12 @@ class Database:
|
|||
except:# _mysql_exceptions.ProgrammingError:
|
||||
if database != ":memory:":
|
||||
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."))
|
||||
self.recreate_tables()
|
||||
self.check_version(database=database, create=False)
|
||||
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."))
|
||||
self.wrongDbVersion = True
|
||||
else:
|
||||
|
@ -1241,7 +1249,7 @@ class Database:
|
|||
self.createAllIndexes()
|
||||
self.commit()
|
||||
self.get_sites()
|
||||
print _("Finished recreating tables")
|
||||
#print _("Finished recreating tables")
|
||||
log.info(_("Finished recreating tables"))
|
||||
#end def recreate_tables
|
||||
|
||||
|
@ -1256,9 +1264,11 @@ class Database:
|
|||
c.execute(self.sql.query['createActionsTable'])
|
||||
c.execute(self.sql.query['createSitesTable'])
|
||||
c.execute(self.sql.query['createGametypesTable'])
|
||||
c.execute(self.sql.query['createFilesTable'])
|
||||
c.execute(self.sql.query['createPlayersTable'])
|
||||
c.execute(self.sql.query['createAutoratesTable'])
|
||||
c.execute(self.sql.query['createHandsTable'])
|
||||
c.execute(self.sql.query['createBoardsTable'])
|
||||
c.execute(self.sql.query['createTourneyTypesTable'])
|
||||
c.execute(self.sql.query['createTourneysTable'])
|
||||
c.execute(self.sql.query['createTourneysPlayersTable'])
|
||||
|
@ -1857,6 +1867,7 @@ class Database:
|
|||
hdata['gametypeId'],
|
||||
hdata['sessionId'],
|
||||
hdata['gameSessionId'],
|
||||
hdata['fileId'],
|
||||
hdata['startTime'],
|
||||
datetime.utcnow(), #importtime
|
||||
hdata['seats'],
|
||||
|
@ -1868,6 +1879,7 @@ class Database:
|
|||
hdata['boardcard3'],
|
||||
hdata['boardcard4'],
|
||||
hdata['boardcard5'],
|
||||
hdata['runIt'],
|
||||
hdata['playersAtStreet1'],
|
||||
hdata['playersAtStreet2'],
|
||||
hdata['playersAtStreet3'],
|
||||
|
@ -1883,19 +1895,28 @@ class Database:
|
|||
hdata['street3Pot'],
|
||||
hdata['street4Pot'],
|
||||
hdata['showdownPot'],
|
||||
hdata['boards'],
|
||||
hdata['id']
|
||||
])
|
||||
|
||||
if doinsert:
|
||||
bbulk = []
|
||||
for h in hbulk:
|
||||
id = h.pop()
|
||||
if hdata['sc'] and hdata['gsc']:
|
||||
h[4] = hdata['sc'][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 = q.replace('%s', self.sql.query['placeholder'])
|
||||
c = self.get_cursor()
|
||||
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()
|
||||
return hbulk
|
||||
|
||||
|
@ -1941,6 +1962,7 @@ class Database:
|
|||
pdata[p]['street3Seen'],
|
||||
pdata[p]['street4Seen'],
|
||||
pdata[p]['sawShowdown'],
|
||||
pdata[p]['showed'],
|
||||
pdata[p]['wonAtSD'],
|
||||
pdata[p]['street0Aggr'],
|
||||
pdata[p]['street1Aggr'],
|
||||
|
@ -2087,6 +2109,7 @@ class Database:
|
|||
insert_hudcache = insert_hudcache.replace('%s', self.sql.query['placeholder'])
|
||||
|
||||
#print "DEBUG: %s %s %s" %(hid, pids, pdata)
|
||||
hcs = []
|
||||
for p in pdata:
|
||||
#NOTE: Insert new stats at right place because SQL needs strict order
|
||||
line = []
|
||||
|
@ -2179,7 +2202,7 @@ class Database:
|
|||
line.append(pdata[p]['street3Raises'])
|
||||
line.append(pdata[p]['street4Raises'])
|
||||
|
||||
hc, hcs = {}, []
|
||||
hc = {}
|
||||
hc['gametypeId'] = gid
|
||||
hc['playerId'] = pids[p]
|
||||
hc['activeSeats'] = len(pids)
|
||||
|
@ -2187,6 +2210,9 @@ class Database:
|
|||
hc['position'] = pos[pdata[p]['position']]
|
||||
hc['tourneyTypeId'] = pdata[p]['tourneyTypeId']
|
||||
hc['styleKey'] = styleKey
|
||||
for i in range(len(line)):
|
||||
if line[i]: line[i] = 1
|
||||
else: line[i] = 0
|
||||
hc['line'] = line
|
||||
hc['game'] = [hc['gametypeId']
|
||||
,hc['playerId']
|
||||
|
@ -2199,6 +2225,7 @@ class Database:
|
|||
for h in hcs:
|
||||
match = False
|
||||
for b in hcbulk:
|
||||
#print h['game']==b['game'], h['game'], b['game']
|
||||
if h['game']==b['game']:
|
||||
b['line'] = [sum(l) for l in zip(b['line'], h['line'])]
|
||||
match = True
|
||||
|
@ -2206,14 +2233,9 @@ class Database:
|
|||
|
||||
if doinsert:
|
||||
inserts = []
|
||||
exists = []
|
||||
updates = []
|
||||
c = self.get_cursor()
|
||||
for hc in hcbulk:
|
||||
row = hc['line'] + hc['game']
|
||||
if hc['game'] in exists:
|
||||
updates.append(row)
|
||||
continue
|
||||
c = self.get_cursor()
|
||||
num = c.execute(update_hudcache, row)
|
||||
# Try to do the update first. Do insert it did not work
|
||||
if ((self.backend == self.PGSQL and c.statusmessage != "UPDATE 1")
|
||||
|
@ -2224,10 +2246,10 @@ class Database:
|
|||
#num = c.execute(insert_hudcache, row)
|
||||
#print "DEBUG: Successfully(?: %s) updated HudCacho using INSERT" % num
|
||||
else:
|
||||
exists.append(hc['game'])
|
||||
#print "DEBUG: Successfully updated HudCacho using UPDATE"
|
||||
if inserts: c.executemany(insert_hudcache, inserts)
|
||||
if updates: c.executemany(update_hudcache, updates)
|
||||
pass
|
||||
if inserts:
|
||||
c.executemany(insert_hudcache, inserts)
|
||||
|
||||
return hcbulk
|
||||
|
||||
|
@ -2500,6 +2522,52 @@ class Database:
|
|||
|
||||
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):
|
||||
#Grab playerIds using hero names in HUD_Config.xml
|
||||
try:
|
||||
|
@ -2549,40 +2617,6 @@ class Database:
|
|||
dup = True
|
||||
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
|
||||
#################################
|
||||
|
|
|
@ -43,6 +43,7 @@ class DerivedStats():
|
|||
init['street4Aggr'] = False
|
||||
init['wonWhenSeenStreet1'] = 0.0
|
||||
init['sawShowdown'] = False
|
||||
init['showed'] = False
|
||||
init['wonAtSD'] = 0.0
|
||||
init['startCards'] = 0
|
||||
init['position'] = 2
|
||||
|
@ -144,6 +145,20 @@ class DerivedStats():
|
|||
self.hands['boardcard4'] = cards[3]
|
||||
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()
|
||||
totals = hand.getStreetTotals()
|
||||
totals = [int(100*i) for i in totals]
|
||||
|
@ -173,6 +188,8 @@ class DerivedStats():
|
|||
self.handsplayers[player[1]]['tourneysPlayersIds'] = hand.tourneysPlayersIds[player[1]]
|
||||
else:
|
||||
self.handsplayers[player[1]]['tourneysPlayersIds'] = None
|
||||
if player[1] in hand.shown:
|
||||
self.handsplayers[player[1]]['showed'] = True
|
||||
|
||||
#### seen now processed in playersAtStreetX()
|
||||
# XXX: enumerate(list, start=x) is python 2.6 syntax; 'start'
|
||||
|
|
|
@ -148,17 +148,11 @@ class Fulltilt(HandHistoryConverter):
|
|||
##Total Prize Pool: 1,500 Play Chips
|
||||
|
||||
# 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)
|
||||
# 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)
|
||||
|
||||
|
||||
|
||||
|
||||
mixes = { 'HORSE': 'horse', '7-Game': '7game', 'HOSE': 'hose', 'HA': 'ha'}
|
||||
|
||||
|
||||
def compilePlayerRegexs(self, hand):
|
||||
players = set([player[1] for player in hand.players])
|
||||
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_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_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):
|
||||
return [["ring", "hold", "nl"],
|
||||
|
@ -233,6 +227,21 @@ class Fulltilt(HandHistoryConverter):
|
|||
'Badugi' : ('draw','badugi'),
|
||||
'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$' }
|
||||
|
||||
if 'SB' in mg:
|
||||
|
@ -264,6 +273,9 @@ class Fulltilt(HandHistoryConverter):
|
|||
if mg['CURRENCY'] is not None:
|
||||
info['currency'] = currencies[mg['CURRENCY']]
|
||||
# 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
|
||||
|
||||
def readHandInfo(self, hand):
|
||||
|
@ -380,10 +392,16 @@ class Fulltilt(HandHistoryConverter):
|
|||
def markStreets(self, hand):
|
||||
|
||||
if hand.gametype['base'] == 'hold':
|
||||
m = re.search(r"\*\*\* HOLE CARDS \*\*\*(?P<PREFLOP>.+(?=\*\*\* FLOP \*\*\*)|.+)"
|
||||
r"(\*\*\* FLOP \*\*\*(?P<FLOP> \[\S\S \S\S \S\S\].+(?=\*\*\* TURN \*\*\*)|.+))?"
|
||||
r"(\*\*\* TURN \*\*\* \[\S\S \S\S \S\S] (?P<TURN>\[\S\S\].+(?=\*\*\* RIVER \*\*\*)|.+))?"
|
||||
r"(\*\*\* RIVER \*\*\* \[\S\S \S\S \S\S \S\S] (?P<RIVER>\[\S\S\].+))?", hand.handText,re.DOTALL)
|
||||
m = re.search(r"\*\*\* HOLE CARDS \*\*\*(?P<PREFLOP>.+(?=\*\*\* FLOP (1\s)?\*\*\*)|.+)"
|
||||
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 (1\s)?\*\*\*)|.+))?"
|
||||
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":
|
||||
m = re.search(r"(?P<ANTES>.+(?=\*\*\* 3RD 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
|
||||
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])
|
||||
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):
|
||||
try:
|
||||
|
@ -520,10 +541,16 @@ class Fulltilt(HandHistoryConverter):
|
|||
def readShownCards(self,hand):
|
||||
for m in self.re_ShownCards.finditer(hand.handText):
|
||||
if m.group('CARDS') is not None:
|
||||
if m.group('ACT'):
|
||||
hand.addShownCards(cards=m.group('CARDS').split(' '), player=m.group('PNAME'), shown = False, mucked = True)
|
||||
else:
|
||||
hand.addShownCards(cards=m.group('CARDS').split(' '), player=m.group('PNAME'), shown = True, mucked = False)
|
||||
cards = m.group('CARDS')
|
||||
cards = cards.split(' ') # needs to be a list, not a set--stud needs the order
|
||||
string = m.group('STRING')
|
||||
|
||||
(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):
|
||||
"""Return a guess at max_seats when not specified in HH."""
|
||||
|
@ -543,13 +570,6 @@ class Fulltilt(HandHistoryConverter):
|
|||
if mo <= 6: return 6
|
||||
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):
|
||||
self.status = True
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ class Hand(object):
|
|||
self.maxseats = None
|
||||
self.counted_seats = 0
|
||||
self.buttonpos = 0
|
||||
self.runItTimes = 0
|
||||
|
||||
#tourney stuff
|
||||
self.tourNo = None
|
||||
|
@ -112,6 +113,7 @@ class Hand(object):
|
|||
self.board = {} # dict from street names to community cards
|
||||
self.holecards = {}
|
||||
self.discards = {}
|
||||
self.showdownStrings = {}
|
||||
for street in self.allStreets:
|
||||
self.streets[street] = "" # portions of the handText, filled by markStreets()
|
||||
self.actions[street] = []
|
||||
|
@ -273,12 +275,13 @@ dealt whether they were seen in a 'dealt to' line
|
|||
next = id +1
|
||||
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
|
||||
Should not commit, and do minimal selects. Callers may want to cache commits
|
||||
db: a connected Database object"""
|
||||
self.hands['gametypeId'] = self.dbid_gt
|
||||
self.hands['seats'] = len(self.dbid_pids)
|
||||
self.hands['fileId'] = fileId
|
||||
hbulk = db.storeHand(self.hands, hbulk, doinsert, printtest)
|
||||
return hbulk
|
||||
|
||||
|
@ -709,7 +712,7 @@ Add a raise on [street] by [player] to [amountTo]
|
|||
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).
|
||||
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))
|
||||
if cards is not None:
|
||||
self.addHoleCards(cards,player,shown, mucked)
|
||||
if string is not None:
|
||||
self.showdownStrings[player] = string
|
||||
elif holeandboard is not None:
|
||||
holeandboard = set([self.card(c) for c in holeandboard])
|
||||
board = set([c for s in self.board.values() for c in s])
|
||||
|
@ -886,9 +891,8 @@ class HoldemOmahaHand(Hand):
|
|||
hhc.readHeroCards(self)
|
||||
hhc.readShowdownActions(self)
|
||||
# Read actions in street order
|
||||
for street in self.communityStreets:
|
||||
if self.streets[street]:
|
||||
hhc.readCommunityCards(self, street)
|
||||
for street, text in self.streets.iteritems():
|
||||
if text: hhc.readCommunityCards(self, street)
|
||||
for street in self.actionStreets:
|
||||
if self.streets[street]:
|
||||
hhc.readAction(self, street)
|
||||
|
@ -912,7 +916,7 @@ class HoldemOmahaHand(Hand):
|
|||
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 shown: self.shown.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 )
|
||||
if len(diff) == 2 and self.gametype['category'] in ('holdem'):
|
||||
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):
|
||||
# street1Pot INT, /* pot size at flop/street4 */
|
||||
|
@ -1200,13 +1206,15 @@ class DrawHand(Hand):
|
|||
elif builtFrom == "DB":
|
||||
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 shown: self.shown.add(player)
|
||||
if mucked: self.mucked.add(player)
|
||||
else:
|
||||
# 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)
|
||||
if string is not None:
|
||||
self.showdownStrings[player] = string
|
||||
|
||||
|
||||
def discardDrawHoleCards(self, cards, player, street):
|
||||
|
@ -1378,7 +1386,7 @@ class StudHand(Hand):
|
|||
elif builtFrom == "DB":
|
||||
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 shown: self.shown.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)
|
||||
if len(cards) > 6:
|
||||
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=[]):
|
||||
|
|
|
@ -68,7 +68,7 @@ class HandHistoryConverter():
|
|||
|
||||
# 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
|
||||
, autostart=True, starsArchive=False, ftpArchive=False, sitename="PokerStars" ):
|
||||
, autostart=True, starsArchive=False, ftpArchive=False, sitename="PokerStars"):
|
||||
"""\
|
||||
in_path (default '-' = sys.stdin)
|
||||
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
|
||||
else:
|
||||
# See if gametype is supported.
|
||||
if 'mix' not in gametype: gametype['mix'] = 'none'
|
||||
type = gametype['type']
|
||||
base = gametype['base']
|
||||
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')
|
||||
'category' in ('holdem', 'omahahi', omahahilo', 'razz', 'studhi', 'studhilo', 'fivedraw', '27_1draw', '27_3draw', 'badugi')
|
||||
'hilo' in ('h','l','s')
|
||||
'mix' in (site specific, or 'none')
|
||||
'smallBlind' int?
|
||||
'bigBlind' int?
|
||||
'smallBet'
|
||||
|
@ -446,6 +448,7 @@ or None if we fail to get the info """
|
|||
def readCollectPot(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.
|
||||
# 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.
|
||||
|
|
|
@ -37,8 +37,6 @@ class PokerStars(HandHistoryConverter):
|
|||
filetype = "text"
|
||||
codepage = ("utf8", "cp1252")
|
||||
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
|
||||
substitutions = {
|
||||
'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'),
|
||||
'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$' }
|
||||
|
||||
# Static regexes
|
||||
|
@ -90,7 +97,7 @@ class PokerStars(HandHistoryConverter):
|
|||
# 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+)?
|
||||
# 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<LIMIT>No\sLimit|Limit|LIMIT|Pot\sLimit)\)?,?\s
|
||||
(-\s)?
|
||||
|
@ -150,7 +157,7 @@ class PokerStars(HandHistoryConverter):
|
|||
% short_subst, re.MULTILINE|re.VERBOSE)
|
||||
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_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)
|
||||
|
||||
def compilePlayerRegexs(self, hand):
|
||||
|
@ -198,6 +205,8 @@ class PokerStars(HandHistoryConverter):
|
|||
info['bb'] = mg['BB']
|
||||
if 'CURRENCY' in mg:
|
||||
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:
|
||||
info['type'] = 'ring'
|
||||
|
@ -299,8 +308,6 @@ class PokerStars(HandHistoryConverter):
|
|||
if key == 'MAX' and info[key] != None:
|
||||
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:
|
||||
# hand.currency = 'play' # overrides previously set value
|
||||
hand.gametype['currency'] = 'play'
|
||||
|
@ -455,13 +462,14 @@ class PokerStars(HandHistoryConverter):
|
|||
if m.group('CARDS') is not None:
|
||||
cards = m.group('CARDS')
|
||||
cards = cards.split(' ') # needs to be a list, not a set--stud needs the order
|
||||
string = m.group('STRING')
|
||||
|
||||
(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)
|
||||
hand.addShownCards(cards=cards, player=m.group('PNAME'), shown=shown, mucked=mucked, string=string)
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = OptionParser()
|
||||
|
|
215
pyfpdb/SQL.py
215
pyfpdb/SQL.py
|
@ -245,6 +245,7 @@ class Sql:
|
|||
category varchar(9) NOT NULL,
|
||||
limitType char(2) NOT NULL,
|
||||
hiLo char(1) NOT NULL,
|
||||
mix varchar(9) NOT NULL,
|
||||
smallBlind int,
|
||||
bigBlind int,
|
||||
smallBet int NOT NULL,
|
||||
|
@ -252,32 +253,34 @@ class Sql:
|
|||
ENGINE=INNODB"""
|
||||
elif db_server == 'postgresql':
|
||||
self.query['createGametypesTable'] = """CREATE TABLE Gametypes (
|
||||
id SERIAL, PRIMARY KEY (id),
|
||||
siteId INTEGER, FOREIGN KEY (siteId) REFERENCES Sites(id),
|
||||
currency varchar(4),
|
||||
type char(4),
|
||||
base char(4),
|
||||
category varchar(9),
|
||||
limitType char(2),
|
||||
hiLo char(1),
|
||||
id SERIAL NOT NULL, PRIMARY KEY (id),
|
||||
siteId INTEGER NOT NULL, FOREIGN KEY (siteId) REFERENCES Sites(id),
|
||||
currency varchar(4) NOT NULL,
|
||||
type char(4) NOT NULL,
|
||||
base char(4) NOT NULL,
|
||||
category varchar(9) NOT NULL,
|
||||
limitType char(2) NOT NULL,
|
||||
hiLo char(1) NOT NULL,
|
||||
mix char(9) NOT NULL,
|
||||
smallBlind int,
|
||||
bigBlind int,
|
||||
smallBet int,
|
||||
bigBet int)"""
|
||||
smallBet int NOT NULL,
|
||||
bigBet int NOT NULL)"""
|
||||
elif db_server == 'sqlite':
|
||||
self.query['createGametypesTable'] = """CREATE TABLE Gametypes (
|
||||
id INTEGER PRIMARY KEY,
|
||||
siteId INTEGER,
|
||||
currency TEXT,
|
||||
type TEXT,
|
||||
base TEXT,
|
||||
category TEXT,
|
||||
limitType TEXT,
|
||||
hiLo TEXT,
|
||||
id INTEGER PRIMARY KEY NOT NULL,
|
||||
siteId INTEGER NOT NULL,
|
||||
currency TEXT NOT NULL,
|
||||
type TEXT NOT NULL,
|
||||
base TEXT NOT NULL,
|
||||
category TEXT NOT NULL,
|
||||
limitType TEXT NOT NULL,
|
||||
hiLo TEXT NOT NULL,
|
||||
mix TEXT NOT NULL,
|
||||
smallBlind INTEGER,
|
||||
bigBlind INTEGER,
|
||||
smallBet INTEGER,
|
||||
bigBet INTEGER,
|
||||
smallBet INTEGER NOT NULL,
|
||||
bigBet INTEGER NOT NULL,
|
||||
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),
|
||||
sessionId INT UNSIGNED,
|
||||
gameSessionId INT UNSIGNED,
|
||||
fileId INT(10) UNSIGNED NOT NULL, FOREIGN KEY (fileId) REFERENCES Files(id),
|
||||
startTime DATETIME NOT NULL,
|
||||
importTime DATETIME NOT NULL,
|
||||
seats TINYINT NOT NULL,
|
||||
|
@ -368,6 +372,7 @@ class Sql:
|
|||
boardcard4 smallint,
|
||||
boardcard5 smallint,
|
||||
texture smallint,
|
||||
runIt BOOLEAN,
|
||||
playersVpi SMALLINT NOT NULL, /* num of players vpi */
|
||||
playersAtStreet1 SMALLINT NOT NULL, /* num of players seeing flop/street4 */
|
||||
playersAtStreet2 SMALLINT NOT NULL,
|
||||
|
@ -396,6 +401,7 @@ class Sql:
|
|||
gametypeId INT NOT NULL, FOREIGN KEY (gametypeId) REFERENCES Gametypes(id),
|
||||
sessionId INT,
|
||||
gameSessionId INT,
|
||||
fileId BIGINT NOT NULL, FOREIGN KEY (fileId) REFERENCES Files(id),
|
||||
startTime timestamp without time zone NOT NULL,
|
||||
importTime timestamp without time zone NOT NULL,
|
||||
seats SMALLINT NOT NULL,
|
||||
|
@ -407,6 +413,7 @@ class Sql:
|
|||
boardcard4 smallint,
|
||||
boardcard5 smallint,
|
||||
texture smallint,
|
||||
runIt BOOLEAN,
|
||||
playersVpi SMALLINT NOT NULL, /* num of players vpi */
|
||||
playersAtStreet1 SMALLINT NOT NULL, /* num of players seeing flop/street4 */
|
||||
playersAtStreet2 SMALLINT NOT NULL,
|
||||
|
@ -434,6 +441,7 @@ class Sql:
|
|||
gametypeId INT NOT NULL,
|
||||
sessionId INT,
|
||||
gameSessionId INT,
|
||||
fileId INT NOT NULL,
|
||||
startTime REAL NOT NULL,
|
||||
importTime REAL NOT NULL,
|
||||
seats INT NOT NULL,
|
||||
|
@ -445,6 +453,7 @@ class Sql:
|
|||
boardcard4 INT,
|
||||
boardcard5 INT,
|
||||
texture INT,
|
||||
runIt BOOLEAN,
|
||||
playersVpi INT NOT NULL, /* num of players vpi */
|
||||
playersAtStreet1 INT NOT NULL, /* num of players seeing flop/street4 */
|
||||
playersAtStreet2 INT NOT NULL,
|
||||
|
@ -464,6 +473,42 @@ class Sql:
|
|||
comment TEXT,
|
||||
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
|
||||
|
@ -686,6 +731,7 @@ class Sql:
|
|||
street3Seen BOOLEAN,
|
||||
street4Seen BOOLEAN,
|
||||
sawShowdown BOOLEAN,
|
||||
showed BOOLEAN,
|
||||
|
||||
street1Aggr BOOLEAN,
|
||||
street2Aggr BOOLEAN,
|
||||
|
@ -826,6 +872,7 @@ class Sql:
|
|||
street3Seen BOOLEAN,
|
||||
street4Seen BOOLEAN,
|
||||
sawShowdown BOOLEAN,
|
||||
showed BOOLEAN,
|
||||
|
||||
street1Aggr BOOLEAN,
|
||||
street2Aggr BOOLEAN,
|
||||
|
@ -965,6 +1012,7 @@ class Sql:
|
|||
street3Seen INT,
|
||||
street4Seen INT,
|
||||
sawShowdown INT,
|
||||
showed INT,
|
||||
|
||||
street1Aggr INT,
|
||||
street2Aggr INT,
|
||||
|
@ -1136,6 +1184,60 @@ class Sql:
|
|||
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
|
||||
|
@ -1498,10 +1600,10 @@ class Sql:
|
|||
elif db_server == 'postgresql':
|
||||
self.query['createSessionsCacheTable'] = """CREATE TABLE SessionsCache (
|
||||
id BIGSERIAL, PRIMARY KEY (id),
|
||||
sessionStart REAL NOT NULL,
|
||||
sessionEnd REAL NOT NULL,
|
||||
gameStart REAL NOT NULL,
|
||||
gameEnd REAL NOT NULL,
|
||||
sessionStart timestamp without time zone NOT NULL,
|
||||
sessionEnd timestamp without time zone NOT NULL,
|
||||
gameStart timestamp without time zone NOT NULL,
|
||||
gameEnd timestamp without time zone NOT NULL,
|
||||
sessionId INT,
|
||||
date CHAR(7) NOT NULL, /* 1st char is style (A/T/H/S), other 6 are the key */
|
||||
type char(7),
|
||||
|
@ -3481,7 +3583,7 @@ class Sql:
|
|||
<limit_test>
|
||||
<game_test>
|
||||
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"""
|
||||
|
||||
self.query['getRingProfitAllHandsPlayerIdSiteInDollars'] = """
|
||||
|
@ -4645,14 +4747,15 @@ class Sql:
|
|||
AND category=%s
|
||||
AND limitType=%s
|
||||
AND currency=%s
|
||||
AND mix=%s
|
||||
AND smallBlind=%s
|
||||
AND bigBlind=%s
|
||||
"""
|
||||
|
||||
self.query['insertGameTypes'] = """INSERT INTO Gametypes
|
||||
(siteId, currency, type, base, category, limitType
|
||||
,hiLo, smallBlind, bigBlind, smallBet, bigBet)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
|
||||
,hiLo, mix, smallBlind, bigBlind, smallBet, bigBet)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
|
||||
|
||||
self.query['isAlreadyInDB'] = """SELECT id FROM Hands
|
||||
WHERE gametypeId=%s AND siteHandNo=%s
|
||||
|
@ -4792,6 +4895,7 @@ class Sql:
|
|||
gametypeid,
|
||||
sessionId,
|
||||
gameSessionId,
|
||||
fileId,
|
||||
startTime,
|
||||
importtime,
|
||||
seats,
|
||||
|
@ -4803,6 +4907,7 @@ class Sql:
|
|||
boardcard3,
|
||||
boardcard4,
|
||||
boardcard5,
|
||||
runIt,
|
||||
playersAtStreet1,
|
||||
playersAtStreet2,
|
||||
playersAtStreet3,
|
||||
|
@ -4822,7 +4927,8 @@ class Sql:
|
|||
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)"""
|
||||
|
||||
|
||||
self.query['store_hands_players'] = """insert into HandsPlayers (
|
||||
|
@ -4860,6 +4966,7 @@ class Sql:
|
|||
street3Seen,
|
||||
street4Seen,
|
||||
sawShowdown,
|
||||
showed,
|
||||
wonAtSD,
|
||||
street0Aggr,
|
||||
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
|
||||
)"""
|
||||
|
||||
self.query['store_hands_actions'] = """insert into HandsActions (
|
||||
|
@ -4991,6 +5098,56 @@ class Sql:
|
|||
%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
|
||||
################################
|
||||
|
|
|
@ -127,7 +127,7 @@ def compare_handsplayers_file(filename, importer, errors):
|
|||
# The stats match - continue
|
||||
pass
|
||||
else:
|
||||
if stat == 'tourneyTypeId' or stat == 'tourneysPlayersIds':
|
||||
if stat == 'tourneyTypeId' or stat == 'tourneysPlayersIds' or stat == 'showed':
|
||||
# Not and error
|
||||
pass
|
||||
else:
|
||||
|
@ -153,6 +153,7 @@ def compare_hands_file(filename, importer, errors):
|
|||
del ghash['gsc']
|
||||
del ghash['sc']
|
||||
del ghash['id']
|
||||
del ghash['board']
|
||||
for datum in ghash:
|
||||
#print "DEBUG: hand: '%s'" % datum
|
||||
try:
|
||||
|
@ -161,7 +162,12 @@ def compare_hands_file(filename, importer, errors):
|
|||
pass
|
||||
else:
|
||||
# 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.
|
||||
#print "DEBUG: Skipping mismatched gamtypeId"
|
||||
pass
|
||||
|
|
|
@ -166,6 +166,19 @@ class Importer:
|
|||
for i in xrange(len(self.writerdbs)):
|
||||
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
|
||||
def addImportFile(self, filename, site = "default", filter = "passthrough"):
|
||||
#TODO: test it is a valid file -> put that in config!!
|
||||
|
@ -173,7 +186,7 @@ class Importer:
|
|||
# filename not guaranteed to be unicode
|
||||
if filename in self.filelist or not os.path.exists(filename):
|
||||
return
|
||||
self.filelist[filename] = [site] + [filter]
|
||||
self.filelist[filename] = self.addFileToList(filename, site, filter)
|
||||
if site not in self.siteIds:
|
||||
# Get id from Sites table in DB
|
||||
result = self.database.get_site_id(site)
|
||||
|
@ -303,13 +316,15 @@ class Importer:
|
|||
|
||||
ProgressDialog.progress_update()
|
||||
|
||||
(stored, duplicates, partial, errors, ttime) = self.import_file_dict(file
|
||||
,self.filelist[file][0], self.filelist[file][1], q)
|
||||
(stored, duplicates, partial, errors, ttime) = self.import_file_dict(file, self.filelist[file][0]
|
||||
,self.filelist[file][1], self.filelist[file][2], q)
|
||||
totstored += stored
|
||||
totdups += duplicates
|
||||
totpartial += partial
|
||||
toterrors += errors
|
||||
|
||||
self.logImport('bulk', file, stored, duplicates, partial, errors, ttime, self.filelist[file][2])
|
||||
self.database.commit()
|
||||
del ProgressDialog
|
||||
|
||||
for i in xrange( self.settings['threads'] ):
|
||||
|
@ -394,7 +409,9 @@ class Importer:
|
|||
self.caller.addText("\n"+os.path.basename(file))
|
||||
except KeyError: # TODO: What error happens here?
|
||||
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:
|
||||
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))
|
||||
|
@ -425,7 +442,7 @@ class Importer:
|
|||
#rulog.close()
|
||||
|
||||
# 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):
|
||||
self.addToDirList[file] = [site] + [filter]
|
||||
|
@ -449,7 +466,7 @@ class Importer:
|
|||
hhc = obj( self.config, in_path = file, index = idx
|
||||
,starsArchive = self.settings['starsArchive']
|
||||
,ftpArchive = self.settings['ftpArchive']
|
||||
,sitename = site )
|
||||
,sitename = site)
|
||||
|
||||
if hhc.getStatus():
|
||||
if self.caller: hhc.progressNotify()
|
||||
|
@ -476,10 +493,10 @@ class Importer:
|
|||
try:
|
||||
id = hand.getHandId(self.database, id)
|
||||
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)
|
||||
ihands.append(hand)
|
||||
to_hud.append(id)
|
||||
to_hud.append(hand.dbid_hands)
|
||||
except Exceptions.FpdbHandDuplicate:
|
||||
duplicates += 1
|
||||
self.database.commit()
|
||||
|
@ -496,7 +513,7 @@ class Importer:
|
|||
if self.callHud:
|
||||
for hid in to_hud:
|
||||
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)
|
||||
except IOError, e:
|
||||
log.error(_("Failed to send hand to HUD: %s") % e)
|
||||
|
|
Loading…
Reference in New Issue
Block a user