From cf6e818ae5ae784ee778cdc11b9c204337f70da1 Mon Sep 17 00:00:00 2001 From: Carl Gherardi Date: Mon, 14 Dec 2009 16:45:08 +0800 Subject: [PATCH 01/15] [NEWIMPORT] Enable NEWIMPORT by defaul --- pyfpdb/Configuration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index 996ef60c..bf8689a6 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -125,7 +125,7 @@ DATABASE_TYPES = ( DATABASE_TYPE_MYSQL, ) -NEWIMPORT = False +NEWIMPORT = True ######################################################################## def string_to_bool(string, default=True): From f03a9c287fba9398aba1eff20a17e5b398656d99 Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 17 Dec 2009 15:53:12 +0800 Subject: [PATCH 02/15] Add some code to kinda detect hand cancellation hhc.readHandInfo(self) hhc.readPlayerStacks(self) hhc.compilePlayerRegexs(self) hhc.markStreets(self) Is the order, the first correctly failing regex is markStreets --- pyfpdb/Hand.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 6901340e..32140256 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -54,6 +54,7 @@ class Hand(object): self.starttime = 0 self.handText = handText self.handid = 0 + self.cancelled = False self.dbid_hands = 0 self.dbid_pids = None self.dbid_gt = 0 @@ -263,6 +264,8 @@ If a player has None chips he won't be added.""" log.debug("markStreets:\n"+ str(self.streets)) else: log.error("markstreets didn't match") + log.error(" - Assuming hand cancelled") + self.cancelled = True def checkPlayerExists(self,player): if player not in [p[1] for p in self.players]: @@ -613,6 +616,8 @@ class HoldemOmahaHand(Hand): hhc.readPlayerStacks(self) hhc.compilePlayerRegexs(self) hhc.markStreets(self) + if self.cancelled: + return hhc.readBlinds(self) hhc.readAntes(self) hhc.readButton(self) From 26fc0b592837765c515277fc1f0b373b9934667b Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 17 Dec 2009 18:42:50 +0800 Subject: [PATCH 03/15] Add ability to import Stars archive files. PokerStars support can provide a HH archive. The format is similar but not the same as a a standard hh format as it contains an additional line "Hand #X" between each hand. Patch adds an option -s to GuiBulkImport, which when specified will strip these lines out and continue parsing. --- pyfpdb/GuiBulkImport.py | 4 ++++ pyfpdb/Hand.py | 1 + pyfpdb/HandHistoryConverter.py | 8 +++++++- pyfpdb/fpdb_import.py | 19 +++++++++++++------ 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/pyfpdb/GuiBulkImport.py b/pyfpdb/GuiBulkImport.py index 7db420c7..16131ab2 100755 --- a/pyfpdb/GuiBulkImport.py +++ b/pyfpdb/GuiBulkImport.py @@ -326,6 +326,8 @@ def main(argv=None): help="How often to print a one-line status report (0 (default) means never)") parser.add_option("-u", "--usage", action="store_true", dest="usage", default=False, help="Print some useful one liners") + parser.add_option("-s", "--starsarchive", action="store_true", dest="starsArchive", default=False, + help="Do the required conversion for Stars Archive format (ie. as provided by support") (options, argv) = parser.parse_args(args = argv) if options.usage == True: @@ -369,6 +371,8 @@ def main(argv=None): importer.setThreads(-1) importer.addBulkImportImportFileOrDir(os.path.expanduser(options.filename), site=options.filtername) importer.setCallHud(False) + if options.starsArchive: + importer.setStarsArchive(True) (stored, dups, partial, errs, ttime) = importer.runImport() importer.clearFileList() print 'GuiBulkImport done: Stored: %d \tDuplicates: %d \tPartial: %d \tErrors: %d in %s seconds - %.0f/sec'\ diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 32140256..3467216a 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -266,6 +266,7 @@ If a player has None chips he won't be added.""" log.error("markstreets didn't match") log.error(" - Assuming hand cancelled") self.cancelled = True + raise FpdbParseError def checkPlayerExists(self,player): if player not in [p[1] for p in self.players]: diff --git a/pyfpdb/HandHistoryConverter.py b/pyfpdb/HandHistoryConverter.py index 27bb9b1a..a18797df 100644 --- a/pyfpdb/HandHistoryConverter.py +++ b/pyfpdb/HandHistoryConverter.py @@ -57,7 +57,7 @@ class HandHistoryConverter(): codepage = "cp1252" - def __init__(self, in_path = '-', out_path = '-', follow=False, index=0, autostart=True): + def __init__(self, in_path = '-', out_path = '-', follow=False, index=0, autostart=True, starsArchive=False): """\ in_path (default '-' = sys.stdin) out_path (default '-' = sys.stdout) @@ -66,6 +66,7 @@ follow : whether to tail -f the input""" log.info("HandHistory init - %s subclass, in_path '%s'; out_path '%s'" % (self.sitename, in_path, out_path) ) self.index = 0 + self.starsArchive = starsArchive self.in_path = in_path self.out_path = out_path @@ -254,6 +255,11 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py. self.readFile() self.obs = self.obs.strip() self.obs = self.obs.replace('\r\n', '\n') + if self.starsArchive == True: + log.debug("Converting starsArchive format to readable") + m = re.compile('^Hand #\d+', re.MULTILINE) + self.obs = m.sub('', self.obs) + if self.obs is None or self.obs == "": log.info("Read no hands.") return [] diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index 7b3dd4f1..8921d9d8 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -91,6 +91,7 @@ class Importer: self.settings.setdefault("writeQMaxWait", 10) # not used self.settings.setdefault("dropIndexes", "don't drop") self.settings.setdefault("dropHudCache", "don't drop") + self.settings.setdefault("starsArchive", False) self.writeq = None self.database = Database.Database(self.config, sql = self.sql) @@ -134,6 +135,9 @@ class Importer: def setDropHudCache(self, value): self.settings['dropHudCache'] = value + def setStarsArchive(self, value): + self.settings['starsArchive'] = value + # def setWatchTime(self): # self.updated = time() @@ -425,7 +429,7 @@ class Importer: mod = __import__(filter) obj = getattr(mod, filter_name, None) if callable(obj): - hhc = obj(in_path = file, out_path = out_path, index = 0) # Index into file 0 until changeover + hhc = obj(in_path = file, out_path = out_path, index = 0, starsArchive = self.settings['starsArchive']) # Index into file 0 until changeover if hhc.getStatus() and self.NEWIMPORT == False: (stored, duplicates, partial, errors, ttime) = self.import_fpdb_file(db, out_path, site, q) elif hhc.getStatus() and self.NEWIMPORT == True: @@ -435,11 +439,14 @@ class Importer: to_hud = [] for hand in handlist: - #try, except duplicates here? - hand.prepInsert(self.database) - hand.insert(self.database) - if self.callHud and hand.dbid_hands != 0: - to_hud.append(hand.dbid_hands) + if hand is not None: + #try, except duplicates here? + hand.prepInsert(self.database) + hand.insert(self.database) + if self.callHud and hand.dbid_hands != 0: + to_hud.append(hand.dbid_hands) + else: + log.error("Hand processed but empty") self.database.commit() #pipe the Hands.id out to the HUD From 1093b1e43c3a12af748e0768cd71513e70d6d060 Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 18 Dec 2009 10:27:09 +0800 Subject: [PATCH 04/15] Remove dead code --- pyfpdb/fpdb_import.py | 160 +----------------------------------------- 1 file changed, 1 insertion(+), 159 deletions(-) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index 8921d9d8..21aa5d5c 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -430,9 +430,7 @@ class Importer: obj = getattr(mod, filter_name, None) if callable(obj): hhc = obj(in_path = file, out_path = out_path, index = 0, starsArchive = self.settings['starsArchive']) # Index into file 0 until changeover - if hhc.getStatus() and self.NEWIMPORT == False: - (stored, duplicates, partial, errors, ttime) = self.import_fpdb_file(db, out_path, site, q) - elif hhc.getStatus() and self.NEWIMPORT == True: + if hhc.getStatus() and self.NEWIMPORT == True: #This code doesn't do anything yet handlist = hhc.getProcessedHands() self.pos_in_file[file] = hhc.getLastCharacterRead() @@ -468,162 +466,6 @@ class Importer: return (stored, duplicates, partial, errors, ttime) - def import_fpdb_file(self, db, file, site, q): - starttime = time() - last_read_hand = 0 - loc = 0 - (stored, duplicates, partial, errors, ttime) = (0, 0, 0, 0, 0) - # print "file =", file - if file == "stdin": - inputFile = sys.stdin - else: - if os.path.exists(file): - inputFile = open(file, "rU") - else: - self.removeFromFileList[file] = True - return (0, 0, 0, 1, 0) - try: - loc = self.pos_in_file[file] - #size = os.path.getsize(file) - #print "loc =", loc, 'size =', size - except KeyError: - pass - # Read input file into class and close file - inputFile.seek(loc) - #tmplines = inputFile.readlines() - #if tmplines == None or tmplines == []: - # print "tmplines = ", tmplines - #else: - # print "tmplines[0] =", tmplines[0] - self.lines = fpdb_simple.removeTrailingEOL(inputFile.readlines()) - self.pos_in_file[file] = inputFile.tell() - inputFile.close() - - x = clock() - (stored, duplicates, partial, errors, ttime, handsId) = self.import_fpdb_lines(db, self.lines, starttime, file, site, q) - - db.commit() - y = clock() - ttime = y - x - #ttime = time() - starttime - if q is None: - log.info("Total stored: %(stored)d\tduplicates:%(duplicates)d\terrors:%(errors)d\ttime:%(ttime)s" % locals()) - - if not stored: - if duplicates: - for line_no in xrange(len(self.lines)): - if self.lines[line_no].find("Game #") != -1: - final_game_line = self.lines[line_no] - handsId=fpdb_simple.parseSiteHandNo(final_game_line) - else: - print "failed to read a single hand from file:", inputFile - handsId = 0 - #todo: this will cause return of an unstored hand number if the last hand was error - self.handsId = handsId - - return (stored, duplicates, partial, errors, ttime) - # end def import_fpdb_file - - - def import_fpdb_lines(self, db, lines, starttime, file, site, q = None): - """Import an fpdb hand history held in the list lines, could be one hand or many""" - - #db.lock_for_insert() # should be ok when using one thread, but doesn't help?? - while gtk.events_pending(): - gtk.main_iteration(False) - - try: # sometimes we seem to be getting an empty self.lines, in which case, we just want to return. - firstline = lines[0] - except: - # just skip the debug message and return silently: - #print "DEBUG: import_fpdb_file: failed on lines[0]: '%s' '%s' '%s' '%s' " %( file, site, lines, loc) - return (0,0,0,1,0,0) - - if "Tournament Summary" in firstline: - print "TODO: implement importing tournament summaries" - #self.faobs = readfile(inputFile) - #self.parseTourneyHistory() - return (0,0,0,1,0,0) - - category = fpdb_simple.recogniseCategory(firstline) - - startpos = 0 - stored = 0 #counter - duplicates = 0 #counter - partial = 0 #counter - errors = 0 #counter - ttime = 0 - handsId = 0 - - for i in xrange(len(lines)): - if len(lines[i]) < 2: #Wierd way to detect for '\r\n' or '\n' - endpos = i - hand = lines[startpos:endpos] - - if len(hand[0]) < 2: - hand=hand[1:] - - if len(hand) < 3: - pass - #TODO: This is ugly - we didn't actually find the start of the - # hand with the outer loop so we test again... - else: - isTourney = fpdb_simple.isTourney(hand[0]) - if not isTourney: - hand = fpdb_simple.filterAnteBlindFold(hand) - self.hand = hand - - try: - handsId = fpdb_parse_logic.mainParser( self.settings, self.siteIds[site] - , category, hand, self.config - , db, q ) - db.commit() - - stored += 1 - if self.callHud: - #print "call to HUD here. handsId:",handsId - #pipe the Hands.id out to the HUD - # print "fpdb_import: sending hand to hud", handsId, "pipe =", self.caller.pipe_to_hud - try: - self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep) - except IOError: # hud closed - self.callHud = False - pass # continue import without hud - except Exceptions.DuplicateError: - duplicates += 1 - db.rollback() - except (ValueError), fe: - errors += 1 - self.printEmailErrorMessage(errors, file, hand) - - if (self.settings['failOnError']): - db.commit() #dont remove this, in case hand processing was cancelled. - raise - else: - db.rollback() - except (fpdb_simple.FpdbError), fe: - errors += 1 - self.printEmailErrorMessage(errors, file, hand) - db.rollback() - - if self.settings['failOnError']: - db.commit() #dont remove this, in case hand processing was cancelled. - raise - - if self.settings['minPrint']: - if not ((stored+duplicates+errors) % self.settings['minPrint']): - print "stored:", stored, " duplicates:", duplicates, "errors:", errors - - if self.settings['handCount']: - if ((stored+duplicates+errors) >= self.settings['handCount']): - if not self.settings['quiet']: - print "quitting due to reaching the amount of hands to be imported" - print "Total stored:", stored, "duplicates:", duplicates, "errors:", errors, " time:", (time() - starttime) - sys.exit(0) - startpos = endpos - return (stored, duplicates, partial, errors, ttime, handsId) - # end def import_fpdb_lines - def printEmailErrorMessage(self, errors, filename, line): traceback.print_exc(file=sys.stderr) print "Error No.",errors,", please send the hand causing this to steffen@sycamoretest.info so I can fix it." From 975eb360ef96d3f669269117c9fe78f151662379 Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 18 Dec 2009 10:27:43 +0800 Subject: [PATCH 05/15] [NEWIMPORT] Add stubbed variable to insert --- pyfpdb/Database.py | 3 ++- pyfpdb/SQL.py | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 9d1f3f85..72b41336 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -1651,7 +1651,8 @@ class Database: pdata[p]['street2CheckCallRaiseDone'], pdata[p]['street3CheckCallRaiseChance'], pdata[p]['street3CheckCallRaiseDone'], - pdata[p]['street4CheckCallRaiseChance'] + pdata[p]['street4CheckCallRaiseChance'], + pdata[p]['street4CheckCallRaiseDone'] ) ) q = self.sql.query['store_hands_players'] diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index c0319dfe..56c1f388 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -3404,10 +3404,11 @@ class Sql: street2CheckCallRaiseDone, street3CheckCallRaiseChance, street3CheckCallRaiseDone, - street4CheckCallRaiseChance + street4CheckCallRaiseChance, + street4CheckCallRaiseDone ) VALUES ( - %s, %s, %s, %s, + %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, From 2b7d34c4842e40b9d8fdb950eefd23c99068e95d Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 18 Dec 2009 13:32:09 +0800 Subject: [PATCH 06/15] [NEWIMPORT] Fix syntax to be 2.5 compatible. Python 2.6 enumerate() function contains a useful 'start' paramater, apparently this did not exist in 2.5. Patch frim Mika Bostrom --- pyfpdb/DerivedStats.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/pyfpdb/DerivedStats.py b/pyfpdb/DerivedStats.py index 1a34db1e..5943a10f 100644 --- a/pyfpdb/DerivedStats.py +++ b/pyfpdb/DerivedStats.py @@ -168,8 +168,10 @@ class DerivedStats(): for player in hand.players: hcs = hand.join_holecards(player[1], asList=True) hcs = hcs + [u'0x', u'0x', u'0x', u'0x', u'0x'] - for i, card in enumerate(hcs[:7], 1): - self.handsplayers[player[1]]['card%s' % i] = Card.encodeCard(card) + #for i, card in enumerate(hcs[:7], 1): #Python 2.6 syntax + # self.handsplayers[player[1]]['card%s' % i] = Card.encodeCard(card) + for i, card in enumerate(hcs[:7]): + self.handsplayers[player[1]]['card%s' % (i+1)] = Card.encodeCard(card) # position, @@ -266,13 +268,17 @@ class DerivedStats(): # Then no bets before the player with initiatives first action on current street # ie. if player on street-1 had initiative # and no donkbets occurred - for i, street in enumerate(hand.actionStreets[2:], start=1): - name = self.lastBetOrRaiser(hand.actionStreets[i]) + + # XXX: enumerate(list, start=x) is python 2.6 syntax; 'start' + # came there + #for i, street in enumerate(hand.actionStreets[2:], start=1): + for i, street in enumerate(hand.actionStreets[2:]: + name = self.lastBetOrRaiser(hand.actionStreets[i+1]) if name: - chance = self.noBetsBefore(hand.actionStreets[i+1], name) - self.handsplayers[name]['street%dCBChance' %i] = True + chance = self.noBetsBefore(hand.actionStreets[i+2], name) + self.handsplayers[name]['street%dCBChance' % (i+1)] = True if chance == True: - self.handsplayers[name]['street%dCBDone' %i] = self.betStreet(hand.actionStreets[i+1], name) + self.handsplayers[name]['street%dCBDone' % (i+1)] = self.betStreet(hand.actionStreets[i+2], name) def seen(self, hand, i): pas = set() From 02453ce3c09096b50405265b433e29702b0859ec Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 22 Dec 2009 13:47:33 +0800 Subject: [PATCH 07/15] Move locale variable to Configuration --- pyfpdb/fpdb_import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index 21aa5d5c..577562b8 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -409,7 +409,7 @@ class Importer: conv = None (stored, duplicates, partial, errors, ttime) = (0, 0, 0, 0, 0) - file = file.decode(fpdb_simple.LOCALE_ENCODING) + file = file.decode(Configuration.LOCALE_ENCODING) # Load filter, process file, pass returned filename to import_fpdb_file if self.settings['threads'] > 0 and self.writeq is not None: From 262eb5200d85cdc13691a09dab0885a8df11922d Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 22 Dec 2009 13:49:22 +0800 Subject: [PATCH 08/15] Add LOCALE static to Configuration --- pyfpdb/Configuration.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index bf8689a6..174d0673 100755 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -31,6 +31,7 @@ import inspect import string import traceback import shutil +import locale import xml.dom.minidom from xml.dom.minidom import Node @@ -126,6 +127,7 @@ DATABASE_TYPES = ( ) NEWIMPORT = True +LOCALE_ENCODING = locale.getdefaultlocale()[1] ######################################################################## def string_to_bool(string, default=True): From 1b82f20411f02dfcaf3cc57aceebca514ecb5c45 Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 22 Dec 2009 14:44:35 +0800 Subject: [PATCH 09/15] [NEWIMPORT] Remove legacy code. --- pyfpdb/CliFpdb.py | 66 -- pyfpdb/Database.py | 350 -------- pyfpdb/GuiBulkImport.py | 1 - pyfpdb/GuiTableViewer.py | 1 - pyfpdb/fpdb_db.py | 1 - pyfpdb/fpdb_import.py | 2 - pyfpdb/fpdb_parse_logic.py | 235 ----- pyfpdb/fpdb_simple.py | 1728 ------------------------------------ 8 files changed, 2384 deletions(-) delete mode 100755 pyfpdb/CliFpdb.py delete mode 100644 pyfpdb/fpdb_parse_logic.py delete mode 100644 pyfpdb/fpdb_simple.py diff --git a/pyfpdb/CliFpdb.py b/pyfpdb/CliFpdb.py deleted file mode 100755 index abdddb45..00000000 --- a/pyfpdb/CliFpdb.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/python - -#Copyright 2008 Steffen Jobbagy-Felso -#This program is free software: you can redistribute it and/or modify -#it under the terms of the GNU Affero General Public License as published by -#the Free Software Foundation, version 3 of the License. -# -#This program is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#GNU General Public License for more details. -# -#You should have received a copy of the GNU Affero General Public License -#along with this program. If not, see . -#In the "official" distribution you can find the license in -#agpl-3.0.txt in the docs folder of the package. - -import os -import sys -import fpdb_simple -from optparse import OptionParser - -try: - import MySQLdb -except: - diaSQLLibMissing = gtk.Dialog(title="Fatal Error - SQL interface library missing", parent=None, flags=0, buttons=(gtk.STOCK_QUIT,gtk.RESPONSE_OK)) - - print "Please note that the CLI importer only works with MySQL, if you use PostgreSQL this error is expected." - -import fpdb_import -import fpdb_db - -if __name__ == "__main__": - #process CLI parameters - parser = OptionParser() - parser.add_option("-c", "--handCount", default="0", type="int", - help="Number of hands to import (default 0 means unlimited)") - parser.add_option("-d", "--database", default="fpdb", help="The MySQL database to use (default fpdb)") - parser.add_option("-e", "--errorFile", default="failed.txt", - help="File to store failed hands into. (default: failed.txt) Not implemented.") - parser.add_option("-f", "--inputFile", "--file", "--inputfile", default="stdin", - help="The file you want to import (remember to use quotes if necessary)") - parser.add_option("-m", "--minPrint", "--status", default="50", type="int", - help="How often to print a one-line status report (0 means never, default is 50)") - parser.add_option("-p", "--password", help="The password for the MySQL user") - parser.add_option("-q", "--quiet", action="store_true", - help="If this is passed it doesn't print a total at the end nor the opening line. Note that this purposely does NOT change --minPrint") - parser.add_option("-s", "--server", default="localhost", - help="Hostname/IP of the MySQL server (default localhost)") - parser.add_option("-u", "--user", default="fpdb", help="The MySQL username (default fpdb)") - parser.add_option("-x", "--failOnError", action="store_true", - help="If this option is passed it quits when it encounters any error") - - (options, argv) = parser.parse_args() - - settings={'callFpdbHud':False, 'db-backend':2} - settings['db-host']=options.server - settings['db-user']=options.user - settings['db-password']=options.password - settings['db-databaseName']=options.database - settings['handCount']=options.handCount - settings['failOnError']=options.failOnError - - importer = fpdb_import.Importer(options, settings) - importer.addImportFile(options.inputFile) - importer.runImport() diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 72b41336..412036ab 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -43,7 +43,6 @@ import Queue # FreePokerTools modules import fpdb_db -import fpdb_simple import Configuration import SQL import Card @@ -724,120 +723,6 @@ class Database: return ret - #stores a stud/razz hand into the database - def ring_stud(self, config, settings, base, category, site_hand_no, gametype_id, hand_start_time - ,names, player_ids, start_cashes, antes, card_values, card_suits, winnings, rakes - ,action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName - ,seatNos): - - fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits) - - hands_id = self.storeHands(self.backend, site_hand_no, gametype_id - ,hand_start_time, names, tableName, maxSeats, hudImportData - ,(None, None, None, None, None), (None, None, None, None, None)) - - #print "before calling store_hands_players_stud, antes:", antes - hands_players_ids = self.store_hands_players_stud(self.backend, hands_id, player_ids - ,start_cashes, antes, card_values - ,card_suits, winnings, rakes, seatNos) - - if 'dropHudCache' not in settings or settings['dropHudCache'] != 'drop': - self.storeHudCache(self.backend, base, category, gametype_id, hand_start_time, player_ids, hudImportData) - - return hands_id - #end def ring_stud - - def ring_holdem_omaha(self, config, settings, base, category, site_hand_no, gametype_id - ,hand_start_time, names, player_ids, start_cashes, positions, card_values - ,card_suits, board_values, board_suits, winnings, rakes, action_types, allIns - ,action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos): - """stores a holdem/omaha hand into the database""" - - t0 = time() - #print "in ring_holdem_omaha" - fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits) - t1 = time() - fpdb_simple.fill_board_cards(board_values, board_suits) - t2 = time() - - hands_id = self.storeHands(self.backend, site_hand_no, gametype_id - ,hand_start_time, names, tableName, maxSeats - ,hudImportData, board_values, board_suits) - #TEMPORARY CALL! - Just until all functions are migrated - t3 = time() - hands_players_ids = self.store_hands_players_holdem_omaha( - self.backend, category, hands_id, player_ids, start_cashes - , positions, card_values, card_suits, winnings, rakes, seatNos, hudImportData) - t4 = time() - if 'dropHudCache' not in settings or settings['dropHudCache'] != 'drop': - self.storeHudCache(self.backend, base, category, gametype_id, hand_start_time, player_ids, hudImportData) - t5 = time() - #print "fills=(%4.3f) saves=(%4.3f,%4.3f,%4.3f)" % (t2-t0, t3-t2, t4-t3, t5-t4) - return hands_id - #end def ring_holdem_omaha - - def tourney_holdem_omaha(self, config, settings, base, category, siteTourneyNo, buyin, fee, knockout - ,entries, prizepool, tourney_start, payin_amounts, ranks, tourneyTypeId - ,siteId #end of tourney specific params - ,site_hand_no, gametype_id, hand_start_time, names, player_ids - ,start_cashes, positions, card_values, card_suits, board_values - ,board_suits, winnings, rakes, action_types, allIns, action_amounts - ,actionNos, hudImportData, maxSeats, tableName, seatNos): - """stores a tourney holdem/omaha hand into the database""" - - fpdb_simple.fillCardArrays(len(names), base, category, card_values, card_suits) - fpdb_simple.fill_board_cards(board_values, board_suits) - - tourney_id = self.store_tourneys(tourneyTypeId, siteTourneyNo, entries, prizepool, tourney_start) - tourneys_players_ids = self.store_tourneys_players(tourney_id, player_ids, payin_amounts, ranks, winnings) - - hands_id = self.storeHands(self.backend, site_hand_no, gametype_id - ,hand_start_time, names, tableName, maxSeats - ,hudImportData, board_values, board_suits) - - hands_players_ids = self.store_hands_players_holdem_omaha_tourney( - self.backend, category, hands_id, player_ids, start_cashes, positions - , card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids - , hudImportData, tourneyTypeId) - - #print "tourney holdem, backend=%d" % backend - if 'dropHudCache' not in settings or settings['dropHudCache'] != 'drop': - self.storeHudCache(self.backend, base, category, gametype_id, hand_start_time, player_ids, hudImportData) - - return hands_id - #end def tourney_holdem_omaha - - def tourney_stud(self, config, settings, base, category, siteTourneyNo, buyin, fee, knockout, entries - ,prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteId - ,siteHandNo, gametypeId, handStartTime, names, playerIds, startCashes, antes - ,cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts - ,actionNos, hudImportData, maxSeats, tableName, seatNos): - #stores a tourney stud/razz hand into the database - - fpdb_simple.fillCardArrays(len(names), base, category, cardValues, cardSuits) - - tourney_id = self.store_tourneys(tourneyTypeId, siteTourneyNo, entries, prizepool, tourneyStartTime) - - tourneys_players_ids = self.store_tourneys_players(tourney_id, playerIds, payin_amounts, ranks, winnings) - - hands_id = self.storeHands( self.backend, siteHandNo, gametypeId - , handStartTime, names, tableName, maxSeats - , hudImportData, (None, None, None, None, None), (None, None, None, None, None) ) - # changed board_values and board_suits to arrays of None, just like the - # cash game version of this function does - i don't believe this to be - # the correct thing to do (tell me if i'm wrong) but it should keep the - # importer from crashing - - hands_players_ids = self.store_hands_players_stud_tourney(self.backend, hands_id - , playerIds, startCashes, antes, cardValues, cardSuits - , winnings, rakes, seatNos, tourneys_players_ids, tourneyTypeId) - - if 'dropHudCache' not in settings or settings['dropHudCache'] != 'drop': - self.storeHudCache(self.backend, base, category, gametypeId, handStartTime, playerIds, hudImportData) - - return hands_id - #end def tourney_stud - def prepareBulkImport(self): """Drop some indexes/foreign keys to prepare for bulk import. Currently keeping the standalone indexes as needed to import quickly""" @@ -1465,64 +1350,6 @@ class Database: print "Error during fdb.lock_for_insert:", str(sys.exc_value) #end def lock_for_insert - def store_the_hand(self, h): - """Take a HandToWrite object and store it in the db""" - - # Following code writes hands to database and commits (or rolls back if there is an error) - try: - result = None - if h.isTourney: - ranks = map(lambda x: 0, h.names) # create an array of 0's equal to the length of names - payin_amounts = fpdb_simple.calcPayin(len(h.names), h.buyin, h.fee) - - if h.base == "hold": - result = self.tourney_holdem_omaha( - h.config, h.settings, h.base, h.category, h.siteTourneyNo, h.buyin - , h.fee, h.knockout, h.entries, h.prizepool, h.tourneyStartTime - , payin_amounts, ranks, h.tourneyTypeId, h.siteID, h.siteHandNo - , h.gametypeID, h.handStartTime, h.names, h.playerIDs, h.startCashes - , h.positions, h.cardValues, h.cardSuits, h.boardValues, h.boardSuits - , h.winnings, h.rakes, h.actionTypes, h.allIns, h.actionAmounts - , h.actionNos, h.hudImportData, h.maxSeats, h.tableName, h.seatNos) - elif h.base == "stud": - result = self.tourney_stud( - h.config, h.settings, h.base, h.category, h.siteTourneyNo - , h.buyin, h.fee, h.knockout, h.entries, h.prizepool, h.tourneyStartTime - , payin_amounts, ranks, h.tourneyTypeId, h.siteID, h.siteHandNo - , h.gametypeID, h.handStartTime, h.names, h.playerIDs, h.startCashes - , h.antes, h.cardValues, h.cardSuits, h.winnings, h.rakes, h.actionTypes - , h.allIns, h.actionAmounts, h.actionNos, h.hudImportData, h.maxSeats - , h.tableName, h.seatNos) - else: - raise FpdbError("unrecognised category") - else: - if h.base == "hold": - result = self.ring_holdem_omaha( - h.config, h.settings, h.base, h.category, h.siteHandNo - , h.gametypeID, h.handStartTime, h.names, h.playerIDs - , h.startCashes, h.positions, h.cardValues, h.cardSuits - , h.boardValues, h.boardSuits, h.winnings, h.rakes - , h.actionTypes, h.allIns, h.actionAmounts, h.actionNos - , h.hudImportData, h.maxSeats, h.tableName, h.seatNos) - elif h.base == "stud": - result = self.ring_stud( - h.config, h.settings, h.base, h.category, h.siteHandNo, h.gametypeID - , h.handStartTime, h.names, h.playerIDs, h.startCashes, h.antes - , h.cardValues, h.cardSuits, h.winnings, h.rakes, h.actionTypes, h.allIns - , h.actionAmounts, h.actionNos, h.hudImportData, h.maxSeats, h.tableName - , h.seatNos) - else: - raise FpdbError("unrecognised category") - except: - print "Error storing hand: " + str(sys.exc_value) - self.rollback() - # re-raise the exception so that the calling routine can decide what to do: - # (e.g. a write thread might try again) - raise - - return result - #end def store_the_hand - ########################### # NEWIMPORT CODE ########################### @@ -2583,183 +2410,6 @@ class Database: #end def tRecogniseTourneyType - def tRecognizeTourney(self, tourney, dbTourneyTypeId): - logging.debug("Database.tRecognizeTourney") - tourneyID = 1 - # Check if tourney exists in db (based on tourney.siteId and tourney.tourNo) - # If so retrieve all data to check for consistency - cursor = self.get_cursor() - cursor.execute (self.sql.query['getTourney'].replace('%s', self.sql.query['placeholder']), - (tourney.tourNo, tourney.siteId) - ) - result=cursor.fetchone() - - expectedValuesDecimal = { 2 : "entries", 3 : "prizepool", 6 : "buyInChips", 9 : "rebuyChips", - 10 : "addOnChips", 11 : "rebuyAmount", 12 : "addOnAmount", 13 : "totalRebuys", - 14 : "totalAddOns", 15 : "koBounty" } - expectedValues = { 7 : "tourneyName", 16 : "tourneyComment" } - - tourneyDataMatch = True - tCommentTs = None - starttime = None - endtime = None - - try: - len(result) - tourneyID = result[0] - logging.debug("Tourney found in db with TourneyID = %d" % tourneyID) - if result[1] <> dbTourneyTypeId: - tourneyDataMatch = False - logging.debug("Tourney has wrong type ID (expected : %s - found : %s)" % (dbTourneyTypeId, result[1])) - if (tourney.starttime is None and result[4] is not None) or ( tourney.starttime is not None and fpdb_simple.parseHandStartTime("- %s" % tourney.starttime) <> result[4]) : - tourneyDataMatch = False - logging.debug("Tourney data mismatch : wrong starttime : Tourney=%s / db=%s" % (tourney.starttime, result[4])) - if (tourney.endtime is None and result[5] is not None) or ( tourney.endtime is not None and fpdb_simple.parseHandStartTime("- %s" % tourney.endtime) <> result[5]) : - tourneyDataMatch = False - logging.debug("Tourney data mismatch : wrong endtime : Tourney=%s / db=%s" % (tourney.endtime, result[5])) - - for ev in expectedValues : - if ( getattr( tourney, expectedValues.get(ev) ) <> result[ev] ): - logging.debug("Tourney data mismatch : wrong %s : Tourney=%s / db=%s" % (expectedValues.get(ev), getattr( tourney, expectedValues.get(ev)), result[ev]) ) - tourneyDataMatch = False - #break - for evD in expectedValuesDecimal : - if ( Decimal(getattr( tourney, expectedValuesDecimal.get(evD)) ) <> result[evD] ): - logging.debug("Tourney data mismatch : wrong %s : Tourney=%s / db=%s" % (expectedValuesDecimal.get(evD), getattr( tourney, expectedValuesDecimal.get(evD)), result[evD]) ) - tourneyDataMatch = False - #break - - # TO DO : Deal with matrix summary mutliple parsings - - except: - # Tourney not found : create - logging.debug("Tourney is not found : create") - if tourney.tourneyComment is not None : - tCommentTs = datetime.today() - if tourney.starttime is not None : - starttime = fpdb_simple.parseHandStartTime("- %s" % tourney.starttime) - if tourney.endtime is not None : - endtime = fpdb_simple.parseHandStartTime("- %s" % tourney.endtime) - # TODO : deal with matrix Id processed - cursor.execute (self.sql.query['insertTourney'].replace('%s', self.sql.query['placeholder']), - (dbTourneyTypeId, tourney.tourNo, tourney.entries, tourney.prizepool, starttime, - endtime, tourney.buyInChips, tourney.tourneyName, 0, tourney.rebuyChips, tourney.addOnChips, - tourney.rebuyAmount, tourney.addOnAmount, tourney.totalRebuys, tourney.totalAddOns, tourney.koBounty, - tourney.tourneyComment, tCommentTs) - ) - tourneyID = self.get_last_insert_id(cursor) - - - # Deal with inconsistent tourney in db - if tourneyDataMatch == False : - # Update Tourney - if result[16] <> tourney.tourneyComment : - tCommentTs = datetime.today() - if tourney.starttime is not None : - starttime = fpdb_simple.parseHandStartTime("- %s" % tourney.starttime) - if tourney.endtime is not None : - endtime = fpdb_simple.parseHandStartTime("- %s" % tourney.endtime) - - cursor.execute (self.sql.query['updateTourney'].replace('%s', self.sql.query['placeholder']), - (dbTourneyTypeId, tourney.entries, tourney.prizepool, starttime, - endtime, tourney.buyInChips, tourney.tourneyName, 0, tourney.rebuyChips, tourney.addOnChips, - tourney.rebuyAmount, tourney.addOnAmount, tourney.totalRebuys, tourney.totalAddOns, tourney.koBounty, - tourney.tourneyComment, tCommentTs, tourneyID) - ) - - return tourneyID - #end def tRecognizeTourney - - def tStoreTourneyPlayers(self, tourney, dbTourneyId): - logging.debug("Database.tStoreTourneyPlayers") - # First, get playerids for the players and specifically the one for hero : - playersIds = self.recognisePlayerIDs(tourney.players, tourney.siteId) - # hero may be None for matrix tourneys summaries -# hero = [ tourney.hero ] -# heroId = self.recognisePlayerIDs(hero , tourney.siteId) -# logging.debug("hero Id = %s - playersId = %s" % (heroId , playersIds)) - - tourneyPlayersIds=[] - try: - cursor = self.get_cursor() - - for i in xrange(len(playersIds)): - cursor.execute(self.sql.query['getTourneysPlayers'].replace('%s', self.sql.query['placeholder']) - ,(dbTourneyId, playersIds[i])) - result=cursor.fetchone() - #print "tried SELECTing tourneys_players.id:",tmp - - try: - len(result) - # checking data - logging.debug("TourneysPlayers found : checking data") - expectedValuesDecimal = { 1 : "payinAmounts", 2 : "finishPositions", 3 : "winnings", 4 : "countRebuys", - 5 : "countAddOns", 6 : "countKO" } - - tourneyPlayersIds.append(result[0]); - - tourneysPlayersDataMatch = True - for evD in expectedValuesDecimal : - if ( Decimal(getattr( tourney, expectedValuesDecimal.get(evD))[tourney.players[i]] ) <> result[evD] ): - logging.debug("TourneysPlayers data mismatch for TourneysPlayer id=%d, name=%s : wrong %s : Tourney=%s / db=%s" % (result[0], tourney.players[i], expectedValuesDecimal.get(evD), getattr( tourney, expectedValuesDecimal.get(evD))[tourney.players[i]], result[evD]) ) - tourneysPlayersDataMatch = False - #break - - if tourneysPlayersDataMatch == False: - logging.debug("TourneysPlayers data update needed") - cursor.execute (self.sql.query['updateTourneysPlayers'].replace('%s', self.sql.query['placeholder']), - (tourney.payinAmounts[tourney.players[i]], tourney.finishPositions[tourney.players[i]], - tourney.winnings[tourney.players[i]] , tourney.countRebuys[tourney.players[i]], - tourney.countAddOns[tourney.players[i]] , tourney.countKO[tourney.players[i]], - result[7], result[8], result[0]) - ) - - except TypeError: - logging.debug("TourneysPlayers not found : need insert") - cursor.execute (self.sql.query['insertTourneysPlayers'].replace('%s', self.sql.query['placeholder']), - (dbTourneyId, playersIds[i], - tourney.payinAmounts[tourney.players[i]], tourney.finishPositions[tourney.players[i]], - tourney.winnings[tourney.players[i]] , tourney.countRebuys[tourney.players[i]], - tourney.countAddOns[tourney.players[i]] , tourney.countKO[tourney.players[i]], - None, None) - ) - tourneyPlayersIds.append(self.get_last_insert_id(cursor)) - - except: - raise fpdb_simple.FpdbError( "tStoreTourneyPlayers error: " + str(sys.exc_value) ) - - return tourneyPlayersIds - #end def tStoreTourneyPlayers - - def tUpdateTourneysHandsPlayers(self, tourney, dbTourneysPlayersIds, dbTourneyTypeId): - logging.debug("Database.tCheckTourneysHandsPlayers") - try: - # Massive update seems to take quite some time ... -# query = self.sql.query['updateHandsPlayersForTTypeId2'] % (dbTourneyTypeId, self.sql.query['handsPlayersTTypeId_joiner'].join([self.sql.query['placeholder'] for id in dbTourneysPlayersIds]) ) -# cursor = self.get_cursor() -# cursor.execute (query, dbTourneysPlayersIds) - - query = self.sql.query['selectHandsPlayersWithWrongTTypeId'] % (dbTourneyTypeId, self.sql.query['handsPlayersTTypeId_joiner'].join([self.sql.query['placeholder'] for id in dbTourneysPlayersIds]) ) - #print "query : %s" % query - cursor = self.get_cursor() - cursor.execute (query, dbTourneysPlayersIds) - result=cursor.fetchall() - - if (len(result) > 0): - logging.debug("%d lines need update : %s" % (len(result), result) ) - listIds = [] - for i in result: - listIds.append(i[0]) - - query2 = self.sql.query['updateHandsPlayersForTTypeId'] % (dbTourneyTypeId, self.sql.query['handsPlayersTTypeId_joiner_id'].join([self.sql.query['placeholder'] for id in listIds]) ) - cursor.execute (query2, listIds) - else: - logging.debug("No need to update, HandsPlayers are correct") - - except: - raise fpdb_simple.FpdbError( "tStoreTourneyPlayers error: " + str(sys.exc_value) ) - #end def tUpdateTourneysHandsPlayers - # 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/GuiBulkImport.py b/pyfpdb/GuiBulkImport.py index 16131ab2..a64a9425 100755 --- a/pyfpdb/GuiBulkImport.py +++ b/pyfpdb/GuiBulkImport.py @@ -30,7 +30,6 @@ import gtk import gobject # fpdb/FreePokerTools modules -import fpdb_simple import fpdb_import import Configuration import Exceptions diff --git a/pyfpdb/GuiTableViewer.py b/pyfpdb/GuiTableViewer.py index c730f962..57fc772d 100644 --- a/pyfpdb/GuiTableViewer.py +++ b/pyfpdb/GuiTableViewer.py @@ -20,7 +20,6 @@ import pygtk pygtk.require('2.0') import gtk import os -import fpdb_simple import fpdb_import import fpdb_db diff --git a/pyfpdb/fpdb_db.py b/pyfpdb/fpdb_db.py index 2d7f2e0c..9f6993b9 100644 --- a/pyfpdb/fpdb_db.py +++ b/pyfpdb/fpdb_db.py @@ -38,7 +38,6 @@ except ImportError: logging.info("Not using numpy to define variance in sqlite.") use_numpy = False -import fpdb_simple import FpdbSQLQueries import Configuration diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index 577562b8..a7a21831 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -35,10 +35,8 @@ import gtk # fpdb/FreePokerTools modules -import fpdb_simple import fpdb_db import Database -import fpdb_parse_logic import Configuration import Exceptions diff --git a/pyfpdb/fpdb_parse_logic.py b/pyfpdb/fpdb_parse_logic.py deleted file mode 100644 index 6fac3669..00000000 --- a/pyfpdb/fpdb_parse_logic.py +++ /dev/null @@ -1,235 +0,0 @@ -#!/usr/bin/python - -#Copyright 2008 Steffen Jobbagy-Felso -#This program is free software: you can redistribute it and/or modify -#it under the terms of the GNU Affero General Public License as published by -#the Free Software Foundation, version 3 of the License. -# -#This program is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#GNU General Public License for more details. -# -#You should have received a copy of the GNU Affero General Public License -#along with this program. If not, see . -#In the "official" distribution you can find the license in -#agpl-3.0.txt in the docs folder of the package. - -#parses an in-memory fpdb hand history and calls db routine to store it - -import sys -from time import time, strftime -from Exceptions import * - -import fpdb_simple -import Database - -def mainParser(settings, siteID, category, hand, config, db = None, writeq = None): - """ mainParser for Holdem Hands """ - t0 = time() - backend = settings['db-backend'] - # Ideally db connection is passed in, if not use sql list if passed in, - # otherwise start from scratch - if db is None: - db = Database.Database(c = config, sql = None) - category = fpdb_simple.recogniseCategory(hand[0]) - - base = "hold" if (category == "holdem" or category == "omahahi" or - category == "omahahilo") else "stud" - - #part 0: create the empty arrays - # lineTypes valid values: header, name, cards, action, win, rake, ignore - # lineStreets valid values: predeal, preflop, flop, turn, river - lineTypes = [] - lineStreets = [] - cardValues = [] - cardSuits = [] - boardValues = [] - boardSuits = [] - antes = [] - allIns = [] - actionAmounts = [] - actionNos = [] - actionTypes = [] - actionTypeByNo = [] - seatLines = [] - winnings = [] - rakes = [] - - #part 1: read hand no and check for duplicate - siteHandNo = fpdb_simple.parseSiteHandNo(hand[0]) - handStartTime = fpdb_simple.parseHandStartTime(hand[0]) - isTourney = fpdb_simple.isTourney(hand[0]) - - smallBlindLine = None - for i, line in enumerate(hand): - if 'posts small blind' in line or 'posts the small blind' in line: - if line[-2:] == "$0": continue - smallBlindLine = i - break - else: - smallBlindLine = 0 - # If we did not find a small blind line, what happens? - # if we leave it at None, it errors two lines down. - - gametypeID = fpdb_simple.recogniseGametypeID(backend, db, db.get_cursor(), - hand[0], hand[smallBlindLine], - siteID, category, isTourney) - if isTourney: - siteTourneyNo = fpdb_simple.parseTourneyNo(hand[0]) - buyin = fpdb_simple.parseBuyin(hand[0]) - fee = fpdb_simple.parseFee(hand[0]) - entries = -1 #todo: parse this - prizepool = -1 #todo: parse this - knockout = False - tourneyStartTime= handStartTime #todo: read tourney start time - rebuyOrAddon = fpdb_simple.isRebuyOrAddon(hand[0]) - - # The tourney site id has to be searched because it may already be in - # db with a TourneyTypeId which is different from the one automatically - # calculated (Summary import first) - tourneyTypeId = fpdb_simple.recogniseTourneyTypeId(db, siteID, - siteTourneyNo, - buyin, fee, - knockout, - rebuyOrAddon) - else: - siteTourneyNo = -1 - buyin = -1 - fee = -1 - entries = -1 - prizepool = -1 - knockout = 0 - tourneyStartTime= None - rebuyOrAddon = -1 - - tourneyTypeId = 1 - fpdb_simple.isAlreadyInDB(db, gametypeID, siteHandNo) - - hand = fpdb_simple.filterCrap(hand, isTourney) - - #part 2: classify lines by type (e.g. cards, action, win, sectionchange) and street - fpdb_simple.classifyLines(hand, category, lineTypes, lineStreets) - - #part 3: read basic player info - #3a read player names, startcashes - for i, line in enumerate(hand): - if lineTypes[i] == "name": - seatLines.append(line) - - names = fpdb_simple.parseNames(seatLines) - playerIDs = db.recognisePlayerIDs(names, siteID) # inserts players as needed - tmp = fpdb_simple.parseCashesAndSeatNos(seatLines) - startCashes = tmp['startCashes'] - seatNos = tmp['seatNos'] - - fpdb_simple.createArrays(category, len(names), cardValues, cardSuits, antes, - winnings, rakes, actionTypes, allIns, - actionAmounts, actionNos, actionTypeByNo) - - #3b read positions - if base == "hold": - positions = fpdb_simple.parsePositions(hand, names) - - #part 4: take appropriate action for each line based on linetype - for i, line in enumerate(hand): - if lineTypes[i] == "cards": - fpdb_simple.parseCardLine(category, lineStreets[i], line, names, - cardValues, cardSuits, boardValues, - boardSuits) - #if category=="studhilo": - # print "hand[i]:", hand[i] - # print "cardValues:", cardValues - # print "cardSuits:", cardSuits - elif lineTypes[i] == "action": - fpdb_simple.parseActionLine(base, isTourney, line, lineStreets[i], - playerIDs, names, actionTypes, allIns, - actionAmounts, actionNos, actionTypeByNo) - elif lineTypes[i] == "win": - fpdb_simple.parseWinLine(line, names, winnings, isTourney) - elif lineTypes[i] == "rake": - totalRake = 0 if isTourney else fpdb_simple.parseRake(line) - fpdb_simple.splitRake(winnings, rakes, totalRake) - elif (lineTypes[i] == "header" or lineTypes[i] == "rake" or - lineTypes[i] == "name" or lineTypes[i] == "ignore"): - pass - elif lineTypes[i] == "ante": - fpdb_simple.parseAnteLine(line, isTourney, names, antes) - elif lineTypes[i] == "table": - tableResult=fpdb_simple.parseTableLine(base, line) - else: - raise FpdbError("unrecognised lineType:" + lineTypes[i]) - - maxSeats = tableResult['maxSeats'] - tableName = tableResult['tableName'] - #print "before part5, antes:", antes - - #part 5: final preparations, then call Database.* with - # the arrays as they are - that file will fill them. - fpdb_simple.convertCardValues(cardValues) - if base == "hold": - fpdb_simple.convertCardValuesBoard(boardValues) - fpdb_simple.convertBlindBet(actionTypes, actionAmounts) - fpdb_simple.checkPositions(positions) - - c = db.get_cursor() - c.execute("SELECT limitType FROM Gametypes WHERE id=%s" % (db.sql.query['placeholder'],), (gametypeID, )) - limit_type = c.fetchone()[0] - fpdb_simple.convert3B4B(category, limit_type, actionTypes, actionAmounts) - - totalWinnings = sum(winnings) - - # if hold'em, use positions and not antes, if stud do not use positions, use antes - # this is used for handsplayers inserts, so still needed even if hudcache update is being skipped - if base == "hold": - hudImportData = fpdb_simple.generateHudCacheData(playerIDs, base, - category, actionTypes, - allIns, actionTypeByNo, - winnings, - totalWinnings, - positions, actionTypes, - actionAmounts, None) - else: - hudImportData = fpdb_simple.generateHudCacheData(playerIDs, base, - category, actionTypes, - allIns, actionTypeByNo, - winnings, - totalWinnings, None, - actionTypes, - actionAmounts, antes) - - try: - db.commit() # need to commit new players as different db connection used - # for other writes. maybe this will change maybe not ... - except: # TODO: this really needs to be narrowed down - print "parse: error during commit: " + str(sys.exc_value) - -# HERE's an ugly kludge to keep from failing when positions is undef -# We'll fix this by getting rid of the legacy importer. REB - try: - if positions: - pass - except NameError: - positions = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - # save data structures in a HandToWrite instance and then insert into database: - htw = Database.HandToWrite() - htw.set_all( config, settings, base, category, siteTourneyNo, buyin - , fee, knockout, entries, prizepool, tourneyStartTime - , isTourney, tourneyTypeId, siteID, siteHandNo - , gametypeID, handStartTime, names, playerIDs, startCashes - , positions, antes, cardValues, cardSuits, boardValues, boardSuits - , winnings, rakes, actionTypes, allIns, actionAmounts - , actionNos, hudImportData, maxSeats, tableName, seatNos) - - # save hand in db via direct call or via q if in a thread - if writeq is None: - result = db.store_the_hand(htw) - else: - writeq.put(htw) - result = -999 # meaning unknown - - t9 = time() - #print "parse and save=(%4.3f)" % (t9-t0) - return result -#end def mainParser - diff --git a/pyfpdb/fpdb_simple.py b/pyfpdb/fpdb_simple.py deleted file mode 100644 index 5f0c6507..00000000 --- a/pyfpdb/fpdb_simple.py +++ /dev/null @@ -1,1728 +0,0 @@ -#!/usr/bin/python -# -*- coding: iso-8859-15 -*- - -#Copyright 2008 Steffen Jobbagy-Felso -#This program is free software: you can redistribute it and/or modify -#it under the terms of the GNU Affero General Public License as published by -#the Free Software Foundation, version 3 of the License. -# -#This program is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#GNU General Public License for more details. -# -#You should have received a copy of the GNU Affero General Public License -#along with this program. If not, see . -#In the "official" distribution you can find the license in -#agpl-3.0.txt in the docs folder of the package. - -#This file contains simple functions for fpdb - -#Aiming to eventually remove this module, functions will move to, eg: -#fpdb_db db create/re-create/management/etc -#Hands or related files for saving hands to db, etc - -import datetime -import time -import re -import sys -from Exceptions import * -import locale - -import Card - -PS = 1 -FTP = 2 - -# TODO: these constants are also used in fpdb_save_to_db and others, is there a way to do like C #define, and #include ? -# answer - yes. These are defined in fpdb_db so are accessible through that class. -MYSQL_INNODB = 2 -PGSQL = 3 -SQLITE = 4 - -LOCALE_ENCODING = locale.getdefaultlocale()[1] - -#returns an array of the total money paid. intending to add rebuys/addons here -def calcPayin(count, buyin, fee): - return [buyin + fee for i in xrange(count)] -#end def calcPayin - -def checkPositions(positions): - """ verify positions are valid """ - if any(not (p == "B" or p == "S" or (p >= 0 and p <= 9)) for p in positions): - raise FpdbError("invalid position '"+p+"' found in checkPositions") - ### RHH modified to allow for "position 9" here (pos==9 is when you're a dead hand before the BB - ### eric - position 8 could be valid - if only one blind is posted, but there's still 10 people, ie a sitout is present, and the small is dead... - -def classifyLines(hand, category, lineTypes, lineStreets): - """ makes a list of classifications for each line for further processing - manipulates passed arrays """ - currentStreet = "predeal" - done = False #set this to true once we reach the last relevant line (the summary, except rake, is all repeats) - for i, line in enumerate(hand): - if done: - if "[" not in line or "mucked [" not in line: - lineTypes.append("ignore") - else: - lineTypes.append("cards") - elif line.startswith("Dealt to"): - lineTypes.append("cards") - elif i == 0: - lineTypes.append("header") - elif line.startswith("Table '"): - lineTypes.append("table") - elif line.startswith("Seat ") and ( ("in chips" in line) or "($" in line): - lineTypes.append("name") - elif isActionLine(line): - lineTypes.append("action") - if " posts " in line or " posts the " in line: - currentStreet="preflop" - elif " antes " in line or " posts the ante " in line: - lineTypes.append("ante") - elif line.startswith("*** FLOP *** ["): - lineTypes.append("cards") - currentStreet="flop" - elif line.startswith("*** TURN *** ["): - lineTypes.append("cards") - currentStreet="turn" - elif line.startswith("*** RIVER *** ["): - lineTypes.append("cards") - currentStreet="river" - elif line.startswith("*** 3"): - lineTypes.append("ignore") - currentStreet=0 - elif line.startswith("*** 4"): - lineTypes.append("ignore") - currentStreet=1 - elif line.startswith("*** 5"): - lineTypes.append("ignore") - currentStreet=2 - elif line.startswith("*** 6"): - lineTypes.append("ignore") - currentStreet=3 - elif line.startswith("*** 7") or line == "*** RIVER ***": - lineTypes.append("ignore") - currentStreet=4 - elif isWinLine(line): - lineTypes.append("win") - elif line.startswith("Total pot ") and "Rake" in line: - lineTypes.append("rake") - done=True - elif "*** SHOW DOWN ***" in line or "*** SUMMARY ***" in line: - lineTypes.append("ignore") - #print "in classifyLine, showdown or summary" - elif " shows [" in line: - lineTypes.append("cards") - else: - raise FpdbError("unrecognised linetype in:"+hand[i]) - lineStreets.append(currentStreet) - -def convert3B4B(category, limit_type, actionTypes, actionAmounts): - """calculates the actual bet amounts in the given amount array and changes it accordingly.""" - for i in xrange(len(actionTypes)): - for j in xrange(len(actionTypes[i])): - bets = [] - for k in xrange(len(actionTypes[i][j])): - if (actionTypes[i][j][k] == "bet"): - bets.append((i,j,k)) - if (len(bets)>=2): - #print "len(bets) 2 or higher, need to correct it. bets:",bets,"len:",len(bets) - for betNo in reversed(xrange (1,len(bets))): - amount2 = actionAmounts[bets[betNo][0]][bets[betNo][1]][bets[betNo][2]] - amount1 = actionAmounts[bets[betNo-1][0]][bets[betNo-1][1]][bets[betNo-1][2]] - actionAmounts[bets[betNo][0]][bets[betNo][1]][bets[betNo][2]] = amount2 - amount1 - -def convertBlindBet(actionTypes, actionAmounts): - """ Corrects the bet amount if the player had to pay blinds """ - i = 0#setting street to pre-flop - for j in xrange(len(actionTypes[i])):#playerloop - blinds = [] - bets = [] - for k in xrange(len(actionTypes[i][j])): - if actionTypes[i][j][k] == "blind": - blinds.append((i,j,k)) - - if blinds and actionTypes[i][j][k] == "bet": - bets.append((i,j,k)) - if len(bets) == 1: - blind_amount=actionAmounts[blinds[0][0]][blinds[0][1]][blinds[0][2]] - bet_amount=actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]] - actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]] = bet_amount - blind_amount - -#converts the strings in the given array to ints (changes the passed array, no returning). see table design for conversion details -#todo: make this use convertCardValuesBoard -def convertCardValues(arr): - map(convertCardValuesBoard, arr) - -# a 0-card is one in a stud game that we did not see or was not shown -card_map = { 0: 0, "2": 2, "3" : 3, "4" : 4, "5" : 5, "6" : 6, "7" : 7, "8" : 8, - "9" : 9, "T" : 10, "J" : 11, "Q" : 12, "K" : 13, "A" : 14} - -def convertCardValuesBoard(arr): - """ converts the strings in the given array to ints - (changes the passed array, no returning). see table design for - conversion details """ - for i in xrange(len(arr)): - arr[i] = card_map[arr[i]] - -def createArrays(category, seats, card_values, card_suits, antes, winnings, - rakes, action_types, allIns, action_amounts, actionNos, - actionTypeByNo): - """ this creates the 2D/3D arrays. manipulates the passed arrays instead of returning. """ - for i in xrange(seats):#create second dimension arrays - card_values.append( [] ) - card_suits.append( [] ) - antes.append(0) - winnings.append(0) - rakes.append(0) - - streetCount = 4 if (category == "holdem" or category == "omahahi" or - category == "omahahilo") else 5 - - for i in xrange(streetCount): #build the first dimension array, for streets - action_types.append([]) - allIns.append([]) - action_amounts.append([]) - actionNos.append([]) - actionTypeByNo.append([]) - for j in xrange(seats): # second dimension arrays: players - action_types[i].append([]) - allIns[i].append([]) - action_amounts[i].append([]) - actionNos[i].append([]) -# if (category=="holdem" or category=="omahahi" or category=="omahahilo"): -# pass - if category == "razz" or category == "studhi" or category == "studhilo": #need to fill card arrays. - for i in xrange(seats): - for j in xrange(7): - card_values[i].append(0) - card_suits[i].append("x") -# else: -# raise FpdbError("invalid category") -#end def createArrays - -def fill_board_cards(board_values, board_suits): - """ fill up the two board card arrays """ - while len(board_values) < 5: - board_values.append(0) - board_suits.append("x") - -def fillCardArrays(player_count, base, category, card_values, card_suits): - """fills up the two card arrays""" - if category == "holdem": - cardCount = 2 - elif category == "omahahi" or category == "omahahilo": - cardCount = 4 - elif base == "stud": - cardCount = 7 - else: - raise FpdbError("invalid category:", category) - - for i in xrange(player_count): - while len(card_values[i]) < cardCount: - card_values[i].append(0) - card_suits[i].append("x") -#end def fillCardArrays - -#filters out a player that folded before paying ante or blinds. This should be called -#before calling the actual hand parser. manipulates hand, no return. -def filterAnteBlindFold(hand): - #todo: this'll only get rid of one ante folder, not multiple ones - #todo: in tourneys this should not be removed but - #print "start of filterAnteBlindFold" - pre3rd = [] - for i, line in enumerate(hand): - if line.startswith("*** 3") or line.startswith("*** HOLE"): - pre3rd = hand[0:i] - - foldeeName = None - for line in pre3rd: - if line.endswith("folds") or line.endswith("is sitting out") or line.endswith(" stands up"): #found ante fold or timeout - pos = line.find(" folds") - foldeeName = line[0:pos] - if pos == -1 and " in chips)" not in line: - pos = line.find(" is sitting out") - foldeeName = line[0:pos] - if pos == -1: - pos = line.find(" stands up") - foldeeName = line[0:pos] - if pos == -1: - pos1 = line.find(": ") + 2 - pos2 = line.find(" (") - foldeeName = line[pos1:pos2] - - if foldeeName is not None: - #print "filterAnteBlindFold, foldeeName:",foldeeName - for i, line in enumerate(hand): - if foldeeName in line: - hand[i] = None - - return [line for line in hand if line] - -def stripEOLspaces(str): - return str.rstrip() - -def filterCrap(hand, isTourney): - """ removes useless lines as well as trailing spaces """ - - #remove trailing spaces at end of line - hand = [line.rstrip() for line in hand] - - #general variable position word filter/string filter - for i in xrange(len(hand)): - if hand[i].startswith("Board ["): - hand[i] = False - elif hand[i].find(" out of hand ")!=-1: - hand[i]=hand[i][:-56] - elif "($0 in chips)" in hand[i]: - hand[i] = False - elif hand[i]=="*** HOLE CARDS ***": - hand[i] = False - elif hand[i].endswith("has been disconnected"): - hand[i] = False - elif hand[i].endswith("has requested TIME"): - hand[i] = False - elif hand[i].endswith("has returned"): - hand[i] = False - elif hand[i].endswith("will be allowed to play after the button"): - hand[i] = False - elif hand[i].endswith("has timed out"): - hand[i] = False - elif hand[i].endswith("has timed out while disconnected"): - hand[i] = False - elif hand[i].endswith("has timed out while being disconnected"): - hand[i] = False - elif hand[i].endswith("is connected"): - hand[i] = False - elif hand[i].endswith("is disconnected"): - hand[i] = False - elif hand[i].find(" is low with [")!=-1: - hand[i] = False - elif hand[i].endswith(" mucks"): - hand[i] = False - elif hand[i].endswith(": mucks hand"): - hand[i] = False - elif hand[i] == "No low hand qualified": - hand[i] = False - elif hand[i] == "Pair on board - a double bet is allowed": - hand[i] = False - elif " shows " in hand[i] and "[" not in hand[i]: - hand[i] = False - elif hand[i].startswith("The button is in seat #"): - hand[i] = False - #above is alphabetic, reorder below if bored - elif hand[i].startswith("Time has expired"): - hand[i] = False - elif hand[i].endswith("has reconnected"): - hand[i] = False - elif hand[i].endswith("seconds left to act"): - hand[i] = False - elif hand[i].endswith("seconds to reconnect"): - hand[i] = False - elif hand[i].endswith("was removed from the table for failing to post"): - hand[i] = False - elif "joins the table at seat " in hand[i]: - hand[i] = False - elif (hand[i].endswith("leaves the table")): - hand[i] = False - elif "is high with " in hand[i]: - hand[i] = False - elif hand[i].endswith("doesn't show hand"): - hand[i] = False - elif hand[i].endswith("is being treated as all-in"): - hand[i] = False - elif " adds $" in hand[i]: - hand[i] = False - elif hand[i] == "Betting is capped": - hand[i] = False - elif (hand[i].find(" said, \"")!=-1): - hand[i] = False - - if isTourney and not hand[i] == False: - if (hand[i].endswith(" is sitting out") and (not hand[i].startswith("Seat "))): - hand[i] = False - elif hand[i]: - if (hand[i].endswith(": sits out")): - hand[i] = False - elif (hand[i].endswith(" is sitting out")): - hand[i] = False - # python docs say this is identical to filter(None, list) - # which removes all false items from the passed list (hand) - hand = [line for line in hand if line] - - return hand - -def float2int(string): - """ takes a poker float (including , for thousand seperator) and - converts it to an int """ - # Note that this automagically assumes US style currency formatters - pos = string.find(",") - if pos != -1: #remove , the thousand seperator - string = "%s%s" % (string[0:pos], string[pos+1:]) - - pos = string.find(".") - if pos != -1: #remove decimal point - string = "%s%s" % (string[0:pos], string[pos+1:]) - - result = int(string) - if pos == -1: #no decimal point - was in full dollars - need to multiply with 100 - result *= 100 - return result - -ActionLines = ( "calls $", ": calls ", "brings in for", "completes it to", - "posts small blind", "posts the small blind", "posts big blind", - "posts the big blind", "posts small & big blinds", "posts $", - "posts a dead", "bets $", ": bets ", " raises") - -def isActionLine(line): - if line.endswith("folds"): - return True - elif line.endswith("checks"): - return True - elif line.startswith("Uncalled bet"): - return True - - # searches for each member of ActionLines being in line, returns true - # on first match .. neat func - return any(x for x in ActionLines if x in line) - -def isAlreadyInDB(db, gametypeID, siteHandNo): - c = db.get_cursor() - c.execute(db.sql.query['isAlreadyInDB'], (gametypeID, siteHandNo)) - result = c.fetchall() - if len(result) >= 1: - raise DuplicateError ("dupl") - -def isRebuyOrAddon(topline): - """isRebuyOrAddon not implemented yet""" - return False - -#returns whether the passed topline indicates a tournament or not -def isTourney(topline): - return "Tournament" in topline - -WinLines = ( "wins the pot", "ties for the ", "wins side pot", "wins the low main pot", "wins the high main pot", - "wins the low", - "wins the high pot", "wins the high side pot", "wins the main pot", "wins the side pot", "collected" ) - -def isWinLine(line): - """ returns boolean whether the passed line is a win line """ - return any(x for x in WinLines if x in line) - -#returns the amount of cash/chips put into the put in the given action line -def parseActionAmount(line, atype, isTourney): - #if (line.endswith(" and is all-in")): - # line=line[:-14] - #elif (line.endswith(", and is all in")): - # line=line[:-15] - - #ideally we should recognise this as an all-in if category is capXl - if line.endswith(", and is capped"): - line=line[:-15] - if line.endswith(" and is capped"): - line=line[:-14] - - if atype == "fold" or atype == "check": - amount = 0 - elif atype == "unbet": - pos1 = line.find("$") + 1 - if pos1 == 0: - pos1 = line.find("(") + 1 - pos2 = line.find(")") - amount = float2int(line[pos1:pos2]) - elif atype == "bet" and ": raises $" in line and "to $" in line: - pos = line.find("to $")+4 - amount = float2int(line[pos:]) - else: - if not isTourney: - pos = line.rfind("$")+1 - #print "parseActionAmount, line:", line, "line[pos:]:", line[pos:] - amount = float2int(line[pos:]) - else: - #print "line:"+line+"EOL" - pos = line.rfind(" ")+1 - #print "pos:",pos - #print "pos of 20:", line.find("20") - amount = int(line[pos:]) - - if atype == "unbet": - amount *= -1 - return amount -#end def parseActionAmount - -#doesnt return anything, simply changes the passed arrays action_types and -# action_amounts. For stud this expects numeric streets (3-7), for -# holdem/omaha it expects predeal, preflop, flop, turn or river -def parseActionLine(base, isTourney, line, street, playerIDs, names, action_types, allIns, action_amounts, actionNos, actionTypeByNo): - if street == "predeal" or street == "preflop": - street = 0 - elif street == "flop": - street = 1 - elif street == "turn": - street = 2 - elif street == "river": - street = 3 - - nextActionNo = 0 - for player in xrange(len(actionNos[street])): - for count in xrange(len(actionNos[street][player])): - if actionNos[street][player][count]>=nextActionNo: - nextActionNo=actionNos[street][player][count]+1 - - (line, allIn) = goesAllInOnThisLine(line) - atype = parseActionType(line) - playerno = recognisePlayerNo(line, names, atype) - amount = parseActionAmount(line, atype, isTourney) - - action_types[street][playerno].append(atype) - allIns[street][playerno].append(allIn) - action_amounts[street][playerno].append(amount) - actionNos[street][playerno].append(nextActionNo) - tmp=(playerIDs[playerno], atype) - actionTypeByNo[street].append(tmp) - -def goesAllInOnThisLine(line): - """returns whether the player went all-in on this line and removes the all-in text from the line.""" - isAllIn = False - if (line.endswith(" and is all-in")): - line = line[:-14] - isAllIn = True - elif (line.endswith(", and is all in")): - line = line[:-15] - isAllIn = True - return (line, isAllIn) - -#returns the action type code (see table design) of the given action line -ActionTypes = { 'brings in for' :"blind", - ' posts $' :"blind", - ' posts a dead ' :"blind", - ' posts the small blind of $' :"blind", - ': posts big blind ' :"blind", - ': posts small blind ' :"blind", - ' posts the big blind of $' :"blind", - ': posts small & big blinds $' :"blind", - ': posts small blind $' :"blind", - 'calls' :"call", - 'completes it to' :"bet", - ' bets' :"bet", - ' raises' :"bet" - } -def parseActionType(line): - if (line.startswith("Uncalled bet")): - return "unbet" - elif (line.endswith(" folds")): - return "fold" - elif (line.endswith(" checks")): - return "check" - else: - for x in ActionTypes: - if x in line: - return ActionTypes[x] - raise FpdbError ("failed to recognise actiontype in parseActionLine in: "+line) - -#parses the ante out of the given line and checks which player paid it, updates antes accordingly. -def parseAnteLine(line, isTourney, names, antes): - for i, name in enumerate(names): - if line.startswith(name.encode(LOCALE_ENCODING)): - pos = line.rfind("$") + 1 - if not isTourney: - antes[i] += float2int(line[pos:]) - else: - if "all-in" not in line: - pos = line.rfind(" ") + 1 - antes[i] += int(line[pos:]) - else: - pos1 = line.rfind("ante") + 5 - pos2 = line.find(" ", pos1) - antes[i] += int(line[pos1:pos2]) - -#returns the buyin of a tourney in cents -def parseBuyin(topline): - pos1 = topline.find("$")+1 - if pos1 != 0: - pos2 = topline.find("+") - else: - pos1 = topline.find("€")+3 - pos2 = topline.find("+") - return float2int(topline[pos1:pos2]) - -#parses a card line and changes the passed arrays accordingly -#todo: reorganise this messy method -def parseCardLine(category, street, line, names, cardValues, cardSuits, boardValues, boardSuits): - if line.startswith("Dealt to") or " shows [" in line or "mucked [" in line: - playerNo = recognisePlayerNo(line, names, "card") #anything but unbet will be ok for that string - - pos = line.rfind("[")+1 - if category == "holdem": - for i in (pos, pos+3): - cardValues[playerNo].append(line[i:i+1]) - cardSuits[playerNo].append(line[i+1:i+2]) - if len(cardValues[playerNo]) != 2: - if (cardValues[playerNo][0] == cardValues[playerNo][2] and - cardSuits[playerNo][1] == cardSuits[playerNo][3]): - cardValues[playerNo]=cardValues[playerNo][0:2] - cardSuits[playerNo]=cardSuits[playerNo][0:2] - else: - print "line:",line,"cardValues[playerNo]:",cardValues[playerNo] - raise FpdbError("read too many/too few holecards in parseCardLine") - elif category == "omahahi" or category == "omahahilo": - for i in (pos, pos+3, pos+6, pos+9): - cardValues[playerNo].append(line[i:i+1]) - cardSuits[playerNo].append(line[i+1:i+2]) - if (len(cardValues[playerNo])!=4): - if (cardValues[playerNo][0] == cardValues[playerNo][4] and - cardSuits[playerNo][3] == cardSuits[playerNo][7]): #two tests will do - cardValues[playerNo] = cardValues[playerNo][0:4] - cardSuits[playerNo] = cardSuits[playerNo][0:4] - else: - print "line:",line,"cardValues[playerNo]:",cardValues[playerNo] - raise FpdbError("read too many/too few holecards in parseCardLine") - elif category == "razz" or category == "studhi" or category == "studhilo": - if "shows" not in line and "mucked" not in line: - #print "parseCardLine(in stud if), street:", street - if line[pos+2]=="]": #-> not (hero and 3rd street) - cardValues[playerNo][street+2]=line[pos:pos+1] - cardSuits[playerNo][street+2]=line[pos+1:pos+2] - else: - #print "hero card1:", line[pos:pos+2], "hero card2:", line[pos+3:pos+5], "hero card3:", line[pos+6:pos+8], - cardValues[playerNo][street]=line[pos:pos+1] - cardSuits[playerNo][street]=line[pos+1:pos+2] - cardValues[playerNo][street+1]=line[pos+3:pos+4] - cardSuits[playerNo][street+1]=line[pos+4:pos+5] - cardValues[playerNo][street+2]=line[pos+6:pos+7] - cardSuits[playerNo][street+2]=line[pos+7:pos+8] - else: - #print "parseCardLine(in stud else), street:", street - cardValues[playerNo][0]=line[pos:pos+1] - cardSuits[playerNo][0]=line[pos+1:pos+2] - pos+=3 - cardValues[playerNo][1]=line[pos:pos+1] - cardSuits[playerNo][1]=line[pos+1:pos+2] - if street==4: - pos=pos=line.rfind("]")-2 - cardValues[playerNo][6]=line[pos:pos+1] - cardSuits[playerNo][6]=line[pos+1:pos+2] - #print "cardValues:", cardValues - #print "cardSuits:", cardSuits - else: - print "line:",line,"street:",street - raise FpdbError("invalid category") - #print "end of parseCardLine/playercards, cardValues:",cardValues - elif (line.startswith("*** FLOP ***")): - pos=line.find("[")+1 - for i in (pos, pos+3, pos+6): - boardValues.append(line[i:i+1]) - boardSuits.append(line[i+1:i+2]) - #print boardValues - elif (line.startswith("*** TURN ***") or line.startswith("*** RIVER ***")): - pos=line.find("[")+1 - pos=line.find("[", pos+1)+1 - boardValues.append(line[pos:pos+1]) - boardSuits.append(line[pos+1:pos+2]) - #print boardValues - else: - raise FpdbError ("unrecognised line:"+line) - -def parseCashesAndSeatNos(lines): - """parses the startCashes and seatNos of each player out of the given lines and returns them as a dictionary of two arrays""" - cashes = [] - seatNos = [] - for i in xrange (len(lines)): - pos2=lines[i].find(":") - seatNos.append(int(lines[i][5:pos2])) - - pos1=lines[i].rfind("($")+2 - if pos1==1: #for tourneys - it's 1 instead of -1 due to adding 2 above - pos1=lines[i].rfind("(")+1 - pos2=lines[i].find(" in chips") - cashes.append(float2int(lines[i][pos1:pos2])) - return {'startCashes':cashes, 'seatNos':seatNos} - -#returns the buyin of a tourney in cents -def parseFee(topline): - pos1 = topline.find("$")+1 - if pos1 != 0: - pos1 = topline.find("$", pos1)+1 - pos2 = topline.find(" ", pos1) - else: - pos1 = topline.find("€")+3 - pos1 = topline.find("€", pos1)+3 - pos2 = topline.find(" ", pos1) - return float2int(topline[pos1:pos2]) - -#returns a datetime object with the starttime indicated in the given topline -def parseHandStartTime(topline): - #convert x:13:35 to 0x:13:35 - counter=0 - while counter < 10: - pos = topline.find(" %d:" % counter) - if pos != -1: - topline = "%s0%s" % (topline[0:pos+1], topline[pos+1:]) - break - counter += 1 - - isUTC=False - if topline.find("UTC")!=-1: - pos1 = topline.find("-")+2 - pos2 = topline.find("UTC") - tmp=topline[pos1:pos2] - isUTC=True - else: - tmp=topline - #print "parsehandStartTime, tmp:", tmp - pos = tmp.find("-")+2 - tmp = tmp[pos:] - #Need to match either - # 2008/09/07 06:23:14 ET or - # 2008/08/17 - 01:14:43 (ET) or - # 2008/11/12 9:33:31 CET [2008/11/12 3:33:31 ET] - rexx = '(?P[0-9]{4})\/(?P[0-9]{2})\/(?P[0-9]{2})[\- ]+(?P
[0-9]+):(?P[0-9]+):(?P[0-9]+)' - m = re.search(rexx,tmp) - result = datetime.datetime(int(m.group('YEAR')), int(m.group('MON')), int(m.group('DAY')), int(m.group('HR')), int(m.group('MIN')), int(m.group('SEC'))) - - if not isUTC: #these use US ET - result += datetime.timedelta(hours=5) - - return result - -#parses the names out of the given lines and returns them as an array -def findName(line): - pos1 = line.find(":") + 2 - pos2 = line.rfind("(") - 1 - return unicode(line[pos1:pos2], LOCALE_ENCODING) - -def parseNames(lines): - return [findName(line) for line in lines] - -def parsePositions(hand, names): - positions = [-1 for i in names] - sb, bb = -1, -1 - - for line in hand: - if sb == -1 and "small blind" in line and "dead small blind" not in line: - sb = line - if bb == -1 and "big blind" in line and "dead big blind" not in line: - bb = line - -#identify blinds -#print "parsePositions before recognising sb/bb. names:",names - sbExists = True - if sb != -1: - sb = recognisePlayerNo(sb, names, "bet") - else: - sbExists = False - if bb != -1: - bb = recognisePlayerNo(bb, names, "bet") - -# print "sb = ", sb, "bb = ", bb - if bb == sb: # if big and small are same, then don't duplicate the small - sbExists = False - sb = -1 - - #write blinds into array - if sbExists: - positions[sb]="S" - positions[bb]="B" - - #fill up rest of array - arraypos = sb - 1 if sbExists else bb - 1 - - distFromBtn=0 - while arraypos >= 0 and arraypos != bb: - #print "parsePositions first while, arraypos:",arraypos,"positions:",positions - positions[arraypos] = distFromBtn - arraypos -= 1 - distFromBtn += 1 - - # eric - this takes into account dead seats between blinds - if sbExists: - i = bb - 1 - while positions[i] < 0 and i != sb: - positions[i] = 9 - i -= 1 - ### RHH - Changed to set the null seats before BB to "9" - i = sb - 1 if sbExists else bb - 1 - - while positions[i] < 0: - positions[i]=9 - i-=1 - - arraypos=len(names)-1 - if (bb!=0 or (bb==0 and sbExists==False) or (bb == 1 and sb != arraypos) ): - while (arraypos > bb and arraypos > sb): - positions[arraypos] = distFromBtn - arraypos -= 1 - distFromBtn += 1 - - if any(p == -1 for p in positions): - print "parsePositions names:",names - print "result:",positions - raise FpdbError ("failed to read positions") -# print str(positions), "\n" - return positions - -#simply parses the rake amount and returns it as an int -def parseRake(line): - pos = line.find("Rake")+6 - rake = float2int(line[pos:]) - return rake - -def parseSiteHandNo(topline): - """returns the hand no assigned by the poker site""" - pos1 = topline.find("#")+1 - pos2 = topline.find(":") - return topline[pos1:pos2] - -def parseTableLine(base, line): - """returns a dictionary with maxSeats and tableName""" - pos1=line.find('\'')+1 - pos2=line.find('\'', pos1) - #print "table:",line[pos1:pos2] - pos3=pos2+2 - pos4=line.find("-max") - #print "seats:",line[pos3:pos4] - return {'maxSeats':int(line[pos3:pos4]), 'tableName':line[pos1:pos2]} -#end def parseTableLine - -#returns the hand no assigned by the poker site -def parseTourneyNo(topline): - pos1 = topline.find("Tournament #")+12 - pos2 = topline.find(",", pos1) - #print "parseTourneyNo pos1:",pos1," pos2:",pos2, " result:",topline[pos1:pos2] - return topline[pos1:pos2] - -#parses a win/collect line. manipulates the passed array winnings, no explicit return -def parseWinLine(line, names, winnings, isTourney): - #print "parseWinLine: line:",line - for i,n in enumerate(names): - n = n.encode(LOCALE_ENCODING) - if line.startswith(n): - if isTourney: - pos1 = line.rfind("collected ") + 10 - pos2 = line.find(" ", pos1) - winnings[i] += int(line[pos1:pos2]) - else: - pos1 = line.rfind("$") + 1 - pos2 = line.find(" ", pos1) - winnings[i] += float2int(line[pos1:pos2]) - -#returns the category (as per database) string for the given line -def recogniseCategory(line): - if "Razz" in line: - return "razz" - elif "Hold'em" in line: - return "holdem" - elif "Omaha" in line: - if "Hi/Lo" not in line and "H/L" not in line: - return "omahahi" - else: - return "omahahilo" - elif "Stud" in line: - if "Hi/Lo" not in line and "H/L" not in line: - return "studhi" - else: - return "studhilo" - else: - raise FpdbError("failed to recognise category, line:"+line) - -#returns the int for the gametype_id for the given line -def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, category, isTourney):#todo: this method is messy - #if (topline.find("HORSE")!=-1): - # raise FpdbError("recogniseGametypeID: HORSE is not yet supported.") - - #note: the below variable names small_bet and big_bet are misleading, in NL/PL they mean small/big blind - if isTourney: - type = "tour" - pos1 = topline.find("(")+1 - if(topline[pos1] == "H" or topline[pos1] == "O" or - topline[pos1] == "R" or topline[pos1]=="S" or - topline[pos1+2] == "C"): - pos1 = topline.find("(", pos1)+1 - pos2 = topline.find("/", pos1) - small_bet = int(topline[pos1:pos2]) - else: - type = "ring" - pos1 = topline.find("$")+1 - pos2 = topline.find("/$") - small_bet = float2int(topline[pos1:pos2]) - - pos1 = pos2+2 - if isTourney: - pos1 -= 1 - pos2 = topline.find(")") - - if pos2 <= pos1: - pos2 = topline.find(")", pos1) - - if isTourney: - big_bet = int(topline[pos1:pos2]) - else: - big_bet = float2int(topline[pos1:pos2]) - - if 'No Limit' in topline: - limit_type = "nl" if 'Cap No' not in topline else "cn" - elif 'Pot Limit' in topline: - limit_type = "pl" if 'Cap Pot' not in topline else "cp" - else: - limit_type = "fl" - - #print "recogniseGametypeID small_bet/blind:",small_bet,"big bet/blind:", big_bet,"limit type:",limit_type - if limit_type == "fl": - cursor.execute(db.sql.query['getGametypeFL'], (site_id, type, category, - limit_type, small_bet, - big_bet)) - else: - cursor.execute(db.sql.query['getGametypeNL'], (site_id, type, category, - limit_type, small_bet, - big_bet)) - result = cursor.fetchone() - #print "recgt1 result=",result - #ret=result[0] - #print "recgt1 ret=",ret - #print "tried SELECTing gametypes.id, result:",result - - try: - len(result) - except TypeError: - if category=="holdem" or category=="omahahi" or category=="omahahilo": - base="hold" - else: - base="stud" - - if category=="holdem" or category=="omahahi" or category=="studhi": - hiLo='h' - elif category=="razz": - hiLo='l' - else: - hiLo='s' - - if (limit_type=="fl"): - big_blind=small_bet - if base=="hold": - if smallBlindLine==topline: - raise FpdbError("invalid small blind line") - elif isTourney: - pos=smallBlindLine.rfind(" ")+1 - small_blind=int(smallBlindLine[pos:]) - else: - pos=smallBlindLine.rfind("$")+1 - small_blind=float2int(smallBlindLine[pos:]) - else: - small_blind=0 - result = db.insertGameTypes( (site_id, type, base, category, limit_type, hiLo - ,small_blind, big_blind, small_bet, big_bet) ) - #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s - #AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet)) - else: - result = db.insertGameTypes( (site_id, type, base, category, limit_type, hiLo - ,small_bet, big_bet, 0, 0) )#remember, for these bet means blind - #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s - #AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet)) - - return result[0] -#end def recogniseGametypeID - -def recogniseTourneyTypeId(db, siteId, tourneySiteId, buyin, fee, knockout, rebuyOrAddon): - ret = -1 - cursor = db.get_cursor() - # First we try to find the tourney itself (by its tourneySiteId) in case it has already been inserted before (by a summary file for instance) - # The reason is that some tourneys may not be identified correctly in the HH toplines (especially Buy-In and Fee which are used to search/create the TourneyTypeId) - #TODO: When the summary file will be dumped to BD, if the tourney is already in, Buy-In/Fee may need an update (e.g. creation of a new type and link to the Tourney) - cursor.execute (db.sql.query['getTourneyTypeIdByTourneyNo'].replace('%s', db.sql.query['placeholder']), (tourneySiteId, siteId)) - result = cursor.fetchone() - - try: - len(result) - ret = result[0] - except: - cursor.execute( """SELECT id FROM TourneyTypes - WHERE siteId=%s AND buyin=%s AND fee=%s - AND knockout=%s AND rebuyOrAddon=%s""".replace('%s', db.sql.query['placeholder']) - , (siteId, buyin, fee, knockout, rebuyOrAddon) ) - result = cursor.fetchone() - #print "tried selecting tourneytypes.id, result:", result - - try: - len(result) - ret = result[0] - except TypeError:#this means we need to create a new entry - #print "insert new tourneytype record ..." - try: - cursor.execute( """INSERT INTO TourneyTypes (siteId, buyin, fee, knockout, rebuyOrAddon) - VALUES (%s, %s, %s, %s, %s)""".replace('%s', db.sql.query['placeholder']) - , (siteId, buyin, fee, knockout, rebuyOrAddon) ) - ret = db.get_last_insert_id(cursor) - except: - #print "maybe tourneytype was created since select, try selecting again ..." - cursor.execute( """SELECT id FROM TourneyTypes - WHERE siteId=%s AND buyin=%s AND fee=%s - AND knockout=%s AND rebuyOrAddon=%s""".replace('%s', db.sql.query['placeholder']) - , (siteId, buyin, fee, knockout, rebuyOrAddon) ) - result = cursor.fetchone() - try: - len(result) - ret = result[0] - except: - print "Failed to find or insert TourneyTypes record" - ret = -1 # failed to find or insert record - #print "tried selecting tourneytypes.id again, result:", result - - #print "recogniseTourneyTypeId: returning", ret - return ret -#end def recogniseTourneyTypeId - - -#recognises the name in the given line and returns its array position in the given array -def recognisePlayerNo(line, names, atype): - #print "recogniseplayerno, names:",names - for i in xrange(len(names)): - encodedName = names[i].encode(LOCALE_ENCODING) - if (atype=="unbet"): - if (line.endswith(encodedName)): - return (i) - elif (line.startswith("Dealt to ")): - #print "recognisePlayerNo, card precut, line:",line - tmp=line[9:] - #print "recognisePlayerNo, card postcut, tmp:",tmp - if (tmp.startswith(encodedName)): - return (i) - elif (line.startswith("Seat ")): - if (line.startswith("Seat 10")): - tmp=line[9:] - else: - tmp=line[8:] - - if (tmp.startswith(encodedName)): - return (i) - else: - if (line.startswith(encodedName)): - return (i) - #if we're here we mustve failed - raise FpdbError ("failed to recognise player in: "+line+" atype:"+atype) -#end def recognisePlayerNo - - -#removes trailing \n from the given array -def removeTrailingEOL(arr): - for i in xrange(len(arr)): - if (arr[i].endswith("\n")): - #print "arr[i] before removetrailingEOL:", arr[i] - arr[i]=arr[i][:-1] - #print "arr[i] after removetrailingEOL:", arr[i] - return arr -#end def removeTrailingEOL - -#splits the rake according to the proportion of pot won. manipulates the second passed array. -def splitRake(winnings, rakes, totalRake): - winnercnt=0 - totalWin=0 - for i in xrange(len(winnings)): - if winnings[i]!=0: - winnercnt+=1 - totalWin+=winnings[i] - firstWinner=i - if winnercnt==1: - rakes[firstWinner]=totalRake - else: - totalWin=float(totalWin) - for i in xrange(len(winnings)): - if winnings[i]!=0: - winPortion=winnings[i]/totalWin - rakes[i]=totalRake*winPortion -#end def splitRake - -def generateHudCacheData(player_ids, base, category, action_types, allIns, actionTypeByNo - ,winnings, totalWinnings, positions, actionTypes, actionAmounts, antes): - """calculates data for the HUD during import. IMPORTANT: if you change this method make -sure to also change the following storage method and table_viewer.prepare_data if necessary -""" - #print "generateHudCacheData, len(player_ids)=", len(player_ids) - #setup subarrays of the result dictionary. - street0VPI=[] - street0Aggr=[] - street0_3BChance=[] - street0_3BDone=[] - street1Seen=[] - street2Seen=[] - street3Seen=[] - street4Seen=[] - sawShowdown=[] - street1Aggr=[] - street2Aggr=[] - street3Aggr=[] - street4Aggr=[] - otherRaisedStreet1=[] - otherRaisedStreet2=[] - otherRaisedStreet3=[] - otherRaisedStreet4=[] - foldToOtherRaisedStreet1=[] - foldToOtherRaisedStreet2=[] - foldToOtherRaisedStreet3=[] - foldToOtherRaisedStreet4=[] - wonWhenSeenStreet1=[] - - wonAtSD=[] - stealAttemptChance=[] - stealAttempted=[] - hudDataPositions=[] - - street0Calls=[] - street1Calls=[] - street2Calls=[] - street3Calls=[] - street4Calls=[] - street0Bets=[] - street1Bets=[] - street2Bets=[] - street3Bets=[] - street4Bets=[] - #street0Raises=[] - #street1Raises=[] - #street2Raises=[] - #street3Raises=[] - #street4Raises=[] - - # Summary figures for hand table: - result={} - result['playersVpi']=0 - result['playersAtStreet1']=0 - result['playersAtStreet2']=0 - result['playersAtStreet3']=0 - result['playersAtStreet4']=0 - result['playersAtShowdown']=0 - result['street0Raises']=0 - result['street1Raises']=0 - result['street2Raises']=0 - result['street3Raises']=0 - result['street4Raises']=0 - result['street1Pot']=0 - result['street2Pot']=0 - result['street3Pot']=0 - result['street4Pot']=0 - result['showdownPot']=0 - - firstPfRaiseByNo=-1 - firstPfRaiserId=-1 - firstPfRaiserNo=-1 - firstPfCallByNo=-1 - firstPfCallerId=-1 - - for i, action in enumerate(actionTypeByNo[0]): - if action[1] == "bet": - firstPfRaiseByNo = i - firstPfRaiserId = action[0] - for j, pid in enumerate(player_ids): - if pid == firstPfRaiserId: - firstPfRaiserNo = j - break - break - for i, action in enumerate(actionTypeByNo[0]): - if action[1] == "call": - firstPfCallByNo = i - firstPfCallerId = action[0] - break - firstPlayId = firstPfCallerId - if firstPfRaiseByNo <> -1: - if firstPfRaiseByNo < firstPfCallByNo or firstPfCallByNo == -1: - firstPlayId = firstPfRaiserId - - - cutoffId=-1 - buttonId=-1 - sbId=-1 - bbId=-1 - if base=="hold": - for player, pos in enumerate(positions): - if pos == 1: - cutoffId = player_ids[player] - if pos == 0: - buttonId = player_ids[player] - if pos == 'S': - sbId = player_ids[player] - if pos == 'B': - bbId = player_ids[player] - - someoneStole=False - - #run a loop for each player preparing the actual values that will be commited to SQL - for player in xrange(len(player_ids)): - #set default values - myStreet0VPI=False - myStreet0Aggr=False - myStreet0_3BChance=False - myStreet0_3BDone=False - myStreet1Seen=False - myStreet2Seen=False - myStreet3Seen=False - myStreet4Seen=False - mySawShowdown=False - myStreet1Aggr=False - myStreet2Aggr=False - myStreet3Aggr=False - myStreet4Aggr=False - myOtherRaisedStreet1=False - myOtherRaisedStreet2=False - myOtherRaisedStreet3=False - myOtherRaisedStreet4=False - myFoldToOtherRaisedStreet1=False - myFoldToOtherRaisedStreet2=False - myFoldToOtherRaisedStreet3=False - myFoldToOtherRaisedStreet4=False - myWonWhenSeenStreet1=0.0 - myWonAtSD=0.0 - myStealAttemptChance=False - myStealAttempted=False - myStreet0Calls=0 - myStreet1Calls=0 - myStreet2Calls=0 - myStreet3Calls=0 - myStreet4Calls=0 - myStreet0Bets=0 - myStreet1Bets=0 - myStreet2Bets=0 - myStreet3Bets=0 - myStreet4Bets=0 - #myStreet0Raises=0 - #myStreet1Raises=0 - #myStreet2Raises=0 - #myStreet3Raises=0 - #myStreet4Raises=0 - - #calculate VPIP and PFR - street=0 - heroPfRaiseCount=0 - for currentAction in action_types[street][player]: # finally individual actions - if currentAction == "bet": - myStreet0Aggr = True - if currentAction == "bet" or currentAction == "call": - myStreet0VPI = True - - if myStreet0VPI: - result['playersVpi'] += 1 - myStreet0Calls = action_types[street][player].count('call') - myStreet0Bets = action_types[street][player].count('bet') - # street0Raises = action_types[street][player].count('raise') bet count includes raises for now - result['street0Raises'] += myStreet0Bets - - #PF3BChance and PF3B - pfFold=-1 - pfRaise=-1 - if firstPfRaiseByNo != -1: - for i, actionType in enumerate(actionTypeByNo[0]): - if actionType[0] == player_ids[player]: - if actionType[1] == "bet" and pfRaise == -1 and i > firstPfRaiseByNo: - pfRaise = i - if actionType[1] == "fold" and pfFold == -1: - pfFold = i - if pfFold == -1 or pfFold > firstPfRaiseByNo: - myStreet0_3BChance = True - if pfRaise > firstPfRaiseByNo: - myStreet0_3BDone = True - - #steal calculations - if base=="hold": - if len(player_ids)>=3: # no point otherwise # was 5, use 3 to match pokertracker definition - if positions[player]==1: - if firstPfRaiserId==player_ids[player] \ - and (firstPfCallByNo==-1 or firstPfCallByNo>firstPfRaiseByNo): - myStealAttempted=True - myStealAttemptChance=True - if firstPlayId==cutoffId or firstPlayId==buttonId or firstPlayId==sbId or firstPlayId==bbId or firstPlayId==-1: - myStealAttemptChance=True - if positions[player]==0: - if firstPfRaiserId==player_ids[player] \ - and (firstPfCallByNo==-1 or firstPfCallByNo>firstPfRaiseByNo): - myStealAttempted=True - myStealAttemptChance=True - if firstPlayId==buttonId or firstPlayId==sbId or firstPlayId==bbId or firstPlayId==-1: - myStealAttemptChance=True - if positions[player]=='S': - if firstPfRaiserId==player_ids[player] \ - and (firstPfCallByNo==-1 or firstPfCallByNo>firstPfRaiseByNo): - myStealAttempted=True - myStealAttemptChance=True - if firstPlayId==sbId or firstPlayId==bbId or firstPlayId==-1: - myStealAttemptChance=True - if positions[player]=='B': - pass - - if myStealAttempted: - someoneStole=True - - - #calculate saw* values - isAllIn = any(i for i in allIns[0][player]) - if isAllIn or len(action_types[1][player]) > 0: - myStreet1Seen = True - - if not isAllIn: - isAllIn = any(i for i in allIns[1][player]) - if isAllIn or len(action_types[2][player]) > 0: - if all(actiontype != "fold" for actiontype in action_types[1][player]): - myStreet2Seen = True - - if not isAllIn: - isAllAin = any(i for i in allIns[2][player]) - if isAllIn or len(action_types[3][player]) > 0: - if all(actiontype != "fold" for actiontype in action_types[2][player]): - myStreet3Seen = True - - #print "base:", base - if base == "hold": - mySawShowdown = not any(actiontype == "fold" for actiontype in action_types[3][player]) - else: - #print "in else" - if not isAllIn: - isAllIn = any(i for i in allIns[3][player]) - if isAllIn or len(action_types[4][player]) > 0: - #print "in if" - myStreet4Seen = True - - mySawShowdown = not any(actiontype == "fold" for actiontype in action_types[4][player]) - - if myStreet1Seen: - result['playersAtStreet1'] += 1 - if myStreet2Seen: - result['playersAtStreet2'] += 1 - if myStreet3Seen: - result['playersAtStreet3'] += 1 - if myStreet4Seen: - result['playersAtStreet4'] += 1 - if mySawShowdown: - result['playersAtShowdown'] += 1 - - #flop stuff - street = 1 - if myStreet1Seen: - myStreet1Aggr = any(actiontype == "bet" for actiontype in action_types[street][player]) - myStreet1Calls = action_types[street][player].count('call') - myStreet1Bets = action_types[street][player].count('bet') - # street1Raises = action_types[street][player].count('raise') bet count includes raises for now - result['street1Raises'] += myStreet1Bets - - for otherPlayer in xrange(len(player_ids)): - if player == otherPlayer: - pass - else: - for countOther in xrange(len(action_types[street][otherPlayer])): - if action_types[street][otherPlayer][countOther] == "bet": - myOtherRaisedStreet1 = True - for countOtherFold in xrange(len(action_types[street][player])): - if action_types[street][player][countOtherFold] == "fold": - myFoldToOtherRaisedStreet1 = True - - #turn stuff - copy of flop with different vars - street = 2 - if myStreet2Seen: - myStreet2Aggr = any(actiontype == "bet" for actiontype in action_types[street][player]) - myStreet2Calls = action_types[street][player].count('call') - myStreet2Bets = action_types[street][player].count('bet') - # street2Raises = action_types[street][player].count('raise') bet count includes raises for now - result['street2Raises'] += myStreet2Bets - - for otherPlayer in xrange(len(player_ids)): - if player == otherPlayer: - pass - else: - for countOther in xrange(len(action_types[street][otherPlayer])): - if action_types[street][otherPlayer][countOther] == "bet": - myOtherRaisedStreet2 = True - for countOtherFold in xrange(len(action_types[street][player])): - if action_types[street][player][countOtherFold] == "fold": - myFoldToOtherRaisedStreet2 = True - - #river stuff - copy of flop with different vars - street = 3 - if myStreet3Seen: - myStreet3Aggr = any(actiontype == "bet" for actiontype in action_types[street][player]) - myStreet3Calls = action_types[street][player].count('call') - myStreet3Bets = action_types[street][player].count('bet') - # street3Raises = action_types[street][player].count('raise') bet count includes raises for now - result['street3Raises'] += myStreet3Bets - - for otherPlayer in xrange(len(player_ids)): - if player == otherPlayer: - pass - else: - for countOther in xrange(len(action_types[street][otherPlayer])): - if action_types[street][otherPlayer][countOther] == "bet": - myOtherRaisedStreet3 = True - for countOtherFold in xrange(len(action_types[street][player])): - if action_types[street][player][countOtherFold] == "fold": - myFoldToOtherRaisedStreet3 = True - - #stud river stuff - copy of flop with different vars - street = 4 - if myStreet4Seen: - myStreet4Aggr = any(actiontype == "bet" for actiontype in action_types[street][player]) - myStreet4Calls = action_types[street][player].count('call') - myStreet4Bets = action_types[street][player].count('bet') - # street4Raises = action_types[street][player].count('raise') bet count includes raises for now - result['street4Raises'] += myStreet4Bets - - for otherPlayer in xrange(len(player_ids)): - if player == otherPlayer: - pass - else: - for countOther in xrange(len(action_types[street][otherPlayer])): - if action_types[street][otherPlayer][countOther] == "bet": - myOtherRaisedStreet4 = True - for countOtherFold in xrange(len(action_types[street][player])): - if action_types[street][player][countOtherFold] == "fold": - myFoldToOtherRaisedStreet4 = True - - if winnings[player] != 0: - if myStreet1Seen: - myWonWhenSeenStreet1 = winnings[player] / float(totalWinnings) - if mySawShowdown: - myWonAtSD = myWonWhenSeenStreet1 - - #add each value to the appropriate array - street0VPI.append(myStreet0VPI) - street0Aggr.append(myStreet0Aggr) - street0_3BChance.append(myStreet0_3BChance) - street0_3BDone.append(myStreet0_3BDone) - street1Seen.append(myStreet1Seen) - street2Seen.append(myStreet2Seen) - street3Seen.append(myStreet3Seen) - street4Seen.append(myStreet4Seen) - sawShowdown.append(mySawShowdown) - street1Aggr.append(myStreet1Aggr) - street2Aggr.append(myStreet2Aggr) - street3Aggr.append(myStreet3Aggr) - street4Aggr.append(myStreet4Aggr) - otherRaisedStreet1.append(myOtherRaisedStreet1) - otherRaisedStreet2.append(myOtherRaisedStreet2) - otherRaisedStreet3.append(myOtherRaisedStreet3) - otherRaisedStreet4.append(myOtherRaisedStreet4) - foldToOtherRaisedStreet1.append(myFoldToOtherRaisedStreet1) - foldToOtherRaisedStreet2.append(myFoldToOtherRaisedStreet2) - foldToOtherRaisedStreet3.append(myFoldToOtherRaisedStreet3) - foldToOtherRaisedStreet4.append(myFoldToOtherRaisedStreet4) - wonWhenSeenStreet1.append(myWonWhenSeenStreet1) - wonAtSD.append(myWonAtSD) - stealAttemptChance.append(myStealAttemptChance) - stealAttempted.append(myStealAttempted) - if base=="hold": - pos=positions[player] - if pos=='B': - hudDataPositions.append('B') - elif pos=='S': - hudDataPositions.append('S') - elif pos==0: - hudDataPositions.append('D') - elif pos==1: - hudDataPositions.append('C') - elif pos>=2 and pos<=4: - hudDataPositions.append('M') - elif pos>=5 and pos<=8: - hudDataPositions.append('E') - ### RHH Added this elif to handle being a dead hand before the BB (pos==9) - elif pos==9: - hudDataPositions.append('X') - else: - raise FpdbError("invalid position") - elif base=="stud": - #todo: stud positions and steals - pass - - street0Calls.append(myStreet0Calls) - street1Calls.append(myStreet1Calls) - street2Calls.append(myStreet2Calls) - street3Calls.append(myStreet3Calls) - street4Calls.append(myStreet4Calls) - street0Bets.append(myStreet0Bets) - street1Bets.append(myStreet1Bets) - street2Bets.append(myStreet2Bets) - street3Bets.append(myStreet3Bets) - street4Bets.append(myStreet4Bets) - #street0Raises.append(myStreet0Raises) - #street1Raises.append(myStreet1Raises) - #street2Raises.append(myStreet2Raises) - #street3Raises.append(myStreet3Raises) - #street4Raises.append(myStreet4Raises) - - #add each array to the to-be-returned dictionary - result['street0VPI']=street0VPI - result['street0Aggr']=street0Aggr - result['street0_3BChance']=street0_3BChance - result['street0_3BDone']=street0_3BDone - result['street1Seen']=street1Seen - result['street2Seen']=street2Seen - result['street3Seen']=street3Seen - result['street4Seen']=street4Seen - result['sawShowdown']=sawShowdown - - result['street1Aggr']=street1Aggr - result['otherRaisedStreet1']=otherRaisedStreet1 - result['foldToOtherRaisedStreet1']=foldToOtherRaisedStreet1 - result['street2Aggr']=street2Aggr - result['otherRaisedStreet2']=otherRaisedStreet2 - result['foldToOtherRaisedStreet2']=foldToOtherRaisedStreet2 - result['street3Aggr']=street3Aggr - result['otherRaisedStreet3']=otherRaisedStreet3 - result['foldToOtherRaisedStreet3']=foldToOtherRaisedStreet3 - result['street4Aggr']=street4Aggr - result['otherRaisedStreet4']=otherRaisedStreet4 - result['foldToOtherRaisedStreet4']=foldToOtherRaisedStreet4 - result['wonWhenSeenStreet1']=wonWhenSeenStreet1 - result['wonAtSD']=wonAtSD - result['stealAttemptChance']=stealAttemptChance - result['stealAttempted']=stealAttempted - result['street0Calls']=street0Calls - result['street1Calls']=street1Calls - result['street2Calls']=street2Calls - result['street3Calls']=street3Calls - result['street4Calls']=street4Calls - result['street0Bets']=street0Bets - result['street1Bets']=street1Bets - result['street2Bets']=street2Bets - result['street3Bets']=street3Bets - result['street4Bets']=street4Bets - #result['street0Raises']=street0Raises - #result['street1Raises']=street1Raises - #result['street2Raises']=street2Raises - #result['street3Raises']=street3Raises - #result['street4Raises']=street4Raises - - #now the various steal values - foldBbToStealChance=[] - foldedBbToSteal=[] - foldSbToStealChance=[] - foldedSbToSteal=[] - for player in xrange(len(player_ids)): - myFoldBbToStealChance=False - myFoldedBbToSteal=False - myFoldSbToStealChance=False - myFoldedSbToSteal=False - - if base=="hold": - if someoneStole and (positions[player]=='B' or positions[player]=='S') and firstPfRaiserId!=player_ids[player]: - street=0 - for count in xrange(len(action_types[street][player])):#individual actions - if positions[player]=='B': - myFoldBbToStealChance=True - if action_types[street][player][count]=="fold": - myFoldedBbToSteal=True - if positions[player]=='S': - myFoldSbToStealChance=True - if action_types[street][player][count]=="fold": - myFoldedSbToSteal=True - - - foldBbToStealChance.append(myFoldBbToStealChance) - foldedBbToSteal.append(myFoldedBbToSteal) - foldSbToStealChance.append(myFoldSbToStealChance) - foldedSbToSteal.append(myFoldedSbToSteal) - result['foldBbToStealChance']=foldBbToStealChance - result['foldedBbToSteal']=foldedBbToSteal - result['foldSbToStealChance']=foldSbToStealChance - result['foldedSbToSteal']=foldedSbToSteal - - #now CB - street1CBChance=[] - street1CBDone=[] - didStreet1CB=[] - for player in xrange(len(player_ids)): - myStreet1CBChance=False - myStreet1CBDone=False - - if street0VPI[player]: - myStreet1CBChance=True - if street1Aggr[player]: - myStreet1CBDone=True - didStreet1CB.append(player_ids[player]) - - street1CBChance.append(myStreet1CBChance) - street1CBDone.append(myStreet1CBDone) - result['street1CBChance']=street1CBChance - result['street1CBDone']=street1CBDone - - #now 2B - street2CBChance=[] - street2CBDone=[] - didStreet2CB=[] - for player in xrange(len(player_ids)): - myStreet2CBChance=False - myStreet2CBDone=False - - if street1CBDone[player]: - myStreet2CBChance=True - if street2Aggr[player]: - myStreet2CBDone=True - didStreet2CB.append(player_ids[player]) - - street2CBChance.append(myStreet2CBChance) - street2CBDone.append(myStreet2CBDone) - result['street2CBChance']=street2CBChance - result['street2CBDone']=street2CBDone - - #now 3B - street3CBChance=[] - street3CBDone=[] - didStreet3CB=[] - for player in xrange(len(player_ids)): - myStreet3CBChance=False - myStreet3CBDone=False - - if street2CBDone[player]: - myStreet3CBChance=True - if street3Aggr[player]: - myStreet3CBDone=True - didStreet3CB.append(player_ids[player]) - - street3CBChance.append(myStreet3CBChance) - street3CBDone.append(myStreet3CBDone) - result['street3CBChance']=street3CBChance - result['street3CBDone']=street3CBDone - - #and 4B - street4CBChance=[] - street4CBDone=[] - didStreet4CB=[] - for player in xrange(len(player_ids)): - myStreet4CBChance=False - myStreet4CBDone=False - - if street3CBDone[player]: - myStreet4CBChance=True - if street4Aggr[player]: - myStreet4CBDone=True - didStreet4CB.append(player_ids[player]) - - street4CBChance.append(myStreet4CBChance) - street4CBDone.append(myStreet4CBDone) - result['street4CBChance']=street4CBChance - result['street4CBDone']=street4CBDone - - - result['position']=hudDataPositions - - foldToStreet1CBChance=[] - foldToStreet1CBDone=[] - foldToStreet2CBChance=[] - foldToStreet2CBDone=[] - foldToStreet3CBChance=[] - foldToStreet3CBDone=[] - foldToStreet4CBChance=[] - foldToStreet4CBDone=[] - - for player in xrange(len(player_ids)): - myFoldToStreet1CBChance=False - myFoldToStreet1CBDone=False - foldToStreet1CBChance.append(myFoldToStreet1CBChance) - foldToStreet1CBDone.append(myFoldToStreet1CBDone) - - myFoldToStreet2CBChance=False - myFoldToStreet2CBDone=False - foldToStreet2CBChance.append(myFoldToStreet2CBChance) - foldToStreet2CBDone.append(myFoldToStreet2CBDone) - - myFoldToStreet3CBChance=False - myFoldToStreet3CBDone=False - foldToStreet3CBChance.append(myFoldToStreet3CBChance) - foldToStreet3CBDone.append(myFoldToStreet3CBDone) - - myFoldToStreet4CBChance=False - myFoldToStreet4CBDone=False - foldToStreet4CBChance.append(myFoldToStreet4CBChance) - foldToStreet4CBDone.append(myFoldToStreet4CBDone) - - if len(didStreet1CB)>=1: - generateFoldToCB(1, player_ids, didStreet1CB, street1CBDone, foldToStreet1CBChance, foldToStreet1CBDone, actionTypeByNo) - - if len(didStreet2CB)>=1: - generateFoldToCB(2, player_ids, didStreet2CB, street2CBDone, foldToStreet2CBChance, foldToStreet2CBDone, actionTypeByNo) - - if len(didStreet3CB)>=1: - generateFoldToCB(3, player_ids, didStreet3CB, street3CBDone, foldToStreet3CBChance, foldToStreet3CBDone, actionTypeByNo) - - if len(didStreet4CB)>=1: - generateFoldToCB(4, player_ids, didStreet4CB, street4CBDone, foldToStreet4CBChance, foldToStreet4CBDone, actionTypeByNo) - - result['foldToStreet1CBChance']=foldToStreet1CBChance - result['foldToStreet1CBDone']=foldToStreet1CBDone - result['foldToStreet2CBChance']=foldToStreet2CBChance - result['foldToStreet2CBDone']=foldToStreet2CBDone - result['foldToStreet3CBChance']=foldToStreet3CBChance - result['foldToStreet3CBDone']=foldToStreet3CBDone - result['foldToStreet4CBChance']=foldToStreet4CBChance - result['foldToStreet4CBDone']=foldToStreet4CBDone - - - totalProfit=[] - - street1CheckCallRaiseChance=[] - street1CheckCallRaiseDone=[] - street2CheckCallRaiseChance=[] - street2CheckCallRaiseDone=[] - street3CheckCallRaiseChance=[] - street3CheckCallRaiseDone=[] - street4CheckCallRaiseChance=[] - street4CheckCallRaiseDone=[] - #print "b4 totprof calc, len(playerIds)=", len(player_ids) - for pl in xrange(len(player_ids)): - #print "pl=", pl - myTotalProfit=winnings[pl] # still need to deduct other costs - if antes: - myTotalProfit=winnings[pl] - antes[pl] - for i in xrange(len(actionTypes)): #iterate through streets - #for j in xrange(len(actionTypes[i])): #iterate through names (using pl loop above) - for k in xrange(len(actionTypes[i][pl])): #iterate through individual actions of that player on that street - myTotalProfit -= actionAmounts[i][pl][k] - - myStreet1CheckCallRaiseChance=False - myStreet1CheckCallRaiseDone=False - myStreet2CheckCallRaiseChance=False - myStreet2CheckCallRaiseDone=False - myStreet3CheckCallRaiseChance=False - myStreet3CheckCallRaiseDone=False - myStreet4CheckCallRaiseChance=False - myStreet4CheckCallRaiseDone=False - - #print "myTotalProfit=", myTotalProfit - totalProfit.append(myTotalProfit) - #print "totalProfit[]=", totalProfit - - street1CheckCallRaiseChance.append(myStreet1CheckCallRaiseChance) - street1CheckCallRaiseDone.append(myStreet1CheckCallRaiseDone) - street2CheckCallRaiseChance.append(myStreet2CheckCallRaiseChance) - street2CheckCallRaiseDone.append(myStreet2CheckCallRaiseDone) - street3CheckCallRaiseChance.append(myStreet3CheckCallRaiseChance) - street3CheckCallRaiseDone.append(myStreet3CheckCallRaiseDone) - street4CheckCallRaiseChance.append(myStreet4CheckCallRaiseChance) - street4CheckCallRaiseDone.append(myStreet4CheckCallRaiseDone) - - result['totalProfit']=totalProfit - #print "res[totalProfit]=", result['totalProfit'] - - result['street1CheckCallRaiseChance']=street1CheckCallRaiseChance - result['street1CheckCallRaiseDone']=street1CheckCallRaiseDone - result['street2CheckCallRaiseChance']=street2CheckCallRaiseChance - result['street2CheckCallRaiseDone']=street2CheckCallRaiseDone - result['street3CheckCallRaiseChance']=street3CheckCallRaiseChance - result['street3CheckCallRaiseDone']=street3CheckCallRaiseDone - result['street4CheckCallRaiseChance']=street4CheckCallRaiseChance - result['street4CheckCallRaiseDone']=street4CheckCallRaiseDone - return result -#end def generateHudCacheData - -def generateFoldToCB(street, playerIDs, didStreetCB, streetCBDone, foldToStreetCBChance, foldToStreetCBDone, actionTypeByNo): - """fills the passed foldToStreetCB* arrays appropriately depending on the given street""" - #print "beginning of generateFoldToCB, street:", street, "len(actionTypeByNo):", len(actionTypeByNo) - #print "len(actionTypeByNo[street]):",len(actionTypeByNo[street]) - firstCBReaction=0 - for action in xrange(len(actionTypeByNo[street])): - if actionTypeByNo[street][action][1]=="bet": - for player in didStreetCB: - if player==actionTypeByNo[street][action][0] and firstCBReaction==0: - firstCBReaction=action+1 - break - - for action in actionTypeByNo[street][firstCBReaction:]: - for player in xrange(len(playerIDs)): - if playerIDs[player]==action[0]: - foldToStreetCBChance[player]=True - if action[1]=="fold": - foldToStreetCBDone[player]=True -#end def generateFoldToCB From 0898ddf8a15700f01cdf43f3ac8d73207daeefcd Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 22 Dec 2009 17:20:07 +0800 Subject: [PATCH 10/15] [NEWIMPORT] HandsPlayers.startCards Dodgy function just to get things kinda working again. --- pyfpdb/Card.py | 21 ++++++++++++++++++++- pyfpdb/DerivedStats.py | 4 ++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/pyfpdb/Card.py b/pyfpdb/Card.py index 287a0f6a..8639fd35 100755 --- a/pyfpdb/Card.py +++ b/pyfpdb/Card.py @@ -16,6 +16,25 @@ #agpl-3.0.txt in the docs folder of the package. +# From fpdb_simple +card_map = { "0": 0, "2": 2, "3" : 3, "4" : 4, "5" : 5, "6" : 6, "7" : 7, "8" : 8, + "9" : 9, "T" : 10, "J" : 11, "Q" : 12, "K" : 13, "A" : 14} + +# FIXME: the following is a workaround until switching to newimport. +# This should be moved into DerivedStats +# I'd also like to change HandsPlayers.startCards to a different datatype +# so we can 'trivially' add different start card classifications + +def calcStartCards(hand, player): + if hand.gametype['category'] == 'holdem': + hcs = hand.join_holecards(player, asList=True) + #print "DEBUG: hcs: %s" % hcs + value1 = card_map[hcs[0][0]] + value2 = card_map[hcs[1][0]] + return twoStartCards(value1, hcs[0][1], value2, hcs[1][1]) + else: + # FIXME: Only do startCards value for holdem at the moment + return 0 def twoStartCards(value1, suit1, value2, suit2): @@ -127,4 +146,4 @@ if __name__ == '__main__': (i, valueSuitFromCard(i), i+13, valueSuitFromCard(i+13), i+26, valueSuitFromCard(i+26), i+39, valueSuitFromCard(i+39)) print - print encodeCard('7c') \ No newline at end of file + print encodeCard('7c') diff --git a/pyfpdb/DerivedStats.py b/pyfpdb/DerivedStats.py index dbd655a3..b65b0d05 100644 --- a/pyfpdb/DerivedStats.py +++ b/pyfpdb/DerivedStats.py @@ -47,6 +47,7 @@ class DerivedStats(): self.handsplayers[player[1]]['wonWhenSeenStreet1'] = 0.0 self.handsplayers[player[1]]['sawShowdown'] = False self.handsplayers[player[1]]['wonAtSD'] = 0.0 + self.handsplayers[player[1]]['startCards'] = 0 for i in range(5): self.handsplayers[player[1]]['street%dCalls' % i] = 0 self.handsplayers[player[1]]['street%dBets' % i] = 0 @@ -57,7 +58,6 @@ class DerivedStats(): #FIXME - Everything below this point is incomplete. self.handsplayers[player[1]]['position'] = 2 self.handsplayers[player[1]]['tourneyTypeId'] = 1 - self.handsplayers[player[1]]['startCards'] = 0 self.handsplayers[player[1]]['street0_3BChance'] = False self.handsplayers[player[1]]['street0_3BDone'] = False self.handsplayers[player[1]]['stealAttemptChance'] = False @@ -172,7 +172,7 @@ class DerivedStats(): # self.handsplayers[player[1]]['card%s' % i] = Card.encodeCard(card) for i, card in enumerate(hcs[:7]): self.handsplayers[player[1]]['card%s' % (i+1)] = Card.encodeCard(card) - + self.handsplayers[player[1]]['startCards'] = Card.calcStartCards(hand, player[1]) # position, #Stud 3rd street card test From ae55a89d7f16ee918c39372127ccb25de1ec31b7 Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 22 Dec 2009 20:22:05 +0800 Subject: [PATCH 11/15] Remove reference to fpdb_simple --- pyfpdb/Tables.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyfpdb/Tables.py b/pyfpdb/Tables.py index ea5dfc4c..75bc574c 100755 --- a/pyfpdb/Tables.py +++ b/pyfpdb/Tables.py @@ -39,7 +39,6 @@ if os.name == 'nt': # FreePokerTools modules import Configuration -from fpdb_simple import LOCALE_ENCODING # Each TableWindow object must have the following attributes correctly populated: # tw.name = the table name from the title bar, which must to match the table name @@ -238,7 +237,7 @@ def discover_nt_by_name(c, tablename): try: # maybe it's better to make global titles[hwnd] decoding? # this can blow up in XP on some windows, eg firefox displaying http://docs.python.org/tutorial/classes.html - if not tablename.lower() in titles[hwnd].decode(LOCALE_ENCODING).lower(): + if not tablename.lower() in titles[hwnd].decode(Configuration.LOCALE_ENCODING).lower(): continue except: continue From 4d8d678d644a1cf7b439c5d4dc2ae8986a6f4656 Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 22 Dec 2009 21:40:37 +0800 Subject: [PATCH 12/15] [NEWIMPORT] Make seek into autoimport function Now that the legacy import path is gone, enable the index for HHC --- pyfpdb/HandHistoryConverter.py | 2 +- pyfpdb/fpdb_import.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pyfpdb/HandHistoryConverter.py b/pyfpdb/HandHistoryConverter.py index a18797df..9d4807a2 100644 --- a/pyfpdb/HandHistoryConverter.py +++ b/pyfpdb/HandHistoryConverter.py @@ -65,7 +65,7 @@ follow : whether to tail -f the input""" log.info("HandHistory init - %s subclass, in_path '%s'; out_path '%s'" % (self.sitename, in_path, out_path) ) - self.index = 0 + self.index = index self.starsArchive = starsArchive self.in_path = in_path diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index a7a21831..2decf6b6 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -427,7 +427,12 @@ class Importer: mod = __import__(filter) obj = getattr(mod, filter_name, None) if callable(obj): - hhc = obj(in_path = file, out_path = out_path, index = 0, starsArchive = self.settings['starsArchive']) # Index into file 0 until changeover + idx = 0 + if file in self.pos_in_file: + idx = self.pos_in_file[file] + else: + self.pos_in_file[file] = 0 + hhc = obj(in_path = file, out_path = out_path, index = idx, starsArchive = self.settings['starsArchive']) # Index into file 0 until changeover if hhc.getStatus() and self.NEWIMPORT == True: #This code doesn't do anything yet handlist = hhc.getProcessedHands() From 284693e95e820e0e8e41428f82f6d93784ec23a7 Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 22 Dec 2009 22:02:36 +0800 Subject: [PATCH 13/15] [NEWIMPORT] Rebuild hudcache after hand is committed --- pyfpdb/fpdb_import.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index 2decf6b6..a2a466de 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -449,6 +449,7 @@ class Importer: else: log.error("Hand processed but empty") self.database.commit() + self.database.rebuild_hudcache() #pipe the Hands.id out to the HUD for hid in to_hud: From d8a87b92d4101ca406ab0866964737e2d3baba30 Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 22 Dec 2009 22:15:27 +0800 Subject: [PATCH 14/15] [NEWIMPORT] Make hudcache rebuild only happen no call to hud --- pyfpdb/fpdb_import.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index a2a466de..24f16000 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -449,7 +449,8 @@ class Importer: else: log.error("Hand processed but empty") self.database.commit() - self.database.rebuild_hudcache() + if self.callHud: + self.database.rebuild_hudcache() #pipe the Hands.id out to the HUD for hid in to_hud: From 355225fc258e26b34e078e8baec5143267f9a0e5 Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 22 Dec 2009 23:03:05 +0800 Subject: [PATCH 15/15] [NEWIMPORT] Remove test_fpdb_simple --- pyfpdb/test_fpdb_simple.py | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100755 pyfpdb/test_fpdb_simple.py diff --git a/pyfpdb/test_fpdb_simple.py b/pyfpdb/test_fpdb_simple.py deleted file mode 100755 index 3d9615cb..00000000 --- a/pyfpdb/test_fpdb_simple.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -import fpdb_simple -import datetime -import py - -def checkDateParse(header, site, result): - assert fpdb_simple.parseHandStartTime(header, site) == result - -def testPokerStarsHHDate(): - tuples = ( - ("PokerStars Game #21969660557: Hold'em No Limit ($0.50/$1.00) - 2008/11/12 10:00:48 CET [2008/11/12 4:00:48 ET]", "ps", - datetime.datetime(2008,11,12,15,00,48)), - ("PokerStars Game #21969660557: Hold'em No Limit ($0.50/$1.00) - 2008/08/17 - 01:14:43 (ET)", "ps", - datetime.datetime(2008,8,17,6,14,43)), - ("PokerStars Game #21969660557: Hold'em No Limit ($0.50/$1.00) - 2008/09/07 06:23:14 ET", "ps", - datetime.datetime(2008,9,7,11,23,14)) - ) - -#def testTableDetection(): -# result = Tables.clean_title("French (deep)") -# assert result == "French" -# result = Tables.clean_title("French (deep) - $0.25/$0.50 - No Limit Hold'em - Logged In As xxxx") -# assert result == "French" -# -# for (header, site, result) in tuples: -# yield checkDateParse, header, site, result -