parsing PS summary emails now. just need to write insert/update code now
This commit is contained in:
parent
e3ce1b8c2d
commit
92a4b105cc
|
@ -670,10 +670,10 @@ class Fulltilt(HandHistoryConverter):
|
||||||
heroName = n.group('HERO_NAME')
|
heroName = n.group('HERO_NAME')
|
||||||
tourney.hero = heroName
|
tourney.hero = heroName
|
||||||
# Is this really useful ?
|
# Is this really useful ?
|
||||||
if heroName not in tourney.finishPositions:
|
if heroName not in tourney.ranks:
|
||||||
print "FullTilt:", heroName, "not found in tourney.finishPositions ..."
|
print "FullTilt:", heroName, "not found in tourney.ranks ..."
|
||||||
elif (tourney.finishPositions[heroName] != Decimal(n.group('HERO_FINISHING_POS'))):
|
elif (tourney.ranks[heroName] != Decimal(n.group('HERO_FINISHING_POS'))):
|
||||||
print "FullTilt: Bad parsing : finish position incoherent : %s / %s" % (tourney.finishPositions[heroName], n.group('HERO_FINISHING_POS'))
|
print "FullTilt: Bad parsing : finish position incoherent : %s / %s" % (tourney.ranks[heroName], n.group('HERO_FINISHING_POS'))
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -19,14 +19,22 @@
|
||||||
#see http://docs.python.org/library/imaplib.html for the python interface
|
#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
|
#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
|
import sys
|
||||||
configPw=sys.argv[1]
|
|
||||||
|
|
||||||
from imaplib import IMAP4_SSL
|
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
|
server = IMAP4_SSL(configHost) #TODO: optionally non-SSL
|
||||||
response = server.login(configUser, configPw) #TODO catch authentication error
|
response = server.login(configUser, configPw) #TODO catch authentication error
|
||||||
|
@ -46,15 +54,22 @@ for messageNumber in searchData[0].split(" "):
|
||||||
if response!="OK":
|
if response!="OK":
|
||||||
raise error #TODO: show error message
|
raise error #TODO: show error message
|
||||||
if headerData[1].find("Subject: PokerStars Tournament History Request - Last x")!=1:
|
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
|
raise error #TODO: show error message
|
||||||
for messageNumber in neededMessages:
|
for messageData in neededMessages:
|
||||||
response, bodyData = server.fetch(messageNumber, "(UID BODY[TEXT])")
|
response, bodyData = server.fetch(messageData[1], "(UID BODY[TEXT])")
|
||||||
|
bodyData=bodyData[0][1]
|
||||||
if response!="OK":
|
if response!="OK":
|
||||||
raise error #TODO: show error message
|
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.close()
|
||||||
server.logout()
|
server.logout()
|
||||||
|
|
|
@ -41,6 +41,30 @@ class PokerStars(HandHistoryConverter):
|
||||||
'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes
|
'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes
|
||||||
'LS' : "\$|\xe2\x82\xac|" # legal currency symbols - Euro(cp1252, utf-8)
|
'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
|
# Static regexes
|
||||||
re_GameInfo = re.compile(u"""
|
re_GameInfo = re.compile(u"""
|
||||||
|
@ -144,43 +168,20 @@ class PokerStars(HandHistoryConverter):
|
||||||
raise FpdbParseError("Unable to recognise gametype from: '%s'" % tmp)
|
raise FpdbParseError("Unable to recognise gametype from: '%s'" % tmp)
|
||||||
|
|
||||||
mg = m.groupdict()
|
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
|
# 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
|
# 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
|
# have a value of None. It is OK if it throws an exception when it
|
||||||
# runs across an unknown game or limit or whatever.
|
# runs across an unknown game or limit or whatever.
|
||||||
if 'LIMIT' in mg:
|
if 'LIMIT' in mg:
|
||||||
info['limitType'] = limits[mg['LIMIT']]
|
info['limitType'] = self.limits[mg['LIMIT']]
|
||||||
if 'GAME' in mg:
|
if 'GAME' in mg:
|
||||||
(info['base'], info['category']) = games[mg['GAME']]
|
(info['base'], info['category']) = self.games[mg['GAME']]
|
||||||
if 'SB' in mg:
|
if 'SB' in mg:
|
||||||
info['sb'] = mg['SB']
|
info['sb'] = mg['SB']
|
||||||
if 'BB' in mg:
|
if 'BB' in mg:
|
||||||
info['bb'] = mg['BB']
|
info['bb'] = mg['BB']
|
||||||
if 'CURRENCY' in mg:
|
if 'CURRENCY' in mg:
|
||||||
info['currency'] = currencies[mg['CURRENCY']]
|
info['currency'] = self.currencies[mg['CURRENCY']]
|
||||||
|
|
||||||
if 'TOURNO' in mg and mg['TOURNO'] is None:
|
if 'TOURNO' in mg and mg['TOURNO'] is None:
|
||||||
info['type'] = 'ring'
|
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':
|
if info['limitType'] == 'fl' and info['bb'] is not None and info['type'] == 'ring' and info['base'] != 'stud':
|
||||||
try:
|
try:
|
||||||
info['sb'] = Lim_Blinds[mg['BB']][0]
|
info['sb'] = self.Lim_Blinds[mg['BB']][0]
|
||||||
info['bb'] = Lim_Blinds[mg['BB']][1]
|
info['bb'] = self.Lim_Blinds[mg['BB']][1]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
log.error("determineGameType: Lim_Blinds has no lookup for '%s'" % mg['BB'])
|
log.error("determineGameType: Lim_Blinds has no lookup for '%s'" % mg['BB'])
|
||||||
log.error("determineGameType: Raising FpdbParseError")
|
log.error("determineGameType: Raising FpdbParseError")
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#along with this program. If not, see <http://www.gnu.org/licenses/>.
|
#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.
|
#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
|
# TODO: check to keep only the needed modules
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
@ -90,16 +92,21 @@ class TourneySummary(object):
|
||||||
self.guarantee = 0
|
self.guarantee = 0
|
||||||
|
|
||||||
# Collections indexed by player names
|
# Collections indexed by player names
|
||||||
self.finishPositions = {}
|
self.ranks = {}
|
||||||
self.winnings = {}
|
self.winnings = {}
|
||||||
self.winningsCurrency = {}
|
self.winningsCurrency = {}
|
||||||
self.rebuyCounts = {}
|
self.rebuyCounts = {}
|
||||||
self.addOnCounts = {}
|
self.addOnCounts = {}
|
||||||
self.koCounts = {}
|
self.koCounts = {}
|
||||||
|
|
||||||
# currency symbol for this summary
|
# currency symbol for this summary
|
||||||
self.sym = None
|
self.sym = None
|
||||||
#self.sym = self.SYMBOL[self.gametype['currency']] # save typing! delete this attr when done
|
#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):
|
def __str__(self):
|
||||||
#TODO : Update
|
#TODO : Update
|
||||||
|
@ -143,7 +150,7 @@ class TourneySummary(object):
|
||||||
|
|
||||||
structs = ( ("GAMETYPE", self.gametype),
|
structs = ( ("GAMETYPE", self.gametype),
|
||||||
("PLAYERS", self.players),
|
("PLAYERS", self.players),
|
||||||
("POSITIONS", self.finishPositions),
|
("RANKS", self.ranks),
|
||||||
("WINNINGS", self.winnings),
|
("WINNINGS", self.winnings),
|
||||||
("COUNT REBUYS", self.rebuyCounts),
|
("COUNT REBUYS", self.rebuyCounts),
|
||||||
("COUNT ADDONS", self.addOnCounts),
|
("COUNT ADDONS", self.addOnCounts),
|
||||||
|
@ -156,6 +163,10 @@ class TourneySummary(object):
|
||||||
for (name, struct) in structs:
|
for (name, struct) in structs:
|
||||||
str = str + "\n%s =\n" % name + pprint.pformat(struct, 4)
|
str = str + "\n%s =\n" % name + pprint.pformat(struct, 4)
|
||||||
return str
|
return str
|
||||||
|
#end def __str__
|
||||||
|
|
||||||
|
def parseSummary(self): abstract
|
||||||
|
"""should fill the class variables with the parsed information"""
|
||||||
|
|
||||||
def getSummaryText(self):
|
def getSummaryText(self):
|
||||||
return self.summaryText
|
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))
|
log.debug("addPlayer: rank:%s - name : '%s' - Winnings (%s)" % (rank, name, winnings))
|
||||||
self.players.append(name)
|
self.players.append(name)
|
||||||
self.finishPositions.update( { name : Decimal(rank) } )
|
self.ranks.update( { name : Decimal(rank) } )
|
||||||
self.winnings.update( { name : Decimal(winnings) } )
|
self.winnings.update( { name : Decimal(winnings) } )
|
||||||
self.winningsCurrency.update( { name : winningsCurrency } )
|
self.winningsCurrency.update( { name : winningsCurrency } )
|
||||||
self.rebuyCounts.update( {name: Decimal(rebuyCount) } )
|
self.rebuyCounts.update( {name: Decimal(rebuyCount) } )
|
||||||
|
|
Loading…
Reference in New Issue
Block a user