From 92a4b105ccc3be40af7ed2fa7fb146f56b0f3b7e Mon Sep 17 00:00:00 2001 From: steffen123 Date: Wed, 7 Jul 2010 06:58:42 +0200 Subject: [PATCH] parsing PS summary emails now. just need to write insert/update code now --- pyfpdb/FulltiltToFpdb.py | 8 +++--- pyfpdb/ImapSummaries.py | 41 ++++++++++++++++++--------- pyfpdb/PokerStarsToFpdb.py | 57 +++++++++++++++++++------------------- pyfpdb/TourneySummary.py | 19 ++++++++++--- 4 files changed, 76 insertions(+), 49 deletions(-) diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index 50b2a648..9b287edc 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -670,10 +670,10 @@ class Fulltilt(HandHistoryConverter): heroName = n.group('HERO_NAME') tourney.hero = heroName # Is this really useful ? - if heroName not in tourney.finishPositions: - print "FullTilt:", heroName, "not found in tourney.finishPositions ..." - elif (tourney.finishPositions[heroName] != Decimal(n.group('HERO_FINISHING_POS'))): - print "FullTilt: Bad parsing : finish position incoherent : %s / %s" % (tourney.finishPositions[heroName], n.group('HERO_FINISHING_POS')) + if heroName not in tourney.ranks: + print "FullTilt:", heroName, "not found in tourney.ranks ..." + elif (tourney.ranks[heroName] != Decimal(n.group('HERO_FINISHING_POS'))): + print "FullTilt: Bad parsing : finish position incoherent : %s / %s" % (tourney.ranks[heroName], n.group('HERO_FINISHING_POS')) return True diff --git a/pyfpdb/ImapSummaries.py b/pyfpdb/ImapSummaries.py index e2620411..3aaaf8c2 100755 --- a/pyfpdb/ImapSummaries.py +++ b/pyfpdb/ImapSummaries.py @@ -19,14 +19,22 @@ #see http://docs.python.org/library/imaplib.html for the python interface #see http://tools.ietf.org/html/rfc2060#section-6.4.4 for IMAP4 search criteria -#TODO: move all these into config file -#TODO: This is currently for PS only. If anyone wants to expand IMAP -configHost="schaumburger.info" -configUser="fpdb-test@schaumburger.info" import sys -configPw=sys.argv[1] - from imaplib import IMAP4_SSL +import PokerStarsSummary + +def splitPokerStarsSummaries(emailText): + splitSummaries=emailText.split("\nPokerStars Tournament #")[1:] + for i in range(len(splitSummaries)): + splitSummaries[i]="PokerStars Tournament #"+splitSummaries[i] + return splitSummaries +#end def emailText + +#TODO: move all these into the config file. until then usage is: ./ImapSummaries.py YourImapHost YourImapUser YourImapPw +configHost=sys.argv[1] +configUser=sys.argv[2] +configPw=sys.argv[3] +#TODO: specify folder, whether to use SSL server = IMAP4_SSL(configHost) #TODO: optionally non-SSL response = server.login(configUser, configPw) #TODO catch authentication error @@ -46,15 +54,22 @@ for messageNumber in searchData[0].split(" "): if response!="OK": raise error #TODO: show error message if headerData[1].find("Subject: PokerStars Tournament History Request - Last x")!=1: - neededMessages.append(messageNumber) - -if len(neededMessages)==0: + neededMessages.append(("PS", messageNumber)) + +if (len(neededMessages)==0): raise error #TODO: show error message -for messageNumber in neededMessages: - response, bodyData = server.fetch(messageNumber, "(UID BODY[TEXT])") +for messageData in neededMessages: + response, bodyData = server.fetch(messageData[1], "(UID BODY[TEXT])") + bodyData=bodyData[0][1] if response!="OK": raise error #TODO: show error message - print "bodyData",bodyData[0][1] - + if messageData[0]=="PS": + summaryTexts=(splitPokerStarsSummaries(bodyData)) + for summaryText in summaryTexts: + result=PokerStarsSummary.PokerStarsSummary(sitename="PokerStars", gametype=None, summaryText=summaryText, builtFrom = "IMAP") + print "result:",result + #TODO: count results and output to shell like hand importer does + +print "completed running Imap import, closing server connection" server.close() server.logout() diff --git a/pyfpdb/PokerStarsToFpdb.py b/pyfpdb/PokerStarsToFpdb.py index cc4f6567..33e68d5a 100644 --- a/pyfpdb/PokerStarsToFpdb.py +++ b/pyfpdb/PokerStarsToFpdb.py @@ -41,6 +41,30 @@ class PokerStars(HandHistoryConverter): 'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes 'LS' : "\$|\xe2\x82\xac|" # legal currency symbols - Euro(cp1252, utf-8) } + + # translations from captured groups to fpdb info strings + Lim_Blinds = { '0.04': ('0.01', '0.02'), '0.10': ('0.02', '0.05'), '0.20': ('0.05', '0.10'), + '0.40': ('0.10', '0.20'), '0.50': ('0.10', '0.25'), '1.00': ('0.25', '0.50'), + '2.00': ('0.50', '1.00'), '2': ('0.50', '1.00'), '4' : ('1.00', '2.00'), + '4.00': ('1.00', '2.00'), '6': ('1.00', '3.00'), '6.00': ('1.00', '3.00'), + '10.00': ('2.00', '5.00'), '20.00': ('5.00', '10.00'), '30.00': ('10.00', '15.00'), + '60.00': ('15.00', '30.00'), '100.00': ('25.00', '50.00'), '200.00': ('50.00', '100.00'), + '400.00': ('100.00', '200.00'), '1000.00': ('250.00', '500.00')} + + limits = { 'No Limit':'nl', 'Pot Limit':'pl', 'Limit':'fl', 'LIMIT':'fl' } + games = { # base, category + "Hold'em" : ('hold','holdem'), + 'Omaha' : ('hold','omahahi'), + 'Omaha Hi/Lo' : ('hold','omahahilo'), + 'Razz' : ('stud','razz'), + 'RAZZ' : ('stud','razz'), + '7 Card Stud' : ('stud','studhi'), + '7 Card Stud Hi/Lo' : ('stud','studhilo'), + 'Badugi' : ('draw','badugi'), + 'Triple Draw 2-7 Lowball' : ('draw','27_3draw'), + '5 Card Draw' : ('draw','fivedraw') + } + currencies = { u'€':'EUR', '$':'USD', '':'T$' } # Static regexes re_GameInfo = re.compile(u""" @@ -144,43 +168,20 @@ class PokerStars(HandHistoryConverter): raise FpdbParseError("Unable to recognise gametype from: '%s'" % tmp) mg = m.groupdict() - # translations from captured groups to fpdb info strings - Lim_Blinds = { '0.04': ('0.01', '0.02'), '0.10': ('0.02', '0.05'), '0.20': ('0.05', '0.10'), - '0.40': ('0.10', '0.20'), '0.50': ('0.10', '0.25'), '1.00': ('0.25', '0.50'), - '2.00': ('0.50', '1.00'), '2': ('0.50', '1.00'), '4' : ('1.00', '2.00'), - '4.00': ('1.00', '2.00'), '6': ('1.00', '3.00'), '6.00': ('1.00', '3.00'), - '10.00': ('2.00', '5.00'), '20.00': ('5.00', '10.00'), '30.00': ('10.00', '15.00'), - '60.00': ('15.00', '30.00'), '100.00': ('25.00', '50.00'), '200.00': ('50.00', '100.00'), - '400.00': ('100.00', '200.00'), '1000.00': ('250.00', '500.00')} - - limits = { 'No Limit':'nl', 'Pot Limit':'pl', 'Limit':'fl', 'LIMIT':'fl' } - games = { # base, category - "Hold'em" : ('hold','holdem'), - 'Omaha' : ('hold','omahahi'), - 'Omaha Hi/Lo' : ('hold','omahahilo'), - 'Razz' : ('stud','razz'), - 'RAZZ' : ('stud','razz'), - '7 Card Stud' : ('stud','studhi'), - '7 Card Stud Hi/Lo' : ('stud','studhilo'), - 'Badugi' : ('draw','badugi'), - 'Triple Draw 2-7 Lowball' : ('draw','27_3draw'), - '5 Card Draw' : ('draw','fivedraw') - } - currencies = { u'€':'EUR', '$':'USD', '':'T$' } # I don't think this is doing what we think. mg will always have all # the expected keys, but the ones that didn't match in the regex will # have a value of None. It is OK if it throws an exception when it # runs across an unknown game or limit or whatever. if 'LIMIT' in mg: - info['limitType'] = limits[mg['LIMIT']] + info['limitType'] = self.limits[mg['LIMIT']] if 'GAME' in mg: - (info['base'], info['category']) = games[mg['GAME']] + (info['base'], info['category']) = self.games[mg['GAME']] if 'SB' in mg: info['sb'] = mg['SB'] if 'BB' in mg: info['bb'] = mg['BB'] if 'CURRENCY' in mg: - info['currency'] = currencies[mg['CURRENCY']] + info['currency'] = self.currencies[mg['CURRENCY']] if 'TOURNO' in mg and mg['TOURNO'] is None: info['type'] = 'ring' @@ -189,8 +190,8 @@ class PokerStars(HandHistoryConverter): if info['limitType'] == 'fl' and info['bb'] is not None and info['type'] == 'ring' and info['base'] != 'stud': try: - info['sb'] = Lim_Blinds[mg['BB']][0] - info['bb'] = Lim_Blinds[mg['BB']][1] + info['sb'] = self.Lim_Blinds[mg['BB']][0] + info['bb'] = self.Lim_Blinds[mg['BB']][1] except KeyError: log.error("determineGameType: Lim_Blinds has no lookup for '%s'" % mg['BB']) log.error("determineGameType: Raising FpdbParseError") diff --git a/pyfpdb/TourneySummary.py b/pyfpdb/TourneySummary.py index 8953421b..f1133217 100644 --- a/pyfpdb/TourneySummary.py +++ b/pyfpdb/TourneySummary.py @@ -15,6 +15,8 @@ #along with this program. If not, see . #In the "official" distribution you can find the license in agpl-3.0.txt. +"""parses and stores summary sections from e.g. eMail or summary files""" + # TODO: check to keep only the needed modules import re @@ -90,16 +92,21 @@ class TourneySummary(object): self.guarantee = 0 # Collections indexed by player names - self.finishPositions = {} + self.ranks = {} self.winnings = {} self.winningsCurrency = {} self.rebuyCounts = {} self.addOnCounts = {} - self.koCounts = {} + self.koCounts = {} # currency symbol for this summary self.sym = None #self.sym = self.SYMBOL[self.gametype['currency']] # save typing! delete this attr when done + + if builtFrom=="IMAP": + self.parseSummary() + #TODO: self.insert() + #end def __init__ def __str__(self): #TODO : Update @@ -143,7 +150,7 @@ class TourneySummary(object): structs = ( ("GAMETYPE", self.gametype), ("PLAYERS", self.players), - ("POSITIONS", self.finishPositions), + ("RANKS", self.ranks), ("WINNINGS", self.winnings), ("COUNT REBUYS", self.rebuyCounts), ("COUNT ADDONS", self.addOnCounts), @@ -156,6 +163,10 @@ class TourneySummary(object): for (name, struct) in structs: str = str + "\n%s =\n" % name + pprint.pformat(struct, 4) return str + #end def __str__ + + def parseSummary(self): abstract + """should fill the class variables with the parsed information""" def getSummaryText(self): return self.summaryText @@ -203,7 +214,7 @@ winnings (decimal) the money the player ended the tourney with (can be 0, or """ log.debug("addPlayer: rank:%s - name : '%s' - Winnings (%s)" % (rank, name, winnings)) self.players.append(name) - self.finishPositions.update( { name : Decimal(rank) } ) + self.ranks.update( { name : Decimal(rank) } ) self.winnings.update( { name : Decimal(winnings) } ) self.winningsCurrency.update( { name : winningsCurrency } ) self.rebuyCounts.update( {name: Decimal(rebuyCount) } )