parsing PS summary emails now. just need to write insert/update code now

This commit is contained in:
steffen123 2010-07-07 06:58:42 +02:00
parent e3ce1b8c2d
commit 92a4b105cc
4 changed files with 76 additions and 49 deletions

View File

@ -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

View File

@ -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)
neededMessages.append(("PS", messageNumber))
if len(neededMessages)==0:
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()

View File

@ -42,6 +42,30 @@ class PokerStars(HandHistoryConverter):
'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"""
PokerStars\sGame\s\#(?P<HID>[0-9]+):\s+
@ -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")

View File

@ -15,6 +15,8 @@
#along with this program. If not, see <http://www.gnu.org/licenses/>.
#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,17 +92,22 @@ 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
vars = ( ("SITE", self.sitename),
@ -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) } )