diff --git a/pyfpdb/GuiTourneyGraphViewer.py b/pyfpdb/GuiTourneyGraphViewer.py index e213e1f4..e8a3d41e 100644 --- a/pyfpdb/GuiTourneyGraphViewer.py +++ b/pyfpdb/GuiTourneyGraphViewer.py @@ -268,7 +268,7 @@ class GuiTourneyGraphViewer (threading.Thread): if len(winnings) == 0: return None - green = map(lambda x:float(x[0]), winnings) + green = map(lambda x:float(x[1]), winnings) #blue = map(lambda x: float(x[1]) if x[2] == True else 0.0, winnings) #red = map(lambda x: float(x[1]) if x[2] == False else 0.0, winnings) greenline = cumsum(green) diff --git a/pyfpdb/ImapFetcher.py b/pyfpdb/ImapFetcher.py index befecd6f..b3b5785f 100755 --- a/pyfpdb/ImapFetcher.py +++ b/pyfpdb/ImapFetcher.py @@ -20,8 +20,17 @@ #see http://tools.ietf.org/html/rfc2060#section-6.4.4 for IMAP4 search criteria from imaplib import IMAP4, IMAP4_SSL +import sys +import codecs +import re + +import Configuration +import Database +import SQL +import Options import PokerStarsSummary + import locale lang=locale.getdefaultlocale()[0][0:2] if lang=="en": @@ -89,4 +98,56 @@ def run(config, db): # finally: # pass server.logout() - \ No newline at end of file + +def readFile(filename): + kodec = "utf8" + in_fh = codecs.open(filename, 'r', kodec) + whole_file = in_fh.read() + in_fh.close() + return whole_file + + + +def runFake(db, config, infile): + summaryText = readFile(infile) + # This regex should be part of PokerStarsSummary + re_SplitGames = re.compile("PokerStars Tournament ") + summaryList = re.split(re_SplitGames, summaryText) + + if len(summaryList) <= 1: + print "DEBUG: re_SplitGames isn't matching" + + for summary in summaryList[1:]: + result = PokerStarsSummary.PokerStarsSummary(db=db, config=config, siteName=u"PokerStars", summaryText=summary, builtFrom = "file") + print "DEBUG: Processed: %s: tournNo: %s" % (result.tourneyId, result.tourNo) + +def splitPokerStarsSummaries(emailText): + splitSummaries=emailText.split("\nPokerStars Tournament #")[1:] + + +def main(argv=None): + if argv is None: + argv = sys.argv[1:] + + (options, argv) = Options.fpdb_options() + + if options.usage == True: + #Print usage examples and exit + print _("USAGE:") + sys.exit(0) + + # These options should really come from the OptionsParser + config = Configuration.Config() + db = Database.Database(config) + sql = SQL.Sql(db_server = 'sqlite') + settings = {} + settings.update(config.get_db_parameters()) + settings.update(config.get_import_parameters()) + settings.update(config.get_default_paths()) + db.recreate_tables() + + runFake(db, config, options.infile) + +if __name__ == '__main__': + sys.exit(main()) + diff --git a/pyfpdb/Options.py b/pyfpdb/Options.py index 11ef9d43..19139278 100644 --- a/pyfpdb/Options.py +++ b/pyfpdb/Options.py @@ -60,6 +60,9 @@ def fpdb_options(): default = 'EMPTY') parser.add_option("-v", "--version", action = "store_true", help = _("Print version information and exit.")) + parser.add_option("-u", "--usage", action="store_true", dest="usage", default=False, + help=_("Print some useful one liners")) + (options, argv) = parser.parse_args() return (options, argv) diff --git a/pyfpdb/PokerStarsSummary.py b/pyfpdb/PokerStarsSummary.py index 14b9cadc..36ceae48 100644 --- a/pyfpdb/PokerStarsSummary.py +++ b/pyfpdb/PokerStarsSummary.py @@ -37,8 +37,6 @@ else: except IOError: def _(string): return string - - class PokerStarsSummary(TourneySummary): limits = { 'No Limit':'nl', 'Pot Limit':'pl', 'Limit':'fl', 'LIMIT':'fl' } games = { # base, category @@ -53,16 +51,42 @@ class PokerStarsSummary(TourneySummary): 'Triple Draw 2-7 Lowball' : ('draw','27_3draw'), '5 Card Draw' : ('draw','fivedraw') } + + substitutions = { + 'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes + 'LS' : "\$|\xe2\x82\xac|" # legal currency symbols - Euro(cp1252, utf-8) + } + + re_SplitGames = re.compile("^PokerStars") - re_TourNo = re.compile("\#[0-9]+,") + re_TourNo = re.compile("\#(?P[0-9]+),") + + re_TourneyInfo = re.compile(u""" + \#(?P[0-9]+),\s + (?PNo\sLimit|Limit|LIMIT|Pot\sLimit)\s + (?PHold\'em|Razz|RAZZ|7\sCard\sStud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball|5\sCard\sDraw)\s + (?P[ a-zA-Z]+\s)? + (Buy-In:\s\$(?P[.0-9]+)(\/\$(?P[.0-9]+))?\s)? + (?P[0-9]+)\splayers\s + (\$?(?P[.\d]+)\sadded\sto\sthe\sprize\spool\sby\sPokerStars\.com\s)? + (Total\sPrize\sPool:\s\$?(?P[.0-9]+)\s)? + (Target\sTournament\s.*)? + Tournament\sstarted\s-\s + (?P[0-9]{4})\/(?P[0-9]{2})\/(?P[0-9]{2})[\-\s]+(?P[0-9]+):(?P[0-9]+):(?P[0-9]+)\s?\(?(?P[A-Z]+)\)\s + """ % substitutions ,re.VERBOSE|re.MULTILINE|re.DOTALL) + + re_Currency = re.compile(u"""(?P[%(LS)s]|FPP)""" % substitutions) + + re_Player = re.compile(u"""(?P[0-9]+):\s(?P.*)\s\(.*\),(\s)?(\$(?P[0-9]+\.[0-9]+))?(?Pstill\splaying)?""") + + re_DateTime = re.compile("\[(?P[0-9]{4})\/(?P[0-9]{2})\/(?P[0-9]{2})[\- ]+(?P[0-9]+):(?P[0-9]+):(?P[0-9]+)") + re_Entries = re.compile("[0-9]+") re_Prizepool = re.compile("\$[0-9]+\.[0-9]+") - re_Player = re.compile(u"""(?P[0-9]+):\s(?P.*)\s\(.*\),(\s)?(\$(?P[0-9]+\.[0-9]+))?(?Pstill\splaying)?""") re_BuyInFee = re.compile("(?P[0-9]+\.[0-9]+).*(?P[0-9]+\.[0-9]+)") re_FPP = re.compile("(?P[0-9]+)\sFPP") #note: the dollar and cent in the below line are currency-agnostic re_Added = re.compile("(?P[0-9]+)\.(?P[0-9]+)\s(?P[A-Z]+)(\sadded\sto\sthe\sprize\spool\sby\sPokerStars)") - re_DateTime = re.compile("\[(?P[0-9]{4})\/(?P[0-9]{2})\/(?P[0-9]{2})[\- ]+(?P[0-9]+):(?P[0-9]+):(?P[0-9]+)") re_DateTimeET = re.compile("(?P[0-9]{4})\/(?P[0-9]{2})\/(?P[0-9]{2})[\- ]+(?P[0-9]+):(?P[0-9]+):(?P[0-9]+)") re_GameInfo = re.compile(u""".+(?PNo\sLimit|Limit|LIMIT|Pot\sLimit)\s(?PHold\'em|Razz|RAZZ|7\sCard\sStud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball|5\sCard\sDraw)""") @@ -101,7 +125,7 @@ class PokerStarsSummary(TourneySummary): currentLine+=1 #note that I chose to make the code keep state (the current line number) #as that means it'll fail rather than silently skip potentially valuable information #print "after entries lines[currentLine]", lines[currentLine] - + result=self.re_Added.search(lines[currentLine]) if result: result=result.groupdict() @@ -112,7 +136,7 @@ class PokerStarsSummary(TourneySummary): self.added=0 self.addedCurrency="NA" #print "after added/entries lines[currentLine]", lines[currentLine] - + result=self.re_Prizepool.findall(lines[currentLine]) if result: self.prizepool = result[0] @@ -131,7 +155,7 @@ class PokerStarsSummary(TourneySummary): self.startTime= datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S") # also timezone at end, e.g. " ET" self.startTime = HandHistoryConverter.changeTimezone(self.startTime, "ET", "UTC") currentLine+=1 - + if useET: result=self.re_DateTimeET.search(lines[currentLine]) else: @@ -154,7 +178,7 @@ class PokerStarsSummary(TourneySummary): rank=result['RANK'] name=result['NAME'] winnings=result['WINNINGS'] - + if winnings: winnings=int(100*Decimal(winnings)) else: @@ -167,4 +191,68 @@ class PokerStarsSummary(TourneySummary): self.addPlayer(rank, name, winnings, self.currency, None, None, None)#TODO: currency, ko/addon/rebuy count -> need examples! #end def parseSummary + + def parseSummaryFile(self): + m = self.re_TourneyInfo.search(self.summaryText) + if m == None: + tmp = self.summaryText[0:200] + log.error(_("parseSummaryFile: Unable to recognise Tourney Info: '%s'") % tmp) + log.error(_("parseSummaryFile: Raising FpdbParseError")) + raise FpdbParseError(_("Unable to recognise Tourney Info: '%s'") % tmp) + + #print "DEBUG: m.groupdict(): %s" % m.groupdict() + + mg = m.groupdict() + if 'TOURNO' in mg: self.tourNo = mg['TOURNO'] + if 'LIMIT' in mg: self.gametype['limitType'] = self.limits[mg['LIMIT']] + if 'GAME' in mg: self.gametype['category'] = self.games[mg['GAME']][1] + if mg['BUYIN'] != None: + self.buyin = int(100*Decimal(mg['BUYIN'])) + if mg['FEE'] != None: + self.fee = int(100*Decimal(mg['FEE'])) + if 'PRIZEPOOL' in mg: self.prizepool = mg['PRIZEPOOL'] + if 'ENTRIES' in mg: self.entries = mg['ENTRIES'] + + datetimestr = "%s/%s/%s %s:%s:%s" % (mg['Y'], mg['M'], mg['D'], mg['H'], mg['MIN'], mg['S']) + self.startTime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S") + + if 'TZ' in mg: + self.startTime = HandHistoryConverter.changeTimezone(self.startTime, mg['TZ'], "UTC") + + + m = self.re_Currency.search(self.summaryText) + if m == None: + log.error(_("parseSummaryFile: Unable to locate currency")) + log.error(_("parseSummaryFile: Raising FpdbParseError")) + raise FpdbParseError(_("Unable to locate currency")) + #print "DEBUG: m.groupdict(): %s" % m.groupdict() + + mg = m.groupdict() + if mg['CURRENCY'] == "$": self.currency = "USD" + elif mg['CURRENCY'] == u"€": self.currency="EUR" + elif mg['CURRENCY'] == "FPP": self.currency="PSFP" + + m = self.re_Player.finditer(self.summaryText) + for a in m: + mg = a.groupdict() + #print "DEBUG: a.groupdict(): %s" % mg + name = mg['NAME'] + rank = mg['RANK'] + winnings = 0 + + if 'WINNINGS' in mg and mg['WINNINGS'] != None: + winnings = int(100*Decimal(mg['WINNINGS'])) + + if 'STILLPLAYING' in mg and mg['STILLPLAYING'] != None: + #print "stillplaying" + rank=None + winnings=None + + #TODO: currency, ko/addon/rebuy count -> need examples! + #print "DEBUG: addPlayer(%s, %s, %s, %s, None, None, None)" %(rank, name, winnings, self.currency) + #print "DEBUG: self.buyin: %s self.fee %s" %(self.buyin, self.fee) + self.addPlayer(rank, name, winnings, self.currency, None, None, None) + + #print self + #end class PokerStarsSummary diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 87857908..fff3f07e 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -3050,7 +3050,7 @@ class Sql: # Tourney Results query #################################### self.query['tourneyResults'] = """ - SELECT (tp.winnings - tt.buyIn - tt.fee) as profit, tp.koCount, tp.rebuyCount, tp.addOnCount, tt.buyIn, tt.fee + SELECT tp.tourneyId, (tp.winnings - tt.buyIn - tt.fee) as profit, tp.koCount, tp.rebuyCount, tp.addOnCount, tt.buyIn, tt.fee, t.siteTourneyNo FROM TourneysPlayers tp INNER JOIN Players pl ON (pl.id = tp.playerId) INNER JOIN Tourneys t ON (t.id = tp.tourneyId) diff --git a/pyfpdb/TourneySummary.py b/pyfpdb/TourneySummary.py index 105141d5..f78d96de 100644 --- a/pyfpdb/TourneySummary.py +++ b/pyfpdb/TourneySummary.py @@ -74,8 +74,8 @@ class TourneySummary(object): self.endTime = None self.tourNo = None self.currency = None - self.buyin = None - self.fee = None + self.buyin = 0 + self.fee = 0 self.hero = None self.maxseats = 0 self.entries = 0 @@ -127,6 +127,9 @@ class TourneySummary(object): if builtFrom=="IMAP": self.parseSummary() self.insertOrUpdate() + elif builtFrom == "file": + self.parseSummaryFile() + self.insertOrUpdate() #end def __init__ def __str__(self):