From d01435d068b0efcaf80a058e0700d1d4b050c860 Mon Sep 17 00:00:00 2001 From: steffen123 Date: Mon, 5 Jul 2010 11:48:26 +0200 Subject: [PATCH] store Tourneys and TourneyTypes for PS tourneys. see ML for more details --- pyfpdb/Database.py | 66 +++++++++++++++++++++++--------------- pyfpdb/Hand.py | 40 +++++++++++++++-------- pyfpdb/PokerStarsToFpdb.py | 23 +++++++++---- pyfpdb/SQL.py | 32 +++++++----------- pyfpdb/Tourney.py | 54 ++++++++++++++++++++----------- 5 files changed, 131 insertions(+), 84 deletions(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 6ab5794a..b499cce3 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -1933,9 +1933,9 @@ class Database: print "***Error sending finish: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1]) # end def send_finish_msg(): - def recogniseTourneyType(self, tourney): - log.debug("Database.recogniseTourneyType") - typeId = 1 + def getTourneyTypeId(self, tourney): + tourneyTypeId = 1 + # Check if Tourney exists, and if so retrieve TTypeId : in that case, check values of the ttype cursor = self.get_cursor() cursor.execute (self.sql.query['getTourneyTypeIdByTourneyNo'].replace('%s', self.sql.query['placeholder']), @@ -1945,47 +1945,61 @@ class Database: expectedValues = { 1 : "buyin", 2 : "fee", 4 : "isKO", 5 : "isRebuy", 6 : "speed", 7 : "isShootout", 8 : "isMatrix" } - typeIdMatch = True + tourneyTypeIdMatch = True try: - len(result) - typeId = result[0] - log.debug("Tourney found in db with Tourney_Type_ID = %d" % typeId) + tourneyTypeId = result[0] + log.debug("Tourney found in db with Tourney_Type_ID = %d" % tourneyTypeId) for ev in expectedValues : if ( getattr( tourney, expectedValues.get(ev) ) <> result[ev] ): log.debug("TypeId mismatch : wrong %s : Tourney=%s / db=%s" % (expectedValues.get(ev), getattr( tourney, expectedValues.get(ev)), result[ev]) ) - typeIdMatch = False + tourneyTypeIdMatch = False #break except: # Tourney not found : a TourneyTypeId has to be found or created for that specific tourney - typeIdMatch = False + tourneyTypeIdMatch = False - if typeIdMatch == False : - # Check for an existing TTypeId that matches tourney info (buyin/fee, knockout, rebuy, speed, matrix, shootout) - # if not found create it - log.debug("Searching for a TourneyTypeId matching TourneyType data") + if tourneyTypeIdMatch == False : + # Check for an existing TTypeId that matches tourney info, if not found create it cursor.execute (self.sql.query['getTourneyTypeId'].replace('%s', self.sql.query['placeholder']), - (tourney.siteId, tourney.buyin, tourney.fee, tourney.isKO, - tourney.isRebuy, tourney.speed, tourney.isShootout, tourney.isMatrix) + (tourney.siteId, tourney.currency, tourney.buyin, tourney.fee, tourney.isKO, + tourney.isRebuy, tourney.isAddOn, tourney.speed, tourney.isShootout, tourney.isMatrix) ) result=cursor.fetchone() try: - len(result) - typeId = result[0] - log.debug("Existing Tourney Type Id found : %d" % typeId) + tourneyTypeId = result[0] except TypeError: #this means we need to create a new entry - log.debug("Tourney Type Id not found : create one") - cursor.execute (self.sql.query['insertTourneyTypes'].replace('%s', self.sql.query['placeholder']), - (tourney.siteId, tourney.buyin, tourney.fee, tourney.isKO, tourney.isRebuy, - tourney.speed, tourney.isShootout, tourney.isMatrix) + cursor.execute (self.sql.query['insertTourneyType'].replace('%s', self.sql.query['placeholder']), + (tourney.siteId, tourney.currency, tourney.buyin, tourney.fee, tourney.buyInChips, + tourney.isKO, tourney.isRebuy, + tourney.isAddOn, tourney.speed, tourney.isShootout, tourney.isMatrix) ) - typeId = self.get_last_insert_id(cursor) - - return typeId - #end def recogniseTourneyType + tourneyTypeId = self.get_last_insert_id(cursor) + return tourneyTypeId + #end def getTourneyTypeId + + def getTourneyId(self, tourney): + cursor = self.get_cursor() + cursor.execute (self.sql.query['getTourneyIdByTourneyNo'].replace('%s', self.sql.query['placeholder']), + (tourney.siteId, tourney.tourNo)) + result=cursor.fetchone() + try: + tourneyId = result[0] + except: + cursor.execute (self.sql.query['insertTourney'].replace('%s', self.sql.query['placeholder']), + (tourney.tourneyTypeId, tourney.tourNo, tourney.entries, tourney.prizepool, + tourney.startTime, tourney.endTime, tourney.tourneyName, None, + tourney.totalRebuyCount, tourney.totalAddOnCount)) + tourneyId = self.get_last_insert_id(cursor) + return tourneyId + #end def getTourneyId + def getTourneysPlayersIds(self, tourney): + print "TODO implement getTourneysPlayersIds" + #end def getTourneysPlayersIds +#end class Database # Class used to hold all the data needed to write a hand to the db # mainParser() in fpdb_parse_logic.py creates one of these and then passes it to diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 78a8d330..25caffe1 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -37,7 +37,7 @@ import Configuration from Exceptions import * import DerivedStats import Card - +import Tourney class Hand(object): @@ -57,7 +57,7 @@ class Hand(object): self.siteId = self.SITEIDS[sitename] self.stats = DerivedStats.DerivedStats(self) self.gametype = gametype - self.starttime = 0 + self.startTime = 0 self.handText = handText self.handid = 0 self.cancelled = False @@ -69,12 +69,15 @@ class Hand(object): self.maxseats = None self.counted_seats = 0 self.buttonpos = 0 + + #tourney stuff + self.tourney = None self.tourNo = None self.buyin = None + self.buyinCurrency = None self.fee = None # the Database code is looking for this one .. ? self.level = None self.mixed = None - # Some attributes for hand from a tourney self.speed = "Normal" self.isRebuy = False self.isKO = False @@ -136,6 +139,8 @@ class Hand(object): ("MAXSEATS", self.maxseats), ("TOURNAMENT NO", self.tourNo), ("BUYIN", self.buyin), + ("BUYIN CURRENCY", self.buyinCurrency), + ("FEE", self.fee), ("LEVEL", self.level), ("MIXED", self.mixed), ("LASTBET", self.lastBet), @@ -151,7 +156,7 @@ class Hand(object): ("TOTAL POT", self.totalpot), ("TOTAL COLLECTED", self.totalcollected), ("RAKE", self.rake), - ("START TIME", self.starttime), + ("START TIME", self.startTime), ) structs = ( ("PLAYERS", self.players), @@ -207,6 +212,16 @@ dealt whether they were seen in a 'dealt to' line #Gametypes self.dbid_gt = db.getGameTypeId(self.siteId, self.gametype) + + if self.tourNo!=None: + self.tourney=Tourney.Tourney(self.sitename, self.gametype, None, builtFrom="HHC-HH", hand=self) + self.tourney.tourneyTypeId = db.getTourneyTypeId(self.tourney) + db.commit() + self.tourney.tourneyId = db.getTourneyId(self.tourney) + db.commit() + self.tourney.tourneysPlayersIds = db.getTourneysPlayersIds(self.tourney) + db.commit() + #end def prepInsert def insert(self, db): """ Function to insert Hand into database @@ -231,15 +246,14 @@ db: a connected Database object""" db.storeHandsPlayers(self.dbid_hands, self.dbid_pids, self.stats.getHandsPlayers()) # HandsActions - all actions for all players for all streets - self.actions # HudCache data can be generated from HandsActions (HandsPlayers?) - # Tourneys ? - # TourneysPlayers + print "TODO: store TourneysPlayers" else: log.info("Hand.insert(): hid #: %s is a duplicate" % hh['siteHandNo']) self.is_duplicate = True # i.e. don't update hudcache raise FpdbHandDuplicate(hh['siteHandNo']) def updateHudCache(self, db): - db.storeHudCache(self.dbid_gt, self.dbid_pids, self.starttime, self.stats.getHandsPlayers()) + db.storeHudCache(self.dbid_gt, self.dbid_pids, self.startTime, self.stats.getHandsPlayers()) def select(self, handId): """ Function to create Hand object from database """ @@ -602,10 +616,10 @@ Map the tuple self.gametype onto the pokerstars string describing it gs = gs + " %s (%s) - " % (self.getGameTypeAsString(), self.getStakesAsString()) try: - timestr = datetime.datetime.strftime(self.starttime, '%Y/%m/%d %H:%M:%S ET') + timestr = datetime.datetime.strftime(self.startTime, '%Y/%m/%d %H:%M:%S ET') except TypeError: - print "*** ERROR - HAND: calling writeGameLine with unexpected STARTTIME value, expecting datetime.date object, received:", self.starttime - print "*** Make sure your HandHistoryConverter is setting hand.starttime properly!" + print "*** ERROR - HAND: calling writeGameLine with unexpected STARTTIME value, expecting datetime.date object, received:", self.startTime + print "*** Make sure your HandHistoryConverter is setting hand.startTime properly!" print "*** Game String:", gs return gs else: @@ -805,7 +819,7 @@ class HoldemOmahaHand(Hand): T.h1[ T.span(class_='site')["%s Game #%s]" % ('PokerStars', self.handid)], T.span(class_='type_limit')[ "%s ($%s/$%s)" %(self.getGameTypeAsString(), self.sb, self.bb) ], - T.span(class_='date')[ datetime.datetime.strftime(self.starttime,'%Y/%m/%d - %H:%M:%S ET') ] + T.span(class_='date')[ datetime.datetime.strftime(self.startTime,'%Y/%m/%d - %H:%M:%S ET') ] ], T.h2[ "Table '%s' %d-max Seat #%s is the button" %(self.tablename, self.maxseats, self.buttonpos)], @@ -1555,7 +1569,7 @@ limit 1""", {'handid':handid}) SELECT h.sitehandno as hid, h.tablename as table, - h.handstart as starttime + h.handstart as startTime FROM hands as h WHERE h.id = %(handid)s @@ -1563,7 +1577,7 @@ WHERE h.id = %(handid)s res = c.fetchone() h.handid = res[0] h.tablename = res[1] - h.starttime = res[2] # automatically a datetime + h.startTime = res[2] # automatically a datetime # PlayerStacks c.execute(""" diff --git a/pyfpdb/PokerStarsToFpdb.py b/pyfpdb/PokerStarsToFpdb.py index b955d7df..84e61970 100644 --- a/pyfpdb/PokerStarsToFpdb.py +++ b/pyfpdb/PokerStarsToFpdb.py @@ -22,6 +22,7 @@ import sys from HandHistoryConverter import * +from decimal import Decimal # PokerStars HH Format @@ -241,12 +242,22 @@ class PokerStars(HandHistoryConverter): if key == 'TOURNO': hand.tourNo = info[key] if key == 'BUYIN': - if info[key] == 'Freeroll': - hand.buyin = '$0+$0' - else: - #FIXME: The key looks like: '€0.82+€0.18 EUR' - # This should be parsed properly and used - hand.buyin = info[key] + if hand.tourNo!=None: + if info[key] == 'Freeroll': + hand.buyin = 0 + hand.fee = 0 + hand.buyinCurrency = "FREE" + else: + if info[key].find("$")!=-1: + hand.buyinCurrency="USD" + elif info[key].find(u"€")!=-1: + hand.buyinCurrency="EUR" + else: + hand.buyinCurrency="NA" #FIXME: handle other currencies, FPP, play money + info[key]=info[key][:-4] + middle=info[key].find("+") + hand.buyin = 100*Decimal(info[key][1:middle]) + hand.fee = 100*Decimal(info[key][middle+2:]) if key == 'LEVEL': hand.level = info[key] diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 729ac807..622ab03b 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -3599,6 +3599,7 @@ class Sql: self.query['getTourneyTypeId'] = """SELECT id FROM TourneyTypes WHERE siteId=%s + AND currency=%s AND buyin=%s AND fee=%s AND knockout=%s @@ -3609,34 +3610,23 @@ class Sql: AND matrix=%s """ - self.query['insertTourneyTypes'] = """INSERT INTO TourneyTypes - (siteId, buyin, fee, knockout, rebuy, addOn - ,speed, shootout, matrix) - VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s) + self.query['insertTourneyType'] = """INSERT INTO TourneyTypes + (siteId, currency, buyin, fee, buyInChips, knockout, rebuy, + addOn ,speed, shootout, matrix) + VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) """ - self.query['getTourney'] = """SELECT t.id, - t.tourneyTypeId, - t.entries, - t.prizepool, - t.startTime, - t.endTime, - t.tourneyName, - t.matrixIdProcessed, - t.totalRebuyCount, - t.totalAddOnCount, - t.comment - FROM Tourneys t - INNER JOIN TourneyTypes tt ON (t.tourneyTypeId = tt.id) - WHERE t.siteTourneyNo=%s AND tt.siteId=%s + self.query['getTourneyIdByTourneyNo'] = """SELECT t.id + FROM Tourneys t + INNER JOIN TourneyTypes tt ON (t.tourneyTypeId = tt.id) + WHERE tt.siteId=%s AND t.siteTourneyNo=%s """ self.query['insertTourney'] = """INSERT INTO Tourneys (tourneyTypeId, siteTourneyNo, entries, prizepool, startTime, endTime, tourneyName, matrixIdProcessed, - totalRebuyCount, totalAddOnCount, comment, commentTs) - VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, - %s, %s) + totalRebuyCount, totalAddOnCount) + VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s) """ self.query['updateTourney'] = """UPDATE Tourneys diff --git a/pyfpdb/Tourney.py b/pyfpdb/Tourney.py index ac57f4e4..0639f8ca 100644 --- a/pyfpdb/Tourney.py +++ b/pyfpdb/Tourney.py @@ -45,25 +45,41 @@ class Tourney(object): SITEIDS = {'Fulltilt':1, 'PokerStars':2, 'Everleaf':3, 'Win2day':4, 'OnGame':5, 'UltimateBet':6, 'Betfair':7, 'Absolute':8, 'PartyPoker':9 } - def __init__(self, sitename, gametype, summaryText, builtFrom = "HHC"): + def __init__(self, sitename, gametype, summaryText, builtFrom = "HHC", hand=None): self.sitename = sitename self.siteId = self.SITEIDS[sitename] self.gametype = gametype - self.starttime = None - self.endtime = None + self.summaryText = summaryText self.tourneyName = None - self.tourNo = None - self.buyin = None - self.fee = None # the Database code is looking for this one .. ? + self.tourneyTypeId = None + self.tourneyId = None + if builtFrom=="HHC": + self.startTime = None + self.endTime = None + self.tourNo = None + self.currency = None + self.buyin = None + self.fee = None + elif builtFrom=="HHC-HH": + self.startTime = hand.startTime + #since tourney.startTime should only be stored to DB when the first hand of a tourney is imported this should actually be correct + self.endTime = hand.startTime #TODO parse this + self.tourNo = hand.tourNo + self.currency = hand.buyinCurrency + self.buyin = int(hand.buyin) + self.fee = int(hand.fee) + else: + print "need to bail" self.hero = None self.maxseats = None self.entries = 0 self.speed = "Normal" - self.prizepool = None # Make it a dict in order to deal (eventually later) with non-money winnings : {'MONEY' : amount, 'OTHER' : Value ??} - self.buyInChips = None + self.prizepool = 0 # Make it a dict in order to deal (eventually later) with non-money winnings : {'MONEY' : amount, 'OTHER' : Value ??} + self.buyInChips = 0 self.mixed = None self.isRebuy = False + self.isAddOn = False self.isKO = False self.isMatrix = False self.isShootout = False @@ -99,10 +115,12 @@ class Tourney(object): def __str__(self): #TODO : Update vars = ( ("SITE", self.sitename), - ("START TIME", self.starttime), - ("END TIME", self.endtime), + ("START TIME", self.startTime), + ("END TIME", self.endTime), ("TOURNEY NAME", self.tourneyName), ("TOURNEY NO", self.tourNo), + ("TOURNEY TYPE ID", self.tourneyTypeId), + ("TOURNEY ID", self.tourneyId), ("BUYIN", self.buyin), ("FEE", self.fee), ("HERO", self.hero), @@ -112,7 +130,8 @@ class Tourney(object): ("PRIZE POOL", self.prizepool), ("STARTING CHIP COUNT", self.buyInChips), ("MIXED", self.mixed), - ("REBUY ADDON", self.isRebuy), + ("REBUY", self.isRebuy), + ("ADDON", self.isAddOn), ("KO", self.isKO), ("MATRIX", self.isMatrix), ("SHOOTOUT", self.isShootout), @@ -151,11 +170,10 @@ class Tourney(object): def getSummaryText(self): return self.summaryText - - def prepInsert(self, db): - pass - + def insert(self, db): + # Note that this method is not used by the PS tourney storage stuff - this is for summary files only + # First : check all needed info is filled in the object, especially for the initial select # Notes on DB Insert @@ -166,7 +184,7 @@ class Tourney(object): # Starttime may not match the one in the Summary file : HH = time of the first Hand / could be slighltly different from the one in the summary file # Note: If the TourneyNo could be a unique id .... this would really be a relief to deal with matrix matches ==> Ask on the IRC / Ask Fulltilt ?? - dbTourneyTypeId = db.recogniseTourneyType(self) + dbTourneyTypeId = db.getTourneyTypeId(self) logging.debug("Tourney Type ID = %d" % dbTourneyTypeId) dbTourneyId = db.tRecognizeTourney(self, dbTourneyTypeId) logging.debug("Tourney ID = %d" % dbTourneyId) @@ -317,7 +335,7 @@ limit 1""", {'handid':handid}) SELECT h.sitehandno as hid, h.tablename as table, - h.handstart as starttime + h.handstart as startTime FROM hands as h WHERE h.id = %(handid)s @@ -325,7 +343,7 @@ WHERE h.id = %(handid)s res = c.fetchone() h.handid = res[0] h.tablename = res[1] - h.starttime = res[2] # automatically a datetime + h.startTime = res[2] # automatically a datetime # PlayerStacks c.execute("""