From 838c626bba1ffcf8da1d31e2d1735ed9e90ae327 Mon Sep 17 00:00:00 2001 From: "chaz@pokeit.co" Date: Fri, 31 Dec 2010 15:30:29 -0500 Subject: [PATCH 001/182] Changed the HandsActions table join index from 'handsPlayersId' to 'handId' and 'playerId'. This allows us to use executemany(), which is faster, in storeHandsPlayers when storing actions. --- pyfpdb/Database.py | 31 +++++++++++++------------------ pyfpdb/Hand.py | 8 ++++---- pyfpdb/SQL.py | 30 ++++++++++++++++-------------- 3 files changed, 33 insertions(+), 36 deletions(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 8ed0e3bc..e1b097fd 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -73,7 +73,7 @@ except ImportError: use_numpy = False -DB_VERSION = 147 +DB_VERSION = 148 # Variance created as sqlite has a bunch of undefined aggregate functions. @@ -125,7 +125,8 @@ class Database: {'tab':'Gametypes', 'col':'siteId', 'drop':0} , {'tab':'Hands', 'col':'gametypeId', 'drop':0} # mct 22/3/09 #, {'tab':'Hands', 'col':'siteHandNo', 'drop':0} unique indexes not dropped - , {'tab':'HandsActions', 'col':'handsPlayerId', 'drop':0} + , {'tab':'HandsActions', 'col':'handId', 'drop':1} + , {'tab':'HandsActions', 'col':'playerId', 'drop':1} , {'tab':'HandsActions', 'col':'actionId', 'drop':1} , {'tab':'HandsPlayers', 'col':'handId', 'drop':1} , {'tab':'HandsPlayers', 'col':'playerId', 'drop':1} @@ -150,7 +151,8 @@ class Database: , {'tab':'HandsPlayers', 'col':'handId', 'drop':0} , {'tab':'HandsPlayers', 'col':'playerId', 'drop':0} , {'tab':'HandsPlayers', 'col':'tourneysPlayersId', 'drop':0} - , {'tab':'HandsActions', 'col':'handsPlayerId', 'drop':0} + , {'tab':'HandsActions', 'col':'handId', 'drop':0} + , {'tab':'HandsActions', 'col':'playerId', 'drop':0} , {'tab':'HandsActions', 'col':'actionId', 'drop':1} , {'tab':'HudCache', 'col':'gametypeId', 'drop':1} , {'tab':'HudCache', 'col':'playerId', 'drop':0} @@ -174,7 +176,8 @@ class Database: , {'fktab':'HandsPlayers', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'tourneysPlayersId','rtab':'TourneysPlayers','rcol':'id', 'drop':1} - , {'fktab':'HandsActions', 'fkcol':'handsPlayerId', 'rtab':'HandsPlayers', 'rcol':'id', 'drop':1} + , {'fktab':'HandsActions', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1} + , {'fktab':'HandsActions', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1} , {'fktab':'HandsActions', 'fkcol':'actionId', 'rtab':'Actions', 'rcol':'id', 'drop':1} , {'fktab':'HudCache', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1} , {'fktab':'HudCache', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':0} @@ -184,7 +187,8 @@ class Database: {'fktab':'Hands', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1} , {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1} - , {'fktab':'HandsActions', 'fkcol':'handsPlayerId', 'rtab':'HandsPlayers', 'rcol':'id', 'drop':1} + , {'fktab':'HandsActions', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1} + , {'fktab':'HandsActions', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1} , {'fktab':'HandsActions', 'fkcol':'actionId', 'rtab':'Actions', 'rcol':'id', 'drop':1} , {'fktab':'HudCache', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1} , {'fktab':'HudCache', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':0} @@ -1755,7 +1759,6 @@ class Database: pp.pprint(pdata) inserts = [] - hpid = {} for p in pdata: inserts.append( (hid, pids[p], @@ -1860,17 +1863,9 @@ class Database: #print "DEBUG: inserts: %s" %inserts #print "DEBUG: q: %s" % q c = self.get_cursor() + c.executemany(q, inserts) - if self.import_options['saveActions']: - for r in inserts: - c.execute(q, r) - hpid[(r[0], r[1])] = self.get_last_insert_id(c) - else: - c.executemany(q, inserts) - - return hpid - - def storeHandsActions(self, hid, pids, hpid, adata, printdata = False): + def storeHandsActions(self, hid, pids, adata, printdata = False): #print "DEBUG: %s %s %s" %(hid, pids, adata) # This can be used to generate test data. Currently unused @@ -1881,8 +1876,8 @@ class Database: inserts = [] for a in adata: - inserts.append( (hpid[(hid, pids[adata[a]['player']])], - #self.getHandsPlayerId(self.hid, pids[adata[a]['player']]), + inserts.append( (hid, + pids[adata[a]['player']], adata[a]['street'], adata[a]['actionNo'], adata[a]['streetActionNo'], diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 405a56e5..a3a1059f 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -266,11 +266,11 @@ db: a connected Database object""" hh['seats'] = len(self.dbid_pids) self.dbid_hands = db.storeHand(hh, printdata = printtest) - self.dbid_hpid = db.storeHandsPlayers(self.dbid_hands, self.dbid_pids, - self.stats.getHandsPlayers(), printdata = printtest) + db.storeHandsPlayers(self.dbid_hands, self.dbid_pids, self.stats.getHandsPlayers(), + printdata = printtest) if self.saveActions: - db.storeHandsActions(self.dbid_hands, self.dbid_pids, self.dbid_hpid, - self.stats.getHandsActions(), printdata = printtest) + db.storeHandsActions(self.dbid_hands, self.dbid_pids, self.stats.getHandsActions(), + printdata = printtest) else: log.info(_("Hand.insert(): hid #: %s is a duplicate") % hh['siteHandNo']) self.is_duplicate = True # i.e. don't update hudcache diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 6a87b433..d396b43c 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -1007,7 +1007,8 @@ class Sql: if db_server == 'mysql': self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions ( id BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, PRIMARY KEY (id), - handsPlayerId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handsPlayerId) REFERENCES HandsPlayers(id), + handId BIGINT UNSIGNED NOT NULL, FOREIGN KEY (handId) REFERENCES Hands(id), + playerId INT UNSIGNED NOT NULL, FOREIGN KEY (playerId) REFERENCES Players(id), street SMALLINT NOT NULL, actionNo SMALLINT NOT NULL, streetActionNo SMALLINT NOT NULL, @@ -1022,7 +1023,8 @@ class Sql: elif db_server == 'postgresql': self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions ( id BIGSERIAL, PRIMARY KEY (id), - handsPlayerId BIGINT, FOREIGN KEY (handsPlayerId) REFERENCES HandsPlayers(id), + handId BIGINT NOT NULL, FOREIGN KEY (handId) REFERENCES Hands(id), + playerId INT NOT NULL, FOREIGN KEY (playerId) REFERENCES Players(id), street SMALLINT, actionNo SMALLINT, streetActionNo SMALLINT, @@ -1036,7 +1038,8 @@ class Sql: elif db_server == 'sqlite': self.query['createHandsActionsTable'] = """CREATE TABLE HandsActions ( id INTEGER PRIMARY KEY, - handsPlayerId BIGINT, + handId INT NOT NULL, + playerId INT NOT NULL, street SMALLINT, actionNo SMALLINT, streetActionNo SMALLINT, @@ -1046,9 +1049,7 @@ class Sql: amountCalled INT, numDiscarded SMALLINT, cardsDiscarded TEXT, - allIn BOOLEAN, - FOREIGN KEY (handsPlayerId) REFERENCES HandsPlayers(id), - FOREIGN KEY (actionId) REFERENCES Actions(id) ON DELETE CASCADE + allIn BOOLEAN )""" @@ -4323,7 +4324,7 @@ class Sql: self.query['handsPlayersTTypeId_joiner'] = " OR TourneysPlayersId+0=" self.query['handsPlayersTTypeId_joiner_id'] = " OR id=" - self.query['store_hand'] = """INSERT INTO Hands ( + self.query['store_hand'] = """insert into Hands ( tablename, gametypeid, sitehandno, @@ -4355,13 +4356,13 @@ class Sql: street4Pot, showdownPot ) - VALUES + 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, %s, %s, %s, %s, %s, %s)""" - self.query['store_hands_players'] = """INSERT INTO HandsPlayers ( + self.query['store_hands_players'] = """insert into HandsPlayers ( handId, playerId, startCash, @@ -4458,7 +4459,7 @@ class Sql: street3Raises, street4Raises ) - VALUES ( + values ( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, @@ -4480,8 +4481,9 @@ class Sql: %s, %s, %s, %s, %s )""" - self.query['store_hands_actions'] = """INSERT INTO HandsActions ( - handsPlayerId, + self.query['store_hands_actions'] = """insert into HandsActions ( + handId, + playerId, street, actionNo, streetActionNo, @@ -4493,10 +4495,10 @@ class Sql: cardsDiscarded, allIn ) - VALUES ( + values ( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, - %s + %s, %s )""" ################################ From 990e2262547142fa937dea96d43a89183b1965ad Mon Sep 17 00:00:00 2001 From: "chaz@pokeit.co" Date: Sat, 1 Jan 2011 03:35:14 -0500 Subject: [PATCH 002/182] storeSessionsCache() now adds a sessionId to the Hands table --- pyfpdb/Database.py | 69 +++++++------ pyfpdb/DerivedStats.py | 1 + pyfpdb/HUD_config.test.xml | 194 +++++++++++++++++++++++++++++++++++-- pyfpdb/Hand.py | 9 +- pyfpdb/SQL.py | 72 ++++++++------ pyfpdb/TestHandsPlayers.py | 4 +- pyfpdb/fpdb_import.py | 8 -- 7 files changed, 279 insertions(+), 78 deletions(-) mode change 100755 => 100644 pyfpdb/TestHandsPlayers.py diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index e1b097fd..9c924ff1 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -73,7 +73,7 @@ except ImportError: use_numpy = False -DB_VERSION = 148 +DB_VERSION = 149 # Variance created as sqlite has a bunch of undefined aggregate functions. @@ -1718,10 +1718,11 @@ class Database: c.execute(q, ( p['tableName'], - p['gametypeId'], p['siteHandNo'], p['tourneyId'], - p['startTime'], + p['gametypeId'], + p['sessionId'], + p['startTime'], datetime.utcnow(), #importtime p['seats'], p['maxSeats'], @@ -2035,10 +2036,9 @@ class Database: pass def storeSessionsCache(self, pids, startTime, game, pdata): - """Update cached sessions. If update fails because no record exists, do an insert""" + """Update cached sessions. If no record exists, do an insert""" THRESHOLD = timedelta(seconds=int(self.sessionTimeout * 60)) - bigBet = int(Decimal(game['bb'])*200) select_sessionscache = self.sql.query['select_sessionscache'] select_sessionscache = select_sessionscache.replace('%s', self.sql.query['placeholder']) @@ -2061,6 +2061,9 @@ class Database: delete_sessions = self.sql.query['delete_sessions'] delete_sessions = delete_sessions.replace('%s', self.sql.query['placeholder']) + update_hands_sessionid = self.sql.query['update_hands_sessionid'] + update_hands_sessionid = update_hands_sessionid.replace('%s', self.sql.query['placeholder']) + #Grab playerIds using hero names in HUD_Config.xml try: # derive list of program owner's player ids @@ -2090,30 +2093,35 @@ class Database: if (game['type']=='ring'): line[0] = 1 # count ring hands if (game['type']=='tour'): line[1] = 1 # count tour hands - if (game['type']=='ring'): line[2] = pdata[p]['totalProfit'] #sum of profit - if (game['type']=='ring'): line[3] = 0 #float(Decimal(pdata[p]['totalProfit'])/Decimal(bigBet)) #sum of big bets won + if (game['type']=='ring' and game['currency']=='USD'): line[2] = pdata[p]['totalProfit'] #sum of ring profit in USD + if (game['type']=='ring' and game['currency']=='EUR'): line[3] = pdata[p]['totalProfit'] #sum of ring profit in EUR line[4] = startTime inserts.append(line) cursor = self.get_cursor() + id = None for row in inserts: threshold = [] + session_records = [] threshold.append(row[-1]-THRESHOLD) threshold.append(row[-1]+THRESHOLD) cursor.execute(select_sessionscache, threshold) - num = cursor.rowcount + for r in cursor: + if r: session_records.append(r[0]) + num = len(session_records) if (num == 1): + id = session_records[0] #grab the sessionId # Try to do the update first: #print "DEBUG: found 1 record to update" update_mid = row + row[-1:] cursor.execute(select_sessionscache_mid, update_mid[-2:]) - mid = cursor.rowcount - if (mid == 0): + mid = cursor.fetchone() + if mid: update_startend = row[-1:] + row + threshold cursor.execute(select_sessionscache_start, update_startend[-3:]) - start = cursor.rowcount - if (start == 0): + start = cursor.fetchone() + if start: #print "DEBUG:", start, " start record found. Update stats and start time" cursor.execute(update_sessionscache_end, update_startend) else: @@ -2123,37 +2131,36 @@ class Database: #print "DEBUG: update stats mid-session" cursor.execute(update_sessionscache_mid, update_mid) elif (num > 1): + session_ids = [session_records[0][0], session_records[1][0]] + session_ids.sort() # Multiple matches found - merge them into one session and update: - #print "DEBUG:", num, "matches found" - cursor.execute(merge_sessionscache, threshold) + # - Obtain the session start and end times for the new combined session + cursor.execute(merge_sessionscache, session_ids) merge = cursor.fetchone() - cursor.execute(delete_sessions, threshold) + # - Delete the old records + for id in session_ids: + cursor.execute(delete_sessions, id) + # - Insert the new updated record cursor.execute(insert_sessionscache, merge) + # - Obtain the new sessionId and write over the old ids in Hands + id = self.get_last_insert_id(cursor) #grab the sessionId + update_hands = [id] + session_ids + cursor.execute(update_hands_sessionid, update_hands) + # - Update the newly combined record in SessionsCache with data from this hand update_mid = row + row[-1:] - cursor.execute(select_sessionscache_mid, update_mid[-2:]) - mid = cursor.rowcount - if (mid == 0): - update_startend = row[-1:] + row + threshold - cursor.execute(select_sessionscache_start, update_startend[-3:]) - start = cursor.rowcount - if (start == 0): - #print "DEBUG:", start, " start record found. Update stats and start time" - cursor.execute(update_sessionscache_end, update_startend) - else: - #print "DEBUG: 1 end record found. Update stats and end time time" - cursor.execute(update_sessionscache_start, update_startend) - else: - #print "DEBUG: update stats mid-session" - cursor.execute(update_sessionscache_mid, update_mid) + cursor.execute(update_sessionscache_mid, update_mid) elif (num == 0): # No matches found, insert new session: insert = row + row[-1:] insert = insert[-2:] + insert[:-2] #print "DEBUG: No matches found. Insert record", insert cursor.execute(insert_sessionscache, insert) + id = self.get_last_insert_id(cursor) #grab the sessionId else: # Something bad happened - pass + pass + + return id def isDuplicate(self, gametypeID, siteHandNo): dup = False diff --git a/pyfpdb/DerivedStats.py b/pyfpdb/DerivedStats.py index 003f5270..e069db7f 100644 --- a/pyfpdb/DerivedStats.py +++ b/pyfpdb/DerivedStats.py @@ -102,6 +102,7 @@ class DerivedStats(): self.hands['tableName'] = hand.tablename self.hands['siteHandNo'] = hand.handid self.hands['gametypeId'] = None # Leave None, handled later after checking db + self.hands['sessionId'] = None # Leave None, added later if caching sessions self.hands['startTime'] = hand.startTime # format this! self.hands['importTime'] = None self.hands['seats'] = self.countPlayers(hand) diff --git a/pyfpdb/HUD_config.test.xml b/pyfpdb/HUD_config.test.xml index 7ce84651..8352b468 100644 --- a/pyfpdb/HUD_config.test.xml +++ b/pyfpdb/HUD_config.test.xml @@ -2,7 +2,7 @@ - + From ec477110cfb11471cc12a2065f09a29ce184c993 Mon Sep 17 00:00:00 2001 From: "chaz@pokeit.co" Date: Tue, 18 Jan 2011 03:53:35 -0500 Subject: [PATCH 006/182] fixed an import bug which prevented handsplayers and handsactions records from ever getting inserted --- pyfpdb/fpdb_import.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index 92bbcadb..e7b019a6 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -478,6 +478,7 @@ class Importer: i = 0 for hand in handlist: + i += 1 if hand is not None: hand.prepInsert(self.database) try: From bd5b0769e82b329187b5a017a4ec1d717c86873b Mon Sep 17 00:00:00 2001 From: Worros Date: Mon, 24 Jan 2011 13:16:38 +0800 Subject: [PATCH 007/182] HHC: FTP archive regex fix. The number of '*'s in the FTP header changes as the handid gets higher. Allow for between 20 and 25 '*'s --- pyfpdb/HandHistoryConverter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/HandHistoryConverter.py b/pyfpdb/HandHistoryConverter.py index b283b6f2..3f0c51bd 100644 --- a/pyfpdb/HandHistoryConverter.py +++ b/pyfpdb/HandHistoryConverter.py @@ -258,7 +258,7 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py. if self.ftpArchive == True: log.debug(_("Converting ftpArchive format to readable")) # Remove ******************** # 1 ************************* - m = re.compile('\*{20}\s#\s\d+\s\*{25}\s+', re.MULTILINE) + m = re.compile('\*{20}\s#\s\d+\s\*{20,25}\s+', re.MULTILINE) self.obs = m.sub('', self.obs) if self.obs is None or self.obs == "": From e6be901cf30bac42632b520df0bd6480048079d5 Mon Sep 17 00:00:00 2001 From: Worros Date: Mon, 24 Jan 2011 14:00:25 +0800 Subject: [PATCH 008/182] FTP: Fixes for Multi entry rush and FTP archive files - Minor fix for table name match - Make the word 'Table|Match' optional as it isn't in the archive file - Add optional section for 'Entry #id' --- pyfpdb/FulltiltToFpdb.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index d4d59473..11323939 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -77,11 +77,12 @@ class Fulltilt(HandHistoryConverter): ''' % substitutions, re.VERBOSE) re_SplitHands = re.compile(r"\n\n\n+") re_TailSplitHands = re.compile(r"(\n\n+)") - re_HandInfo = re.compile(r'''.*\#(?P[0-9]+):\s + re_HandInfo = re.compile(u'''.*\#(?P[0-9]+):\s (?:(?P.+)\s\((?P\d+)\),\s)? - (Table|Match)\s + ((Table|Match)\s)? (?PPlay\sChip\s|PC)? - (?P[%(TAB)s]+)\s + (?P
[%(TAB)s]+\s?) + (?P,\sEntry\s\#\d+\s)? (\((?P.+)\)\s)?-\s [%(LS)s]?(?P[%(NUM)s]+)/[%(LS)s]?(?P[%(NUM)s]+)\s(Ante\s[%(LS)s]?(?P[.0-9]+)\s)?-\s [%(LS)s]?(?P[.0-9]+\sCap\s)? @@ -262,6 +263,8 @@ class Fulltilt(HandHistoryConverter): tmp = hand.handText[0:100] log.error(_("readHandInfo: Unable to recognise handinfo from: '%s'") % tmp) raise FpdbParseError(_("No match in readHandInfo.")) + + #print "DEBUG: m.groupdict: %s" % m.groupdict() hand.handid = m.group('HID') hand.tablename = m.group('TABLE') From 5a30d793c7ff4e04c20c4f3e54674562b1205d8a Mon Sep 17 00:00:00 2001 From: Worros Date: Mon, 24 Jan 2011 14:13:03 +0800 Subject: [PATCH 009/182] FTP: Update re_HandInfo After last patch the regex was greedy when including space. Fixes 7 issues noted by THP --- pyfpdb/FulltiltToFpdb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index 11323939..348338ba 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -81,8 +81,8 @@ class Fulltilt(HandHistoryConverter): (?:(?P.+)\s\((?P\d+)\),\s)? ((Table|Match)\s)? (?PPlay\sChip\s|PC)? - (?P
[%(TAB)s]+\s?) - (?P,\sEntry\s\#\d+\s)? + ((?P
[%(TAB)s]+)(\s|,)) + (?P\sEntry\s\#\d+\s)? (\((?P.+)\)\s)?-\s [%(LS)s]?(?P[%(NUM)s]+)/[%(LS)s]?(?P[%(NUM)s]+)\s(Ante\s[%(LS)s]?(?P[.0-9]+)\s)?-\s [%(LS)s]?(?P[.0-9]+\sCap\s)? From 341f5198b844c4686f75b01d9d3c251599277d93 Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 25 Jan 2011 13:10:50 +0800 Subject: [PATCH 010/182] Hand: Throw error when Draw hand has no deal section Resolves: https://sourceforge.net/apps/mantisbt/fpdb/view.php?id=76 --- pyfpdb/Hand.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index 8c2d6bbe..fd781448 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -349,15 +349,13 @@ db: a connected Database object""" # Need to find MySQL and Postgres equivalents # MySQL maybe: cursorclass=MySQLdb.cursors.DictCursor res = c.fetchone() + + #res['tourneyId'] #res['seats'] #res['rush'] self.tablename = res['tableName'] self.handid = res['siteHandNo'] self.startTime = datetime.datetime.strptime(res['startTime'], "%Y-%m-%d %H:%M:%S+00:00") - #res['tourneyId'] - #gametypeId - #res['importTime'] # Don't really care about this - #res['seats'] self.maxseats = res['maxSeats'] - #res['rush'] + cards = map(Card.valueSuitFromCard, [res['boardcard1'], res['boardcard2'], res['boardcard3'], res['boardcard4'], res['boardcard5']]) #print "DEBUG: res['boardcard1']: %s" % res['boardcard1'] #print "DEBUG: cards: %s" % cards @@ -1140,6 +1138,9 @@ class DrawHand(Hand): hhc.readPlayerStacks(self) hhc.compilePlayerRegexs(self) hhc.markStreets(self) + # markStreets in Draw may match without dealing cards + if self.streets['DEAL'] == None: + raise FpdbParseError(_("DrawHand.__init__: street 'DEAL' is empty. Hand cancelled?")) hhc.readBlinds(self) hhc.readAntes(self) hhc.readButton(self) From 9685d46c388edc15345460737ff59b349f851732 Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 25 Jan 2011 13:12:56 +0800 Subject: [PATCH 011/182] Regression: Add previously failing hand. As reported in: https://sourceforge.net/apps/mantisbt/fpdb/view.php?id=76 --- .../3-Draw-Limit-USD-1-2-200809.Hand.cancelled.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 pyfpdb/regression-test-files/cash/Stars/Draw/3-Draw-Limit-USD-1-2-200809.Hand.cancelled.txt diff --git a/pyfpdb/regression-test-files/cash/Stars/Draw/3-Draw-Limit-USD-1-2-200809.Hand.cancelled.txt b/pyfpdb/regression-test-files/cash/Stars/Draw/3-Draw-Limit-USD-1-2-200809.Hand.cancelled.txt new file mode 100644 index 00000000..c3be02bf --- /dev/null +++ b/pyfpdb/regression-test-files/cash/Stars/Draw/3-Draw-Limit-USD-1-2-200809.Hand.cancelled.txt @@ -0,0 +1,12 @@ +PokerStars Game #20349633663: Triple Draw 2-7 Lowball Limit ($1/$2 USD) - 2008/09/12 14:09:41 ET +Table 'Miriam III' 6-max Seat #5 is the button +Seat 5: Hero ($32.75 in chips) +Hero: posts small blind $0.50 +VillainA: is sitting out +VillainB: is sitting out +Hand cancelled +*** SUMMARY *** +Seat 5: Hero (button) collected ($0) + + + From a790ced223facd542ac55cede18244c87699b80e Mon Sep 17 00:00:00 2001 From: Eratosthenes Date: Wed, 26 Jan 2011 17:10:24 -0500 Subject: [PATCH 012/182] Mika's modifications. Still probs with set_transient_(). --- pyfpdb/OSXTables.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pyfpdb/OSXTables.py b/pyfpdb/OSXTables.py index 8baa6aec..a3473fbb 100644 --- a/pyfpdb/OSXTables.py +++ b/pyfpdb/OSXTables.py @@ -52,8 +52,8 @@ class Table(Table_Window): if re.search(self.search_string, d.get(kCGWindowName, ""), re.I): title = d[kCGWindowName] if self.check_bad_words(title): continue - self.number = d[kCGWindowNumber] - self.title = title + self.number = int(d[kCGWindowNumber]) + self.title = title; return self.title if self.number is None: return None @@ -63,11 +63,11 @@ class Table(Table_Window): WinListDict = CGWindowListCreateDescriptionFromArray(WinList) for d in WinListDict: - if d[CGWindowNumber] == self.number: - return {'x' : d[kCGWindowBounds][X], - 'y' : d[kCGWindowBounds][Y], - 'width' : d[kCGWindowBounds][Width], - 'height' : d[kCGWindowBounds][Height] + if d[kCGWindowNumber] == self.number: + return {'x' : int(d[kCGWindowBounds]['X']), + 'y' : int(d[kCGWindowBounds]['Y']), + 'width' : int(d[kCGWindowBounds]['Width']), + 'height' : int(d[kCGWindowBounds]['Height']) } return None @@ -86,5 +86,5 @@ class Table(Table_Window): # the hud window was a dialog belonging to the table. # This is the gdkhandle for the HUD window - gdkwindow = gtk.gdk.window_foreign_new(window.number) - gdkwindow.set_transient_for(self.gdkhandle) + gdkwindow = gtk.gdk.window_foreign_new(window.window.xid) + gdkwindow.set_transient_for(window.window) From d862cd6bd2b86e1dbda2e92e47b529279d9f18f6 Mon Sep 17 00:00:00 2001 From: Eratosthenes Date: Wed, 26 Jan 2011 17:12:47 -0500 Subject: [PATCH 013/182] Make executable. --- pyfpdb/Stats.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 pyfpdb/Stats.py diff --git a/pyfpdb/Stats.py b/pyfpdb/Stats.py old mode 100644 new mode 100755 From 5dc06c7ba7ac23752dfc0fe0d8d281d402670b12 Mon Sep 17 00:00:00 2001 From: Eratosthenes Date: Wed, 26 Jan 2011 21:45:12 -0500 Subject: [PATCH 014/182] Get correct hand# and max from HHs sent by user. --- pyfpdb/WinamaxToFpdb.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/pyfpdb/WinamaxToFpdb.py b/pyfpdb/WinamaxToFpdb.py index c6b49c4c..8fdab097 100644 --- a/pyfpdb/WinamaxToFpdb.py +++ b/pyfpdb/WinamaxToFpdb.py @@ -89,7 +89,7 @@ class Winamax(HandHistoryConverter): buyIn:\s(?P(?P[%(LS)s\d\,]+)?\s\+?\s(?P[%(LS)s\d\,]+)?\+?(?P[%(LS)s\d\.]+)?\s?(?P%(LEGAL_ISO)s)?|Gratuit|Ticket\suniquement)?\s (level:\s(?P\d+))? .*)? - \s-\sHandId:\s\#(?P\d+)-(?P\d+)-(?P\d+).*\s + \s-\sHandId:\s\#(?P\d+)-(?P\d+)-(?P\d+).*\s # REB says: HID3 is the correct hand number (?PHoldem|Omaha)\s (?Pno\slimit|pot\slimit)\s \( @@ -219,15 +219,19 @@ class Winamax(HandHistoryConverter): # TODO: Manually adjust time against OFFSET hand.startTime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S") # also timezone at end, e.g. " ET" hand.startTime = HandHistoryConverter.changeTimezone(hand.startTime, "CET", "UTC") - if key == 'HID1': - # Need to remove non-alphanumerics for MySQL - hand.handid = "1%.9d%s%s"%(int(info['HID2']),info['HID1'],info['HID3']) - if len (hand.handid) > 19: - hand.handid = "%s" % info['HID1'] +# if key == 'HID1': +# # Need to remove non-alphanumerics for MySQL +# hand.handid = "1%.9d%s%s"%(int(info['HID2']),info['HID1'],info['HID3']) +# if len (hand.handid) > 19: +# hand.handid = "%s" % info['HID1'] + if key == 'HID3': + hand.handid = int(info['HID3']) # correct hand no (REB) if key == 'TOURNO': hand.tourNo = info[key] if key == 'TABLE': hand.tablename = info[key] + if key == 'MAXPLAYER' and info[key] != None: + hand.maxseats = int(info[key]) if key == 'BUYIN': if hand.tourNo!=None: @@ -280,7 +284,7 @@ class Winamax(HandHistoryConverter): # TODO: These hand.buttonpos = 1 - hand.maxseats = 10 # Set to None - Hand.py will guessMaxSeats() +# hand.maxseats = 10 # Set to None - Hand.py will guessMaxSeats() hand.mixed = None def readPlayerStacks(self, hand): From de28aa7dc037f52a774ce7d14f0e30c3bf8cae36 Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 27 Jan 2011 12:12:27 +0800 Subject: [PATCH 015/182] FTP: Add 1k/2k limit to lookup. Also remove a noisy debug line --- pyfpdb/FulltiltToFpdb.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index 348338ba..4e9a4cc8 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -60,7 +60,8 @@ class Fulltilt(HandHistoryConverter): '400.00': ('100.00', '200.00'), '400': ('100.00', '200.00'), '500.00': ('125.00', '250.00'), '500': ('125.00', '250.00'), '800.00': ('200.00', '400.00'), '800': ('200.00', '400.00'), - '1000.00': ('250.00', '500.00'),'1000': ('250.00', '500.00') + '1000.00': ('250.00', '500.00'),'1000': ('250.00', '500.00'), + '2000.00': ('500.00', '1000.00'),'2000': ('500.00', '1000.00'), } # Static regexes @@ -351,7 +352,7 @@ class Fulltilt(HandHistoryConverter): n = self.re_SummarySitout.finditer(post) for b in n: del plist[b.group('PNAME')] - print "DEBUG: Deleting '%s' from player dict" %(b.group('PNAME')) + #print "DEBUG: Deleting '%s' from player dict" %(b.group('PNAME')) # Add remaining players for a in plist: From db3df7b42eed8ee303580c9b5fae618dc142c16e Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 27 Jan 2011 12:42:06 +0800 Subject: [PATCH 016/182] FTP: Make Summary split more careful This prevents the import from crashing on Run It Twice hand histories. --- pyfpdb/FulltiltToFpdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index 4e9a4cc8..a95eaf53 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -339,7 +339,7 @@ class Fulltilt(HandHistoryConverter): def readPlayerStacks(self, hand): # Split hand text for FTP, as the regex matches the player names incorrectly # in the summary section - pre, post = hand.handText.split('SUMMARY') + pre, post = hand.handText.split('*** SUMMARY ***') m = self.re_PlayerInfo.finditer(pre) plist = {} From 25d0c36022fb0d1c188bb3320f4d63058562bfea Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 27 Jan 2011 15:58:38 +0800 Subject: [PATCH 017/182] FTP: Add additional blind levels --- pyfpdb/FulltiltToFpdb.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index a95eaf53..6d037505 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -62,6 +62,10 @@ class Fulltilt(HandHistoryConverter): '800.00': ('200.00', '400.00'), '800': ('200.00', '400.00'), '1000.00': ('250.00', '500.00'),'1000': ('250.00', '500.00'), '2000.00': ('500.00', '1000.00'),'2000': ('500.00', '1000.00'), + '3000.00': ('750.00', '1500.00'),'3000': ('750.00', '1500.00'), + '4000.00': ('1000.00', '2000.00'),'4000': ('1000.00', '2000.00'), + '5000.00': ('1250.00', '2500.00'),'5000': ('1250.00', '2500.00'), + '6000.00': ('1500.00', '3000.00'),'6000': ('1500.00', '3000.00'), } # Static regexes @@ -198,11 +202,6 @@ class Fulltilt(HandHistoryConverter): ] def determineGameType(self, handText): - # Full Tilt Poker Game #10777181585: Table Deerfly (deep 6) - $0.01/$0.02 - Pot Limit Omaha Hi - 2:24:44 ET - 2009/02/22 - # Full Tilt Poker Game #10773265574: Table Butte (6 max) - $0.01/$0.02 - Pot Limit Hold'em - 21:33:46 ET - 2009/02/21 - # Full Tilt Poker Game #9403951181: Table CR - tay - $0.05/$0.10 - No Limit Hold'em - 9:40:20 ET - 2008/12/09 - # Full Tilt Poker Game #10809877615: Table Danville - $0.50/$1 Ante $0.10 - Limit Razz - 21:47:27 ET - 2009/02/23 - # Full Tilt Poker.fr Game #23057874034: Table Douai–Lens (6 max) - €0.01/€0.02 - No Limit Hold'em - 21:59:17 CET - 2010/08/13 info = {'type':'ring'} m = self.re_GameInfo.search(handText) @@ -244,12 +243,12 @@ class Fulltilt(HandHistoryConverter): if info['limitType'] == 'fl' and info['bb'] is not None and info['type'] == 'ring': try: - info['sb'] = self.Lim_Blinds[mg['BB']][0] - info['bb'] = self.Lim_Blinds[mg['BB']][1] + info['sb'] = self.Lim_Blinds[self.clearMoneyString(mg['BB'])][0] + info['bb'] = self.Lim_Blinds[self.clearMoneyString(mg['BB'])][1] except KeyError: - log.error(_("determineGameType: Lim_Blinds has no lookup for '%s'" % mg['BB'])) + log.error(_("determineGameType: Lim_Blinds has no lookup for '%s'" % self.clearMoneyString(mg['BB']))) log.error(_("determineGameType: Raising FpdbParseError")) - raise FpdbParseError(_("Lim_Blinds has no lookup for '%s'") % mg['BB']) + raise FpdbParseError(_("Lim_Blinds has no lookup for '%s'") % self.clearMoneyString(mg['BB'])) if mg['GAME'] is not None: (info['base'], info['category']) = games[mg['GAME']] From 841226e5448b6371efa6146715bbb0d7527df35d Mon Sep 17 00:00:00 2001 From: Eratosthenes Date: Thu, 27 Jan 2011 15:09:50 -0500 Subject: [PATCH 018/182] Implement getting button position in Winamax. --- pyfpdb/WinamaxToFpdb.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyfpdb/WinamaxToFpdb.py b/pyfpdb/WinamaxToFpdb.py index 8fdab097..2baf3558 100644 --- a/pyfpdb/WinamaxToFpdb.py +++ b/pyfpdb/WinamaxToFpdb.py @@ -282,9 +282,9 @@ class Winamax(HandHistoryConverter): if key == 'LEVEL': hand.level = info[key] - # TODO: These - hand.buttonpos = 1 -# hand.maxseats = 10 # Set to None - Hand.py will guessMaxSeats() + m = self.re_Button.search(hand.handText) + hand.buttonpos = m.groupdict().get('BUTTON', None) + hand.mixed = None def readPlayerStacks(self, hand): From 59c7985410546d9c1b96a55883e87530f30fad66 Mon Sep 17 00:00:00 2001 From: Eratosthenes Date: Thu, 27 Jan 2011 19:42:55 -0500 Subject: [PATCH 019/182] Add name attr to layout element in site element. --- pyfpdb/Configuration.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index a0ad4bad..a25b13eb 100644 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -231,6 +231,8 @@ class Layout: self.max = int( node.getAttribute('max') ) if node.hasAttribute('fav_seat'): self.fav_seat = int( node.getAttribute('fav_seat') ) + if node.hasAttribute('name'): self.name = node.getAttribute('name') + else: self.name = None self.width = int( node.getAttribute('width') ) self.height = int( node.getAttribute('height') ) @@ -244,7 +246,11 @@ class Layout: self.common = (int( location_node.getAttribute('x') ), int( location_node.getAttribute('y'))) def __str__(self): - temp = " Layout = %d max, width= %d, height = %d" % (self.max, self.width, self.height) + if hasattr(self, 'name'): + name = self.name + ", " + else: + name = "" + temp = " Layout = %s%d max, width= %d, height = %d" % (name, self.max, self.width, self.height) if hasattr(self, 'fav_seat'): temp = temp + ", fav_seat = %d\n" % self.fav_seat else: temp = temp + "\n" if hasattr(self, "common"): @@ -1485,7 +1491,7 @@ if __name__== "__main__": print "----------- END POPUP WINDOW FORMATS -----------" print "\n----------- IMPORT -----------" - print c.imp +# print c.imp # Need to add an str method for imp to print print "----------- END IMPORT -----------" c.edit_layout("PokerStars", 6, locations=( (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6) )) From e26abfeb71067caddb7dc9a917f15b9851952fbc Mon Sep 17 00:00:00 2001 From: Worros Date: Sat, 29 Jan 2011 03:17:55 +0800 Subject: [PATCH 020/182] FTP: Make re_SummarySitout ungreedy The line Seat 5: evv888 (button) is sitting out Was crashing as (button) was becoming part of the player name, Made the name match ungreedy, and allowed (button) as optional. --- pyfpdb/FulltiltToFpdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/FulltiltToFpdb.py b/pyfpdb/FulltiltToFpdb.py index 6d037505..56346673 100755 --- a/pyfpdb/FulltiltToFpdb.py +++ b/pyfpdb/FulltiltToFpdb.py @@ -105,7 +105,7 @@ class Fulltilt(HandHistoryConverter): ''' % substitutions, re.VERBOSE) re_Button = re.compile('^The button is in seat #(?P
[-\'\w\s]+)\s\[\d+\]\s\( ( - (?PNO_LIMIT|Limit|LIMIT|Pot\sLimit)\s + (?PNO_LIMIT|Limit|LIMIT|Pot\sLimit|POT_LIMIT)\s (?PTEXAS_HOLDEM|OMAHA_HI|SEVEN_CARD_STUD|SEVEN_CARD_STUD_HI_LO|RAZZ|FIVE_CARD_DRAW)\s (?P%(LS)s|)?(?P[.0-9]+)/ (%(LS)s)?(?P[.0-9]+) @@ -140,6 +140,7 @@ class OnGame(HandHistoryConverter): def readSupportedGames(self): return [ ["ring", "hold", "fl"], + ["ring", "hold", "pl"], ["ring", "hold", "nl"], ["ring", "stud", "fl"], ["ring", "draw", "fl"], @@ -158,6 +159,7 @@ class OnGame(HandHistoryConverter): raise FpdbParseError(_("Unable to recognise gametype from: '%s'") % tmp) mg = m.groupdict() + #print "DEBUG: mg: %s" % mg info['type'] = 'ring' if 'CURRENCY' in mg: From 3b2c30344a84e61091905c3d10ee494043c67bb4 Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 8 Feb 2011 11:25:32 +0800 Subject: [PATCH 076/182] Regression: PLO OnGame sample --- .../Flop/PLO-6max-EUR-1-1-2011002.Sample.txt | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 pyfpdb/regression-test-files/cash/OnGame/Flop/PLO-6max-EUR-1-1-2011002.Sample.txt diff --git a/pyfpdb/regression-test-files/cash/OnGame/Flop/PLO-6max-EUR-1-1-2011002.Sample.txt b/pyfpdb/regression-test-files/cash/OnGame/Flop/PLO-6max-EUR-1-1-2011002.Sample.txt new file mode 100644 index 00000000..b9a68bb4 --- /dev/null +++ b/pyfpdb/regression-test-files/cash/OnGame/Flop/PLO-6max-EUR-1-1-2011002.Sample.txt @@ -0,0 +1,44 @@ +***** History for hand R5-21973400-50 ***** +Start hand: Mon Feb 7 15:22:00 GMT+0100 2011 +Table: Oullins [21973414] (POT_LIMIT OMAHA_HI €1/€1, Real money) +User: Hero +Button: seat 7 +Players in round: 6 +Seat 8: Player8 (€89) +Seat 10: Hero (€100) +Seat 2: Player2 (€50) +Seat 3: Player3 (€93.50) +Seat 5: Player5 (€86.15) +Seat 7: Player7 (€149.40) +Player8 posts small blind (€0.50) +Hero posts big blind (€1) +--- +Dealing pocket cards +Dealing to Hero: [3c, 7c, 4c, 5h] +Player2 calls €1 +Player3 raises €4.50 to €4.50 +Player5 folds +Player7 calls €4.50 +Player8 calls €4 +Hero calls €3.50 +Player2 folds +--- Dealing flop [7s, 4d, 3h] +Player8 checks +Hero bets €12 +Player3 calls €12 +Player7 folds +Player8 folds +--- Dealing turn [6d] +Hero bets €21.50 +Player3 folds +--- +Summary: +Main pot: €43 won by Hero (€40.85) +Rake taken: €2.15 +Seat 8: Player8 (€84.50), net: -€4.50 +Seat 10: Hero (€124.35), net: +€24.35 +Seat 2: Player2 (€49), net: -€1 +Seat 3: Player3 (€77), net: -€16.50 +Seat 5: Player5 (€86.15) +Seat 7: Player7 (€144.90), net: -€4.50 +***** End of hand R5-21973414-50 ***** From f4729fb5f80197efea02467a35132a45d4d52f8e Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 8 Feb 2011 14:33:55 +0800 Subject: [PATCH 077/182] Database: Add Everest --- pyfpdb/Database.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index f4385835..ba643edd 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -1514,6 +1514,7 @@ class Database: c.execute("INSERT INTO Sites (name,code) VALUES ('PKR', 'PK')") c.execute("INSERT INTO Sites (name,code) VALUES ('iPoker', 'IP')") c.execute("INSERT INTO Sites (name,code) VALUES ('Winamax', 'WM')") + c.execute("INSERT INTO Sites (name,code) VALUES ('Everest', 'EP')") #Fill Actions c.execute("INSERT INTO Actions (name,code) VALUES ('ante', 'A')") c.execute("INSERT INTO Actions (name,code) VALUES ('small blind', 'SB')") From d4688633b3f4e2b046011d919654078a1d438400 Mon Sep 17 00:00:00 2001 From: Donoban Date: Thu, 3 Feb 2011 02:50:51 +0100 Subject: [PATCH 078/182] Database.py code rewroten line[X] replaced by line.append(), easy to read and mantain --- pyfpdb/Database.py | 181 +++++++++++++++++++++++---------------------- 1 file changed, 91 insertions(+), 90 deletions(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index ba643edd..ccad9b67 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -1938,99 +1938,100 @@ class Database: #print "DEBUG: %s %s %s" %(hid, pids, pdata) inserts = [] for p in pdata: - line = [0]*89 + #NOTE: Insert new stats at right place because SQL needs strict order + line = [] - line[0] = 1 # HDs - if pdata[p]['street0VPI']: line[1] = 1 - if pdata[p]['street0Aggr']: line[2] = 1 - if pdata[p]['street0_3BChance']: line[3] = 1 - if pdata[p]['street0_3BDone']: line[4] = 1 - if pdata[p]['street0_4BChance']: line[5] = 1 - if pdata[p]['street0_4BDone']: line[6] = 1 - if pdata[p]['street0_FoldTo3BChance']: line[7] = 1 - if pdata[p]['street0_FoldTo3BDone']: line[8] = 1 - if pdata[p]['street0_FoldTo4BChance']: line[9] = 1 - if pdata[p]['street0_FoldTo4BDone']: line[10] = 1 - if pdata[p]['other3BStreet0']: line[11] = 1 - if pdata[p]['other4BStreet0']: line[12] = 1 - if pdata[p]['street1Seen']: line[13] = 1 - if pdata[p]['street2Seen']: line[14] = 1 - if pdata[p]['street3Seen']: line[15] = 1 - if pdata[p]['street4Seen']: line[16] = 1 - if pdata[p]['sawShowdown']: line[17] = 1 - if pdata[p]['street1Aggr']: line[18] = 1 - if pdata[p]['street2Aggr']: line[19] = 1 - if pdata[p]['street3Aggr']: line[20] = 1 - if pdata[p]['street4Aggr']: line[21] = 1 - if pdata[p]['otherRaisedStreet0']: line[22] = 1 - if pdata[p]['otherRaisedStreet1']: line[23] = 1 - if pdata[p]['otherRaisedStreet2']: line[24] = 1 - if pdata[p]['otherRaisedStreet3']: line[25] = 1 - if pdata[p]['otherRaisedStreet4']: line[26] = 1 - if pdata[p]['foldToOtherRaisedStreet0']: line[27] = 1 - if pdata[p]['foldToOtherRaisedStreet1']: line[28] = 1 - if pdata[p]['foldToOtherRaisedStreet2']: line[29] = 1 - if pdata[p]['foldToOtherRaisedStreet3']: line[30] = 1 - if pdata[p]['foldToOtherRaisedStreet4']: line[31] = 1 - line[32] = pdata[p]['wonWhenSeenStreet1'] - line[33] = pdata[p]['wonWhenSeenStreet2'] - line[34] = pdata[p]['wonWhenSeenStreet3'] - line[35] = pdata[p]['wonWhenSeenStreet4'] - line[36] = pdata[p]['wonAtSD'] - if pdata[p]['raiseFirstInChance']: line[37] = 1 - if pdata[p]['raisedFirstIn']: line[38] = 1 - if pdata[p]['foldBbToStealChance']: line[39] = 1 - if pdata[p]['foldedBbToSteal']: line[40] = 1 - if pdata[p]['foldSbToStealChance']: line[41] = 1 - if pdata[p]['foldedSbToSteal']: line[42] = 1 - if pdata[p]['street1CBChance']: line[43] = 1 - if pdata[p]['street1CBDone']: line[44] = 1 - if pdata[p]['street2CBChance']: line[45] = 1 - if pdata[p]['street2CBDone']: line[46] = 1 - if pdata[p]['street3CBChance']: line[47] = 1 - if pdata[p]['street3CBDone']: line[48] = 1 - if pdata[p]['street4CBChance']: line[49] = 1 - if pdata[p]['street4CBDone']: line[50] = 1 - if pdata[p]['foldToStreet1CBChance']: line[51] = 1 - if pdata[p]['foldToStreet1CBDone']: line[52] = 1 - if pdata[p]['foldToStreet2CBChance']: line[53] = 1 - if pdata[p]['foldToStreet2CBDone']: line[54] = 1 - if pdata[p]['foldToStreet3CBChance']: line[55] = 1 - if pdata[p]['foldToStreet3CBDone']: line[56] = 1 - if pdata[p]['foldToStreet4CBChance']: line[57] = 1 - if pdata[p]['foldToStreet4CBDone']: line[58] = 1 - line[59] = pdata[p]['totalProfit'] - if pdata[p]['street1CheckCallRaiseChance']: line[60] = 1 - if pdata[p]['street1CheckCallRaiseDone']: line[61] = 1 - if pdata[p]['street2CheckCallRaiseChance']: line[62] = 1 - if pdata[p]['street2CheckCallRaiseDone']: line[63] = 1 - if pdata[p]['street3CheckCallRaiseChance']: line[64] = 1 - if pdata[p]['street3CheckCallRaiseDone']: line[65] = 1 - if pdata[p]['street4CheckCallRaiseChance']: line[66] = 1 - if pdata[p]['street4CheckCallRaiseDone']: line[67] = 1 - if pdata[p]['street0Calls']: line[68] = 1 - if pdata[p]['street1Calls']: line[69] = 1 - if pdata[p]['street2Calls']: line[70] = 1 - if pdata[p]['street3Calls']: line[71] = 1 - if pdata[p]['street4Calls']: line[72] = 1 - if pdata[p]['street0Bets']: line[73] = 1 - if pdata[p]['street1Bets']: line[74] = 1 - if pdata[p]['street2Bets']: line[75] = 1 - if pdata[p]['street3Bets']: line[76] = 1 - if pdata[p]['street4Bets']: line[77] = 1 - if pdata[p]['street0Raises']: line[78] = 1 - if pdata[p]['street1Raises']: line[79] = 1 - if pdata[p]['street2Raises']: line[80] = 1 - if pdata[p]['street3Raises']: line[81] = 1 - if pdata[p]['street4Raises']: line[82] = 1 + line.append(1) # HDs + line.append(pdata[p]['street0VPI']) + line.append(pdata[p]['street0Aggr']) + line.append(pdata[p]['street0_3BChance']) + line.append(pdata[p]['street0_3BDone']) + line.append(pdata[p]['street0_4BChance']) + line.append(pdata[p]['street0_4BDone']) + line.append(pdata[p]['street0_FoldTo3BChance']) + line.append(pdata[p]['street0_FoldTo3BDone']) + line.append(pdata[p]['street0_FoldTo4BChance']) + line.append(pdata[p]['street0_FoldTo4BDone']) + line.append(pdata[p]['other3BStreet0']) + line.append(pdata[p]['other4BStreet0']) + line.append(pdata[p]['street1Seen']) + line.append(pdata[p]['street2Seen']) + line.append(pdata[p]['street3Seen']) + line.append(pdata[p]['street4Seen']) + line.append(pdata[p]['sawShowdown']) + line.append(pdata[p]['street1Aggr']) + line.append(pdata[p]['street2Aggr']) + line.append(pdata[p]['street3Aggr']) + line.append(pdata[p]['street4Aggr']) + line.append(pdata[p]['otherRaisedStreet0']) + line.append(pdata[p]['otherRaisedStreet1']) + line.append(pdata[p]['otherRaisedStreet2']) + line.append(pdata[p]['otherRaisedStreet3']) + line.append(pdata[p]['otherRaisedStreet4']) + line.append(pdata[p]['foldToOtherRaisedStreet0']) + line.append(pdata[p]['foldToOtherRaisedStreet1']) + line.append(pdata[p]['foldToOtherRaisedStreet2']) + line.append(pdata[p]['foldToOtherRaisedStreet3']) + line.append(pdata[p]['foldToOtherRaisedStreet4']) + line.append(pdata[p]['wonWhenSeenStreet1']) + line.append(pdata[p]['wonWhenSeenStreet2']) + line.append(pdata[p]['wonWhenSeenStreet3']) + line.append(pdata[p]['wonWhenSeenStreet4']) + line.append(pdata[p]['wonAtSD']) + line.append(pdata[p]['raiseFirstInChance']) + line.append(pdata[p]['raisedFirstIn']) + line.append(pdata[p]['foldBbToStealChance']) + line.append(pdata[p]['foldedBbToSteal']) + line.append(pdata[p]['foldSbToStealChance']) + line.append(pdata[p]['foldedSbToSteal']) + line.append(pdata[p]['street1CBChance']) + line.append(pdata[p]['street1CBDone']) + line.append(pdata[p]['street2CBChance']) + line.append(pdata[p]['street2CBDone']) + line.append(pdata[p]['street3CBChance']) + line.append(pdata[p]['street3CBDone']) + line.append(pdata[p]['street4CBChance']) + line.append(pdata[p]['street4CBDone']) + line.append(pdata[p]['foldToStreet1CBChance']) + line.append(pdata[p]['foldToStreet1CBDone']) + line.append(pdata[p]['foldToStreet2CBChance']) + line.append(pdata[p]['foldToStreet2CBDone']) + line.append(pdata[p]['foldToStreet3CBChance']) + line.append(pdata[p]['foldToStreet3CBDone']) + line.append(pdata[p]['foldToStreet4CBChance']) + line.append(pdata[p]['foldToStreet4CBDone']) + line.append(pdata[p]['totalProfit']) + line.append(pdata[p]['street1CheckCallRaiseChance']) + line.append(pdata[p]['street1CheckCallRaiseDone']) + line.append(pdata[p]['street2CheckCallRaiseChance']) + line.append(pdata[p]['street2CheckCallRaiseDone']) + line.append(pdata[p]['street3CheckCallRaiseChance']) + line.append(pdata[p]['street3CheckCallRaiseDone']) + line.append(pdata[p]['street4CheckCallRaiseChance']) + line.append(pdata[p]['street4CheckCallRaiseDone']) + line.append(pdata[p]['street0Calls']) + line.append(pdata[p]['street1Calls']) + line.append(pdata[p]['street2Calls']) + line.append(pdata[p]['street3Calls']) + line.append(pdata[p]['street4Calls']) + line.append(pdata[p]['street0Bets']) + line.append(pdata[p]['street1Bets']) + line.append(pdata[p]['street2Bets']) + line.append(pdata[p]['street3Bets']) + line.append(pdata[p]['street4Bets']) + line.append(pdata[p]['street0Raises']) + line.append(pdata[p]['street1Raises']) + line.append(pdata[p]['street2Raises']) + line.append(pdata[p]['street3Raises']) + line.append(pdata[p]['street4Raises']) - line[83] = gid # gametypeId - line[84] = pids[p] # playerId - line[85] = len(pids) # activeSeats + line.append(gid) # gametypeId + line.append(pids[p]) # playerId + line.append(len(pids)) # activeSeats pos = {'B':'B', 'S':'S', 0:'D', 1:'C', 2:'M', 3:'M', 4:'M', 5:'E', 6:'E', 7:'E', 8:'E', 9:'E' } - line[86] = pos[pdata[p]['position']] - line[87] = pdata[p]['tourneyTypeId'] - line[88] = styleKey # styleKey + line.append(pos[pdata[p]['position']]) + line.append(pdata[p]['tourneyTypeId']) + line.append(styleKey) # styleKey inserts.append(line) From 674c9640edcd230b4d11c08f1039f59cadfe2b0f Mon Sep 17 00:00:00 2001 From: DoNoBaN Date: Tue, 8 Feb 2011 07:38:18 +0100 Subject: [PATCH 079/182] Fixed some wrong stats in Stats.py --- pyfpdb/Stats.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyfpdb/Stats.py b/pyfpdb/Stats.py index 9e475403..97d4aa8f 100755 --- a/pyfpdb/Stats.py +++ b/pyfpdb/Stats.py @@ -442,12 +442,12 @@ def three_B(stat_dict, player): """ Three bet preflop/3rd.""" stat = 0.0 try: - stat = float(stat_dict[player]['3b_0'])/float(stat_dict[player]['Tb_opp_0']) + stat = float(stat_dict[player]['Tb_0'])/float(stat_dict[player]['Tb_opp_0']) return (stat, '%3.1f' % (100.0*stat), '3B=%3.1f%%' % (100.0*stat), '3B_pf=%3.1f%%' % (100.0*stat), - '(%d/%d)' % (stat_dict[player]['3b_0'], stat_dict[player]['Tb_opp_0']), + '(%d/%d)' % (stat_dict[player]['Tb_0'], stat_dict[player]['Tb_opp_0']), _('% 4 Bet preflop/3rd')) except: return (stat, @@ -461,7 +461,7 @@ def four_B(stat_dict, player): """ Four bet preflop/4rd.""" stat = 0.0 try: - stat = float(stat_dict[player]['4b_0'])/float(stat_dict[player]['Fb_opp_0']) + stat = float(stat_dict[player]['Fb_0'])/float(stat_dict[player]['Fb_opp_0']) return (stat, '%3.1f' % (100.0*stat), '4B=%3.1f%%' % (100.0*stat), From 8d0d3ec20bdf3e85e2bfceacb3a2555dabf88595 Mon Sep 17 00:00:00 2001 From: DoNoBaN Date: Tue, 8 Feb 2011 08:45:57 +0100 Subject: [PATCH 080/182] Added Spanish translation .po and -mo files --- pyfpdb/locale/es/LC_MESSAGES/fpdb.mo | Bin 0 -> 5219 bytes pyfpdb/locale/fpdb-es_ES.po | 3646 ++++++++++++++++++++++++++ 2 files changed, 3646 insertions(+) create mode 100644 pyfpdb/locale/es/LC_MESSAGES/fpdb.mo create mode 100644 pyfpdb/locale/fpdb-es_ES.po diff --git a/pyfpdb/locale/es/LC_MESSAGES/fpdb.mo b/pyfpdb/locale/es/LC_MESSAGES/fpdb.mo new file mode 100644 index 0000000000000000000000000000000000000000..0e72f226bfe3a30a0e51f119eff402433bbabfd2 GIT binary patch literal 5219 zcmbW4O>87b6~_w{2r)^35JJ9y0vz!>o z^Pleec(303zgK_1eZy7HDLxPIcRPPKzF(e>Ki6KR)IB_22i^=WfS&-r0p1CE@Fwtu zX8f1ny*$4G-T+?x0i`|+-U@yUyrX$O4Stg61@Knz>&^QMAWPLV;P=4qfY*UHe^9B9 zfOmlMd=Du5E;R4g!E1T`CU`wK1ed_4!27}9fwJ#aS1a{3@ETD3OF((Q2Yv{A61*FH z7Mufr1fy|``5Er=H1@l=fE3zo&@Dw_klCu9LN$? zg0lZp;4R>H!H^$z$T&o|(d*xdvrUj;Y?eye%^iw55Smw5koP0{EK#q6a*j8_pMYAK+4pt6Wc^=2 zrmBB|;^%+BuYk8e7U7``EUPdwATiOM|XoV|3OgJKLyIZzXyf)Z-V!M z{{(LXTWlixE`tl;Iw<4Mfz#lhz-K@q*`2_%;Ag;}fefiXfO77)LCM!Upqx*VA^YA0 zO1?e?3XkptWqi589!QE*4a)qdL5b_PLCO0M!7qY80_A*v1u>!i0ZQE71wRemi18Wl zE^%VwjLCAF>dNVXt@I#weUt0lCA-r)t90gdQkSJIs(fGX*gVz!eSN~KiL=KOb!B#K z(G2LrPvVNgCKX$|U3K_U7p~IBBmKJKjkZrDc2s4qVBThB%1ZaTH4ZHgM~(-ry1l-u zt7*NGCARQ(TF<-DepU=rx6oO!XYwr73v+tUmY!X-EA=q*o(Z_t&#l)xX3y%r#mm%I z!K=0!H?d(&y5ClFb-vqJRrBZ8&McqRXO>qM_2S0HxeYb%itTKmw~3ehZcc}vn-8sI zmF-Ae=1XfTD;{jvB>wJg1s~Lc^+}nPH5@4LFx4B%U@Fhi?Nk>aj=WxjId zz8;xshg0fm$7)}XBqTQNc`SPEIZHV4b{JkS?Y1RZ2}2jMB6Sz^uq&=&O+0oZn> z)m166lZ)376hA! zUvOor)-m9%PIhdv%N$dM{Ke>aq65)kfsdT^QWKU%Zr7GlAQYu5 zh+t*Qj&9GKtutY6%tL#$uUm;8o7>tBoR!Qf7}7hWhOnd|z$IQ*S*t z`*@F~%Iir=sLmmEs`oN`VLFsBMK&7v$MY$*N#cZoVX~6%+BeXlOvkF^1PLZUeL1)I zl0pd0${h!(D4or!bXb4Hl!bWF(#uU{AFXQYTL}$i%F#fRSp4uB(rL9N`3(6N;z`q? zTJhAB8Ohzoja*Cfi5<=d%M3s+H>6flX^4^(SST-JAxi-^{e&i1$Ns{*g~L-xm9^DY zMiuvMbwS!qtS~S2ORYMJrlYptk^}(a_BO1qbD|t`r_Pi6kf%pXCP$PC>Wz1$o|GYB zr4iMop+BhJlFdh|*KE+B(9YF^9c?M$d}evIyRLdG4ozl2T2l)N73Rf)~O zdexJXS3O~d>TOEbJX%n>)J-WvV^$Di_po`GerQPKYwYd_Avb&2mfBO>S&>mHX*07gbVBV;te@Lz%}ZM0Op654^G?m4JlUE()tWu6XHR$TKKX_D#VzKw zHtb#|6mOuf?q}7+S6l1Oafa0@W9-d$ds5D}2)PE!OQ)akm)^6aAF7Y$r$cVc5~GNmy#baeHTC{iIKeRdg_1k%l# zAv(UpN)a_dk{!HKsKw#PUNoid3HKV>nK;x9;!u>$n(Yf=NxI6Ji}lt9r!6Wy&xZ%g*Yd@!6hJK`7|O zHNCi^yBqUM%MYK^3yV5xiSrxX`Q>wKs#_*IOcqZ#c&y}j95~R#!Ms;gaG5lnh(JVV z4;4jRyJV9c93b;XSM_C*g6quavSuK)d7~>bGK>R5Q#d+hAv0)DVXG@tMhw{=>@)8Jd+B;OiS!6z874M@cQG!BgbHycQWG+e| zni?o|tBHGgTA?9btn`c8@W*=csy_ z6@(7vLU`eq&T}(_kMa{E%orYAdc4jkDLQC34RHzWsHql;hg&t=TUYk5%XTNMO+Y11ost$F=FMinNk7xORhv5hw}=rL=Odpgg^?)#0t3`GB|1?0&9k$Q6vUEl<@@3 zV%CE`lBVi|Is#y(I07A*MQb1kb8sgFpSxBXz*c7AD{-i314qp@I8AK49n|aq`(l5U z=1)FQO2j*C!^K;`<*`Om`x@sZ8+b1E<*3c_NcCQ5(ndHKn{H%au0>R-UU$EySu_I5 zAgqpT!;sSK9sD#{9#>TJrX1iK2GLY{vUC*+2~F3u70yinym`zbtkw_vqv)!flIoqs z;dE^In7}%Uh$KF`t%J}K{\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Spanish\n" +"X-Poedit-Country: SPAIN\n" + +#: AbsoluteToFpdb.py:139 BetfairToFpdb.py:76 CarbonToFpdb.py:130 +#: EverleafToFpdb.py:110 FulltiltToFpdb.py:211 OnGameToFpdb.py:157 +#: PartyPokerToFpdb.py:197 PkrToFpdb.py:128 PokerStarsToFpdb.py:190 +#: Win2dayToFpdb.py:95 WinamaxToFpdb.py:172 iPokerToFpdb.py:122 +msgid "determineGameType: Unable to recognise gametype from: '%s'" +msgstr "" + +#: AbsoluteToFpdb.py:140 BetfairToFpdb.py:77 CarbonToFpdb.py:131 +#: EverleafToFpdb.py:111 FulltiltToFpdb.py:212 FulltiltToFpdb.py:251 +#: OnGameToFpdb.py:158 OnGameToFpdb.py:174 PartyPokerToFpdb.py:198 +#: PkrToFpdb.py:129 PkrToFpdb.py:154 PokerStarsToFpdb.py:191 +#: PokerStarsToFpdb.py:217 Win2dayToFpdb.py:96 WinamaxToFpdb.py:173 +#: WinamaxToFpdb.py:191 iPokerToFpdb.py:123 +msgid "determineGameType: Raising FpdbParseError" +msgstr "" + +#: AbsoluteToFpdb.py:141 BetfairToFpdb.py:78 CarbonToFpdb.py:132 +#: EverleafToFpdb.py:112 FulltiltToFpdb.py:213 OnGameToFpdb.py:159 +#: PartyPokerToFpdb.py:199 PkrToFpdb.py:130 PokerStarsToFpdb.py:192 +#: Win2dayToFpdb.py:97 WinamaxToFpdb.py:174 iPokerToFpdb.py:124 +msgid "Unable to recognise gametype from: '%s'" +msgstr "" + +#: AbsoluteToFpdb.py:204 +msgid "readHandInfo: Didn't match: '%s'" +msgstr "" + +#: AbsoluteToFpdb.py:205 +msgid "Absolute: Didn't match re_HandInfo: '%s'" +msgstr "" + +#: AbsoluteToFpdb.py:207 +msgid "readHandInfo: File name didn't match re_*InfoFromFilename" +msgstr "" + +#: AbsoluteToFpdb.py:208 +msgid "File name: %s" +msgstr "Nombre de archivo: %s" + +#: AbsoluteToFpdb.py:209 +msgid "Absolute: Didn't match re_*InfoFromFilename: '%s'" +msgstr "" + +#: AbsoluteToFpdb.py:278 EverleafToFpdb.py:218 FulltiltToFpdb.py:410 +#: OnGameToFpdb.py:292 PokerStarsToFpdb.py:355 Win2dayToFpdb.py:203 +#: WinamaxToFpdb.py:354 +msgid "reading antes" +msgstr "" + +#: AbsoluteToFpdb.py:290 EverleafToFpdb.py:230 +msgid "No bringin found." +msgstr "" + +#: AbsoluteToFpdb.py:297 EverleafToFpdb.py:237 +msgid "No small blind" +msgstr "" + +#: AbsoluteToFpdb.py:324 +msgid "Absolute readStudPlayerCards is only a stub." +msgstr "" + +#: AbsoluteToFpdb.py:401 BetfairToFpdb.py:222 CarbonToFpdb.py:298 +#: EverleafToFpdb.py:326 FulltiltToFpdb.py:778 PartyPokerToFpdb.py:566 +#: PokerStarsToFpdb.py:465 Win2dayToFpdb.py:368 iPokerToFpdb.py:291 +msgid "parse input hand history" +msgstr "" + +#: AbsoluteToFpdb.py:402 BetfairToFpdb.py:223 CarbonToFpdb.py:299 +#: EverleafToFpdb.py:327 FulltiltToFpdb.py:779 PartyPokerToFpdb.py:567 +#: PokerStarsToFpdb.py:466 Win2dayToFpdb.py:369 iPokerToFpdb.py:292 +msgid "output translation to" +msgstr "" + +#: AbsoluteToFpdb.py:403 BetfairToFpdb.py:224 CarbonToFpdb.py:300 +#: EverleafToFpdb.py:328 FulltiltToFpdb.py:780 PartyPokerToFpdb.py:568 +#: PokerStarsToFpdb.py:467 Win2dayToFpdb.py:370 iPokerToFpdb.py:293 +msgid "follow (tail -f) the input" +msgstr "" + +#: Anonymise.py:49 +msgid "Could not find file %s" +msgstr "" + +#: Anonymise.py:55 +msgid "Output being written to" +msgstr "" + +#: BetfairToFpdb.py:108 CarbonToFpdb.py:163 EverleafToFpdb.py:145 +#: iPokerToFpdb.py:156 iPokerToFpdb.py:158 +msgid "Didn't match re_HandInfo" +msgstr "" + +#: BetfairToFpdb.py:109 CarbonToFpdb.py:165 FulltiltToFpdb.py:266 +#: PokerStarsToFpdb.py:228 +msgid "No match in readHandInfo." +msgstr "" + +#: BetfairToFpdb.py:123 +msgid "readPlayerStacks: Less than 2 players found in a hand" +msgstr "" + +#: BetfairToFpdb.py:163 +msgid "No bringin found" +msgstr "" + +#: BetfairToFpdb.py:199 OnGameToFpdb.py:335 PokerStarsToFpdb.py:437 +#: WinamaxToFpdb.py:400 +msgid "DEBUG: unimplemented readAction: '%s' '%s'" +msgstr "" + +#: Card.py:431 +msgid "fpdb card encoding(same as pokersource)" +msgstr "" + +#: Charset.py:45 Charset.py:60 Charset.py:75 Charset.py:86 Charset.py:94 +msgid "Could not convert: \"%s\"\n" +msgstr "" + +#: Charset.py:48 Charset.py:63 Charset.py:78 +msgid "Could not encode: \"%s\"\n" +msgstr "" + +#: Configuration.py:109 Configuration.py:124 +msgid "Config file has been created at %s.\n" +msgstr "" + +#: Configuration.py:123 +msgid "" +"No %s found\n" +" in %s\n" +" or %s\n" +msgstr "" + +#: Configuration.py:128 Configuration.py:129 +msgid "Error copying .example config file, cannot fall back. Exiting.\n" +msgstr "" + +#: Configuration.py:133 Configuration.py:134 +msgid "No %s found, cannot fall back. Exiting.\n" +msgstr "" + +#: Configuration.py:166 +msgid "Default logger initialised for " +msgstr "" + +#: Configuration.py:167 +msgid "Default logger intialised for " +msgstr "" + +#: Configuration.py:178 Database.py:443 Database.py:444 +msgid "Creating directory: '%s'" +msgstr "" + +#: Configuration.py:204 +msgid "" +"Default encoding set to US-ASCII, defaulting to CP1252 instead -- If you're " +"not on a Mac, please report this problem." +msgstr "" + +#: Configuration.py:308 +msgid "Loading site" +msgstr "" + +#: Configuration.py:528 +msgid "config.general: adding %s = %s" +msgstr "" + +#: Configuration.py:575 Configuration.py:576 +msgid "bad number in xalignment was ignored" +msgstr "" + +#: Configuration.py:625 +msgid "missing config section raw_hands" +msgstr "" + +#: Configuration.py:631 +msgid "Invalid config value for raw_hands.save, defaulting to \"error\"" +msgstr "" + +#: Configuration.py:638 +msgid "Invalid config value for raw_hands.compression, defaulting to \"none\"" +msgstr "" + +#: Configuration.py:651 +msgid "missing config section raw_tourneys" +msgstr "" + +#: Configuration.py:657 +msgid "Invalid config value for raw_tourneys.save, defaulting to \"error\"" +msgstr "" + +#: Configuration.py:664 +msgid "" +"Invalid config value for raw_tourneys.compression, defaulting to \"none\"" +msgstr "" + +#: Configuration.py:682 Configuration.py:683 +msgid "Configuration file %s not found. Using defaults." +msgstr "" + +#: Configuration.py:713 +msgid "Reading configuration file %s" +msgstr "" + +#: Configuration.py:714 +msgid "" +"\n" +"Reading configuration file %s\n" +msgstr "" + +#: Configuration.py:720 +msgid "Error parsing %s. See error log file." +msgstr "" + +#: Configuration.py:836 +msgid "Error parsing example file %s. See error log file." +msgstr "" + +#: Database.py:65 +msgid "Not using sqlalchemy connection pool." +msgstr "" + +#: Database.py:72 +msgid "Not using numpy to define variance in sqlite." +msgstr "" + +#: Database.py:246 +msgid "Creating Database instance, sql = %s" +msgstr "" + +#: Database.py:394 +msgid "*** WARNING UNKNOWN MYSQL ERROR:" +msgstr "" + +#: Database.py:448 +msgid "Connecting to SQLite: %(database)s" +msgstr "" + +#: Database.py:460 +msgid "Some database functions will not work without NumPy support" +msgstr "" + +#: Database.py:490 +msgid "outdated or too new database version (%s) - please recreate tables" +msgstr "" + +#: Database.py:496 Database.py:497 +msgid "Failed to read settings table - recreating tables" +msgstr "" + +#: Database.py:501 Database.py:502 +msgid "Failed to read settings table - please recreate tables" +msgstr "" + +#: Database.py:523 +msgid "commit %s failed: info=%s value=%s" +msgstr "" + +#: Database.py:527 +msgid "commit failed" +msgstr "" + +#: Database.py:696 Database.py:729 +msgid "*** Database Error: " +msgstr "" + +#: Database.py:726 +msgid "Database: date n hands ago = " +msgstr "" + +#: Database.py:883 +msgid "ERROR: query %s result does not have player_id as first column" +msgstr "" + +#: Database.py:975 +msgid "getLastInsertId(): problem fetching insert_id? ret=%d" +msgstr "" + +#: Database.py:987 +msgid "getLastInsertId(%s): problem fetching lastval? row=%d" +msgstr "" + +#: Database.py:994 +msgid "getLastInsertId(): unknown backend: %d" +msgstr "" + +#: Database.py:999 +msgid "*** Database get_last_insert_id error: " +msgstr "" + +#: Database.py:1053 Database.py:1478 +msgid "warning: drop pg fk %s_%s_fkey failed: %s, continuing ..." +msgstr "" + +#: Database.py:1057 Database.py:1482 +msgid "warning: constraint %s_%s_fkey not dropped: %s, continuing ..." +msgstr "" + +#: Database.py:1065 Database.py:1356 +msgid "dropping mysql index " +msgstr "" + +#: Database.py:1071 Database.py:1361 Database.py:1369 Database.py:1376 +msgid " drop index failed: " +msgstr "" + +#: Database.py:1076 Database.py:1363 +msgid "dropping pg index " +msgstr "" + +#: Database.py:1089 +msgid "warning: drop index %s_%s_idx failed: %s, continuing ..." +msgstr "" + +#: Database.py:1093 +msgid "warning: index %s_%s_idx not dropped %s, continuing ..." +msgstr "" + +#: Database.py:1133 Database.py:1141 +msgid "Creating foreign key " +msgstr "" + +#: Database.py:1139 Database.py:1148 Database.py:1160 +msgid "Create foreign key failed: " +msgstr "" + +#: Database.py:1155 Database.py:1314 Database.py:1315 +msgid "Creating mysql index %s %s" +msgstr "" + +#: Database.py:1164 +msgid "Creating pg index " +msgstr "" + +#: Database.py:1169 Database.py:1320 Database.py:1329 Database.py:1337 +msgid "Create index failed: " +msgstr "" + +#: Database.py:1210 Database.py:1211 +msgid "Finished recreating tables" +msgstr "" + +#: Database.py:1252 +msgid "***Error creating tables: " +msgstr "" + +#: Database.py:1262 +msgid "*** Error unable to get databasecursor" +msgstr "" + +#: Database.py:1274 Database.py:1285 Database.py:1295 Database.py:1302 +msgid "***Error dropping tables: " +msgstr "" + +#: Database.py:1300 +msgid "*** Error in committing table drop" +msgstr "" + +#: Database.py:1323 Database.py:1324 +msgid "Creating pgsql index %s %s" +msgstr "" + +#: Database.py:1331 Database.py:1332 +msgid "Creating sqlite index %s %s" +msgstr "" + +#: Database.py:1339 +msgid "Unknown database: MySQL, Postgres and SQLite supported" +msgstr "" + +#: Database.py:1344 +msgid "Error creating indexes: " +msgstr "" + +#: Database.py:1371 +msgid "Dropping sqlite index " +msgstr "" + +#: Database.py:1378 +msgid "" +"Fpdb only supports MySQL, Postgres and SQLITE, what are you trying to use?" +msgstr "" + +#: Database.py:1392 Database.py:1432 +msgid " set_isolation_level failed: " +msgstr "" + +#: Database.py:1409 Database.py:1417 +msgid "creating foreign key " +msgstr "" + +#: Database.py:1415 +msgid " create foreign key failed: " +msgstr "" + +#: Database.py:1424 +msgid " create foreign key failed: " +msgstr "" + +#: Database.py:1426 Database.py:1485 +msgid "Only MySQL and Postgres supported so far" +msgstr "" + +#: Database.py:1456 +msgid "dropping mysql foreign key" +msgstr "" + +#: Database.py:1460 +msgid " drop failed: " +msgstr "" + +#: Database.py:1463 +msgid "dropping pg foreign key" +msgstr "" + +#: Database.py:1475 +msgid "dropped pg foreign key %s_%s_fkey, continuing ..." +msgstr "" + +#: Database.py:1596 +msgid "Rebuild hudcache took %.1f seconds" +msgstr "" + +#: Database.py:1599 Database.py:1637 +msgid "Error rebuilding hudcache:" +msgstr "" + +#: Database.py:1649 Database.py:1655 +msgid "Error during analyze:" +msgstr "" + +#: Database.py:1659 +msgid "Analyze took %.1f seconds" +msgstr "" + +#: Database.py:1669 Database.py:1675 +msgid "Error during vacuum:" +msgstr "" + +#: Database.py:1679 +msgid "Vacuum took %.1f seconds" +msgstr "" + +#: Database.py:1691 +msgid "Error during lock_for_insert:" +msgstr "" + +#: Database.py:1700 +msgid "######## Hands ##########" +msgstr "" + +#: Database.py:1704 +msgid "###### End Hands ########" +msgstr "" + +#: Database.py:2098 +msgid "Error aquiring hero ids:" +msgstr "" + +#: Database.py:2204 +msgid "######## Gametype ##########" +msgstr "" + +#: Database.py:2208 +msgid "###### End Gametype ########" +msgstr "" + +#: Database.py:2235 +msgid "queue empty too long - writer stopping ..." +msgstr "" + +#: Database.py:2238 +msgid "writer stopping, error reading queue: " +msgstr "" + +#: Database.py:2263 +msgid "deadlock detected - trying again ..." +msgstr "" + +#: Database.py:2268 +msgid "too many deadlocks - failed to store hand " +msgstr "" + +#: Database.py:2272 +msgid "***Error storing hand: " +msgstr "" + +#: Database.py:2282 +msgid "db writer finished: stored %d hands (%d fails) in %.1f seconds" +msgstr "" + +#: Database.py:2292 +msgid "***Error sending finish: " +msgstr "" + +#: Database.py:2374 +msgid "invalid source in Database.createOrUpdateTourney" +msgstr "" + +#: Database.py:2387 +msgid "invalid source in Database.createOrUpdateTourneysPlayers" +msgstr "" + +#: Database.py:2513 +msgid "HandToWrite.init error: " +msgstr "" + +#: Database.py:2563 +msgid "HandToWrite.set_all error: " +msgstr "" + +#: Database.py:2594 +msgid "nutOmatic is id_player = %d" +msgstr "" + +#: Database.py:2602 +msgid "query plan: " +msgstr "" + +#: Database.py:2611 +msgid "cards =" +msgstr "" + +#: Database.py:2614 +msgid "get_stats took: %4.3f seconds" +msgstr "" + +#: Database.py:2616 +msgid "press enter to continue" +msgstr "" + +#: EverleafToFpdb.py:265 +msgid "Everleaf readStudPlayerCards is only a stub." +msgstr "" + +#: Filters.py:53 +msgid "All" +msgstr "" + +#: Filters.py:53 +msgid "None" +msgstr "" + +#: Filters.py:53 +msgid "Show _Limits" +msgstr "" + +#: Filters.py:54 +msgid "Show Number of _Players" +msgstr "" + +#: Filters.py:54 TourneyFilters.py:51 +msgid "And:" +msgstr "" + +#: Filters.py:54 TourneyFilters.py:51 +msgid "Between:" +msgstr "" + +#: Filters.py:55 +msgid "Games:" +msgstr "" + +#: Filters.py:55 TourneyFilters.py:50 +msgid "Hero:" +msgstr "" + +#: Filters.py:55 TourneyFilters.py:50 +msgid "Sites:" +msgstr "" + +#: Filters.py:56 +msgid "Limits:" +msgstr "" + +#: Filters.py:56 TourneyFilters.py:50 +msgid "Number of Players:" +msgstr "" + +#: Filters.py:57 +msgid "Grouping:" +msgstr "" + +#: Filters.py:57 +msgid "Show Position Stats" +msgstr "" + +#: Filters.py:58 TourneyFilters.py:51 +msgid "Date:" +msgstr "" + +#: Filters.py:59 +msgid "All Players" +msgstr "" + +#: Filters.py:60 +msgid "Ring" +msgstr "" + +#: Filters.py:60 +msgid "Tourney" +msgstr "" + +#: Filters.py:96 TourneyFilters.py:107 +msgid "Either 0 or more than one site matched (%s) - EEK" +msgstr "" + +#: Filters.py:328 +msgid "%s was toggled %s" +msgstr "" + +#: Filters.py:328 +msgid "OFF" +msgstr "" + +#: Filters.py:328 +msgid "ON" +msgstr "" + +#: Filters.py:409 +msgid "self.sites[%s] set to %s" +msgstr "" + +#: Filters.py:415 +msgid "self.games[%s] set to %s" +msgstr "" + +#: Filters.py:421 +msgid "self.limit[%s] set to %s" +msgstr "" + +#: Filters.py:565 +msgid "self.seats[%s] set to %s" +msgstr "" + +#: Filters.py:571 +msgid "self.groups[%s] set to %s" +msgstr "" + +#: Filters.py:612 +msgid "Min # Hands:" +msgstr "" + +#: Filters.py:678 +msgid "INFO: No tourney types returned from database" +msgstr "" + +#: Filters.py:679 +msgid "No tourney types returned from database" +msgstr "" + +#: Filters.py:705 Filters.py:794 +msgid "INFO: No games returned from database" +msgstr "" + +#: Filters.py:706 Filters.py:795 +msgid "No games returned from database" +msgstr "" + +#: Filters.py:974 +msgid "From:" +msgstr "" + +#: Filters.py:988 +msgid "To:" +msgstr "" + +#: Filters.py:993 +msgid " Clear Dates " +msgstr "" + +#: Filters.py:1020 fpdb.pyw:720 +msgid "Pick a date" +msgstr "" + +#: Filters.py:1026 fpdb.pyw:726 +msgid "Done" +msgstr "Hecho" + +#: FullTiltPokerSummary.py:92 PokerStarsSummary.py:81 +msgid "parseSummary: Unable to recognise Tourney Info: '%s'" +msgstr "" + +#: FullTiltPokerSummary.py:93 FullTiltPokerSummary.py:119 +#: PokerStarsSummary.py:82 PokerStarsSummary.py:108 +msgid "parseSummary: Raising FpdbParseError" +msgstr "" + +#: FullTiltPokerSummary.py:94 PokerStarsSummary.py:83 +msgid "Unable to recognise Tourney Info: '%s'" +msgstr "" + +#: FullTiltPokerSummary.py:118 PokerStarsSummary.py:107 +msgid "parseSummary: Unable to locate currency" +msgstr "" + +#: FullTiltPokerSummary.py:120 PokerStarsSummary.py:109 +msgid "Unable to locate currency" +msgstr "" + +#: FulltiltToFpdb.py:252 PkrToFpdb.py:155 PokerStarsToFpdb.py:218 +msgid "Lim_Blinds has no lookup for '%s'" +msgstr "" + +#: FulltiltToFpdb.py:265 +msgid "readHandInfo: Unable to recognise handinfo from: '%s'" +msgstr "" + +#: FulltiltToFpdb.py:420 +msgid "Player bringing in: %s for %s" +msgstr "" + +#: FulltiltToFpdb.py:423 +msgid "No bringin found, handid =%s" +msgstr "" + +#: FulltiltToFpdb.py:430 +msgid "FTP: readButton: Failed to detect button (hand #%s cancelled?)" +msgstr "" + +#: FulltiltToFpdb.py:484 +msgid "FullTilt: DEBUG: unimplemented readAction: '%s' '%s'" +msgstr "" + +#: FulltiltToFpdb.py:560 +msgid "determineTourneyType : Parsing NOK" +msgstr "" + +#: FulltiltToFpdb.py:618 +msgid "Unable to get a valid Tournament ID -- File rejected" +msgstr "" + +#: FulltiltToFpdb.py:649 +msgid "Conflict between buyins read in topline (%s) and in BuyIn field (%s)" +msgstr "" + +#: FulltiltToFpdb.py:656 +msgid "Conflict between fees read in topline (%s) and in BuyIn field (%s)" +msgstr "" + +#: FulltiltToFpdb.py:660 +msgid "Unable to affect a buyin to this tournament : assume it's a freeroll" +msgstr "" + +#: FulltiltToFpdb.py:761 +msgid "FullTilt: Player finishing stats unreadable : %s" +msgstr "" + +#: FulltiltToFpdb.py:770 +msgid "FullTilt: %s not found in tourney.ranks ..." +msgstr "" + +#: FulltiltToFpdb.py:772 +msgid "FullTilt: Bad parsing : finish position incoherent : %s / %s" +msgstr "" + +#: GuiAutoImport.py:90 +msgid "Time between imports in seconds:" +msgstr "Tiempo entre importaciones en segundos:" + +#: GuiAutoImport.py:121 GuiAutoImport.py:189 GuiAutoImport.py:274 +msgid " Start _Auto Import " +msgstr "Empezar _auto importación" + +#: GuiAutoImport.py:140 +msgid "Auto Import Ready." +msgstr "Auto importación preparada." + +#: GuiAutoImport.py:153 +msgid "Please choose the path that you want to Auto Import" +msgstr "" + +#: GuiAutoImport.py:176 +msgid " _Auto Import Running " +msgstr "" + +#: GuiAutoImport.py:187 +msgid " Stop _Auto Import " +msgstr "" + +#: GuiAutoImport.py:213 +msgid "" +"\n" +"Global lock taken ... Auto Import Started.\n" +msgstr "" + +#: GuiAutoImport.py:215 +msgid " _Stop Auto Import " +msgstr "" + +#: GuiAutoImport.py:235 +msgid "opening pipe to HUD" +msgstr "abriendo tubería hacia el HUD" + +#: GuiAutoImport.py:249 +msgid "" +"\n" +"*** GuiAutoImport Error opening pipe: " +msgstr "" + +#: GuiAutoImport.py:261 +msgid "" +"\n" +"Auto Import aborted - global lock not available" +msgstr "" + +#: GuiAutoImport.py:266 +msgid "" +"\n" +"Stopping Auto Import - global lock released." +msgstr "" + +#: GuiAutoImport.py:268 +msgid "" +"\n" +" * Stop Auto Import: HUD already terminated" +msgstr "" + +#: GuiAutoImport.py:296 +msgid "Browse..." +msgstr "" + +#: GuiBulkImport.py:59 +msgid "" +"\n" +"Global lock taken ..." +msgstr "" + +#: GuiBulkImport.py:60 +msgid "Importing..." +msgstr "Importando..." + +#: GuiBulkImport.py:113 +msgid "" +"GuiBulkImport.load done: Stored: %d \tDuplicates: %d \tPartial: %d \tErrors: " +"%d in %s seconds - %.0f/sec" +msgstr "" + +#: GuiBulkImport.py:127 +msgid "Import Complete" +msgstr "Importación completada" + +#: GuiBulkImport.py:135 GuiTourneyImport.py:78 +msgid "bulk import aborted - global lock not available" +msgstr "importación masiva abortada - reloj global no disponible" + +#: GuiBulkImport.py:163 +msgid "Print Start/Stop Info" +msgstr "" + +#: GuiBulkImport.py:170 +msgid "Hands/status print:" +msgstr "" + +#: GuiBulkImport.py:187 +msgid "Number of threads:" +msgstr "Número de hilos:" + +#: GuiBulkImport.py:207 +msgid "Archive File" +msgstr "" + +#: GuiBulkImport.py:212 +msgid "Hands/file:" +msgstr "Manos/archivo:" + +#: GuiBulkImport.py:227 +msgid "Drop indexes:" +msgstr "" + +#: GuiBulkImport.py:236 GuiBulkImport.py:286 +msgid "auto" +msgstr "auto" + +#: GuiBulkImport.py:237 GuiBulkImport.py:287 GuiBulkImport.py:395 +msgid "don't drop" +msgstr "" + +#: GuiBulkImport.py:238 GuiBulkImport.py:288 +msgid "drop" +msgstr "" + +#: GuiBulkImport.py:244 +msgid "HUD Test mode" +msgstr "HUD en modo de prueba" + +#: GuiBulkImport.py:249 GuiTourneyImport.py:106 +msgid "Site filter:" +msgstr "" + +#: GuiBulkImport.py:277 +msgid "Drop HudCache:" +msgstr "" + +#: GuiBulkImport.py:295 GuiTourneyImport.py:135 fpdb.pyw:815 +msgid "_Bulk Import" +msgstr "Importación _masiva" + +#: GuiBulkImport.py:297 GuiTourneyImport.py:137 +msgid "Import clicked" +msgstr "" + +#: GuiBulkImport.py:315 +msgid "Waiting..." +msgstr "Esperando..." + +#: GuiBulkImport.py:344 Options.py:58 +msgid "Input file in quiet mode" +msgstr "" + +#: GuiBulkImport.py:346 +msgid "don't start gui; deprecated (just give a filename with -f)." +msgstr "" + +#: GuiBulkImport.py:348 +msgid "Conversion filter (*Full Tilt Poker, PokerStars, Everleaf, Absolute)" +msgstr "" + +#: GuiBulkImport.py:350 +msgid "If this option is passed it quits when it encounters any error" +msgstr "" + +#: GuiBulkImport.py:352 Options.py:55 +msgid "Print some useful one liners" +msgstr "" + +#: GuiBulkImport.py:354 +msgid "" +"Do the required conversion for Stars Archive format (ie. as provided by " +"support" +msgstr "" + +#: GuiBulkImport.py:356 +msgid "" +"Do the required conversion for FTP Archive format (ie. as provided by support" +msgstr "" + +#: GuiBulkImport.py:358 +msgid "" +"Output the pprinted version of the HandsPlayer hash for regresion testing" +msgstr "" + +#: GuiBulkImport.py:363 GuiTourneyImport.py:267 ImapFetcher.py:172 +msgid "USAGE:" +msgstr "" + +#: GuiBulkImport.py:364 +msgid "PokerStars converter: ./GuiBulkImport.py -c PokerStars -f filename" +msgstr "" +"Convertertidor de PokerStars : ./GuiBulkImport.py -c PokerStars -f filename" + +#: GuiBulkImport.py:365 +msgid "" +"Full Tilt converter: ./GuiBulkImport.py -c \"Full Tilt Poker\" -f filename" +msgstr "" + +#: GuiBulkImport.py:366 +msgid "Everleaf converter: ./GuiBulkImport.py -c Everleaf -f filename" +msgstr "" + +#: GuiBulkImport.py:367 +msgid "Absolute converter: ./GuiBulkImport.py -c Absolute -f filename" +msgstr "" + +#: GuiBulkImport.py:368 +msgid "PartyPoker converter: ./GuiBulkImport.py -c PartyPoker -f filename" +msgstr "" + +#: GuiBulkImport.py:382 +msgid "-q is deprecated. Just use \"-f filename\" instead" +msgstr "" + +#: GuiBulkImport.py:408 +msgid "" +"GuiBulkImport done: Stored: %d \tDuplicates: %d \tPartial: %d \tErrors: %d " +"in %s seconds - %.0f/sec" +msgstr "" + +#: GuiDatabase.py:107 +msgid "_Add" +msgstr "" + +#: GuiDatabase.py:111 +msgid "_Refresh" +msgstr "" + +#: GuiDatabase.py:115 +msgid "Type" +msgstr "" + +#: GuiDatabase.py:116 +msgid "Name" +msgstr "Nombre" + +#: GuiDatabase.py:117 +msgid "Description" +msgstr "Descripción" + +#: GuiDatabase.py:118 GuiDatabase.py:448 GuiImapFetcher.py:110 +msgid "Username" +msgstr "Nombre de usuario" + +#: GuiDatabase.py:119 GuiDatabase.py:455 GuiImapFetcher.py:110 +msgid "Password" +msgstr "Contraseña" + +#: GuiDatabase.py:120 +msgid "Host" +msgstr "" + +#: GuiDatabase.py:121 +msgid "Open" +msgstr "Abrir" + +#: GuiDatabase.py:122 +msgid "Status" +msgstr "Estado" + +#: GuiDatabase.py:256 +msgid "Testing database connections ... " +msgstr "Comprobando conexiones a la base de datos..." + +#: GuiDatabase.py:283 +msgid "finished." +msgstr "Completado." + +#: GuiDatabase.py:293 +msgid "loadDbs error: " +msgstr "" + +#: GuiDatabase.py:314 GuiLogView.py:191 GuiTourneyPlayerStats.py:457 +msgid "***sortCols error: " +msgstr "" + +#: GuiDatabase.py:316 +msgid "sortCols error: " +msgstr "" + +#: GuiDatabase.py:361 +msgid "testDB: trying to connect to: %s/%s, %s, %s/%s" +msgstr "testDB: intentando conectar a: %s/%s, %s, %s/%s" + +#: GuiDatabase.py:364 +msgid " connected ok" +msgstr " conectado bien" + +#: GuiDatabase.py:371 +msgid " not connected but no exception" +msgstr " no conectado pero sin excepción" + +#: GuiDatabase.py:373 fpdb.pyw:891 +msgid "" +"MySQL Server reports: Access denied. Are your permissions set correctly?" +msgstr "" +"MySQL Server dice: Acceso denegado. ¿Estan tus permisos bien configurados?" + +#: GuiDatabase.py:377 fpdb.pyw:893 +msgid "MySQL client reports: 2002 or 2003 error. Unable to connect - " +msgstr "MySQL client dice: error 2002 o 2003. Incapaz de conectar -" + +#: GuiDatabase.py:378 fpdb.pyw:894 +msgid "Please check that the MySQL service has been started" +msgstr "Por favor, compruebe que el servicio MySQL ha sido iniciado" + +#: GuiDatabase.py:382 fpdb.pyw:896 +msgid "" +"PostgreSQL Server reports: Access denied. Are your permissions set correctly?" +msgstr "" + +#: GuiDatabase.py:385 fpdb.pyw:898 +msgid "PostgreSQL client reports: Unable to connect - " +msgstr "" + +#: GuiDatabase.py:386 fpdb.pyw:899 +msgid "Please check that the PostgreSQL service has been started" +msgstr "" + +#: GuiDatabase.py:396 +msgid "db connection to %s, %s, %s, %s, %s failed: %s" +msgstr "" + +#: GuiDatabase.py:404 +msgid "AddDB starting" +msgstr "" + +#: GuiDatabase.py:413 +msgid "Add New Database" +msgstr "" + +#: GuiDatabase.py:423 +msgid "DB Type" +msgstr "" + +#: GuiDatabase.py:433 +msgid "DB Name" +msgstr "" + +#: GuiDatabase.py:441 +msgid "DB Description" +msgstr "" + +#: GuiDatabase.py:462 +msgid "Host Computer" +msgstr "" + +#: GuiDatabase.py:495 +msgid "start creating new db" +msgstr "" + +#: GuiDatabase.py:514 +msgid "tested new db, result=%s" +msgstr "" + +#: GuiDatabase.py:517 +msgid "Database created" +msgstr "" + +#: GuiDatabase.py:520 +msgid "Database creation failed" +msgstr "" + +#: GuiDatabase.py:533 +msgid "check_fields: starting" +msgstr "" + +#: GuiDatabase.py:539 +msgid "No Database Name given" +msgstr "" + +#: GuiDatabase.py:542 +msgid "No Database Description given" +msgstr "" + +#: GuiDatabase.py:545 +msgid "No Username given" +msgstr "" + +#: GuiDatabase.py:548 +msgid "No Password given" +msgstr "" + +#: GuiDatabase.py:551 +msgid "No Host given" +msgstr "" + +#: GuiDatabase.py:565 +msgid "Unknown Database Type selected" +msgstr "" + +#: GuiDatabase.py:569 +msgid "check_fields: open dialog" +msgstr "" + +#: GuiDatabase.py:578 +msgid "Do you want to try again?" +msgstr "" + +#: GuiDatabase.py:585 +msgid "check_fields: destroy dialog" +msgstr "" + +#: GuiDatabase.py:589 +msgid "check_fields: returning ok as %s, try_again as %s" +msgstr "" + +#: GuiDatabase.py:691 GuiLogView.py:204 +msgid "Test Log Viewer" +msgstr "" + +#: GuiDatabase.py:696 GuiLogView.py:209 +msgid "Log Viewer" +msgstr "" + +#: GuiGraphViewer.py:49 GuiTourneyGraphViewer.py:49 +msgid "" +"Failed to load libs for graphing, graphing will not function. Please\n" +" install numpy and matplotlib if you want to use graphs." +msgstr "" + +#: GuiGraphViewer.py:51 GuiTourneyGraphViewer.py:51 +msgid "" +"This is of no consequence for other parts of the program, e.g. import \n" +" and HUD are NOT affected by this problem." +msgstr "" + +#: GuiGraphViewer.py:85 GuiTourneyGraphViewer.py:84 +msgid "Refresh _Graph" +msgstr "" + +#: GuiGraphViewer.py:87 GuiTourneyGraphViewer.py:86 +msgid "_Export to File" +msgstr "" + +#: GuiGraphViewer.py:135 GuiGraphViewer.py:251 GuiSessionViewer.py:372 +#: GuiTourneyGraphViewer.py:134 GuiTourneyGraphViewer.py:232 +msgid "***Error: " +msgstr "" + +#: GuiGraphViewer.py:168 GuiPositionalStats.py:168 GuiRingPlayerStats.py:267 +#: GuiSessionViewer.py:212 GuiTourneyGraphViewer.py:159 +#: GuiTourneyPlayerStats.py:268 +msgid "No sites selected - defaulting to PokerStars" +msgstr "" + +#: GuiGraphViewer.py:173 GuiPositionalStats.py:171 GuiRingPlayerStats.py:270 +#: GuiSessionViewer.py:215 GuiTourneyGraphViewer.py:164 +#: GuiTourneyPlayerStats.py:271 +msgid "No player ids found" +msgstr "" + +#: GuiGraphViewer.py:178 GuiPositionalStats.py:174 GuiRingPlayerStats.py:273 +#: GuiSessionViewer.py:218 +msgid "No limits found" +msgstr "" + +#: GuiGraphViewer.py:188 GuiTourneyGraphViewer.py:174 +msgid "Graph generated in: %s" +msgstr "" + +#: GuiGraphViewer.py:193 +msgid "Hands" +msgstr "" + +#: GuiGraphViewer.py:198 GuiTourneyGraphViewer.py:182 +msgid "No Data for Player(s) Found" +msgstr "" + +#: GuiGraphViewer.py:221 +msgid "" +"Hands: %d\n" +"Profit: $%.2f" +msgstr "" + +#: GuiGraphViewer.py:222 +msgid "Showdown: $%.2f" +msgstr "" + +#: GuiGraphViewer.py:223 +msgid "Non-showdown: $%.2f" +msgstr "" + +#: GuiGraphViewer.py:234 +msgid "" +"Hands: %d\n" +"Profit (%s): %.2f" +msgstr "" + +#: GuiGraphViewer.py:236 +msgid "Showdown (%s): %.2f" +msgstr "" + +#: GuiGraphViewer.py:238 +msgid "Non-showdown (%s): %.2f" +msgstr "" + +#: GuiGraphViewer.py:356 GuiTourneyGraphViewer.py:276 +msgid "Please choose the directory you wish to export to:" +msgstr "" + +#: GuiGraphViewer.py:369 GuiTourneyGraphViewer.py:289 +msgid "Closed, no graph exported" +msgstr "" + +#: GuiGraphViewer.py:387 GuiTourneyGraphViewer.py:307 +msgid "Graph created" +msgstr "" + +#: GuiImapFetcher.py:40 +msgid "To cancel just close this tab." +msgstr "" + +#: GuiImapFetcher.py:43 +msgid "_Save" +msgstr "" + +#: GuiImapFetcher.py:47 +msgid "_Import All" +msgstr "" + +#: GuiImapFetcher.py:51 +msgid "If you change the config you must save before importing" +msgstr "" + +#: GuiImapFetcher.py:89 +msgid "Starting import. Please wait." +msgstr "" + +#: GuiImapFetcher.py:94 +msgid "Finished import without error." +msgstr "" + +#: GuiImapFetcher.py:97 +msgid "" +"Login to mailserver failed: please check mailserver, username and password" +msgstr "" + +#: GuiImapFetcher.py:100 +msgid "" +"Could not connect to mailserver: check mailserver and use SSL settings and " +"internet connectivity" +msgstr "" + +#: GuiImapFetcher.py:110 +msgid "Fetch Type" +msgstr "" + +#: GuiImapFetcher.py:110 +msgid "Mail Folder" +msgstr "" + +#: GuiImapFetcher.py:110 +msgid "Mailserver" +msgstr "" + +#: GuiImapFetcher.py:110 +msgid "Site" +msgstr "" + +#: GuiImapFetcher.py:110 +msgid "Use SSL" +msgstr "" + +#: GuiImapFetcher.py:142 +msgid "Yes" +msgstr "" + +#: GuiImapFetcher.py:143 +msgid "No" +msgstr "" + +#: GuiLogView.py:52 +msgid "Log Messages" +msgstr "" + +#: GuiLogView.py:87 +msgid "Refresh" +msgstr "" + +#: GuiPositionalStats.py:137 +msgid "DEBUG: activesite set to %s" +msgstr "" + +#: GuiPositionalStats.py:323 +msgid "Positional Stats page displayed in %4.2f seconds" +msgstr "" + +#: GuiPrefs.py:72 +msgid "Setting" +msgstr "" + +#: GuiPrefs.py:78 +msgid "Value (double-click to change)" +msgstr "" + +#: GuiPrefs.py:178 +msgid "Test Preferences Dialog" +msgstr "" + +#: GuiPrefs.py:183 fpdb.pyw:294 +msgid "Preferences" +msgstr "" + +#: GuiRingPlayerStats.py:44 +msgid "Type of Game" +msgstr "" + +#: GuiRingPlayerStats.py:45 +msgid "Hole cards" +msgstr "" + +#: GuiRingPlayerStats.py:46 +msgid "Position" +msgstr "" + +#: GuiRingPlayerStats.py:47 +msgid "Name of the player" +msgstr "" + +#: GuiRingPlayerStats.py:48 +msgid "Number of hands played" +msgstr "" + +#: GuiRingPlayerStats.py:49 +msgid "Number of Seats" +msgstr "" + +#: GuiRingPlayerStats.py:50 +msgid "" +"Voluntarily Putting In the pot\n" +"(blinds excluded)" +msgstr "" + +#: GuiRingPlayerStats.py:51 +msgid "% Pre Flop Raise" +msgstr "" + +#: GuiRingPlayerStats.py:52 +msgid "% Pre Flop Re-Raise / 3Bet" +msgstr "" + +#: GuiRingPlayerStats.py:53 +msgid "Aggression Factor\n" +msgstr "" + +#: GuiRingPlayerStats.py:54 +msgid "" +"Aggression Frequency\n" +"Bet or Raise vs Fold" +msgstr "" + +#: GuiRingPlayerStats.py:55 +msgid "Continuation Bet post-flop" +msgstr "" + +#: GuiRingPlayerStats.py:56 +msgid "% Raise First In\\% Raise when first to bet" +msgstr "" + +#: GuiRingPlayerStats.py:57 +msgid "" +"% First to raise pre-flop\n" +"and steal blinds" +msgstr "" + +#: GuiRingPlayerStats.py:58 +msgid "% Saw Flop vs hands dealt" +msgstr "" + +#: GuiRingPlayerStats.py:59 +msgid "Saw Show Down / River" +msgstr "" + +#: GuiRingPlayerStats.py:60 +msgid "Went To Show Down When Saw Flop" +msgstr "" + +#: GuiRingPlayerStats.py:61 +msgid "% Won some money at showdown" +msgstr "" + +#: GuiRingPlayerStats.py:62 +msgid "" +"Flop Aggression\n" +"% Bet or Raise after seeing Flop" +msgstr "" + +#: GuiRingPlayerStats.py:63 +msgid "" +"Turn Aggression\n" +"% Bet or Raise after seeing Turn" +msgstr "" + +#: GuiRingPlayerStats.py:64 +msgid "" +"River Aggression\n" +"% Bet or Raise after seeing River" +msgstr "" + +#: GuiRingPlayerStats.py:65 +msgid "" +"Coming Soon\n" +"Total % agression" +msgstr "" + +#: GuiRingPlayerStats.py:66 +msgid "Amount won" +msgstr "" + +#: GuiRingPlayerStats.py:67 +msgid "" +"Number of Big Blinds won\n" +"or lost per 100 hands" +msgstr "" + +#: GuiRingPlayerStats.py:68 +msgid "Amount of rake paid" +msgstr "" + +#: GuiRingPlayerStats.py:69 +msgid "" +"Number of Big Blinds won\n" +"or lost per 100 hands\n" +"when excluding rake" +msgstr "" + +#: GuiRingPlayerStats.py:70 +msgid "" +"Measure of uncertainty\n" +"The lower, the more stable the amounts won" +msgstr "" + +#: GuiRingPlayerStats.py:338 GuiSessionViewer.py:257 +#: GuiTourneyPlayerStats.py:243 +msgid "Stats page displayed in %4.2f seconds" +msgstr "" + +#: GuiRingPlayerStats.py:385 +msgid "***sortnums error: " +msgstr "" + +#: GuiRingPlayerStats.py:407 +msgid "***sortcols error: " +msgstr "" + +#: GuiRingPlayerStats.py:703 +msgid "Detailed Filters" +msgstr "" + +#: GuiRingPlayerStats.py:712 +msgid "Hand Filters:" +msgstr "" + +#: GuiRingPlayerStats.py:725 +msgid "between" +msgstr "" + +#: GuiRingPlayerStats.py:726 +msgid "and" +msgstr "" + +#: GuiSessionViewer.py:42 +msgid "Failed to load numpy and/or matplotlib in Session Viewer" +msgstr "" + +#: GuiSessionViewer.py:43 +msgid "ImportError: %s" +msgstr "" + +#: GuiSessionViewer.py:81 +msgid "Hand Breakdown for all levels listed above" +msgstr "" + +#: GuiSessionViewer.py:158 +msgid "Session Viewer is proof of concept code only, and contains many bugs.\n" +msgstr "" + +#: GuiSessionViewer.py:159 +msgid "" +"Feel free to use the viewer, but there is no guarantee that the data is " +"accurate.\n" +msgstr "" + +#: GuiSessionViewer.py:160 +msgid "" +"If you are interested in developing the code further please contact us via " +"the usual channels.\n" +msgstr "" + +#: GuiSessionViewer.py:161 +msgid "Thankyou" +msgstr "" + +#: GuiSessionViewer.py:164 GuiStove.py:70 fpdb.pyw:1286 +msgid "FPDB WARNING" +msgstr "" + +#: GuiSessionViewer.py:393 +msgid "Session candlestick graph" +msgstr "" + +#: GuiSessionViewer.py:396 +msgid "Sessions" +msgstr "" + +#: GuiStove.py:63 +msgid "" +"Stove is a GUI mockup of a EV calculation page, and completely non " +"functional.\n" +msgstr "" + +#: GuiStove.py:64 +msgid "" +"Unless you are interested in developing this feature, please ignore this " +"page.\n" +msgstr "" + +#: GuiStove.py:65 +msgid "" +"If you are interested in developing the code further see GuiStove.py and " +"Stove.py\n" +msgstr "" + +#: GuiStove.py:66 +msgid "Thank you" +msgstr "" + +#: GuiTourneyGraphViewer.py:178 +msgid "Tournaments" +msgstr "" + +#: GuiTourneyGraphViewer.py:205 GuiTourneyGraphViewer.py:218 +msgid "" +"Tournaments: %d\n" +"Profit: $%.2f" +msgstr "" + +#: GuiTourneyGraphViewer.py:215 +msgid "Tournament Results" +msgstr "" + +#: GuiTourneyImport.py:72 GuiTourneyImport.py:290 +msgid "" +"GuiTourneyImport.load done: Stored: %d\tErrors: %d in %s seconds - %.0f/sec" +msgstr "" + +#: GuiTourneyImport.py:175 fpdb_import.py:223 +msgid "Attempted to add non-directory '%s' as an import directory" +msgstr "" + +#: GuiTourneyImport.py:191 +msgid "Tourney Summary Import started at %s - %d files to import." +msgstr "" + +#: GuiTourneyImport.py:217 +msgid "TourneyImport: Removing text < 100 characters from end of file" +msgstr "" + +#: GuiTourneyImport.py:221 +msgid "TourneyImport: Removing text < 100 characters from start of file" +msgstr "" + +#: GuiTourneyImport.py:231 +msgid "Finished importing %s/%s tournament summaries" +msgstr "" + +#: GuiTourneyImport.py:252 +msgid "GTI.readFile: '%s'" +msgstr "" + +#: GuiTourneyImport.py:271 ImapFetcher.py:176 +msgid "Need to define a converter" +msgstr "" + +#: GuiTourneyImport.py:278 +msgid "Need a filename to import" +msgstr "" + +#: GuiTourneyPlayerStats.py:75 +msgid "_Refresh Stats" +msgstr "" + +#: GuiTourneyViewer.py:40 +msgid "Enter the tourney number you want to display:" +msgstr "" + +#: GuiTourneyViewer.py:46 +msgid "_Display" +msgstr "" + +#: GuiTourneyViewer.py:53 +msgid "Display _Player" +msgstr "" + +#: GuiTourneyViewer.py:68 +msgid "" +"Tournament not found - please ensure you imported it and selected the " +"correct site" +msgstr "" + +#: GuiTourneyViewer.py:96 +msgid "" +"Player or tourney not found - please ensure you imported it and selected the " +"correct site" +msgstr "" + +#: GuiTourneyViewer.py:110 +msgid "N/A" +msgstr "" + +#: GuiTourneyViewer.py:131 +msgid "invalid entry in tourney number - must enter numbers only" +msgstr "" + +#: HUD_main.pyw:282 +msgid "Table \"%s\" no longer exists\n" +msgstr "" + +#: HUD_main.pyw:314 +msgid "Error resizing HUD for table: %s." +msgstr "" + +#: HUD_main.pyw:328 +msgid "Error killing HUD for table: %s." +msgstr "" + +#: HUD_main.pyw:351 +msgid "Error creating HUD for hand %s." +msgstr "" + +#: HUD_main.pyw:362 +msgid "Error updating HUD for hand %s." +msgstr "" + +#: HUD_run_me.py:45 +msgid "HUD_main starting\n" +msgstr "" + +#: HUD_run_me.py:51 TournamentTracker.py:306 +msgid "Using db name = %s\n" +msgstr "" + +#: HUD_run_me.py:62 +msgid "Closing this window will exit from the HUD." +msgstr "" + +#: HUD_run_me.py:66 +msgid "HUD Main Window" +msgstr "Ventana principal del HUD" + +#: Hand.py:145 +msgid "BB" +msgstr "" + +#: Hand.py:146 +msgid "SB" +msgstr "" + +#: Hand.py:147 +msgid "BUTTONPOS" +msgstr "" + +#: Hand.py:148 +msgid "HAND NO." +msgstr "" + +#: Hand.py:149 TourneySummary.py:131 +msgid "SITE" +msgstr "" + +#: Hand.py:150 +msgid "TABLE NAME" +msgstr "" + +#: Hand.py:151 TourneySummary.py:141 +msgid "HERO" +msgstr "" + +#: Hand.py:152 TourneySummary.py:142 +msgid "MAXSEATS" +msgstr "" + +#: Hand.py:153 +msgid "LEVEL" +msgstr "" + +#: Hand.py:154 TourneySummary.py:147 +msgid "MIXED" +msgstr "" + +#: Hand.py:155 +msgid "LASTBET" +msgstr "" + +#: Hand.py:156 +msgid "ACTION STREETS" +msgstr "" + +#: Hand.py:157 +msgid "STREETS" +msgstr "" + +#: Hand.py:158 +msgid "ALL STREETS" +msgstr "" + +#: Hand.py:159 +msgid "COMMUNITY STREETS" +msgstr "" + +#: Hand.py:160 +msgid "HOLE STREETS" +msgstr "" + +#: Hand.py:161 +msgid "COUNTED SEATS" +msgstr "" + +#: Hand.py:162 +msgid "DEALT" +msgstr "" + +#: Hand.py:163 +msgid "SHOWN" +msgstr "" + +#: Hand.py:164 +msgid "MUCKED" +msgstr "" + +#: Hand.py:165 +msgid "TOTAL POT" +msgstr "" + +#: Hand.py:166 +msgid "TOTAL COLLECTED" +msgstr "" + +#: Hand.py:167 +msgid "RAKE" +msgstr "" + +#: Hand.py:168 TourneySummary.py:132 +msgid "START TIME" +msgstr "" + +#: Hand.py:169 +msgid "TOURNAMENT NO" +msgstr "" + +#: Hand.py:170 TourneySummary.py:137 +msgid "TOURNEY ID" +msgstr "" + +#: Hand.py:171 TourneySummary.py:136 +msgid "TOURNEY TYPE ID" +msgstr "" + +#: Hand.py:172 TourneySummary.py:138 +msgid "BUYIN" +msgstr "" + +#: Hand.py:173 +msgid "BUYIN CURRENCY" +msgstr "" + +#: Hand.py:174 +msgid "BUYIN CHIPS" +msgstr "" + +#: Hand.py:175 TourneySummary.py:139 +msgid "FEE" +msgstr "" + +#: Hand.py:176 +msgid "IS REBUY" +msgstr "" + +#: Hand.py:177 +msgid "IS ADDON" +msgstr "" + +#: Hand.py:178 +msgid "IS KO" +msgstr "" + +#: Hand.py:179 TourneySummary.py:163 +msgid "KO BOUNTY" +msgstr "" + +#: Hand.py:180 +msgid "IS MATRIX" +msgstr "" + +#: Hand.py:181 +msgid "IS SHOOTOUT" +msgstr "" + +#: Hand.py:182 TourneySummary.py:164 +msgid "TOURNEY COMMENT" +msgstr "" + +#: Hand.py:185 TourneySummary.py:176 +msgid "PLAYERS" +msgstr "" + +#: Hand.py:186 +msgid "STACKS" +msgstr "" + +#: Hand.py:187 +msgid "POSTED" +msgstr "" + +#: Hand.py:188 +msgid "POT" +msgstr "" + +#: Hand.py:189 +msgid "SEATING" +msgstr "" + +#: Hand.py:190 +msgid "GAMETYPE" +msgstr "" + +#: Hand.py:191 +msgid "ACTION" +msgstr "" + +#: Hand.py:192 +msgid "COLLECTEES" +msgstr "" + +#: Hand.py:193 +msgid "BETS" +msgstr "" + +#: Hand.py:194 +msgid "BOARD" +msgstr "" + +#: Hand.py:195 +msgid "DISCARDS" +msgstr "" + +#: Hand.py:196 +msgid "HOLECARDS" +msgstr "" + +#: Hand.py:197 +msgid "TOURNEYS PLAYER IDS" +msgstr "" + +#: Hand.py:220 Hand.py:1360 +msgid "[ERROR] Tried to add holecards for unknown player: %s" +msgstr "" + +#: Hand.py:287 +msgid "Hand.insert(): hid #: %s is a duplicate" +msgstr "" + +#: Hand.py:455 +msgid "markstreets didn't match - Assuming hand %s was cancelled" +msgstr "" + +#: Hand.py:457 +msgid "FpdbParseError: markStreets appeared to fail: First 100 chars: '%s'" +msgstr "" + +#: Hand.py:461 +msgid "DEBUG: checkPlayerExists %s fail on hand number %s" +msgstr "" + +#: Hand.py:462 +msgid "checkPlayerExists: '%s fail on hand number %s" +msgstr "" + +#: Hand.py:549 +msgid "%s %s calls %s" +msgstr "" + +#: Hand.py:619 +msgid "%s %s raise %s" +msgstr "" + +#: Hand.py:630 +msgid "%s %s bets %s" +msgstr "" + +#: Hand.py:649 +msgid "%s %s folds" +msgstr "" + +#: Hand.py:658 +msgid "%s %s checks" +msgstr "" + +#: Hand.py:678 +msgid "addShownCards %s hole=%s all=%s" +msgstr "" + +#: Hand.py:789 +msgid "" +"*** ERROR - HAND: calling writeGameLine with unexpected STARTTIME value, " +"expecting datetime.date object, received:" +msgstr "" + +#: Hand.py:790 +msgid "" +"*** Make sure your HandHistoryConverter is setting hand.startTime properly!" +msgstr "" + +#: Hand.py:791 +msgid "*** Game String:" +msgstr "" + +#: Hand.py:872 +msgid "HoldemOmahaHand.__init__:Neither HHC nor DB+handid provided" +msgstr "" + +#: Hand.py:1228 +msgid "*** DEALING HANDS ***" +msgstr "" + +#: Hand.py:1233 +msgid "Dealt to %s: [%s]" +msgstr "" + +#: Hand.py:1238 +msgid "*** FIRST DRAW ***" +msgstr "" + +#: Hand.py:1248 +msgid "*** SECOND DRAW ***" +msgstr "" + +#: Hand.py:1258 +msgid "*** THIRD DRAW ***" +msgstr "" + +#: Hand.py:1268 Hand.py:1487 +msgid "*** SHOW DOWN ***" +msgstr "" + +#: Hand.py:1283 Hand.py:1502 +msgid "*** SUMMARY ***" +msgstr "" + +#: Hand.py:1369 +msgid "%s %s completes %s" +msgstr "" + +#: Hand.py:1387 +msgid "Bringin: %s, %s" +msgstr "" + +#: Hand.py:1427 +msgid "*** 3RD STREET ***" +msgstr "" + +#: Hand.py:1441 +msgid "*** 4TH STREET ***" +msgstr "" + +#: Hand.py:1453 +msgid "*** 5TH STREET ***" +msgstr "" + +#: Hand.py:1465 +msgid "*** 6TH STREET ***" +msgstr "" + +#: Hand.py:1475 +msgid "*** RIVER ***" +msgstr "" + +#: Hand.py:1567 +msgid "" +"join_holecards: # of holecards should be either < 4, 4 or 7 - 5 and 6 should " +"be impossible for anyone who is not a hero" +msgstr "" + +#: Hand.py:1568 +msgid "join_holcards: holecards(%s): %s" +msgstr "" + +#: Hand.py:1570 +msgid "join_holecards: Player '%s' appears not to have been dealt a card" +msgstr "" + +#: Hand.py:1660 +msgid "DEBUG: call Pot.end() before printing pot total" +msgstr "" + +#: Hand.py:1662 +msgid "FpdbError in printing Hand object" +msgstr "" + +#: HandHistoryConverter.py:130 +msgid "Failed sanity check" +msgstr "" + +#: HandHistoryConverter.py:138 +msgid "Tailing '%s'" +msgstr "" + +#: HandHistoryConverter.py:145 +msgid "HHC.start(follow): processHand failed: Exception msg: '%s'" +msgstr "" + +#: HandHistoryConverter.py:149 +msgid "handsList is " +msgstr "" + +#: HandHistoryConverter.py:160 +msgid "HHC.start(): processHand failed: Exception msg: '%s'" +msgstr "" + +#: HandHistoryConverter.py:164 +msgid "Read %d hands (%d failed) in %.3f seconds" +msgstr "" + +#: HandHistoryConverter.py:170 +msgid "Summary file '%s' correctly parsed (took %.3f seconds)" +msgstr "" + +#: HandHistoryConverter.py:172 +msgid "Error converting summary file '%s' (took %.3f seconds)" +msgstr "" + +#: HandHistoryConverter.py:175 +msgid "Error converting '%s'" +msgstr "" + +#: HandHistoryConverter.py:206 +msgid "%s changed inode numbers from %d to %d" +msgstr "" + +#: HandHistoryConverter.py:254 +msgid "Converting starsArchive format to readable" +msgstr "" + +#: HandHistoryConverter.py:259 +msgid "Converting ftpArchive format to readable" +msgstr "" + +#: HandHistoryConverter.py:265 +msgid "Read no hands." +msgstr "" + +#: HandHistoryConverter.py:273 +msgid "Removing text < 50 characters" +msgstr "" + +#: HandHistoryConverter.py:481 +msgid "HH Sanity Check: output and input files are the same, check config" +msgstr "" + +#: HandHistoryConverter.py:504 +msgid "Reading stdin with %s" +msgstr "" + +#: HandHistoryConverter.py:519 +msgid "unable to read file with any codec in list!" +msgstr "" + +#: HandHistoryConverter.py:586 +msgid " given TZ:" +msgstr "" + +#: HandHistoryConverter.py:586 +msgid "raw time:" +msgstr "" + +#: HandHistoryConverter.py:596 +msgid "changeTimeZone: offset=" +msgstr "" + +#: HandHistoryConverter.py:659 +msgid "utcTime:" +msgstr "" + +#: HandHistoryConverter.py:708 +msgid "Unable to create output directory %s for HHC!" +msgstr "" + +#: HandHistoryConverter.py:709 +msgid "*** ERROR: UNABLE TO CREATE OUTPUT DIRECTORY" +msgstr "" + +#: HandHistoryConverter.py:711 +msgid "Created directory '%s'" +msgstr "" + +#: HandHistoryConverter.py:715 +msgid "out_path %s couldn't be opened" +msgstr "" + +#: Hello.py:46 +msgid "creating Hello" +msgstr "" + +#: Hello.py:49 +msgid "Hello World" +msgstr "" + +#: Hello.py:67 +msgid "site =" +msgstr "" + +#: Hello.py:75 +msgid "YOUR NAME HERE" +msgstr "" + +#: Hello.py:106 +msgid "" +"Hello %s\n" +"You have played %d hands\n" +" on %s." +msgstr "" + +#: Hud.py:148 +msgid "Kill This HUD" +msgstr "" + +#: Hud.py:153 +msgid "Save HUD Layout" +msgstr "" + +#: Hud.py:157 +msgid "Reposition StatWindows" +msgstr "" + +#: Hud.py:161 +msgid "Show Player Stats" +msgstr "" + +#: Hud.py:166 Hud.py:235 +msgid "For This Blind Level Only" +msgstr "" + +#: Hud.py:171 Hud.py:240 +msgid "For Multiple Blind Levels:" +msgstr "" + +#: Hud.py:174 Hud.py:243 +msgid " 0.5 to 2.0 x Current Blinds" +msgstr "" + +#: Hud.py:179 Hud.py:248 +msgid " 0.33 to 3.0 x Current Blinds" +msgstr "" + +#: Hud.py:184 Hud.py:253 +msgid " 0.1 to 10 x Current Blinds" +msgstr "" + +#: Hud.py:189 Hud.py:258 +msgid " All Levels" +msgstr "" + +#: Hud.py:194 Hud.py:263 +msgid "For #Seats:" +msgstr "" + +#: Hud.py:197 Hud.py:266 +msgid " Any Number" +msgstr "" + +#: Hud.py:202 Hud.py:271 +msgid " Custom" +msgstr "" + +#: Hud.py:207 Hud.py:276 +msgid " Exact" +msgstr "" + +#: Hud.py:212 Hud.py:281 +msgid "Since:" +msgstr "" + +#: Hud.py:215 Hud.py:284 +msgid " All Time" +msgstr "" + +#: Hud.py:220 Hud.py:289 +msgid " Session" +msgstr "" + +#: Hud.py:225 Hud.py:294 +msgid " %s Days" +msgstr "" + +#: Hud.py:230 +msgid "Show Opponent Stats" +msgstr "" + +#: Hud.py:352 +msgid "Debug StatWindows" +msgstr "" + +#: Hud.py:356 +msgid "Set max seats" +msgstr "" + +#: Hud.py:577 +msgid "Updating config file" +msgstr "" + +#: Hud.py:586 +msgid "No layout found for %d-max games for site %s\n" +msgstr "" + +#: Hud.py:600 +msgid "" +"exception in Hud.adj_seats\n" +"\n" +msgstr "" + +#: Hud.py:601 +msgid "error is %s" +msgstr "" + +#: Hud.py:608 +msgid "Error finding actual seat.\n" +msgstr "" + +#: Hud.py:624 +msgid "Creating hud from hand " +msgstr "" + +#: Hud.py:673 +msgid "" +"KeyError at the start of the for loop in update in hud_main. How this can " +"possibly happen is totally beyond my comprehension. Your HUD may be about to " +"get really weird. -Eric" +msgstr "" + +#: Hud.py:674 +msgid "(btw, the key was %s and statd is %s" +msgstr "" + +#: ImapFetcher.py:44 ImapFetcher.py:53 +msgid "DEBUG: re_SplitTourneys isn't matching" +msgstr "" + +#: ImapFetcher.py:67 +msgid "response to logging in:" +msgstr "" + +#: ImapFetcher.py:83 +msgid "ImapFetcher: Found %s messages to fetch" +msgstr "" + +#: ImapFetcher.py:103 +msgid "Completed retrieving IMAP messages, closing server connection" +msgstr "" + +#: ImapFetcher.py:109 +msgid "No Tournament summaries found." +msgstr "" + +#: ImapFetcher.py:159 +msgid "Finished importing %s/%s PS summaries" +msgstr "" + +#: Mucked.py:327 +msgid "No Name" +msgstr "" + +#: OnGameToFpdb.py:173 WinamaxToFpdb.py:190 +msgid "determineGameType: limit not found in self.limits(%s). hand: '%s'" +msgstr "" + +#: OnGameToFpdb.py:175 WinamaxToFpdb.py:192 +msgid "limit not found in self.limits(%s). hand: '%s'" +msgstr "" + +#: OnGameToFpdb.py:262 PartyPokerToFpdb.py:354 PokerStarsToFpdb.py:317 +#: Win2dayToFpdb.py:162 WinamaxToFpdb.py:323 +msgid "readButton: not found" +msgstr "" + +#: OnGameToFpdb.py:281 WinamaxToFpdb.py:343 +msgid "readBlinds in noSB exception - no SB created" +msgstr "" + +#: Options.py:31 +msgid "If passed error output will go to the console rather than ." +msgstr "" + +#: Options.py:34 +msgid "Overrides the default database name" +msgstr "" + +#: Options.py:37 +msgid "Specifies a configuration file." +msgstr "" + +#: Options.py:40 +msgid "" +"Indicates program was restarted with a different path (only allowed once)." +msgstr "" + +#: Options.py:43 +msgid "Module name for Hand History Converter" +msgstr "" + +#: Options.py:46 +msgid "A sitename" +msgstr "" + +#: Options.py:50 +msgid "Error logging level:" +msgstr "" + +#: Options.py:53 +msgid "Print version information and exit." +msgstr "" + +#: Options.py:60 +msgid "Input out path in quiet mode" +msgstr "" + +#: Options.py:62 +msgid "File to be split is a PokerStars or Full Tilt Poker archive file" +msgstr "" + +#: Options.py:64 +msgid "How many hands do you want saved to each file. Default is 100" +msgstr "" + +#: Options.py:66 +msgid "X location to open window" +msgstr "" + +#: Options.py:68 +msgid "Y location to open Window" +msgstr "" + +#: Options.py:70 +msgid "Auto-start Auto-import" +msgstr "" + +#: Options.py:72 +msgid "Start Minimized" +msgstr "" + +#: Options.py:74 +msgid "Start Hidden" +msgstr "" + +#: Options.py:116 +msgid "press enter to end" +msgstr "" + +#: P5sResultsParser.py:10 +msgid "You need to manually enter the playername" +msgstr "" + +#: PartyPokerToFpdb.py:213 +msgid "Cannot fetch field '%s'" +msgstr "" + +#: PartyPokerToFpdb.py:217 +msgid "Unknown limit '%s'" +msgstr "" + +#: PartyPokerToFpdb.py:222 +msgid "Unknown game type '%s'" +msgstr "" + +#: PartyPokerToFpdb.py:261 +msgid "Cannot read Handinfo for current hand" +msgstr "" + +#: PartyPokerToFpdb.py:266 +msgid "Cannot read GameType for current hand" +msgstr "" + +#: PartyPokerToFpdb.py:525 +msgid "Unimplemented readAction: '%s' '%s'" +msgstr "" + +#: SplitHandHistory.py:76 +msgid "File not found" +msgstr "" + +#: SplitHandHistory.py:126 +msgid "Unexpected error processing file" +msgstr "" + +#: SplitHandHistory.py:165 +msgid "End of file reached" +msgstr "" + +#: Stats.py:127 Stats.py:128 +msgid "Total Profit" +msgstr "" + +#: Stats.py:149 Stats.py:156 +msgid "Voluntarily Put In Pot Pre-Flop%" +msgstr "" + +#: Stats.py:169 Stats.py:177 +msgid "Pre-Flop Raise %" +msgstr "" + +#: Stats.py:190 Stats.py:198 +msgid "% went to showdown" +msgstr "" + +#: Stats.py:211 Stats.py:219 +msgid "% won money at showdown" +msgstr "" + +#: Stats.py:234 Stats.py:243 +msgid "profit/100hands" +msgstr "" + +#: Stats.py:237 +msgid "exception calcing p/100: 100 * %d / %d" +msgstr "" + +#: Stats.py:256 Stats.py:265 +msgid "big blinds/100 hands" +msgstr "" + +#: Stats.py:278 Stats.py:287 +msgid "Big Bets/100 hands" +msgstr "" + +#: Stats.py:281 +msgid "exception calcing BB/100: " +msgstr "" + +#: Stats.py:301 Stats.py:310 +msgid "Flop Seen %" +msgstr "" + +#: Stats.py:333 Stats.py:342 +msgid "number hands seen" +msgstr "" + +#: Stats.py:355 Stats.py:363 +msgid "folded flop/4th" +msgstr "" + +#: Stats.py:376 +msgid "% steal attempted" +msgstr "" + +#: Stats.py:391 Stats.py:398 +msgid "% folded SB to steal" +msgstr "" + +#: Stats.py:410 Stats.py:417 +msgid "% folded BB to steal" +msgstr "" + +#: Stats.py:432 Stats.py:439 +msgid "% folded blind to steal" +msgstr "" + +#: Stats.py:451 +msgid "% 4 Bet preflop/3rd" +msgstr "" + +#: Stats.py:458 +msgid "% 3 Bet preflop/3rd" +msgstr "" + +#: Stats.py:470 Stats.py:477 +msgid "% 4 Bet preflop/4rd" +msgstr "" + +#: Stats.py:489 Stats.py:496 +msgid "% Fold to 3 Bet preflop" +msgstr "" + +#: Stats.py:508 Stats.py:515 +msgid "% Fold to 4 Bet preflop" +msgstr "" + +#: Stats.py:529 Stats.py:536 +msgid "% won$/saw flop/4th" +msgstr "" + +#: Stats.py:548 Stats.py:555 +msgid "Aggression Freq flop/4th" +msgstr "" + +#: Stats.py:567 Stats.py:574 +msgid "Aggression Freq turn/5th" +msgstr "" + +#: Stats.py:586 Stats.py:593 +msgid "Aggression Freq river/6th" +msgstr "" + +#: Stats.py:605 Stats.py:612 +msgid "Aggression Freq 7th" +msgstr "" + +#: Stats.py:631 Stats.py:638 +msgid "Post-Flop Aggression Freq" +msgstr "" + +#: Stats.py:659 Stats.py:666 +msgid "Aggression Freq" +msgstr "" + +#: Stats.py:685 Stats.py:692 +msgid "Aggression Factor" +msgstr "" + +#: Stats.py:709 Stats.py:716 +msgid "% continuation bet " +msgstr "" + +#: Stats.py:728 Stats.py:735 +msgid "% continuation bet flop/4th" +msgstr "" + +#: Stats.py:747 Stats.py:754 +msgid "% continuation bet turn/5th" +msgstr "" + +#: Stats.py:766 Stats.py:773 +msgid "% continuation bet river/6th" +msgstr "" + +#: Stats.py:785 Stats.py:792 +msgid "% continuation bet 7th" +msgstr "" + +#: Stats.py:804 Stats.py:811 +msgid "% fold frequency flop/4th" +msgstr "" + +#: Stats.py:823 Stats.py:830 +msgid "% fold frequency turn/5th" +msgstr "" + +#: Stats.py:842 Stats.py:849 +msgid "% fold frequency river/6th" +msgstr "" + +#: Stats.py:861 Stats.py:868 +msgid "% fold frequency 7th" +msgstr "" + +#: Stats.py:888 +msgid "Example stats, player = %s hand = %s:" +msgstr "" + +#: Stats.py:921 +msgid "" +"\n" +"\n" +"Legal stats:" +msgstr "" + +#: Stats.py:922 +msgid "" +"(add _0 to name to display with 0 decimal places, _1 to display with 1, " +"etc)\n" +msgstr "" + +#: Stove.py:290 +msgid "No board given. Using Monte-Carlo simulation..." +msgstr "" + +#: Tables_Demo.py:61 +msgid "Fake HUD Main Window" +msgstr "" + +#: Tables_Demo.py:91 +msgid "enter table name to find: " +msgstr "" + +#: TournamentTracker.py:39 +msgid "" +"Note: error output is being diverted to fpdb-error-log.txt and HUD-error." +"txt. Any major error will be reported there _only_." +msgstr "" + +#: TournamentTracker.py:100 +msgid "tournament edit window=" +msgstr "" + +#: TournamentTracker.py:103 +msgid "FPDB Tournament Entry" +msgstr "" + +#: TournamentTracker.py:143 +msgid "Closing this window will stop the Tournament Tracker" +msgstr "" + +#: TournamentTracker.py:145 +msgid "Enter Tournament" +msgstr "" + +#: TournamentTracker.py:150 +msgid "FPDB Tournament Tracker" +msgstr "" + +#: TournamentTracker.py:161 +msgid "Edit" +msgstr "" + +#: TournamentTracker.py:164 +msgid "Rebuy" +msgstr "" + +#: TournamentTracker.py:263 +msgid "db error: skipping " +msgstr "" + +#: TournamentTracker.py:265 +msgid "Database error %s in hand %d. Skipping.\n" +msgstr "" + +#: TournamentTracker.py:274 +msgid "could not find tournament: skipping" +msgstr "" + +#: TournamentTracker.py:275 +msgid "Could not find tournament %d in hand %d. Skipping.\n" +msgstr "" + +#: TournamentTracker.py:298 +msgid "table name %s not found, skipping.\n" +msgstr "" + +#: TournamentTracker.py:305 +msgid "tournament tracker starting\n" +msgstr "" + +#: TourneyFilters.py:52 +msgid "Tourney Type" +msgstr "" + +#: TourneyFilters.py:79 +msgid "setting numTourneys:" +msgstr "" + +#: TourneySummary.py:133 +msgid "END TIME" +msgstr "" + +#: TourneySummary.py:134 +msgid "TOURNEY NAME" +msgstr "" + +#: TourneySummary.py:135 +msgid "TOURNEY NO" +msgstr "" + +#: TourneySummary.py:140 +msgid "CURRENCY" +msgstr "" + +#: TourneySummary.py:143 +msgid "ENTRIES" +msgstr "" + +#: TourneySummary.py:144 +msgid "SPEED" +msgstr "" + +#: TourneySummary.py:145 +msgid "PRIZE POOL" +msgstr "" + +#: TourneySummary.py:146 +msgid "STARTING CHIP COUNT" +msgstr "" + +#: TourneySummary.py:148 +msgid "REBUY" +msgstr "" + +#: TourneySummary.py:149 +msgid "ADDON" +msgstr "" + +#: TourneySummary.py:150 +msgid "KO" +msgstr "" + +#: TourneySummary.py:151 +msgid "MATRIX" +msgstr "" + +#: TourneySummary.py:152 +msgid "MATRIX ID PROCESSED" +msgstr "" + +#: TourneySummary.py:153 +msgid "SHOOTOUT" +msgstr "" + +#: TourneySummary.py:154 +msgid "MATRIX MATCH ID" +msgstr "" + +#: TourneySummary.py:155 +msgid "SUB TOURNEY BUY IN" +msgstr "" + +#: TourneySummary.py:156 +msgid "SUB TOURNEY FEE" +msgstr "" + +#: TourneySummary.py:157 +msgid "REBUY CHIPS" +msgstr "" + +#: TourneySummary.py:158 +msgid "ADDON CHIPS" +msgstr "" + +#: TourneySummary.py:159 +msgid "REBUY COST" +msgstr "" + +#: TourneySummary.py:160 +msgid "ADDON COST" +msgstr "" + +#: TourneySummary.py:161 +msgid "TOTAL REBUYS" +msgstr "" + +#: TourneySummary.py:162 +msgid "TOTAL ADDONS" +msgstr "" + +#: TourneySummary.py:165 +msgid "SNG" +msgstr "" + +#: TourneySummary.py:166 +msgid "SATELLITE" +msgstr "" + +#: TourneySummary.py:167 +msgid "DOUBLE OR NOTHING" +msgstr "" + +#: TourneySummary.py:168 +msgid "GUARANTEE" +msgstr "" + +#: TourneySummary.py:169 +msgid "ADDED" +msgstr "" + +#: TourneySummary.py:170 +msgid "ADDED CURRENCY" +msgstr "" + +#: TourneySummary.py:171 +msgid "COMMENT" +msgstr "" + +#: TourneySummary.py:172 +msgid "COMMENT TIMESTAMP" +msgstr "" + +#: TourneySummary.py:175 +msgid "PLAYER IDS" +msgstr "" + +#: TourneySummary.py:177 +msgid "TOURNEYS PLAYERS IDS" +msgstr "" + +#: TourneySummary.py:178 +msgid "RANKS" +msgstr "" + +#: TourneySummary.py:179 +msgid "WINNINGS" +msgstr "" + +#: TourneySummary.py:180 +msgid "WINNINGS CURRENCY" +msgstr "" + +#: TourneySummary.py:181 +msgid "COUNT REBUYS" +msgstr "" + +#: TourneySummary.py:182 +msgid "COUNT ADDONS" +msgstr "" + +#: TourneySummary.py:183 +msgid "NB OF KO" +msgstr "" + +#: TourneySummary.py:230 +msgid "Tourney Insert/Update done" +msgstr "" + +#: TourneySummary.py:250 +msgid "addPlayer: rank:%s - name : '%s' - Winnings (%s)" +msgstr "" + +#: TourneySummary.py:277 +msgid "incrementPlayerWinnings: name : '%s' - Add Winnings (%s)" +msgstr "" + +#: TreeViewTooltips.py:108 +msgid "" +"This module was developed and tested with version 2.8.18 of gtk. You are " +"using version %d.%d.%d. Your milage may vary." +msgstr "" + +#: WinTables.py:73 +msgid "self.window doesn't exist? why?" +msgstr "" + +#: WinamaxToFpdb.py:262 +msgid "failed to detect currency" +msgstr "" + +#: WinamaxToFpdb.py:311 +msgid "Failed to add streets. handtext=%s" +msgstr "" + +#: fpdb.pyw:38 +msgid " - press return to continue\n" +msgstr "" + +#: fpdb.pyw:45 +msgid "" +"\n" +"python 2.5-2.7 not found, please install python 2.5, 2.6 or 2.7 for fpdb\n" +msgstr "" + +#: fpdb.pyw:46 fpdb.pyw:58 fpdb.pyw:80 +msgid "Press ENTER to continue." +msgstr "" + +#: fpdb.pyw:57 +msgid "" +"We appear to be running in Windows, but the Windows Python Extensions are " +"not loading. Please install the PYWIN32 package from http://sourceforge.net/" +"projects/pywin32/" +msgstr "" + +#: fpdb.pyw:79 +msgid "" +"Unable to load PyGTK modules required for GUI. Please install PyCairo, " +"PyGObject, and PyGTK from www.pygtk.org." +msgstr "" + +#: fpdb.pyw:244 +msgid "" +"Copyright 2008-2010, Steffen, Eratosthenes, Carl Gherardi, Eric Blade, _mt, " +"sqlcoder, Bostik, and others" +msgstr "" + +#: fpdb.pyw:245 +msgid "" +"You are free to change, and distribute original or changed versions of fpdb " +"within the rules set out by the license" +msgstr "" + +#: fpdb.pyw:246 +msgid "Please see fpdb's start screen for license information" +msgstr "" + +#: fpdb.pyw:250 +msgid "and others" +msgstr "" + +#: fpdb.pyw:256 +msgid "Operating System" +msgstr "" + +#: fpdb.pyw:277 +msgid "Your config file is: " +msgstr "" + +#: fpdb.pyw:282 +msgid "Version Information:" +msgstr "" + +#: fpdb.pyw:289 +msgid "Threads: " +msgstr "" + +#: fpdb.pyw:312 +msgid "" +"Updated preferences have not been loaded because windows are open. Re-start " +"fpdb to load them." +msgstr "" + +#: fpdb.pyw:322 +msgid "Maintain Databases" +msgstr "" + +#: fpdb.pyw:332 +msgid "saving updated db data" +msgstr "" + +#: fpdb.pyw:339 +msgid "guidb response was " +msgstr "" + +#: fpdb.pyw:345 +msgid "" +"Cannot open Database Maintenance window because other windows have been " +"opened. Re-start fpdb to use this option." +msgstr "" + +#: fpdb.pyw:348 +msgid "Number of Hands: " +msgstr "" + +#: fpdb.pyw:349 +msgid "" +"\n" +"Number of Tourneys: " +msgstr "" + +#: fpdb.pyw:350 +msgid "" +"\n" +"Number of TourneyTypes: " +msgstr "" + +#: fpdb.pyw:351 +msgid "Database Statistics" +msgstr "" + +#: fpdb.pyw:360 +msgid "HUD Configurator - choose category" +msgstr "" + +#: fpdb.pyw:366 +msgid "" +"Please select the game category for which you want to configure HUD stats:" +msgstr "" + +#: fpdb.pyw:418 +msgid "HUD Configurator - please choose your stats" +msgstr "" + +#: fpdb.pyw:424 +msgid "Please choose the stats you wish to use in the below table." +msgstr "" + +#: fpdb.pyw:428 +msgid "Note that you may not select any stat more than once or it will crash." +msgstr "" + +#: fpdb.pyw:432 +msgid "" +"It is not currently possible to select \"empty\" or anything else to that " +"end." +msgstr "" + +#: fpdb.pyw:436 +msgid "" +"To configure things like colouring you will still have to use the " +"Preferences dialogue or manually edit your HUD_config.xml." +msgstr "" + +#: fpdb.pyw:543 +msgid "Confirm deleting and recreating tables" +msgstr "" + +#: fpdb.pyw:544 +msgid "Please confirm that you want to (re-)create the tables." +msgstr "" + +#: fpdb.pyw:545 +msgid "" +" If there already are tables in the database %s on %s they will be deleted " +"and you will have to re-import your histories.\n" +msgstr "" + +#: fpdb.pyw:546 +msgid "This may take a while." +msgstr "" + +#: fpdb.pyw:571 +msgid "User cancelled recreating tables" +msgstr "" + +#: fpdb.pyw:578 +msgid "Please confirm that you want to re-create the HUD cache." +msgstr "" + +#: fpdb.pyw:586 +msgid " Hero's cache starts: " +msgstr "" + +#: fpdb.pyw:600 +msgid " Villains' cache starts: " +msgstr "" + +#: fpdb.pyw:613 +msgid " Rebuilding HUD Cache ... " +msgstr "" + +#: fpdb.pyw:621 +msgid "User cancelled rebuilding hud cache" +msgstr "" + +#: fpdb.pyw:633 +msgid "Confirm rebuilding database indexes" +msgstr "" + +#: fpdb.pyw:634 +msgid "Please confirm that you want to rebuild the database indexes." +msgstr "" + +#: fpdb.pyw:642 +msgid " Rebuilding Indexes ... " +msgstr "" + +#: fpdb.pyw:649 +msgid " Cleaning Database ... " +msgstr "" + +#: fpdb.pyw:654 +msgid " Analyzing Database ... " +msgstr "" + +#: fpdb.pyw:659 +msgid "User cancelled rebuilding db indexes" +msgstr "" + +#: fpdb.pyw:754 +msgid "" +"Unimplemented: Save Profile (try saving a HUD layout, that should do it)" +msgstr "" + +#: fpdb.pyw:809 +msgid "_Main" +msgstr "_Principal" + +#: fpdb.pyw:810 fpdb.pyw:841 +msgid "_Quit" +msgstr "_Salir" + +#: fpdb.pyw:811 +msgid "L" +msgstr "" + +#: fpdb.pyw:811 +msgid "_Load Profile (broken)" +msgstr "_Cargar perfil (roto)" + +#: fpdb.pyw:812 +msgid "S" +msgstr "" + +#: fpdb.pyw:812 +msgid "_Save Profile (todo)" +msgstr "_Guardar perfil (todo)" + +#: fpdb.pyw:813 +msgid "F" +msgstr "" + +#: fpdb.pyw:813 +msgid "Pre_ferences" +msgstr "Pre_ferencias" + +#: fpdb.pyw:814 +msgid "_Import" +msgstr "_Importar" + +#: fpdb.pyw:815 +msgid "B" +msgstr "" + +#: fpdb.pyw:816 +msgid "R" +msgstr "" + +#: fpdb.pyw:816 +msgid "Tournament _Results Import" +msgstr "Importar _resultados de torneos" + +#: fpdb.pyw:817 +msgid "I" +msgstr "" + +#: fpdb.pyw:817 +msgid "_Import through eMail/IMAP" +msgstr "_Importar a través de eMail/IMAP" + +#: fpdb.pyw:818 +msgid "_Viewers" +msgstr "" + +#: fpdb.pyw:819 +msgid "A" +msgstr "" + +#: fpdb.pyw:819 +msgid "_Auto Import and HUD" +msgstr "" + +#: fpdb.pyw:820 +msgid "H" +msgstr "" + +#: fpdb.pyw:820 +msgid "_HUD Configurator" +msgstr "Configurador del _HUD" + +#: fpdb.pyw:821 +msgid "G" +msgstr "" + +#: fpdb.pyw:821 +msgid "_Graphs" +msgstr "" + +#: fpdb.pyw:822 fpdb.pyw:1097 +msgid "Tourney Graphs" +msgstr "" + +#: fpdb.pyw:823 +msgid "Stove (preview)" +msgstr "" + +#: fpdb.pyw:824 +msgid "P" +msgstr "" + +#: fpdb.pyw:824 +msgid "Ring _Player Stats (tabulated view, not on pgsql)" +msgstr "Estadísticas de Full Ring (vista tabulada, no en postgresql)" + +#: fpdb.pyw:825 +msgid "T" +msgstr "" + +#: fpdb.pyw:825 +msgid "_Tourney Stats (tabulated view, not on pgsql)" +msgstr "" + +#: fpdb.pyw:826 +msgid "Tourney _Viewer" +msgstr "" + +#: fpdb.pyw:827 +msgid "O" +msgstr "" + +#: fpdb.pyw:827 +msgid "P_ositional Stats (tabulated view, not on sqlite)" +msgstr "" + +#: fpdb.pyw:828 fpdb.pyw:1056 +msgid "Session Stats" +msgstr "Estadísticas de la sesión" + +#: fpdb.pyw:829 +msgid "Hand _Replayer (not working yet)" +msgstr "" + +#: fpdb.pyw:830 +msgid "_Database" +msgstr "" + +#: fpdb.pyw:831 +msgid "_Maintain Databases" +msgstr "" + +#: fpdb.pyw:832 +msgid "Create or Recreate _Tables" +msgstr "Crear o recrear _tablas" + +#: fpdb.pyw:833 +msgid "Rebuild HUD Cache" +msgstr "" + +#: fpdb.pyw:834 +msgid "Rebuild DB Indexes" +msgstr "" + +#: fpdb.pyw:835 +msgid "_Statistics" +msgstr "" + +#: fpdb.pyw:836 +msgid "Dump Database to Textfile (takes ALOT of time)" +msgstr "" + +#: fpdb.pyw:837 +msgid "_Help" +msgstr "_Ayuda" + +#: fpdb.pyw:838 +msgid "_Log Messages" +msgstr "_Registro de mensajes" + +#: fpdb.pyw:839 +msgid "A_bout, License, Copying" +msgstr "Acerca de, Licencia, Copia" + +#: fpdb.pyw:857 +msgid "There is an error in your config file\n" +msgstr "" + +#: fpdb.pyw:858 +msgid "" +"\n" +"\n" +"Error is: " +msgstr "" + +#: fpdb.pyw:859 +msgid "CONFIG FILE ERROR" +msgstr "ERROR EN EL ARCHIVO DE CONFIGURACION" + +#: fpdb.pyw:863 +msgid "Logfile is %s\n" +msgstr "Archivo de registro es %s\n" + +#: fpdb.pyw:865 +msgid "Config file" +msgstr "Archivo de configuración" + +#: fpdb.pyw:866 +msgid "" +"has been created at:\n" +"%s.\n" +msgstr "" +"ha sido creado el:\n" +"%s.\n" + +#: fpdb.pyw:867 +msgid "" +"Edit your screen_name and hand history path in the supported_sites section " +"of the Preferences window (Main menu) before trying to import hands." +msgstr "" +"Edita tu screen_name y la ruta del historial de manos en la sección " +"supported_sites de la ventana de Preferencias (Menú principal) antes de " +"intentar importar manos." + +#: fpdb.pyw:889 +msgid "Connected to SQLite: %s" +msgstr "Conectado a SQLite: %s" + +#: fpdb.pyw:923 +msgid "Strong Warning - Invalid database version" +msgstr "Advertencia importante - Versión incorrecta de base de datos" + +#: fpdb.pyw:925 +msgid "An invalid DB version or missing tables have been detected." +msgstr "" +"Una versión incorrecta de la BD o ausencia de tablas ha sido detectada." + +#: fpdb.pyw:929 +msgid "" +"This error is not necessarily fatal but it is strongly recommended that you " +"recreate the tables by using the Database menu." +msgstr "" +"Este error no es fatal necesariamente pero le recomendamos encarecidamente " +"que recree las tablas usando el menú de Bases de Datos." + +#: fpdb.pyw:933 +msgid "" +"Not doing this will likely lead to misbehaviour including fpdb crashes, " +"corrupt data etc." +msgstr "" +"El no hacerlo es favorable a causar extraño comportamiento en fpdb " +"incluyendo bloqueos, corrupción de datos, etc." + +#: fpdb.pyw:947 +msgid "Status: Connected to %s database named %s on host %s" +msgstr "Estado: Conectado a la base de datos %s llamada %s en la máquina %s" + +#: fpdb.pyw:957 +msgid "" +"\n" +"Global lock taken by %s" +msgstr "" +"\n" +"Reloj global usado por %s" + +#: fpdb.pyw:960 +msgid "" +"\n" +"Failed to get global lock, it is currently held by %s" +msgstr "" +"\n" +"Fallo al acceder al reloj global, está siendo utilizado por %s" + +#: fpdb.pyw:970 +msgid "Quitting normally" +msgstr "Saliendo de forma normal" + +#: fpdb.pyw:995 +msgid "Global lock released.\n" +msgstr "" + +#: fpdb.pyw:1002 +msgid "Auto Import" +msgstr "" + +#: fpdb.pyw:1012 +msgid "Bulk Import" +msgstr "Importe masivo" + +#: fpdb.pyw:1019 +msgid "Tournament Results Import" +msgstr "" + +#: fpdb.pyw:1025 +msgid "eMail Import" +msgstr "" + +#: fpdb.pyw:1032 +msgid "Ring Player Stats" +msgstr "" + +#: fpdb.pyw:1038 +msgid "Tourney Stats" +msgstr "" + +#: fpdb.pyw:1044 +msgid "Tourney Viewer" +msgstr "" + +#: fpdb.pyw:1050 +msgid "Positional Stats" +msgstr "" + +#: fpdb.pyw:1062 +msgid "Hand Replayer" +msgstr "" + +#: fpdb.pyw:1066 +#, fuzzy +msgid "" +"Fpdb needs translators!\n" +"If you speak another language and have a few minutes or more to spare get in " +"touch by emailing steffen@schaumburger.info\n" +"\n" +"Welcome to Fpdb!\n" +"To be notified of new snapshots and releases go to https://lists.sourceforge." +"net/lists/listinfo/fpdb-announce and subscribe.\n" +"If you want to follow development more closely go to https://lists." +"sourceforge.net/lists/listinfo/fpdb-main and subscribe.\n" +"\n" +"This program is currently in an alpha-state, so our database format is still " +"sometimes changed.\n" +"You should therefore always keep your hand history files so that you can re-" +"import after an update, if necessary.\n" +"\n" +"For documentation please visit our website/wiki at http://fpdb.sourceforge." +"net/.\n" +"If you need help click on Contact - Get Help on our website.\n" +"Please note that default.conf is no longer needed nor used, all " +"configuration now happens in HUD_config.xml.\n" +"\n" +"This program is free/libre open source software licensed partially under the " +"AGPL3, and partially under GPL2 or later.\n" +"The Windows installer package includes code licensed under the MIT license.\n" +"You can find the full license texts in agpl-3.0.txt, gpl-2.0.txt, gpl-3.0." +"txt and mit.txt in the fpdb installation directory." +msgstr "" +"Fpdb necesita traductores!\n" +"Si hablas otro idioma y tienes unos pocos minutos o más para dedicarle ponte " +"en contacto con steffen@schaumburger.info\n" +"\n" +"Bienvenido a Fpdb!\n" +"Para ser notificado de nuevas versiones entre en https://lists.sourceforge." +"net/lists/listinfo/fpdb-announce y subscribase.\n" +"Si quiere seguir el desarollo más de cerca vaya a https://lists.sourceforge." +"net/lists/listinfo/fpdb-main y subsribase.\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"lala" + +#: fpdb.pyw:1083 +msgid "Help" +msgstr "" + +#: fpdb.pyw:1090 +msgid "Graphs" +msgstr "" + +#: fpdb.pyw:1104 +msgid "Stove" +msgstr "" + +#: fpdb.pyw:1177 +msgid "" +"\n" +"Note: error output is being diverted to fpdb-errors.txt and HUD-errors.txt " +"in: %s" +msgstr "" + +#: fpdb.pyw:1178 +msgid "" +"\n" +"Any major error will be reported there _only_.\n" +msgstr "" + +#: fpdb.pyw:1207 +msgid "fpdb starting ..." +msgstr "fpdb iniciando ..." + +#: fpdb.pyw:1306 +msgid "" +"WARNING: Unable to find output hand history directory %s\n" +"\n" +" Press YES to create this directory, or NO to select a new one." +msgstr "" + +#: fpdb.pyw:1314 +msgid "" +"WARNING: Unable to create hand output directory. Importing is not likely to " +"work until this is fixed." +msgstr "" + +#: fpdb.pyw:1325 +msgid "" +"WARNING: Unable to find site '%s'\n" +"\n" +"Press YES to add this site to the database." +msgstr "" + +#: fpdb.pyw:1341 +msgid "" +"\n" +"Enter short code for %s\n" +"(up to 3 characters):\n" +msgstr "" + +#: fpdb_import.py:51 +msgid "Import database module: MySQLdb not found" +msgstr "" + +#: fpdb_import.py:58 +msgid "Import database module: psycopg2 not found" +msgstr "" + +#: fpdb_import.py:185 +msgid "Database ID for %s not found" +msgstr "" + +#: fpdb_import.py:187 +msgid "" +"[ERROR] More than 1 Database ID found for %s - Multiple currencies not " +"implemented yet" +msgstr "" + +#: fpdb_import.py:233 +msgid "Started at %s -- %d files to import. indexes: %s" +msgstr "" + +#: fpdb_import.py:242 +msgid "No need to drop indexes." +msgstr "" + +#: fpdb_import.py:261 +msgid "writers finished already" +msgstr "" + +#: fpdb_import.py:264 +msgid "waiting for writers to finish ..." +msgstr "" + +#: fpdb_import.py:274 +msgid " ... writers finished" +msgstr "" + +#: fpdb_import.py:280 +msgid "No need to rebuild indexes." +msgstr "" + +#: fpdb_import.py:284 +msgid "No need to rebuild hudcache." +msgstr "" + +#: fpdb_import.py:318 +msgid "sending finish message queue length =" +msgstr "" + +#: fpdb_import.py:445 fpdb_import.py:447 +msgid "Converting %s" +msgstr "" + +#: fpdb_import.py:485 +msgid "Hand processed but empty" +msgstr "" + +#: fpdb_import.py:506 +msgid "fpdb_import: sending hand to hud" +msgstr "" + +#: fpdb_import.py:509 +msgid "Failed to send hand to HUD: %s" +msgstr "" + +#: fpdb_import.py:524 +msgid "Unknown filter filter_name:'%s' in filter:'%s'" +msgstr "" + +#: fpdb_import.py:535 +msgid "" +"Error No.%s please send the hand causing this to fpdb-main@lists.sourceforge." +"net so we can fix the problem." +msgstr "" + +#: fpdb_import.py:536 +msgid "Filename:" +msgstr "" + +#: fpdb_import.py:537 +msgid "" +"Here is the first line of the hand so you can identify it. Please mention " +"that the error was a ValueError:" +msgstr "" + +#: fpdb_import.py:539 +msgid "Hand logged to hand-errors.txt" +msgstr "" + +#: fpdb_import.py:595 +msgid "Importing" +msgstr "" + +#: fpdb_import.py:623 +msgid "CLI for importing hands is GuiBulkImport.py" +msgstr "" + +#: interlocks.py:52 +msgid "lock already held by:" +msgstr "" + +#: test_Database.py:50 +msgid "DEBUG: Testing variance function" +msgstr "" + +#: test_Database.py:51 +msgid "DEBUG: result: %s expecting: 0.666666 (result-expecting ~= 0.0): %s" +msgstr "" + +#: windows_make_bats.py:39 +msgid "" +"\n" +"This script is only for windows\n" +msgstr "" + +#: windows_make_bats.py:66 +msgid "" +"\n" +"no gtk directories found in your path - install gtk or edit the path " +"manually\n" +msgstr "" From c344d206ff26b62acf91b9b46574edd056657fb8 Mon Sep 17 00:00:00 2001 From: Worros Date: Tue, 8 Feb 2011 17:03:35 +0800 Subject: [PATCH 081/182] Regression: Fix testdata value in Winamax file --- ...0.Real.side.pot.with.bad.collected.Biggest.stack.wins.txt.hp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/regression-test-files/cash/Winamax/Flop/NLHE-FR-EUR-0.02-0.05-201010.Real.side.pot.with.bad.collected.Biggest.stack.wins.txt.hp b/pyfpdb/regression-test-files/cash/Winamax/Flop/NLHE-FR-EUR-0.02-0.05-201010.Real.side.pot.with.bad.collected.Biggest.stack.wins.txt.hp index 18c28727..230e9ebe 100644 --- a/pyfpdb/regression-test-files/cash/Winamax/Flop/NLHE-FR-EUR-0.02-0.05-201010.Real.side.pot.with.bad.collected.Biggest.stack.wins.txt.hp +++ b/pyfpdb/regression-test-files/cash/Winamax/Flop/NLHE-FR-EUR-0.02-0.05-201010.Real.side.pot.with.bad.collected.Biggest.stack.wins.txt.hp @@ -381,7 +381,7 @@ 'street4CheckCallRaiseDone': False, 'street4Raises': 0, 'street4Seen': False, - 'totalProfit': 483, + 'totalProfit': 319, 'tourneyTypeId': None, 'tourneysPlayersIds': None, 'winnings': 656, From 200c3a3ff68d818fb8c495f774c40ca5648910da Mon Sep 17 00:00:00 2001 From: DoNoBaN Date: Tue, 8 Feb 2011 23:02:16 +0100 Subject: [PATCH 082/182] Fixed problems in 3/4 bet --- pyfpdb/SQL.py | 16 ++++++++-------- pyfpdb/Stats.py | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 69b02d25..3f211dd5 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -1876,10 +1876,10 @@ class Sql: cast(hp2.street0_3BDone as integer) AS TB_0, cast(hp2.street0_4BChance as integer) AS FB_opp_0, cast(hp2.street0_4BDone as integer) AS FB_0, - cast(hp2.street0_FoldTo3BChance as integer) AS TTB_opp_0, - cast(hp2.street0_FoldTo3BDone as integer) AS TTB_0, - cast(hp2.street0_FoldTo4BChance as integer) AS FTB_opp_0, - cast(hp2.street0_FoldTo4BDone as integer) AS FTB_0, + cast(hp2.street0_FoldTo3BChance as integer) AS F3B_opp_0, + cast(hp2.street0_FoldTo3BDone as integer) AS F3B_0, + cast(hp2.street0_FoldTo4BChance as integer) AS F4B_opp_0, + cast(hp2.street0_FoldTo4BDone as integer) AS F4B_0, cast(hp2.street1Seen as integer) AS saw_f, cast(hp2.street1Seen as integer) AS saw_1, cast(hp2.street2Seen as integer) AS saw_2, @@ -1987,10 +1987,10 @@ class Sql: cast(hp2.street0_3BDone as integer) AS TB_0, cast(hp2.street0_4BChance as integer) AS FB_opp_0, cast(hp2.street0_4BDone as integer) AS FB_0, - cast(hp2.street0_FoldTo3BChance as integer) AS TB_opp_0, - cast(hp2.street0_FoldTo3BDone as integer) AS TB_0, - cast(hp2.street0_FoldTo4BChance as integer) AS FB_opp_0, - cast(hp2.street0_FoldTo4BDone as integer) AS FB_0, + cast(hp2.street0_FoldTo3BChance as integer) AS F3B_opp_0, + cast(hp2.street0_FoldTo3BDone as integer) AS F3B_0, + cast(hp2.street0_FoldTo4BChance as integer) AS F4B_opp_0, + cast(hp2.street0_FoldTo4BDone as integer) AS F4B_0, cast(hp2.street1Seen as integer) AS saw_f, cast(hp2.street1Seen as integer) AS saw_1, cast(hp2.street2Seen as integer) AS saw_2, diff --git a/pyfpdb/Stats.py b/pyfpdb/Stats.py index 97d4aa8f..97d37d7c 100755 --- a/pyfpdb/Stats.py +++ b/pyfpdb/Stats.py @@ -442,13 +442,13 @@ def three_B(stat_dict, player): """ Three bet preflop/3rd.""" stat = 0.0 try: - stat = float(stat_dict[player]['Tb_0'])/float(stat_dict[player]['Tb_opp_0']) + stat = float(stat_dict[player]['tb_0'])/float(stat_dict[player]['tb_opp_0']) return (stat, '%3.1f' % (100.0*stat), '3B=%3.1f%%' % (100.0*stat), '3B_pf=%3.1f%%' % (100.0*stat), - '(%d/%d)' % (stat_dict[player]['Tb_0'], stat_dict[player]['Tb_opp_0']), - _('% 4 Bet preflop/3rd')) + '(%d/%d)' % (stat_dict[player]['tb_0'], stat_dict[player]['tb_opp_0']), + _('% 3 Bet preflop/3rd')) except: return (stat, 'NA', @@ -461,12 +461,12 @@ def four_B(stat_dict, player): """ Four bet preflop/4rd.""" stat = 0.0 try: - stat = float(stat_dict[player]['Fb_0'])/float(stat_dict[player]['Fb_opp_0']) + stat = float(stat_dict[player]['fb_0'])/float(stat_dict[player]['fb_opp_0']) return (stat, '%3.1f' % (100.0*stat), '4B=%3.1f%%' % (100.0*stat), '4B_pf=%3.1f%%' % (100.0*stat), - '(%d/%d)' % (stat_dict[player]['Fb_0'], stat_dict[player]['Fb_opp_0']), + '(%d/%d)' % (stat_dict[player]['fb_0'], stat_dict[player]['fb_opp_0']), _('% 4 Bet preflop/4rd')) except: return (stat, From ce7f514f085a308a6e570e3b9b9481dd8b0270ec Mon Sep 17 00:00:00 2001 From: Eratosthenes Date: Tue, 8 Feb 2011 18:32:25 -0500 Subject: [PATCH 083/182] Allow crash-free dragging, etc on X. --- pyfpdb/XTables.py | 58 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/pyfpdb/XTables.py b/pyfpdb/XTables.py index b9900054..703d9d39 100644 --- a/pyfpdb/XTables.py +++ b/pyfpdb/XTables.py @@ -88,23 +88,51 @@ class Table(Table_Window): if w.id == id: return (w, top_level) + #def get_geometry(self): + #try: + #my_geo = self.window.get_geometry() + #if self.parent is None: + #return {'x' : my_geo.x, + #'y' : my_geo.y, + #'width' : my_geo.width, + #'height' : my_geo.height + #} + #else: + #pa_geo = self.parent.get_geometry() + #return {'x' : my_geo.x + pa_geo.x, + #'y' : my_geo.y + pa_geo.y, + #'width' : my_geo.width, + #'height' : my_geo.height + #} + #except: + #return None + def get_geometry(self): + geo_re = ''' + Absolute\supper-left\sX: \s+ (?P\d+) # x + .+ + Absolute\supper-left\sY: \s+ (?P\d+) # y + .+ + Width: \s+ (?P\d+) # width + .+ + Height: \s+ (?P\d+) # height + ''' + des_re = 'No such window with id' + + listing = os.popen("xwininfo -id %d -stats" % (self.number)).read() + + mo = re.search(des_re, listing) + if mo is not None: + return None # table has been destroyed + + mo = re.search(geo_re, listing, re.VERBOSE|re.DOTALL) try: - my_geo = self.window.get_geometry() - if self.parent is None: - return {'x' : my_geo.x, - 'y' : my_geo.y, - 'width' : my_geo.width, - 'height' : my_geo.height - } - else: - pa_geo = self.parent.get_geometry() - return {'x' : my_geo.x + pa_geo.x, - 'y' : my_geo.y + pa_geo.y, - 'width' : my_geo.width, - 'height' : my_geo.height - } - except: + return {'x' : int(mo.groupdict()['X']), + 'y' : int(mo.groupdict()['Y']), + 'width' : int(mo.groupdict()['W']), + 'height' : int(mo.groupdict()['H']) + } + except AttributeError: return None def get_window_title(self): From 8c247e11f67bee67ce74b2cebe0f8f2aa1b755a4 Mon Sep 17 00:00:00 2001 From: Eratosthenes Date: Tue, 8 Feb 2011 18:33:22 -0500 Subject: [PATCH 084/182] Turn on HUD dragging and autoclosing. --- pyfpdb/HUD_main.pyw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/HUD_main.pyw b/pyfpdb/HUD_main.pyw index 4a8cbc0d..d9a4ab73 100755 --- a/pyfpdb/HUD_main.pyw +++ b/pyfpdb/HUD_main.pyw @@ -128,7 +128,7 @@ class HUD_main(object): self.main_window.set_icon_stock(gtk.STOCK_HOME) if not options.hidden: self.main_window.show_all() -# gobject.timeout_add(100, self.check_tables) + gobject.timeout_add(100, self.check_tables) except: log.exception("Error initializing main_window") From 4db42086da3cf50aae1501af0abb90ecf7159511 Mon Sep 17 00:00:00 2001 From: Worros Date: Wed, 9 Feb 2011 13:18:53 +0800 Subject: [PATCH 085/182] Example config: Add Everest --- pyfpdb/HUD_config.xml.example | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/pyfpdb/HUD_config.xml.example b/pyfpdb/HUD_config.xml.example index 7bb30e0f..803b9694 100644 --- a/pyfpdb/HUD_config.xml.example +++ b/pyfpdb/HUD_config.xml.example @@ -599,6 +599,42 @@ Left-Drag to Move" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -789,6 +825,7 @@ Left-Drag to Move" + From af5eecd5b3be9537390fa8cb90eec124a4e3ffe0 Mon Sep 17 00:00:00 2001 From: Worros Date: Wed, 9 Feb 2011 13:19:52 +0800 Subject: [PATCH 086/182] EverestToFpdb: New converter Doesn't do much yet, but at least didn't crash --- pyfpdb/EverestToFpdb.py | 259 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 pyfpdb/EverestToFpdb.py diff --git a/pyfpdb/EverestToFpdb.py b/pyfpdb/EverestToFpdb.py new file mode 100644 index 00000000..dbb588be --- /dev/null +++ b/pyfpdb/EverestToFpdb.py @@ -0,0 +1,259 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2011, Carl Gherardi +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# 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 General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +######################################################################## + +import L10n +_ = L10n.get_translation() + +import sys +import logging +from HandHistoryConverter import * +from decimal import Decimal + + +class Everest(HandHistoryConverter): + sitename = "Everest" + filetype = "text" + codepage = "utf8" + siteID = 15 + + substitutions = { + 'LS' : u"\$|\xe2\x82\xac|\u20ac|", + 'TAB' : u"-\u2013'\s\da-zA-Z", # legal characters for tablename + } + + # Static regexes + re_SplitHands = re.compile(r'\n+(?=)') + re_GameInfo = re.compile(u""" + """ % substitutions, re.VERBOSE|re.MULTILINE) + re_HandInfo = re.compile(r'[0-9]+)"\/>') + re_PlayerInfo = re.compile(r'', re.MULTILINE) + re_Board = re.compile(r'(?P.+)<\/COMMUNITY>', re.MULTILINE) + + # The following are also static regexes: there is no need to call + # compilePlayerRegexes (which does nothing), since players are identified + # not by name but by seat number + re_PostSB = re.compile(r'timestamp="[0-9]+" )?player="(?P[0-9])" amount="(?P[.0-9]+)"/>', re.MULTILINE) + re_PostBB = re.compile(r'timestamp="[0-9]+" )?player="(?P[0-9])" amount="(?P[.0-9]+)"/>', re.MULTILINE) + re_PostBoth = re.compile(r'', re.MULTILINE) + #re_Antes = ??? + #re_BringIn = ??? + re_HeroCards = re.compile(r'timestamp="[0-9]+" )?player="(?P[0-9])"( amount="(?P[.0-9]+)")?/>', re.MULTILINE) + re_ShowdownAction = re.compile(r'', re.MULTILINE) + re_CollectPot = re.compile(r'', re.MULTILINE) + re_ShownCards = re.compile(r'', re.MULTILINE) + + def compilePlayerRegexs(self, hand): + pass + + def playerNameFromSeatNo(self, seatNo, hand): + # This special function is required because Carbon Poker records + # actions by seat number, not by the player's name + for p in hand.players: + if p[0] == int(seatNo): + return p[1] + + def readSupportedGames(self): + return [ + ["ring", "hold", "nl"], + ["ring", "hold", "pl"], + #["tour", "hold", "nl"] + ] + + def determineGameType(self, handText): + m = self.re_GameInfo.search(handText) + m2 = self.re_HandInfo.search(handText) + if not m: + # Information about the game type appears only at the beginning of + # a hand history file; hence it is not supplied with the second + # and subsequent hands. In these cases we use the value previously + # stored. + try: + self.info + return self.info + except AttributeError: + tmp = handText[0:100] + log.error(_("determineGameType: Unable to recognise gametype from: '%s'") % tmp) + log.error(_("determineGameType: Raising FpdbParseError")) + raise FpdbParseError(_("Unable to recognise gametype from: '%s'") % tmp) + + if not m2: + tmp = handText[0:100] + raise FpdbParseError(_("Unable to recognise handinfo from: '%s'") % tmp) + + self.info = {} + mg = m.groupdict() + mg.update(m2.groupdict()) + print "DEBUG: mg: %s" % mg + + limits = { 'No Limit':'nl', 'No Limit ':'nl', 'Limit':'fl', 'pot-limit':'pl' } + games = { # base, category + 'Holdem' : ('hold','holdem'), + 'Holdem Tournament' : ('hold','holdem'), + 'omaha-hi' : ('hold','omahahi'), + } + + if 'LIMIT' in mg: + self.info['limitType'] = limits[mg['LIMIT']] + if 'GAME' in mg: + (self.info['base'], self.info['category']) = games[mg['GAME']] + if 'SB' in mg: + self.info['sb'] = mg['SB'] + if 'BB' in mg: + self.info['bb'] = mg['BB'] + + self.info['type'] = 'ring' + if mg['CURRENCY'] == u'\u20ac': + self.info['currency'] = 'EUR' + + # HACK - tablename not in every hand. + self.info['TABLENAME'] = mg['TABLE'] + + print "DEBUG: self.info: %s" % self.info + + return self.info + + def readHandInfo(self, hand): + m = self.re_HandInfo.search(hand.handText) + if m is None: + logging.info(_("Didn't match re_HandInfo")) + logging.info(hand.handText) + raise FpdbParseError(_("No match in readHandInfo.")) + hand.handid = m.group('HID') + hand.tablename = self.info['TABLENAME'] + hand.maxseats = None + #FIXME: u'DATETIME': u'1291155932' + hand.startTime = datetime.datetime.strptime('201102091158', '%Y%m%d%H%M') + #hand.startTime = datetime.datetime.strptime(m.group('DATETIME')[:12], '%Y%m%d%H%M') + + def readPlayerStacks(self, hand): + m = self.re_PlayerInfo.finditer(hand.handText) + for a in m: + print "DEBUG: adding %s %s %s" % (a.group('SEAT'), a.group('PNAME'), a.group('CASH')) + hand.addPlayer(a.group('SEAT'), a.group('PNAME'), a.group('CASH')) + + def markStreets(self, hand): + #if hand.gametype['base'] == 'hold': + + m = re.search(r".+?(?=)|.+)" + r"((?P\S\S, \S\S, \S\S<\/COMMUNITY>.+?(?=)|.+))?" + r"((?P\S\S<\/COMMUNITY>.+?(?=)|.+))?" + r"((?P\S\S<\/COMMUNITY>.+))?", hand.handText,re.DOTALL) + #import pprint + #pp = pprint.PrettyPrinter(indent=4) + #pp.pprint(m.groupdict()) + hand.addStreets(m) + + def readCommunityCards(self, hand, street): + m = self.re_Board.search(hand.streets[street]) + print "DEBUG: hand.streets[street]: %s" % hand.streets[street] + if street == 'FLOP': + hand.setCommunityCards(street, m.group('CARDS').split(',')) + elif street in ('TURN','RIVER'): + hand.setCommunityCards(street, [m.group('CARDS').split(',')[-1]]) + + def readAntes(self, hand): + pass # ??? + + def readBringIn(self, hand): + pass # ??? + + def readBlinds(self, hand): + for a in self.re_PostSB.finditer(hand.handText): + #print "DEBUG: found sb: '%s' '%s'" %(self.playerNameFromSeatNo(a.group('PSEAT'), hand), a.group('SB')) + hand.addBlind(self.playerNameFromSeatNo(a.group('PSEAT'), hand),'small blind', a.group('SB')) + + for a in self.re_PostBB.finditer(hand.handText): + #print "DEBUG: found bb: '%s' '%s'" %(self.playerNameFromSeatNo(a.group('PSEAT'), hand), a.group('BB')) + hand.addBlind(self.playerNameFromSeatNo(a.group('PSEAT'), hand), 'big blind', a.group('BB')) + for a in self.re_PostBoth.finditer(hand.handText): + bb = Decimal(self.info['bb']) + amount = Decimal(a.group('SBBB')) + if amount < bb: + hand.addBlind(self.playerNameFromSeatNo(a.group('PSEAT'), + hand), 'small blind', a.group('SBBB')) + elif amount == bb: + hand.addBlind(self.playerNameFromSeatNo(a.group('PSEAT'), + hand), 'big blind', a.group('SBBB')) + else: + hand.addBlind(self.playerNameFromSeatNo(a.group('PSEAT'), + hand), 'both', a.group('SBBB')) + + def readButton(self, hand): + hand.buttonpos = int(self.re_Button.search(hand.handText).group('BUTTON')) + + def readHeroCards(self, hand): + m = self.re_HeroCards.search(hand.handText) + if m: + hand.hero = self.playerNameFromSeatNo(m.group('PSEAT'), hand) + cards = m.group('CARDS').split(',') + hand.addHoleCards('PREFLOP', hand.hero, closed=cards, shown=False, + mucked=False, dealt=True) + + def readAction(self, hand, street): + logging.debug("readAction (%s)" % street) + m = self.re_Action.finditer(hand.streets[street]) + for action in m: + logging.debug("%s %s" % (action.group('ATYPE'), + action.groupdict())) + player = self.playerNameFromSeatNo(action.group('PSEAT'), hand) + if action.group('ATYPE') == 'RAISE': + hand.addCallandRaise(street, player, action.group('BET')) + elif action.group('ATYPE') == 'CALL': + hand.addCall(street, player, action.group('BET')) + elif action.group('ATYPE') == 'BET': + hand.addBet(street, player, action.group('BET')) + elif action.group('ATYPE') in ('FOLD', 'SIT_OUT'): + hand.addFold(street, player) + elif action.group('ATYPE') == 'CHECK': + hand.addCheck(street, player) + elif action.group('ATYPE') == 'ALL_IN': + hand.addAllIn(street, player, action.group('BET')) + else: + logging.debug(_("Unimplemented readAction: %s %s" + % (action.group('PSEAT'),action.group('ATYPE'),))) + + def readShowdownActions(self, hand): + for shows in self.re_ShowdownAction.finditer(hand.handText): + cards = shows.group('CARDS').split(',') + hand.addShownCards(cards, + self.playerNameFromSeatNo(shows.group('PSEAT'), + hand)) + + def readCollectPot(self, hand): + for m in self.re_CollectPot.finditer(hand.handText): + pots[int(m.group('PSEAT'))] += Decimal(m.group('POT')) + + def readShownCards(self, hand): + for m in self.re_ShownCards.finditer(hand.handText): + cards = m.group('CARDS').split(',') + hand.addShownCards(cards=cards, player=self.playerNameFromSeatNo(m.group('PSEAT'), hand)) + From e29a12a0c4aa8256ef80f24d22bd54de02894c2b Mon Sep 17 00:00:00 2001 From: Worros Date: Wed, 9 Feb 2011 15:28:17 +0800 Subject: [PATCH 087/182] Everest: Partially fix blinds --- pyfpdb/EverestToFpdb.py | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/pyfpdb/EverestToFpdb.py b/pyfpdb/EverestToFpdb.py index dbb588be..abec1c81 100644 --- a/pyfpdb/EverestToFpdb.py +++ b/pyfpdb/EverestToFpdb.py @@ -59,9 +59,7 @@ class Everest(HandHistoryConverter): # The following are also static regexes: there is no need to call # compilePlayerRegexes (which does nothing), since players are identified # not by name but by seat number - re_PostSB = re.compile(r'timestamp="[0-9]+" )?player="(?P[0-9])" amount="(?P[.0-9]+)"/>', re.MULTILINE) - re_PostBB = re.compile(r'timestamp="[0-9]+" )?player="(?P[0-9])" amount="(?P[.0-9]+)"/>', re.MULTILINE) - re_PostBoth = re.compile(r'', re.MULTILINE) + re_PostXB = re.compile(r'', re.MULTILINE) #re_Antes = ??? #re_BringIn = ??? re_HeroCards = re.compile(r' Date: Wed, 9 Feb 2011 16:47:35 +0800 Subject: [PATCH 088/182] Everest: More updates. Now have a graph with bumps in it --- pyfpdb/EverestToFpdb.py | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/pyfpdb/EverestToFpdb.py b/pyfpdb/EverestToFpdb.py index abec1c81..1882bbd8 100644 --- a/pyfpdb/EverestToFpdb.py +++ b/pyfpdb/EverestToFpdb.py @@ -63,9 +63,9 @@ class Everest(HandHistoryConverter): #re_Antes = ??? #re_BringIn = ??? re_HeroCards = re.compile(r'timestamp="[0-9]+" )?player="(?P[0-9])"( amount="(?P[.0-9]+)")?/>', re.MULTILINE) + re_Action = re.compile(r'<(?PFOLD|BET) position="(?P[0-9])"( amount="(?P[.0-9]+)")?\/>', re.MULTILINE) re_ShowdownAction = re.compile(r'', re.MULTILINE) - re_CollectPot = re.compile(r'', re.MULTILINE) re_ShownCards = re.compile(r'', re.MULTILINE) @@ -200,25 +200,34 @@ class Everest(HandHistoryConverter): mucked=False, dealt=True) def readAction(self, hand, street): - logging.debug("readAction (%s)" % street) + print "DEBUG: readAction (%s)" % street m = self.re_Action.finditer(hand.streets[street]) + curr_pot = Decimal('0') for action in m: - logging.debug("%s %s" % (action.group('ATYPE'), - action.groupdict())) + print " DEBUG: %s %s" % (action.group('ATYPE'), action.groupdict()) player = self.playerNameFromSeatNo(action.group('PSEAT'), hand) - if action.group('ATYPE') == 'RAISE': - hand.addCallandRaise(street, player, action.group('BET')) - elif action.group('ATYPE') == 'CALL': - hand.addCall(street, player, action.group('BET')) - elif action.group('ATYPE') == 'BET': + if action.group('ATYPE') == 'BET': + #Gah! BET can mean check, bet, call or raise... + if Decimal(action.group('BET')) > 0 and curr_pot == 0: + # Open + curr_pot = Decimal(action.group('BET')) + hand.addBet(street, player, action.group('BET')) + elif Decimal(action.group('BET')) > 0 and curr_pot > 0: + # Raise or call + if Decimal(action.group('BET')) > curr_pot: + # Raise + curr_pot = Decimal(action.group('BET')) + hand.addCallandRaise(street, player, action.group('BET')) + elif Decimal(action.group('BET')) <= curr_pot: + # Call + hand.addCall(street, player, action.group('BET')) + if action.group('BET') == '0': + hand.addCheck(street, player) hand.addBet(street, player, action.group('BET')) elif action.group('ATYPE') in ('FOLD', 'SIT_OUT'): hand.addFold(street, player) - elif action.group('ATYPE') == 'CHECK': - hand.addCheck(street, player) - elif action.group('ATYPE') == 'ALL_IN': - hand.addAllIn(street, player, action.group('BET')) else: + print "Unimplemented readAction: %s %s" % (action.group('PSEAT'),action.group('ATYPE'),) logging.debug(_("Unimplemented readAction: %s %s" % (action.group('PSEAT'),action.group('ATYPE'),))) @@ -231,7 +240,9 @@ class Everest(HandHistoryConverter): def readCollectPot(self, hand): for m in self.re_CollectPot.finditer(hand.handText): - pots[int(m.group('PSEAT'))] += Decimal(m.group('POT')) + player = self.playerNameFromSeatNo(m.group('PSEAT'), hand) + print "DEBUG: %s collects %s" % (player, m.group('POT')) + hand.addCollectPot(player, m.group('POT')) def readShownCards(self, hand): for m in self.re_ShownCards.finditer(hand.handText): From c2fa4b72caf47d5092634687362b37a30931f9da Mon Sep 17 00:00:00 2001 From: Worros Date: Wed, 9 Feb 2011 17:13:04 +0800 Subject: [PATCH 089/182] Everest: Cleanup and partially functional? --- pyfpdb/EverestToFpdb.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/pyfpdb/EverestToFpdb.py b/pyfpdb/EverestToFpdb.py index 1882bbd8..3c4b408b 100644 --- a/pyfpdb/EverestToFpdb.py +++ b/pyfpdb/EverestToFpdb.py @@ -183,10 +183,12 @@ class Everest(HandHistoryConverter): def readBlinds(self, hand): for a in self.re_PostXB.finditer(hand.handText): + amount = "%.2f" % float(int(a.group('XB'))/100) + print "DEBUG: readBlinds amount: %s" % amount if Decimal(a.group('XB'))/100 == Decimal(self.info['sb']): - hand.addBlind(self.playerNameFromSeatNo(a.group('PSEAT'), hand),'small blind', a.group('XB')) + hand.addBlind(self.playerNameFromSeatNo(a.group('PSEAT'), hand),'small blind', amount) elif Decimal(a.group('XB'))/100 == Decimal(self.info['bb']): - hand.addBlind(self.playerNameFromSeatNo(a.group('PSEAT'), hand),'big blind', a.group('XB')) + hand.addBlind(self.playerNameFromSeatNo(a.group('PSEAT'), hand),'big blind', amount) def readButton(self, hand): hand.buttonpos = int(self.re_Button.search(hand.handText).group('BUTTON')) @@ -207,23 +209,24 @@ class Everest(HandHistoryConverter): print " DEBUG: %s %s" % (action.group('ATYPE'), action.groupdict()) player = self.playerNameFromSeatNo(action.group('PSEAT'), hand) if action.group('ATYPE') == 'BET': + amount = Decimal(action.group('BET')) + amountstr = "%.2f" % float(int(action.group('BET'))/100) #Gah! BET can mean check, bet, call or raise... - if Decimal(action.group('BET')) > 0 and curr_pot == 0: + if amount > 0 and curr_pot == 0: # Open - curr_pot = Decimal(action.group('BET')) - hand.addBet(street, player, action.group('BET')) + curr_pot = amount + hand.addBet(street, player, amountstr) elif Decimal(action.group('BET')) > 0 and curr_pot > 0: # Raise or call - if Decimal(action.group('BET')) > curr_pot: + if amount > curr_pot: # Raise - curr_pot = Decimal(action.group('BET')) - hand.addCallandRaise(street, player, action.group('BET')) - elif Decimal(action.group('BET')) <= curr_pot: + curr_pot = amount + hand.addCallandRaise(street, player, amountstr) + elif amount <= curr_pot: # Call - hand.addCall(street, player, action.group('BET')) + hand.addCall(street, player, amountstr) if action.group('BET') == '0': hand.addCheck(street, player) - hand.addBet(street, player, action.group('BET')) elif action.group('ATYPE') in ('FOLD', 'SIT_OUT'): hand.addFold(street, player) else: @@ -242,7 +245,7 @@ class Everest(HandHistoryConverter): for m in self.re_CollectPot.finditer(hand.handText): player = self.playerNameFromSeatNo(m.group('PSEAT'), hand) print "DEBUG: %s collects %s" % (player, m.group('POT')) - hand.addCollectPot(player, m.group('POT')) + hand.addCollectPot(player, str(int(m.group('POT'))/100)) def readShownCards(self, hand): for m in self.re_ShownCards.finditer(hand.handText): From ec8d3d36325393f1972fa884aa9f29620491c9c0 Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 10 Feb 2011 11:38:36 +0800 Subject: [PATCH 090/182] Regression: Everest sample --- .../Flop/PLO-EUR-5-10-Unknown-Sample.txt | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt diff --git a/pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt b/pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt new file mode 100644 index 00000000..1b983f37 --- /dev/null +++ b/pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt @@ -0,0 +1,34 @@ + + + + + + + + -- + 8h + -- + 2c + -- + Qc + -- + Ah + + + 5750 + 6s, 8c, Jh + + + 17750 + 6h + + + 17750 + 4c + + + + 17750 + + + From a90a63b824ef46017c212d3afe6e6019e5ff4bfd Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 10 Feb 2011 12:14:45 +0800 Subject: [PATCH 091/182] Regression: Everest PLO data --- .../Flop/PLO-EUR-5-10-Unknown-Sample.txt.gt | 1 + .../PLO-EUR-5-10-Unknown-Sample.txt.hands | 30 +++ .../Flop/PLO-EUR-5-10-Unknown-Sample.txt.hp | 196 ++++++++++++++++++ 3 files changed, 227 insertions(+) create mode 100644 pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt.gt create mode 100644 pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt.hands create mode 100644 pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt.hp diff --git a/pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt.gt b/pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt.gt new file mode 100644 index 00000000..4ed55f6d --- /dev/null +++ b/pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt.gt @@ -0,0 +1 @@ +(15, 'EUR', 'ring', 'hold', 'omahahi', 'pl', 'h', 500, 1000, 1000, 2000) diff --git a/pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt.hands b/pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt.hands new file mode 100644 index 00000000..769e5899 --- /dev/null +++ b/pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt.hands @@ -0,0 +1,30 @@ +{ 'boardcard1': 44, + 'boardcard2': 0, + 'boardcard3': 0, + 'boardcard4': 5, + 'boardcard5': 29, + 'gametypeId': 1, + 'importTime': None, + 'maxSeats': 10, + 'playersAtShowdown': 0, + 'playersAtStreet1': 2, + 'playersAtStreet2': 2, + 'playersAtStreet3': 2, + 'playersAtStreet4': 0, + 'playersVpi': 2, + 'seats': 2, + 'showdownPot': 0, + 'siteHandNo': u'6351562000', + 'startTime': datetime.datetime(2011, 2, 9, 11, 58), + 'street0Raises': 1, + 'street1Pot': 18000, + 'street1Raises': 1, + 'street2Pot': 18000, + 'street2Raises': 0, + 'street3Pot': 36000, + 'street3Raises': 1, + 'street4Pot': 0, + 'street4Raises': 0, + 'tableName': u'Toulouse-2', + 'texture': None, + 'tourneyId': None} diff --git a/pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt.hp b/pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt.hp new file mode 100644 index 00000000..933cf44d --- /dev/null +++ b/pyfpdb/regression-test-files/cash/Everest/Flop/PLO-EUR-5-10-Unknown-Sample.txt.hp @@ -0,0 +1,196 @@ +{ u'Hero': { 'card1': 0, + 'card2': 0, + 'card3': 0, + 'card4': 0, + 'card5': 0, + 'card6': 0, + 'card7': 0, + 'foldBbToStealChance': False, + 'foldSbToStealChance': False, + 'foldToOtherRaisedStreet0': False, + 'foldToOtherRaisedStreet1': False, + 'foldToOtherRaisedStreet2': False, + 'foldToOtherRaisedStreet3': True, + 'foldToOtherRaisedStreet4': False, + 'foldToStreet1CBChance': False, + 'foldToStreet1CBDone': False, + 'foldToStreet2CBChance': False, + 'foldToStreet2CBDone': False, + 'foldToStreet3CBChance': False, + 'foldToStreet3CBDone': False, + 'foldToStreet4CBChance': False, + 'foldToStreet4CBDone': False, + 'foldedBbToSteal': False, + 'foldedSbToSteal': False, + 'other3BStreet0': False, + 'other4BStreet0': False, + 'otherRaisedStreet0': False, + 'otherRaisedStreet1': True, + 'otherRaisedStreet2': False, + 'otherRaisedStreet3': True, + 'otherRaisedStreet4': False, + 'position': 'S', + 'raiseFirstInChance': True, + 'raisedFirstIn': True, + 'rake': 0, + 'sawShowdown': False, + 'seatNo': u'0', + 'sitout': False, + 'startCards': 0, + 'startCash': 10000000, + 'street0Aggr': True, + 'street0Bets': 1, + 'street0Calls': 0, + 'street0Raises': 0, + 'street0VPI': True, + 'street0_3BChance': False, + 'street0_3BDone': False, + 'street0_4BChance': False, + 'street0_4BDone': False, + 'street0_FoldTo3BChance': False, + 'street0_FoldTo3BDone': False, + 'street0_FoldTo4BChance': False, + 'street0_FoldTo4BDone': False, + 'street1Aggr': False, + 'street1Bets': 0, + 'street1CBChance': False, + 'street1CBDone': False, + 'street1Calls': 1, + 'street1CheckCallRaiseChance': False, + 'street1CheckCallRaiseDone': False, + 'street1Raises': 0, + 'street1Seen': True, + 'street2Aggr': False, + 'street2Bets': 0, + 'street2CBChance': False, + 'street2CBDone': False, + 'street2Calls': 0, + 'street2CheckCallRaiseChance': False, + 'street2CheckCallRaiseDone': False, + 'street2Raises': 0, + 'street2Seen': True, + 'street3Aggr': False, + 'street3Bets': 0, + 'street3CBChance': False, + 'street3CBDone': False, + 'street3Calls': 0, + 'street3CheckCallRaiseChance': False, + 'street3CheckCallRaiseDone': False, + 'street3Raises': 0, + 'street3Seen': True, + 'street4Aggr': False, + 'street4Bets': 0, + 'street4CBChance': False, + 'street4CBDone': False, + 'street4Calls': 0, + 'street4CheckCallRaiseChance': False, + 'street4CheckCallRaiseDone': False, + 'street4Raises': 0, + 'street4Seen': False, + 'totalProfit': -9000, + 'tourneyTypeId': None, + 'tourneysPlayersIds': None, + 'winnings': 0, + 'wonAtSD': 0.0, + 'wonWhenSeenStreet1': 0.0, + 'wonWhenSeenStreet2': 0.0, + 'wonWhenSeenStreet3': 0.0, + 'wonWhenSeenStreet4': 0.0}, + u'Villain': { 'card1': 0, + 'card2': 0, + 'card3': 0, + 'card4': 0, + 'card5': 0, + 'card6': 0, + 'card7': 0, + 'foldBbToStealChance': True, + 'foldSbToStealChance': False, + 'foldToOtherRaisedStreet0': False, + 'foldToOtherRaisedStreet1': False, + 'foldToOtherRaisedStreet2': False, + 'foldToOtherRaisedStreet3': False, + 'foldToOtherRaisedStreet4': False, + 'foldToStreet1CBChance': False, + 'foldToStreet1CBDone': False, + 'foldToStreet2CBChance': False, + 'foldToStreet2CBDone': False, + 'foldToStreet3CBChance': False, + 'foldToStreet3CBDone': False, + 'foldToStreet4CBChance': False, + 'foldToStreet4CBDone': False, + 'foldedBbToSteal': False, + 'foldedSbToSteal': False, + 'other3BStreet0': False, + 'other4BStreet0': False, + 'otherRaisedStreet0': False, + 'otherRaisedStreet1': False, + 'otherRaisedStreet2': False, + 'otherRaisedStreet3': False, + 'otherRaisedStreet4': False, + 'position': 'B', + 'raiseFirstInChance': False, + 'raisedFirstIn': False, + 'rake': 300, + 'sawShowdown': False, + 'seatNo': u'4', + 'sitout': False, + 'startCards': 0, + 'startCash': 5000000, + 'street0Aggr': False, + 'street0Bets': 0, + 'street0Calls': 1, + 'street0Raises': 0, + 'street0VPI': True, + 'street0_3BChance': True, + 'street0_3BDone': False, + 'street0_4BChance': False, + 'street0_4BDone': False, + 'street0_FoldTo3BChance': False, + 'street0_FoldTo3BDone': False, + 'street0_FoldTo4BChance': False, + 'street0_FoldTo4BDone': False, + 'street1Aggr': True, + 'street1Bets': 1, + 'street1CBChance': False, + 'street1CBDone': False, + 'street1Calls': 0, + 'street1CheckCallRaiseChance': False, + 'street1CheckCallRaiseDone': False, + 'street1Raises': 0, + 'street1Seen': True, + 'street2Aggr': False, + 'street2Bets': 0, + 'street2CBChance': True, + 'street2CBDone': False, + 'street2Calls': 0, + 'street2CheckCallRaiseChance': False, + 'street2CheckCallRaiseDone': False, + 'street2Raises': 0, + 'street2Seen': True, + 'street3Aggr': True, + 'street3Bets': 1, + 'street3CBChance': False, + 'street3CBDone': False, + 'street3Calls': 0, + 'street3CheckCallRaiseChance': False, + 'street3CheckCallRaiseDone': False, + 'street3Raises': 0, + 'street3Seen': True, + 'street4Aggr': False, + 'street4Bets': 0, + 'street4CBChance': False, + 'street4CBDone': False, + 'street4Calls': 0, + 'street4CheckCallRaiseChance': False, + 'street4CheckCallRaiseDone': False, + 'street4Raises': 0, + 'street4Seen': False, + 'totalProfit': 8700, + 'tourneyTypeId': None, + 'tourneysPlayersIds': None, + 'winnings': 17700, + 'wonAtSD': 0.0, + 'wonWhenSeenStreet1': 1.0, + 'wonWhenSeenStreet2': 1.0, + 'wonWhenSeenStreet3': 1.0, + 'wonWhenSeenStreet4': 0.0}} From ab6fade578e953542dcce241fc5578521b82e2cf Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 10 Feb 2011 12:20:22 +0800 Subject: [PATCH 092/182] Option: Add Everest to alias list --- pyfpdb/Options.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyfpdb/Options.py b/pyfpdb/Options.py index 65ed888e..08b1f4cb 100644 --- a/pyfpdb/Options.py +++ b/pyfpdb/Options.py @@ -93,6 +93,7 @@ def site_alias(alias): "iPoker" : "iPoker", "Winamax" : "Winamax", "Win2day" : "Win2day", + "Everest" : "Everest", "Stars" : "PokerStars", "FTP" : "Full Tilt Poker", "Party" : "PartyPoker", From 7bb77a2d1ab827963edf40de5c1940e55aa43b93 Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 10 Feb 2011 12:22:59 +0800 Subject: [PATCH 093/182] THP: Bolt in Everest --- pyfpdb/TestHandsPlayers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyfpdb/TestHandsPlayers.py b/pyfpdb/TestHandsPlayers.py index de0ef6d6..31be4b1f 100755 --- a/pyfpdb/TestHandsPlayers.py +++ b/pyfpdb/TestHandsPlayers.py @@ -245,6 +245,7 @@ def main(argv=None): AbsoluteErrors = FpdbError('Absolute Poker') UltimateBetErrors = FpdbError('Ultimate Bet') EverleafErrors = FpdbError('Everleaf Poker') + EverestErrors = FpdbError('Everest Poker') CarbonErrors = FpdbError('Carbon') PKRErrors = FpdbError('PKR') iPokerErrors = FpdbError('iPoker') @@ -256,7 +257,7 @@ def main(argv=None): BetfairErrors, OnGameErrors, AbsoluteErrors, EverleafErrors, CarbonErrors, PKRErrors, iPokerErrors, WinamaxErrors, UltimateBetErrors, - Win2dayErrors, + Win2dayErrors, EverestErrors, ] sites = { @@ -273,6 +274,7 @@ def main(argv=None): 'iPoker' : False, 'Win2day' : False, 'Winamax' : False, + 'Everest' : False, } if test_all_sites == True: From 08a97fff91607da4df5a1ec641a8e356d7b8725d Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 10 Feb 2011 12:23:32 +0800 Subject: [PATCH 094/182] Regression: Fix fold to 3/4 bet in Stars CAP file --- .../NLHE-CAP-9max-USD-0.25-0.50-201011.Capped.preflop.txt.hp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyfpdb/regression-test-files/cash/Stars/Flop/NLHE-CAP-9max-USD-0.25-0.50-201011.Capped.preflop.txt.hp b/pyfpdb/regression-test-files/cash/Stars/Flop/NLHE-CAP-9max-USD-0.25-0.50-201011.Capped.preflop.txt.hp index 00d955be..cda351cb 100644 --- a/pyfpdb/regression-test-files/cash/Stars/Flop/NLHE-CAP-9max-USD-0.25-0.50-201011.Capped.preflop.txt.hp +++ b/pyfpdb/regression-test-files/cash/Stars/Flop/NLHE-CAP-9max-USD-0.25-0.50-201011.Capped.preflop.txt.hp @@ -49,7 +49,7 @@ 'street0_4BDone': False, 'street0_FoldTo3BChance': False, 'street0_FoldTo3BDone': False, - 'street0_FoldTo4BChance': False, + 'street0_FoldTo4BChance': True, 'street0_FoldTo4BDone': False, 'street1Aggr': False, 'street1Bets': 0, @@ -635,7 +635,7 @@ 'street0_3BDone': False, 'street0_4BChance': True, 'street0_4BDone': True, - 'street0_FoldTo3BChance': False, + 'street0_FoldTo3BChance': True, 'street0_FoldTo3BDone': False, 'street0_FoldTo4BChance': False, 'street0_FoldTo4BDone': False, From d8220e0b2efc4ed0bf68108b5b98fe64fc9668ef Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 10 Feb 2011 17:28:00 +0800 Subject: [PATCH 095/182] FTP: Allow odd FTP summary file to parse. Found an example summary file that only contained the player line: finished in XXXXrd place Player should now be added the TP table, hence the stats should actually show up in the grapher --- pyfpdb/FullTiltPokerSummary.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pyfpdb/FullTiltPokerSummary.py b/pyfpdb/FullTiltPokerSummary.py index 79f50f01..2edcd81e 100644 --- a/pyfpdb/FullTiltPokerSummary.py +++ b/pyfpdb/FullTiltPokerSummary.py @@ -80,6 +80,7 @@ class FullTiltPokerSummary(TourneySummary): re_Currency = re.compile(u"""(?P[%(LS)s]|FPP)""" % substitutions) re_Player = re.compile(u"""(?P[\d]+):\s(?P[^,\r\n]{2,15})(,(\s)?[%(LS)s](?P[.\d]+))?""") + re_Finished = re.compile(u"""(?P[^,\r\n]{2,15}) finished in (?P[\d]+)\S\S place""") re_DateTime = re.compile("\[(?P[0-9]{4})\/(?P[0-9]{2})\/(?P[0-9]{2})[\- ]+(?P[0-9]+):(?P[0-9]+):(?P[0-9]+)") @@ -126,6 +127,7 @@ class FullTiltPokerSummary(TourneySummary): elif mg['CURRENCY'] == "FPP": self.currency="PSFP" m = self.re_Player.finditer(self.summaryText) + playercount = 0 for a in m: mg = a.groupdict() #print "DEBUG: a.groupdict(): %s" % mg @@ -136,4 +138,14 @@ class FullTiltPokerSummary(TourneySummary): if 'WINNINGS' in mg and mg['WINNINGS'] != None: winnings = int(100*Decimal(mg['WINNINGS'])) self.addPlayer(rank, name, winnings, self.currency, None, None, None) + playercount += 1 + # Some files dont contain the normals lines, and only contain the line + # finished in XXXXrd place + if playercount == 0: + m = self.re_Finished.finditer(self.summaryText) + for a in m: + winnings = 0 + name = a.group('NAME') + rank = a.group('RANK') + self.addPlayer(rank, name, winnings, self.currency, None, None, None) From ee5d2feba291852b81a6d7f5a1b75ce3ec9ab6a6 Mon Sep 17 00:00:00 2001 From: Worros Date: Thu, 10 Feb 2011 18:45:12 +0800 Subject: [PATCH 096/182] Party: Fix tournament buyin parsing --- pyfpdb/PartyPokerToFpdb.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/pyfpdb/PartyPokerToFpdb.py b/pyfpdb/PartyPokerToFpdb.py index 2c07e138..65b6f0aa 100755 --- a/pyfpdb/PartyPokerToFpdb.py +++ b/pyfpdb/PartyPokerToFpdb.py @@ -330,13 +330,19 @@ class PartyPoker(HandHistoryConverter): # FIXME: there is no such property in Hand class self.isSNG = True if key == 'BUYIN': - # FIXME: it's dirty hack T_T - # code below assumes that tournament rake is equal to zero - if info[key] == None: - hand.buyin = '$0+$0' - else: - cur = info[key][0] if info[key][0] not in '0123456789' else '' - hand.buyin = info[key] + '+%s0' % cur + if hand.tourNo != None: + hand.buyin = 0 + hand.fee = 0 + hand.buyinCurrency = "FREE" + hand.isKO = False + if info[key].find("$")!=-1: + hand.buyinCurrency="USD" + elif info[key].find(u"€")!=-1: + hand.buyinCurrency="EUR" + else: + raise FpdbParseError(_("Failed to detect currency. HID: %s: '%s'" % (hand.handid, info[key]))) + info[key] = info[key].strip(u'$€') + hand.buyin = int(100*Decimal(info[key])) if key == 'LEVEL': hand.level = info[key] if key == 'PLAY' and info['PLAY'] != 'Real': From 4605b371f1339417e9bf90c10d8544eff40fffea Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 11 Feb 2011 00:02:45 +0800 Subject: [PATCH 097/182] Winamax: Fix tournament buyin and rake info --- pyfpdb/WinamaxToFpdb.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/pyfpdb/WinamaxToFpdb.py b/pyfpdb/WinamaxToFpdb.py index b8b5ed1e..9d4721ec 100644 --- a/pyfpdb/WinamaxToFpdb.py +++ b/pyfpdb/WinamaxToFpdb.py @@ -276,8 +276,15 @@ class Winamax(HandHistoryConverter): hand.isKO = False info['BIRAKE'] = info['BIRAKE'].strip(u'$€') - hand.buyin = int(100*Decimal(info['BIAMT'])) - hand.fee = int(100*Decimal(info['BIRAKE'])) + rake_factor = 1 + bi_factor = 1 + if info['BIAMT'].find(".") == -1: + bi_factor = 100 + if info['BIRAKE'].find(".") == -1: + rake_factor = 100 + + hand.buyin = bi_factor*info['BIAMT'] + hand.fee = rake_factor*info['BIRAKE'] else: hand.buyin = int(Decimal(info['BIAMT'])) hand.fee = 0 From 224e8207fc555220d2f41436e2d4362256457e9c Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 11 Feb 2011 12:47:43 +0800 Subject: [PATCH 098/182] SitenameSummary: Template file for summary importing --- pyfpdb/SitenameSummary.py | 100 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 pyfpdb/SitenameSummary.py diff --git a/pyfpdb/SitenameSummary.py b/pyfpdb/SitenameSummary.py new file mode 100644 index 00000000..d06b9831 --- /dev/null +++ b/pyfpdb/SitenameSummary.py @@ -0,0 +1,100 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +#Copyright 2008-2010 Steffen Schaumburg +#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. + +"""A site template for tounrey summary parsing""" + +import L10n +_ = L10n.get_translation() + +from decimal import Decimal +import datetime + +from Exceptions import FpdbParseError +from HandHistoryConverter import * +import PokerStarsToFpdb +from TourneySummary import * + +class Sitename(TourneySummary): + limits = { 'No Limit':'nl', 'Pot Limit':'pl', 'Limit':'fl', 'LIMIT':'fl' } + games = { # base, category + "Hold'em" : ('hold','holdem'), + 'Omaha' : ('hold','omahahi'), + 'Omaha Hi/Lo' : ('hold','omahahilo'), + 'Razz' : ('stud','razz'), + 'RAZZ' : ('stud','razz'), + '7 Card Stud' : ('stud','studhi'), + '7 Card Stud Hi/Lo' : ('stud','studhilo'), + 'Badugi' : ('draw','badugi'), + 'Triple Draw 2-7 Lowball' : ('draw','27_3draw'), + '5 Card Draw' : ('draw','fivedraw') + } + + substitutions = { + 'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes + 'LS' : u"\$|\xe2\x82\xac|\u20AC|" # legal currency symbols + } + + re_SplitTourneys = re.compile("PokerStars Tournament ") + + re_TourNo = re.compile("\#(?P[0-9]+),") + + re_TourneyInfo = re.compile(u""" + \#(?P[0-9]+),\s + (?PNo\sLimit|Limit|LIMIT|Pot\sLimit)\s + (?PHold\'em|Razz|RAZZ|7\sCard\sStud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball|5\sCard\sDraw)\s+ + (?P[ a-zA-Z]+\s+)? + (Buy-In:\s[%(LS)s](?P[.0-9]+)(\/[%(LS)s](?P[.0-9]+))?(?P\s(%(LEGAL_ISO)s))?\s+)? + (?P[0-9]+)\splayers\s+ + ([%(LS)s]?(?P[.\d]+)\sadded\sto\sthe\sprize\spool\sby\sPokerStars\.com\s+)? + (Total\sPrize\sPool:\s[%(LS)s]?(?P[.0-9]+)(\s(%(LEGAL_ISO)s))?\s+)? + (Target\sTournament\s.*)? + Tournament\sstarted\s+(-\s)? + (?P[0-9]{4})\/(?P[0-9]{2})\/(?P[0-9]{2})[\-\s]+(?P[0-9]+):(?P[0-9]+):(?P[0-9]+)\s?\(?(?P[A-Z]+)\)?\s + """ % substitutions ,re.VERBOSE|re.MULTILINE|re.DOTALL) + + re_Currency = re.compile(u"""(?P[%(LS)s]|FPP)""" % substitutions) + + re_Player = re.compile(u"""(?P[0-9]+):\s(?P.*)\s\(.*\),(\s)?(\$(?P[0-9]+\.[0-9]+))?(?Pstill\splaying)?((?PTournament\sTicket)\s\(WSOP\sStep\s(?P\d)\))?(\s+)?""") + + re_DateTime = re.compile("\[(?P[0-9]{4})\/(?P[0-9]{2})\/(?P[0-9]{2})[\- ]+(?P[0-9]+):(?P[0-9]+):(?P[0-9]+)") + + codepage = ["utf-8"] + + def parseSummary(self): + m = self.re_TourneyInfo.search(self.summaryText) + if m == None: + tmp = self.summaryText[0:200] + log.error(_("parseSummary: Unable to recognise Tourney Info: '%s'") % tmp) + log.error(_("parseSummary: Raising FpdbParseError")) + raise FpdbParseError(_("Unable to recognise Tourney Info: '%s'") % tmp) + + print "DEBUG: m.groupdict(): %s" % m.groupdict() + + mg = m.groupdict() + self.tourNo = '' + self.gametype['limitType'] = '' + self.gametype['category'] = '' + self.buyin = 0 + self.fee = 0 + self.prizepool = 0 + self.entries = 0 + #self.startTime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S") + + self.currency = "USD" + + #self.addPlayer(rank, name, winnings, self.currency, None, None, None) + From 7c45c0b8d20269665b576122f41ed965630e6fd1 Mon Sep 17 00:00:00 2001 From: DoNoBaN Date: Fri, 11 Feb 2011 07:45:44 +0100 Subject: [PATCH 099/182] Revert "Turn on HUD dragging and autoclosing." This reverts commit 8c247e11f67bee67ce74b2cebe0f8f2aa1b755a4. --- pyfpdb/HUD_main.pyw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/HUD_main.pyw b/pyfpdb/HUD_main.pyw index 721644bb..fbbab1ee 100755 --- a/pyfpdb/HUD_main.pyw +++ b/pyfpdb/HUD_main.pyw @@ -116,7 +116,7 @@ class HUD_main(object): self.main_window.set_icon_stock(gtk.STOCK_HOME) if not options.hidden: self.main_window.show_all() - gobject.timeout_add(100, self.check_tables) +# gobject.timeout_add(100, self.check_tables) except: log.exception("Error initializing main_window") From 7c4337bd9630e0a6c0b3de664d9053ac507584a6 Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 11 Feb 2011 17:50:07 +0800 Subject: [PATCH 100/182] Config: Add ResultsDirectory to --- pyfpdb/Configuration.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pyfpdb/Configuration.py b/pyfpdb/Configuration.py index a25b13eb..365f7c4a 100644 --- a/pyfpdb/Configuration.py +++ b/pyfpdb/Configuration.py @@ -483,6 +483,7 @@ class Import: self.interval = node.getAttribute("interval") self.callFpdbHud = node.getAttribute("callFpdbHud") self.hhArchiveBase = node.getAttribute("hhArchiveBase") + self.ResultsDirectory = node.getAttribute("ResultsDirectory") self.hhBulkPath = node.getAttribute("hhBulkPath") self.saveActions = string_to_bool(node.getAttribute("saveActions"), default=False) self.cacheSessions = string_to_bool(node.getAttribute("cacheSessions"), default=False) @@ -491,8 +492,8 @@ class Import: self.saveStarsHH = string_to_bool(node.getAttribute("saveStarsHH"), default=False) def __str__(self): - return " interval = %s\n callFpdbHud = %s\n hhArchiveBase = %s\n saveActions = %s\n fastStoreHudCache = %s\n" \ - % (self.interval, self.callFpdbHud, self.hhArchiveBase, self.saveActions, self.cacheSessions, self.sessionTimeout, self.fastStoreHudCache) + return " interval = %s\n callFpdbHud = %s\n hhArchiveBase = %s\n saveActions = %s\n fastStoreHudCache = %s\nResultsDirectory = %s" \ + % (self.interval, self.callFpdbHud, self.hhArchiveBase, self.saveActions, self.cacheSessions, self.sessionTimeout, self.fastStoreHudCache, self.ResultsDirectory) class HudUI: def __init__(self, node): @@ -1261,6 +1262,14 @@ class Config: try: imp['hhArchiveBase'] = self.imp.hhArchiveBase except: imp['hhArchiveBase'] = "~/.fpdb/HandHistories/" + # ResultsDirectory is the local cache for downloaded results + # NOTE: try: except: doesn'tseem to be triggering + # using if instead + if self.imp.ResultsDirectory != '': + imp['ResultsDirectory'] = self.imp.ResultsDirectory + else: + imp['ResultsDirectory'] = "~/.fpdb/Results/" + # hhBulkPath is the default location for bulk imports (if set) try: imp['hhBulkPath'] = self.imp.hhBulkPath except: imp['hhBulkPath'] = "" From 4a7a24eb68948dbb7392bda1edbdd63627062b64 Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 11 Feb 2011 17:50:45 +0800 Subject: [PATCH 101/182] WinamaxSummary: Add initial parser for Winamax Summary files --- pyfpdb/WinamaxSummary.py | 119 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 pyfpdb/WinamaxSummary.py diff --git a/pyfpdb/WinamaxSummary.py b/pyfpdb/WinamaxSummary.py new file mode 100644 index 00000000..c3a5bd14 --- /dev/null +++ b/pyfpdb/WinamaxSummary.py @@ -0,0 +1,119 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +#Copyright 2008-2011 Carl Gherardi +#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. + +import L10n +_ = L10n.get_translation() + +from decimal import Decimal +import datetime +from BeautifulSoup import BeautifulSoup + +from Exceptions import FpdbParseError +from HandHistoryConverter import * +import PokerStarsToFpdb +from TourneySummary import * + + +class WinamaxSummary(TourneySummary): + limits = { 'No Limit':'nl', 'Pot Limit':'pl', 'Limit':'fl', 'LIMIT':'fl' } + games = { # base, category + "Hold'em" : ('hold','holdem'), + 'Omaha' : ('hold','omahahi'), + 'Omaha Hi/Lo' : ('hold','omahahilo'), + 'Razz' : ('stud','razz'), + 'RAZZ' : ('stud','razz'), + '7 Card Stud' : ('stud','studhi'), + '7 Card Stud Hi/Lo' : ('stud','studhilo'), + 'Badugi' : ('draw','badugi'), + 'Triple Draw 2-7 Lowball' : ('draw','27_3draw'), + '5 Card Draw' : ('draw','fivedraw') + } + + substitutions = { + 'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes + 'LS' : u"\$|\xe2\x82\xac|\u20AC|" # legal currency symbols + } + + re_GameType = re.compile("""

((?PNo Limit|Pot Limit) (?PHold\'em))

""") + + re_SplitTourneys = re.compile("PokerStars Tournament ") + + re_TourNo = re.compile("ID\=(?P[0-9]+)") + + re_Player = re.compile(u"""(?P\d+)<\/td>
""") + + re_Details = re.compile(u"""

(?P

""") + re_Prizepool = re.compile(u"""
.+: (?P[0-9,]+)""") + + re_DateTime = re.compile("\[(?P[0-9]{4})\/(?P[0-9]{2})\/(?P[0-9]{2})[\- ]+(?P[0-9]+):(?P[0-9]+):(?P[0-9]+)") + + codepage = ["utf-8"] + + def parseSummary(self): + self.currency = "EUR" + soup = BeautifulSoup(self.summaryText) + tl = soup.findAll('div', {"class":"left_content"}) + + ps = soup.findAll('p', {"class": "text"}) + for p in ps: + for m in self.re_Details.finditer(str(p)): + mg = m.groupdict() + #print mg + if mg['LABEL'] == 'Buy-in': + mg['VALUE'] = mg['VALUE'].replace(u"€", "") + mg['VALUE'] = mg['VALUE'].replace(u"+", "") + mg['VALUE'] = mg['VALUE'].strip(" $") + bi, fee = mg['VALUE'].split(" ") + self.buyin = int(100*Decimal(bi)) + self.fee = int(100*Decimal(fee)) + #print "DEBUG: bi: '%s' fee: '%s" % (self.buyin, self.fee) + if mg['LABEL'] == 'Nombre de joueurs inscrits': + self.entries = mg['VALUE'] + if mg['LABEL'] == 'D\xc3\xa9but du tournoi': + self.startTime = datetime.datetime.strptime(mg['VALUE'], "%d-%m-%Y %H:%M") + if mg['LABEL'] == 'Nombre de joueurs max': + # Max seats i think + pass + + div = soup.findAll('div', {"class": "title2"}) + for m in self.re_Prizepool.finditer(str(div)): + mg = m.groupdict() + #print mg + self.prizepool = mg['PRIZEPOOL'].replace(u',','.') + + + for m in self.re_GameType.finditer(str(tl[0])): + mg = m.groupdict() + #print mg + self.gametype['limitType'] = self.limits[mg['LIMIT']] + self.gametype['category'] = self.games[mg['GAME']][1] + + for m in self.re_Player.finditer(str(tl[0])): + mg = m.groupdict() + #print mg + winnings = mg['WINNINGS'].strip(u'€').replace(u',','.') + winnings = int(100*Decimal(winnings)) + rank = mg['RANK'] + name = mg['PNAME'] + #print "DEBUG: %s: %s" %(name, winnings) + self.addPlayer(rank, name, winnings, self.currency, None, None, None) + + + for m in self.re_TourNo.finditer(self.summaryText): + mg = m.groupdict() + #print mg + self.tourNo = mg['TOURNO'] From 2a586cf460b9bcb667c0650e758fb4246a313467 Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 11 Feb 2011 17:51:18 +0800 Subject: [PATCH 102/182] SQL: Add function to fetch tourney ids --- pyfpdb/SQL.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 3f211dd5..1dc7e36f 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -4342,6 +4342,13 @@ class Sql: WHERE s.name=%s AND t.siteTourneyNo=%s """ + self.query['getSiteTourneyNos'] = """SELECT t.siteTourneyNo + FROM Tourneys t + INNER JOIN TourneyTypes tt ON (t.tourneyTypeId = tt.id) + INNER JOIN Sites s ON (tt.siteId = s.id) + WHERE tt.siteId=%s + """ + self.query['getTourneyPlayerInfo'] = """SELECT tp.* FROM Tourneys t INNER JOIN TourneyTypes tt ON (t.tourneyTypeId = tt.id) From f0c315969f334de1ed05c3369078508c53905f17 Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 11 Feb 2011 17:52:14 +0800 Subject: [PATCH 103/182] TourneySummary: Add Winamax id --- pyfpdb/TourneySummary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/TourneySummary.py b/pyfpdb/TourneySummary.py index 4ed91b65..d83ac1a8 100644 --- a/pyfpdb/TourneySummary.py +++ b/pyfpdb/TourneySummary.py @@ -49,7 +49,7 @@ class TourneySummary(object): LCS = {'H':'h', 'D':'d', 'C':'c', 'S':'s'} # SAL- TO KEEP ?? SYMBOL = {'USD': '$', 'EUR': u'$', 'T$': '', 'play': ''} MS = {'horse' : 'HORSE', '8game' : '8-Game', 'hose' : 'HOSE', 'ha': 'HA'} - SITEIDS = {'Fulltilt':1, 'Full Tilt Poker':1, 'PokerStars':2, 'Everleaf':3, 'Win2day':4, 'OnGame':5, 'UltimateBet':6, 'Betfair':7, 'Absolute':8, 'PartyPoker':9 } + SITEIDS = {'Fulltilt':1, 'Full Tilt Poker':1, 'PokerStars':2, 'Everleaf':3, 'Win2day':4, 'OnGame':5, 'UltimateBet':6, 'Betfair':7, 'Absolute':8, 'PartyPoker':9, 'Winamax':14 } def __init__(self, db, config, siteName, summaryText, builtFrom = "HHC"): From 059ca2307fee458d4aa99e2a5b7f3568ce0944a8 Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 11 Feb 2011 17:53:18 +0800 Subject: [PATCH 104/182] Database: def getSiteTourneyNos(self, site) --- pyfpdb/Database.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 00cc0657..88fbe166 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -634,6 +634,18 @@ class Database: return c.fetchone()[0] #end def getTourneyCount + def getSiteTourneyNos(self, site): + c = self.connection.cursor() + # FIXME: Take site and actually fetch siteId from that + # Fixed to Winamax atm + q = self.sql.query['getSiteTourneyNos'] + q = q.replace('%s', self.sql.query['placeholder']) + c.execute(q, (14,)) + alist = [] + for row in c.fetchall(): + alist.append(row) + return alist + def get_actual_seat(self, hand_id, name): c = self.connection.cursor() c.execute(self.sql.query['get_actual_seat'], (hand_id, name)) From af1cdfbae764d03663dc40fcc0b4017fbf031d95 Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 11 Feb 2011 17:53:42 +0800 Subject: [PATCH 105/182] Test config mod --- pyfpdb/HUD_config.test.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/HUD_config.test.xml b/pyfpdb/HUD_config.test.xml index 7ce84651..7282d0af 100644 --- a/pyfpdb/HUD_config.test.xml +++ b/pyfpdb/HUD_config.test.xml @@ -577,7 +577,7 @@ Left-Drag to Move" - + From 36f5c5922604edac161c1c236e06531804fc0b22 Mon Sep 17 00:00:00 2001 From: Worros Date: Fri, 11 Feb 2011 18:13:43 +0800 Subject: [PATCH 106/182] Script: Fetch Winamax results This script will fetch all of the known Winamax tourney ids from the database, then fetch the results from the Winamax website and write them to ~/.fpdb/Results/Winamax Initial version is smart enough not to fetch results that have already been downloaded. In combination with the recent WinamaxSummary.py Winamax users should now be able to import and graph tournament results --- pyfpdb/ScriptFetchWinamaxResults.py | 74 +++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 pyfpdb/ScriptFetchWinamaxResults.py diff --git a/pyfpdb/ScriptFetchWinamaxResults.py b/pyfpdb/ScriptFetchWinamaxResults.py new file mode 100644 index 00000000..2bdab268 --- /dev/null +++ b/pyfpdb/ScriptFetchWinamaxResults.py @@ -0,0 +1,74 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +#Copyright 2008-2011 Carl Gherardi +#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 + +"""A script for fetching Winamax tourney results""" + +import Configuration +import Database + +import logging, os, sys +import re, urllib2 + + +def fetch_winamax_results_page(tourney_id): + url = "https://www.winamax.fr/poker/tournament.php?ID=%s" % tourney_id + data = urllib2.urlopen(url).read() + return data + +def write_file(filename, data): + f = open(filename, 'w') + print f + f.write(data) + f.close() + print f + +def main(): + config = Configuration.Config() + db = Database.Database(config) + + tourney_ids = db.getSiteTourneyNos("Winamax") + tids = [] + + for tid in tourney_ids: + blah, = tid # Unpack tuple + tids.append(str(blah)) + # winamax_get_winning(tid,"blah") + results_dir = config.get_import_parameters().get("ResultsDirectory") + results_dir = os.path.expanduser(results_dir) + site_dir = os.path.join(results_dir, "Winamax") + print "DEBUG: site_dir: %s" % site_dir + filelist = [file for file in os.listdir(site_dir) if not file in [".",".."]] + print "DEBUG: filelist : %s" % filelist + print "DEBUG: tids : %s" % tids + + for f in filelist: + try: + tids.remove(f) + except ValueError: + print "Warning: '%s' is not a known tourney_id" % f + + if len(tids) == 0: + print "No tourney results files to fetch" + else: + for tid in tids: + filename = os.path.join(site_dir, tid) + data = fetch_winamax_results_page(tid) + print u"DEBUG: write_file(%s)" %(filename) + write_file(filename, data) + +if __name__ == '__main__': + main() From 0a21e472bad2443a4ad932a52daa5cb6cea2bee4 Mon Sep 17 00:00:00 2001 From: DoNoBaN Date: Fri, 11 Feb 2011 14:59:42 +0100 Subject: [PATCH 107/182] Revert "Revert "Turn on HUD dragging and autoclosing."" This reverts commit 7c45c0b8d20269665b576122f41ed965630e6fd1. --- pyfpdb/HUD_main.pyw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyfpdb/HUD_main.pyw b/pyfpdb/HUD_main.pyw index fbbab1ee..721644bb 100755 --- a/pyfpdb/HUD_main.pyw +++ b/pyfpdb/HUD_main.pyw @@ -116,7 +116,7 @@ class HUD_main(object): self.main_window.set_icon_stock(gtk.STOCK_HOME) if not options.hidden: self.main_window.show_all() -# gobject.timeout_add(100, self.check_tables) + gobject.timeout_add(100, self.check_tables) except: log.exception("Error initializing main_window") From 6370fca9ec77d103559489af7488b16ee0fa3096 Mon Sep 17 00:00:00 2001 From: DoNoBaN Date: Fri, 11 Feb 2011 16:37:28 +0100 Subject: [PATCH 108/182] Added 4bet and fold to 3/4bet at detailed cash stats pages --- pyfpdb/GuiRingPlayerStats.py | 3 ++ pyfpdb/HUD_config.xml.example | 3 ++ pyfpdb/SQL.py | 69 ++++++++++++++++++++++++++++++++++- 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/pyfpdb/GuiRingPlayerStats.py b/pyfpdb/GuiRingPlayerStats.py index 9a64eac6..4d214767 100644 --- a/pyfpdb/GuiRingPlayerStats.py +++ b/pyfpdb/GuiRingPlayerStats.py @@ -50,6 +50,9 @@ onlinehelp = {'Game':_('Type of Game'), 'VPIP':_('Voluntarily Putting In the pot\n(blinds excluded)'), 'PFR':_('% Pre Flop Raise'), 'PF3':_('% Pre Flop Re-Raise / 3Bet'), + 'PF4':_('% Pre Flop Re-Raise / 4Bet'), + 'PFF3':_('% Pre Flop Fold To Re-Raise / F3Bet'), + 'PFF4':_('% Pre Flop Fold To Re-Raise / F4Bet'), 'AggFac':_('Aggression Factor\n'), 'AggFreq':_('Aggression Frequency\nBet or Raise vs Fold'), 'ContBet':_('Continuation Bet post-flop'), diff --git a/pyfpdb/HUD_config.xml.example b/pyfpdb/HUD_config.xml.example index 803b9694..ecab4c76 100644 --- a/pyfpdb/HUD_config.xml.example +++ b/pyfpdb/HUD_config.xml.example @@ -24,6 +24,9 @@
+ + + diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 3f211dd5..57f00abd 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -2225,7 +2225,6 @@ class Sql: from Gametypes gt WHERE type = 'ring' order by type, limitType DESC, bb_or_buyin DESC""" -# FIXME: fold to 3bet don't added if db_server == 'mysql': self.query['playerDetailedStats'] = """ select AS hgametypeid @@ -2244,6 +2243,16 @@ class Sql: ,case when sum(cast(hp.street0_3Bchance as integer)) = 0 then -999 else 100.0*sum(cast(hp.street0_3Bdone as integer))/sum(cast(hp.street0_3Bchance as integer)) end AS pf3 + ,case when sum(cast(hp.street0_4Bchance as integer)) = 0 then -999 + else 100.0*sum(cast(hp.street0_4Bdone as integer))/sum(cast(hp.street0_4Bchance as integer)) + end AS pf4 + ,case when sum(cast(hp.street0_FoldTo3Bchance as integer)) = 0 then -999 + else 100.0*sum(cast(hp.street0_FoldTo3Bdone as integer))/sum(cast(hp.street0_FoldTo3Bchance as integer)) + end AS pff3 + ,case when sum(cast(hp.street0_FoldTo4Bchance as integer)) = 0 then -999 + else 100.0*sum(cast(hp.street0_FoldTo4Bdone as integer))/sum(cast(hp.street0_FoldTo4Bchance as integer)) + end AS pff4 + ,case when sum(cast(hp.raiseFirstInChance as integer)) = 0 then -999 else 100.0 * sum(cast(hp.raisedFirstIn as integer)) / sum(cast(hp.raiseFirstInChance as integer)) @@ -2365,6 +2374,15 @@ class Sql: ,case when sum(cast(hp.street0_3Bchance as integer)) = 0 then -999 else 100.0*sum(cast(hp.street0_3Bdone as integer))/sum(cast(hp.street0_3Bchance as integer)) end AS pf3 + ,case when sum(cast(hp.street0_4Bchance as integer)) = 0 then -999 + else 100.0*sum(cast(hp.street0_4Bdone as integer))/sum(cast(hp.street0_4Bchance as integer)) + end AS pf4 + ,case when sum(cast(hp.street0_FoldTo3Bchance as integer)) = 0 then -999 + else 100.0*sum(cast(hp.street0_FoldTo3Bdone as integer))/sum(cast(hp.street0_FoldTo3Bchance as integer)) + end AS pff3 + ,case when sum(cast(hp.street0_FoldTo4Bchance as integer)) = 0 then -999 + else 100.0*sum(cast(hp.street0_FoldTo4Bdone as integer))/sum(cast(hp.street0_FoldTo4Bchance as integer)) + end AS pff4 ,case when sum(cast(hp.raiseFirstInChance as integer)) = 0 then -999 else 100.0 * sum(cast(hp.raisedFirstIn as integer)) / sum(cast(hp.raiseFirstInChance as integer)) @@ -2487,6 +2505,15 @@ class Sql: ,case when sum(cast(hp.street0_3Bchance as integer)) = 0 then -999 else 100.0*sum(cast(hp.street0_3Bdone as integer))/sum(cast(hp.street0_3Bchance as integer)) end AS pf3 + ,case when sum(cast(hp.street0_4Bchance as integer)) = 0 then -999 + else 100.0*sum(cast(hp.street0_4Bdone as integer))/sum(cast(hp.street0_4Bchance as integer)) + end AS pf4 + ,case when sum(cast(hp.street0_FoldTo3Bchance as integer)) = 0 then -999 + else 100.0*sum(cast(hp.street0_FoldTo3Bdone as integer))/sum(cast(hp.street0_FoldTo3Bchance as integer)) + end AS pff3 + ,case when sum(cast(hp.street0_FoldTo4Bchance as integer)) = 0 then -999 + else 100.0*sum(cast(hp.street0_FoldTo4Bdone as integer))/sum(cast(hp.street0_FoldTo4Bchance as integer)) + end AS pff4 ,case when sum(cast(hp.raiseFirstInChance as integer)) = 0 then -999 else 100.0 * sum(cast(hp.raisedFirstIn as integer)) / sum(cast(hp.raiseFirstInChance as integer)) @@ -2592,6 +2619,7 @@ class Sql: ,s.name """ + #FIXME: 3/4bet and foldTo don't added four tournaments yet if db_server == 'mysql': self.query['tourneyPlayerDetailedStats'] = """ select s.name AS siteName @@ -2715,6 +2743,9 @@ class Sql: ,stats.vpip ,stats.pfr ,stats.pf3 + ,stats.pf4 + ,stats.pff3 + ,stats.pff4 ,stats.steals ,stats.saw_f ,stats.sawsd @@ -2745,6 +2776,15 @@ class Sql: ,case when sum(street0_3Bchance) = 0 then '0' else format(100.0*sum(street0_3Bdone)/sum(street0_3Bchance),1) end AS pf3 + ,case when sum(street0_4Bchance) = 0 then '0' + else format(100.0*sum(street0_4Bdone)/sum(street0_4Bchance),1) + end AS pf4 + ,case when sum(street0_FoldTo3Bchance) = 0 then '0' + else format(100.0*sum(street0_FoldTo3Bdone)/sum(street0_FoldTo3Bchance),1) + end AS pff3 + ,case when sum(street0_FoldTo4Bchance) = 0 then '0' + else format(100.0*sum(street0_FoldTo4Bdone)/sum(street0_FoldTo4Bchance),1) + end AS pff4 ,case when sum(raiseFirstInChance) = 0 then '-' else format(100.0*sum(raisedFirstIn)/sum(raiseFirstInChance),1) end AS steals @@ -2821,6 +2861,9 @@ class Sql: ,stats.vpip ,stats.pfr ,stats.pf3 + ,stats.pf4 + ,stats.pff3 + ,stats.pff4 ,stats.steals ,stats.saw_f ,stats.sawsd @@ -2935,6 +2978,9 @@ class Sql: ,stats.vpip ,stats.pfr ,stats.pf3 + ,stats.pf4 + ,stats.pff3 + ,stats.pff4 ,stats.steals ,stats.saw_f ,stats.sawsd @@ -2973,6 +3019,15 @@ class Sql: ,case when sum(street0_3Bchance) = 0 then '0' else format(100.0*sum(street0_3Bdone)/sum(street0_3Bchance),1) end AS pf3 + ,case when sum(street0_4Bchance) = 0 then '0' + else format(100.0*sum(street0_4Bdone)/sum(street0_4Bchance),1) + end AS pf4 + ,case when sum(street0_FoldTo3Bchance) = 0 then '0' + else format(100.0*sum(street0_FoldTo3Bdone)/sum(street0_FoldTo3Bchance),1) + end AS pff3 + ,case when sum(street0_FoldTo4Bchance) = 0 then '0' + else format(100.0*sum(street0_FoldTo4Bdone)/sum(street0_FoldTo4Bchance),1) + end AS pff4 ,case when sum(raiseFirstInChance) = 0 then '-' else format(100.0*sum(raisedFirstIn)/sum(raiseFirstInChance),1) end AS steals @@ -3071,6 +3126,9 @@ class Sql: ,stats.vpip ,stats.pfr ,stats.pf3 + ,stats.pf4 + ,stats.pff3 + ,stats.pff4 ,stats.steals ,stats.saw_f ,stats.sawsd @@ -3109,6 +3167,15 @@ class Sql: ,case when sum(street0_3Bchance) = 0 then '0' else to_char(100.0*sum(street0_3Bdone)/sum(street0_3Bchance),'90D0') end AS pf3 + ,case when sum(street0_4Bchance) = 0 then '0' + else to_char(100.0*sum(street0_4Bdone)/sum(street0_4Bchance),'90D0') + end AS pf4 + ,case when sum(street0_FoldTo3Bchance) = 0 then '0' + else to_char(100.0*sum(street0_FoldTo3Bdone)/sum(street0_FoldTo3Bchance),'90D0') + end AS pff3 + ,case when sum(street0_FoldTo4Bchance) = 0 then '0' + else to_char(100.0*sum(street0_FoldTo4Bdone)/sum(street0_FoldTo4Bchance),'90D0') + end AS pff4 ,case when sum(raiseFirstInChance) = 0 then '-' else to_char(100.0*sum(raisedFirstIn)/sum(raiseFirstInChance),'90D0') end AS steals From 0a1389244d0aedf715a0b3f0619013c79c6f8f96 Mon Sep 17 00:00:00 2001 From: DoNoBaN Date: Sat, 12 Feb 2011 14:11:41 +0100 Subject: [PATCH 109/182] Added cold 4bet, squeeze and success steal 4bet and foldto3/4bet enabled for Detailed Stats Removed street0 other raises (they was unused) --- pyfpdb/Database.py | 16 ++-- pyfpdb/HUD_config.xml.example | 8 +- pyfpdb/SQL.py | 138 ++++++++++++++++++++++++++-------- pyfpdb/Stats.py | 58 +++++++++++++- 4 files changed, 179 insertions(+), 41 deletions(-) diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 00cc0657..4d68a075 100644 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -73,7 +73,7 @@ except ImportError: use_numpy = False -DB_VERSION = 148 +DB_VERSION = 149 # Variance created as sqlite has a bunch of undefined aggregate functions. @@ -1814,12 +1814,15 @@ class Database: pdata[p]['street0_3BDone'], pdata[p]['street0_4BChance'], pdata[p]['street0_4BDone'], + pdata[p]['street0_C4BChance'], + pdata[p]['street0_C4BDone'], pdata[p]['street0_FoldTo3BChance'], pdata[p]['street0_FoldTo3BDone'], pdata[p]['street0_FoldTo4BChance'], pdata[p]['street0_FoldTo4BDone'], - pdata[p]['other3BStreet0'], - pdata[p]['other4BStreet0'], + pdata[p]['street0_SqueezeChance'], + pdata[p]['street0_SqueezeDone'], + pdata[p]['success_Steal'], pdata[p]['otherRaisedStreet0'], pdata[p]['otherRaisedStreet1'], pdata[p]['otherRaisedStreet2'], @@ -1941,12 +1944,15 @@ class Database: line.append(pdata[p]['street0_3BDone']) line.append(pdata[p]['street0_4BChance']) line.append(pdata[p]['street0_4BDone']) + line.append(pdata[p]['street0_C4BChance']) + line.append(pdata[p]['street0_C4BDone']) line.append(pdata[p]['street0_FoldTo3BChance']) line.append(pdata[p]['street0_FoldTo3BDone']) line.append(pdata[p]['street0_FoldTo4BChance']) line.append(pdata[p]['street0_FoldTo4BDone']) - line.append(pdata[p]['other3BStreet0']) - line.append(pdata[p]['other4BStreet0']) + line.append(pdata[p]['street0_SqueezeChance']) + line.append(pdata[p]['street0_SqueezeDone']) + line.append(pdata[p]['success_Steal']) line.append(pdata[p]['street1Seen']) line.append(pdata[p]['street2Seen']) line.append(pdata[p]['street3Seen']) diff --git a/pyfpdb/HUD_config.xml.example b/pyfpdb/HUD_config.xml.example index ecab4c76..85e6f443 100644 --- a/pyfpdb/HUD_config.xml.example +++ b/pyfpdb/HUD_config.xml.example @@ -746,8 +746,14 @@ Left-Drag to Move" - + + + + + + + diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 57f00abd..4c1028a9 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -639,13 +639,16 @@ class Sql: street0_3BChance BOOLEAN, street0_3BDone BOOLEAN, street0_4BChance BOOLEAN, + street0_C4BChance BOOLEAN, street0_4BDone BOOLEAN, + street0_C4BDone BOOLEAN, street0_FoldTo3BChance BOOLEAN, street0_FoldTo3BDone BOOLEAN, street0_FoldTo4BChance BOOLEAN, street0_FoldTo4BDone BOOLEAN, - other3BStreet0 BOOLEAN, - other4BStreet0 BOOLEAN, + street0_SqueezeChance BOOLEAN, + street0_SqueezeDone BOOLEAN, + success_Steal BOOLEAN, street1Seen BOOLEAN, street2Seen BOOLEAN, @@ -761,12 +764,15 @@ class Sql: street0_3BDone BOOLEAN, street0_4BChance BOOLEAN, street0_4BDone BOOLEAN, + street0_C4BChance BOOLEAN, + street0_C4BDone BOOLEAN, street0_FoldTo3BChance BOOLEAN, street0_FoldTo3BDone BOOLEAN, street0_FoldTo4BChance BOOLEAN, street0_FoldTo4BDone BOOLEAN, - other3BStreet0 BOOLEAN, - other4BStreet0 BOOLEAN, + street0_SqueezeChance BOOLEAN, + street0_SqueezeDone BOOLEAN, + success_Steal BOOLEAN, street1Seen BOOLEAN, street2Seen BOOLEAN, @@ -881,12 +887,15 @@ class Sql: street0_3BDone INT, street0_4BChance INT, street0_4BDone INT, + street0_C4BChance INT, + street0_C4BDone INT, street0_FoldTo3BChance INT, street0_FoldTo3BDone INT, street0_FoldTo4BChance INT, street0_FoldTo4BDone INT, - other3BStreet0 INT, - other4BStreet0 INT, + street0_SqueezeChance INT, + street0_SqueezeDone INT, + success_Steal INT, street1Seen INT, street2Seen INT, @@ -1091,13 +1100,16 @@ class Sql: street0_3BDone INT, street0_4BChance INT, street0_4BDone INT, + street0_C4BChance INT, + street0_C4BDone INT, street0_FoldTo3BChance INT, street0_FoldTo3BDone INT, street0_FoldTo4BChance INT, street0_FoldTo4BDone INT, + street0_SqueezeChance INT, + street0_SqueezeDone INT, + success_Steal INT, - other3BStreet0 INT, - other4BStreet0 INT, street1Seen INT, street2Seen INT, @@ -1197,12 +1209,15 @@ class Sql: street0_3BDone INT, street0_4BChance INT, street0_4BDone INT, + street0_C4BChance INT, + street0_C4BDone INT, street0_FoldTo3BChance INT, street0_FoldTo3BDone INT, street0_FoldTo4BChance INT, street0_FoldTo4BDone INT, - other3BStreet0 INT, - other4BStreet0 INT, + street0_SqueezeChance INT, + street0_SqueezeDone INT, + success_Steal INT, street1Seen INT, street2Seen INT, @@ -1300,12 +1315,15 @@ class Sql: street0_3BDone INT, street0_4BChance INT, street0_4BDone INT, + street0_C4BChance INT, + street0_C4BDone INT, street0_FoldTo3BChance INT, street0_FoldTo3BDone INT, street0_FoldTo4BChance INT, street0_FoldTo4BDone INT, - other3BStreet0 INT, - other4BStreet0 INT, + street0_SqueezeChance INT, + street0_SqueezeDone INT, + success_Steal INT, street1Seen INT, street2Seen INT, @@ -1515,10 +1533,15 @@ class Sql: sum(hc.street0_3BDone) AS TB_0, sum(hc.street0_4BChance) AS FB_opp_0, sum(hc.street0_4BDone) AS FB_0, + sum(hc.street0_C4BChance) AS CFB_opp_0, + sum(hc.street0_C4BDone) AS CFB_0, sum(hc.street0_FoldTo3BChance) AS F3B_opp_0, sum(hc.street0_FoldTo3BDone) AS F3B_0, sum(hc.street0_FoldTo4BChance) AS F4B_opp_0, sum(hc.street0_FoldTo4BDone) AS F4B_0, + sum(hc.street0_SqueezeChance) AS SQZ_opp_0, + sum(hc.street0_SqueezeDone) AS SQZ_0, + sum(hc.success_Steal) AS SUC_ST, sum(hc.street1Seen) AS saw_f, sum(hc.street1Seen) AS saw_1, sum(hc.street2Seen) AS saw_2, @@ -1632,10 +1655,15 @@ class Sql: sum(hc.street0_3BDone) AS TB_0, sum(hc.street0_4BChance) AS FB_opp_0, sum(hc.street0_4BDone) AS FB_0, + sum(hc.street0_C4BChance) AS CFB_opp_0, + sum(hc.street0_C4BDone) AS CFB_0, sum(hc.street0_FoldTo3BChance) AS F3B_opp_0, sum(hc.street0_FoldTo3BDone) AS F3B_0, sum(hc.street0_FoldTo4BChance) AS F4B_opp_0, sum(hc.street0_FoldTo4BDone) AS F4B_0, + sum(hc.street0_SqueezeChance) AS SQZ_opp_0, + sum(hc.street0_SqueezeDone) AS SQZ_0, + sum(hc.success_Steal) AS SUC_ST, sum(hc.street1Seen) AS saw_f, sum(hc.street1Seen) AS saw_1, sum(hc.street2Seen) AS saw_2, @@ -1766,10 +1794,15 @@ class Sql: cast(hp2.street0_3BDone as integer) AS TB_0, cast(hp2.street0_4BChance as integer) AS FB_opp_0, cast(hp2.street0_4BDone as integer) AS FB_0, + cast(hp2.street0_C4BChance as integer) AS CFB_opp_0, + cast(hp2.street0_C4BDone as integer) AS CFB_0, cast(hp2.street0_FoldTo3BChance as integer) AS F3B_opp_0, cast(hp2.street0_FoldTo3BDone as integer) AS F3B_0, cast(hp2.street0_FoldTo4BChance as integer) AS F4B_opp_0, cast(hp2.street0_FoldTo4BDone as integer) AS F4B_0, + cast(hp2.street0_SqueezeChance as integer) AS SQZ_opp_0, + cast(hp2.street0_SqueezeDone as integer) AS SQZ_0, + cast(hp2.success_Steal as integer) AS SUC_ST, cast(hp2.street1Seen as integer) AS saw_f, cast(hp2.street1Seen as integer) AS saw_1, cast(hp2.street2Seen as integer) AS saw_2, @@ -1876,10 +1909,15 @@ class Sql: cast(hp2.street0_3BDone as integer) AS TB_0, cast(hp2.street0_4BChance as integer) AS FB_opp_0, cast(hp2.street0_4BDone as integer) AS FB_0, + cast(hp2.street0_C4BChance as integer) AS CFB_opp_0, + cast(hp2.street0_C4BDone as integer) AS CFB_0, cast(hp2.street0_FoldTo3BChance as integer) AS F3B_opp_0, cast(hp2.street0_FoldTo3BDone as integer) AS F3B_0, cast(hp2.street0_FoldTo4BChance as integer) AS F4B_opp_0, cast(hp2.street0_FoldTo4BDone as integer) AS F4B_0, + cast(hp2.street0_SqueezeChance as integer) AS SQZ_opp_0, + cast(hp2.street0_SqueezeDone as integer) AS SQZ_0, + cast(hp2.success_Steal as integer) AS SUC_ST, cast(hp2.street1Seen as integer) AS saw_f, cast(hp2.street1Seen as integer) AS saw_1, cast(hp2.street2Seen as integer) AS saw_2, @@ -1987,10 +2025,15 @@ class Sql: cast(hp2.street0_3BDone as integer) AS TB_0, cast(hp2.street0_4BChance as integer) AS FB_opp_0, cast(hp2.street0_4BDone as integer) AS FB_0, + cast(hp2.street0_C4BChance as integer) AS CFB_opp_0, + cast(hp2.street0_C4BDone as integer) AS CFB_0, cast(hp2.street0_FoldTo3BChance as integer) AS F3B_opp_0, cast(hp2.street0_FoldTo3BDone as integer) AS F3B_0, cast(hp2.street0_FoldTo4BChance as integer) AS F4B_opp_0, cast(hp2.street0_FoldTo4BDone as integer) AS F4B_0, + cast(hp2.street0_SqueezeChance as integer) AS SQZ_opp_0, + cast(hp2.street0_SqueezeDone as integer) AS SQZ_0, + cast(hp2.success_Steal as integer) AS SUC_ST, cast(hp2.street1Seen as integer) AS saw_f, cast(hp2.street1Seen as integer) AS saw_1, cast(hp2.street2Seen as integer) AS saw_2, @@ -2225,6 +2268,7 @@ class Sql: from Gametypes gt WHERE type = 'ring' order by type, limitType DESC, bb_or_buyin DESC""" + #FIXME: Some stats not added to DetailedStats if db_server == 'mysql': self.query['playerDetailedStats'] = """ select AS hgametypeid @@ -3401,12 +3445,15 @@ class Sql: ,street0_3BDone ,street0_4BChance ,street0_4BDone + ,street0_C4BChance + ,street0_C4BDone ,street0_FoldTo3BChance ,street0_FoldTo3BDone ,street0_FoldTo4BChance ,street0_FoldTo4BDone - ,other3BStreet0 - ,other4BStreet0 + ,street0_SqueezeChance + ,street0_SqueezeDone + ,success_Steal ,street1Seen ,street2Seen ,street3Seen @@ -3503,13 +3550,15 @@ class Sql: ,sum(street0_3BChance) ,sum(street0_3BDone) ,sum(street0_4BChance) - ,sum(street0_4BDone) + ,sum(street0_C4BChance) + ,sum(street0_C4BDone) ,sum(street0_FoldTo3BChance) ,sum(street0_FoldTo3BDone) ,sum(street0_FoldTo4BChance) ,sum(street0_FoldTo4BDone) - ,sum(other3BStreet0) - ,sum(other4BStreet0) + ,sum(street0_SqueezeChance) + ,sum(street0_SqueezeDone) + ,sum(success_Steal) ,sum(street1Seen) ,sum(street2Seen) ,sum(street3Seen) @@ -3607,12 +3656,15 @@ class Sql: ,street0_3BDone ,street0_4BChance ,street0_4BDone + ,street0_C4BChance + ,street0_C4BDone ,street0_FoldTo3BChance ,street0_FoldTo3BDone ,street0_FoldTo4BChance ,street0_FoldTo4BDone - ,other3BStreet0 - ,other4BStreet0 + ,street0_SqueezeChance + ,street0_SqueezeDone + ,success_Steal ,street1Seen ,street2Seen ,street3Seen @@ -3710,12 +3762,15 @@ class Sql: ,sum(CAST(street0_3BDone as integer)) ,sum(CAST(street0_4BChance as integer)) ,sum(CAST(street0_4BDone as integer)) + ,sum(CAST(street0_C4BChance as integer)) + ,sum(CAST(street0_C4BDone as integer)) ,sum(CAST(street0_FoldTo3BChance as integer)) ,sum(CAST(street0_FoldTo3BDone as integer)) ,sum(CAST(street0_FoldTo4BChance as integer)) ,sum(CAST(street0_FoldTo4BDone as integer)) - ,sum(CAST(other3BStreet0 as integer)) - ,sum(CAST(other4BStreet0 as integer)) + ,sum(CAST(street0_SqueezeChance as integer)) + ,sum(CAST(street0_SqueezeDone as integer)) + ,sum(CAST(success_Steal as integer)) ,sum(CAST(street1Seen as integer)) ,sum(CAST(street2Seen as integer)) ,sum(CAST(street3Seen as integer)) @@ -3813,12 +3868,15 @@ class Sql: ,street0_3BDone ,street0_4BChance ,street0_4BDone + ,street0_C4BChance + ,street0_C4BDone ,street0_FoldTo3BChance ,street0_FoldTo3BDone ,street0_FoldTo4BChance ,street0_FoldTo4BDone - ,other3BStreet0 - ,other4BStreet0 + ,street0_SqueezeChance + ,street0_SqueezeDone + ,success_Steal ,street1Seen ,street2Seen ,street3Seen @@ -3916,12 +3974,15 @@ class Sql: ,sum(CAST(street0_3BDone as integer)) ,sum(CAST(street0_4BChance as integer)) ,sum(CAST(street0_4BDone as integer)) + ,sum(CAST(street0_C4BChance as integer)) + ,sum(CAST(street0_C4BDone as integer)) ,sum(CAST(street0_FoldTo3BChance as integer)) ,sum(CAST(street0_FoldTo3BDone as integer)) ,sum(CAST(street0_FoldTo4BChance as integer)) ,sum(CAST(street0_FoldTo4BDone as integer)) - ,sum(CAST(other3BStreet0 as integer)) - ,sum(CAST(other4BStreet0 as integer)) + ,sum(CAST(street0_SqueezeChance as integer)) + ,sum(CAST(street0_SqueezeDone as integer)) + ,sum(CAST(success_Steal as integer)) ,sum(CAST(street1Seen as integer)) ,sum(CAST(street2Seen as integer)) ,sum(CAST(street3Seen as integer)) @@ -4014,12 +4075,15 @@ class Sql: street0_3BDone, street0_4BChance, street0_4BDone, + street0_C4BChance, + street0_C4BDone, street0_FoldTo3BChance, street0_FoldTo3BDone, street0_FoldTo4BChance, street0_FoldTo4BDone, - other3BStreet0, - other4BStreet0, + street0_SqueezeChance, + street0_SqueezeDone, + success_Steal, street1Seen, street2Seen, street3Seen, @@ -4107,7 +4171,8 @@ class Sql: %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, - %s, %s, %s, %s)""" + %s, %s, %s, %s, %s, + %s, %s)""" self.query['update_hudcache'] = """ UPDATE HudCache SET @@ -4118,12 +4183,15 @@ class Sql: street0_3BDone=street0_3BDone+%s, street0_4BChance=street0_4BChance+%s, street0_4BDone=street0_4BDone+%s, + street0_C4BChance=street0_C4BChance+%s, + street0_C4BDone=street0_C4BDone+%s, street0_FoldTo3BChance=street0_FoldTo3BChance+%s, street0_FoldTo3BDone=street0_FoldTo3BDone+%s, street0_FoldTo4BChance=street0_FoldTo4BChance+%s, street0_FoldTo4BDone=street0_FoldTo4BDone+%s, - other3BStreet0=other3BStreet0+%s, - other4BStreet0=other4BStreet0+%s, + street0_SqueezeChance=street0_SqueezeChance+%s, + street0_SqueezeDone=street0_SqueezeDone+%s, + success_Steal=success_Steal+%s, street1Seen=street1Seen+%s, street2Seen=street2Seen+%s, street3Seen=street3Seen+%s, @@ -4573,12 +4641,15 @@ class Sql: street0_3BDone, street0_4BChance, street0_4BDone, + street0_C4BChance, + street0_C4BDone, street0_FoldTo3BChance, street0_FoldTo3BDone, street0_FoldTo4BChance, street0_FoldTo4BDone, - other3BStreet0, - other4BStreet0, + street0_SqueezeChance, + street0_SqueezeDone, + success_Steal, otherRaisedStreet0, otherRaisedStreet1, otherRaisedStreet2, @@ -4637,7 +4708,8 @@ class Sql: %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, - %s, %s, %s, %s + %s, %s, %s, %s, %s, + %s, %s )""" self.query['store_hands_actions'] = """INSERT INTO HandsActions ( diff --git a/pyfpdb/Stats.py b/pyfpdb/Stats.py index 97d37d7c..a1feedc4 100755 --- a/pyfpdb/Stats.py +++ b/pyfpdb/Stats.py @@ -378,6 +378,21 @@ def steal(stat_dict, player): except: return (stat, 'NA', 'st=NA', 'steal=NA', '(0/0)', '% steal attempted') +def s_steal(stat_dict, player): + """ Success Steal %.""" + stat = 0.0 + try: + stat = float(stat_dict[player]['suc_st'])/float(stat_dict[player]['steal']) + return (stat, + '%3.1f' % (100.0*stat), + 's_st=%3.1f%%' % (100.0*stat), + 's_steal=%3.1f%%' % (100.0*stat), + '(%d/%d)' % (stat_dict[player]['suc_st'], stat_dict[player]['steal']), + _('% success steal') + ) + except: + return (stat, 'NA', 'st=NA', 's_steal=NA', '(0/0)', '% success steal') + def f_SB_steal(stat_dict, player): """ Folded SB to steal.""" stat = 0.0 @@ -465,17 +480,56 @@ def four_B(stat_dict, player): return (stat, '%3.1f' % (100.0*stat), '4B=%3.1f%%' % (100.0*stat), - '4B_pf=%3.1f%%' % (100.0*stat), + '4B=%3.1f%%' % (100.0*stat), '(%d/%d)' % (stat_dict[player]['fb_0'], stat_dict[player]['fb_opp_0']), _('% 4 Bet preflop/4rd')) except: return (stat, 'NA', '4B=NA', - '4B_pf=NA', + '4B=NA', '(0/0)', _('% 4 Bet preflop/4rd')) +def cfour_B(stat_dict, player): + """ Cold Four bet preflop/4rd.""" + stat = 0.0 + try: + stat = float(stat_dict[player]['cfb_0'])/float(stat_dict[player]['cfb_opp_0']) + return (stat, + '%3.1f' % (100.0*stat), + 'C4B=%3.1f%%' % (100.0*stat), + 'C4B_pf=%3.1f%%' % (100.0*stat), + '(%d/%d)' % (stat_dict[player]['cfb_0'], stat_dict[player]['cfb_opp_0']), + _('% Cold 4 Bet preflop/4rd')) + except: + return (stat, + 'NA', + 'C4B=NA', + 'C4B_pf=NA', + '(0/0)', + _('% Cold 4 Bet preflop/4rd')) + +def squeeze(stat_dict, player): + """ Squeeze bet preflop.""" + stat = 0.0 + try: + stat = float(stat_dict[player]['sqz_0'])/float(stat_dict[player]['sqz_opp_0']) + return (stat, + '%3.1f' % (100.0*stat), + 'SQZ=%3.1f%%' % (100.0*stat), + 'SQZ_pf=%3.1f%%' % (100.0*stat), + '(%d/%d)' % (stat_dict[player]['sqz_0'], stat_dict[player]['sqz_opp_0']), + _('% Squeeze preflop')) + except: + return (stat, + 'NA', + 'SQZ=NA', + 'SQZ_pf=NA', + '(0/0)', + _('% Squeeze preflop')) + + def f_3bet(stat_dict, player): """ Fold to 3bet preflop. """ stat = 0.0 From d6a034b1830d8830f517bc784b9e918af5b65b52 Mon Sep 17 00:00:00 2001 From: DoNoBaN Date: Sat, 12 Feb 2011 21:20:53 +0100 Subject: [PATCH 110/182] DerivedStats.py with cold4bet, squeeze and success steal --- pyfpdb/DerivedStats.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/pyfpdb/DerivedStats.py b/pyfpdb/DerivedStats.py index 2bb3542f..a21bc209 100644 --- a/pyfpdb/DerivedStats.py +++ b/pyfpdb/DerivedStats.py @@ -50,10 +50,15 @@ class DerivedStats(): self.handsplayers[player[1]]['street0_3BDone'] = False self.handsplayers[player[1]]['street0_4BChance'] = False self.handsplayers[player[1]]['street0_4BDone'] = False + self.handsplayers[player[1]]['street0_C4BChance'] = False + self.handsplayers[player[1]]['street0_C4BDone'] = False self.handsplayers[player[1]]['street0_FoldTo3BChance']= False self.handsplayers[player[1]]['street0_FoldTo3BDone']= False self.handsplayers[player[1]]['street0_FoldTo4BChance']= False self.handsplayers[player[1]]['street0_FoldTo4BDone']= False + self.handsplayers[player[1]]['street0_SqueezeChance']= False + self.handsplayers[player[1]]['street0_SqueezeDone'] = False + self.handsplayers[player[1]]['success_Steal'] = False self.handsplayers[player[1]]['raiseFirstInChance'] = False self.handsplayers[player[1]]['raisedFirstIn'] = False self.handsplayers[player[1]]['foldBbToStealChance'] = False @@ -417,8 +422,10 @@ class DerivedStats(): #print "\naction:", action[0], posn, type(posn), steal_attempt, act if posn == 'B': #NOTE: Stud games will never hit this section - self.handsplayers[pname]['foldBbToStealChance'] = steal_attempt - self.handsplayers[pname]['foldedBbToSteal'] = steal_attempt and act == 'folds' + if steal_attempt: + self.handsplayers[pname]['foldBbToStealChance'] = True + self.handsplayers[pname]['foldedBbToSteal'] = act == 'folds' + self.handsplayers[stealer]['success_Steal'] = act == 'folds' break elif posn == 'S': self.handsplayers[pname]['foldSbToStealChance'] = steal_attempt @@ -434,6 +441,7 @@ class DerivedStats(): raised = True if posn in steal_positions: steal_attempt = True + stealer = pname if act == 'calls': break @@ -443,8 +451,8 @@ class DerivedStats(): def calc34BetStreet0(self, hand): """Fills street0_(3|4)B(Chance|Done), other(3|4)BStreet0""" bet_level = 1 # bet_level after 3-bet is equal to 3 + squeeze_chance = 0 for action in hand.actions[hand.actionStreets[1]]: - # FIXME: fill other(3|4)BStreet0 - i have no idea what does it mean pname, act, aggr = action[0], action[1], action[1] in ('raises', 'bets') if bet_level == 1: if aggr: @@ -453,8 +461,13 @@ class DerivedStats(): continue elif bet_level == 2: self.handsplayers[pname]['street0_3BChance'] = True + self.handsplayers[pname]['street0_SqueezeChance'] = squeeze_chance + if not squeeze_chance and act == 'calls': + squeeze_chance = 1 + continue if aggr: self.handsplayers[pname]['street0_3BDone'] = True + self.handsplayers[pname]['street0_SqueezeDone'] = squeeze_chance second_agressor = pname bet_level += 1 continue @@ -468,6 +481,11 @@ class DerivedStats(): elif act == 'folds': self.handsplayers[pname]['street0_FoldTo3BDone'] = True break + else: + self.handsplayers[pname]['street0_C4BChance'] = True + if aggr: + self.handsplayers[pname]['street0_C4BDone'] = True + bet_level += 1 continue elif bet_level == 4: if pname == second_agressor: From e570e34f28b628d40c9a8f605ef33a3ee9d2de61 Mon Sep 17 00:00:00 2001 From: Worros Date: Sun, 13 Feb 2011 21:59:36 +0800 Subject: [PATCH 111/182] Options - add a -D option for directory --- pyfpdb/Options.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pyfpdb/Options.py b/pyfpdb/Options.py index 08b1f4cb..e6591a4c 100644 --- a/pyfpdb/Options.py +++ b/pyfpdb/Options.py @@ -55,7 +55,9 @@ def fpdb_options(): help=_("Print some useful one liners")) # The following options are used for SplitHandHistory.py parser.add_option("-f", "--file", dest="filename", metavar="FILE", default=None, - help=_("Input file in quiet mode")) + help=_("Input file")) + parser.add_option("-D", "--directory", dest="directory", metavar="FILE", default=None, + help=_("Input directory")) parser.add_option("-o", "--outpath", dest="outpath", metavar="FILE", default=None, help=_("Input out path in quiet mode")) parser.add_option("-a", "--archive", action="store_true", dest="archive", default=False, From 2da7dc84953abf3807c0169a8dc659e102656257 Mon Sep 17 00:00:00 2001 From: Worros Date: Sun, 13 Feb 2011 22:04:09 +0800 Subject: [PATCH 112/182] OnGame: Modify re_HandInfo to parse SPEED tables --- pyfpdb/OnGameToFpdb.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pyfpdb/OnGameToFpdb.py b/pyfpdb/OnGameToFpdb.py index d69170a6..889f2d24 100755 --- a/pyfpdb/OnGameToFpdb.py +++ b/pyfpdb/OnGameToFpdb.py @@ -68,17 +68,19 @@ class OnGame(HandHistoryConverter): # ***** End of hand R5-75443872-57 ***** re_SplitHands = re.compile(u'\*\*\*\*\*\sEnd\sof\shand\s[-A-Z\d]+.*\n(?=\*)') + #TODO: detect play money + # "Play money" rather than "Real money" and set currency accordingly re_HandInfo = re.compile(u""" \*\*\*\*\*\sHistory\sfor\shand\s(?P[-A-Z\d]+).* Start\shand:\s(?P.*) - Table:\s(?P
(?P.+?)<\/td>(?P.+?)
[-\'\w\s]+)\s\[\d+\]\s\( + Table:\s(\[SPEED\]\s)?(?P
[-\'\w\s]+)\s\[\d+\]\s\( ( (?PNO_LIMIT|Limit|LIMIT|Pot\sLimit|POT_LIMIT)\s (?PTEXAS_HOLDEM|OMAHA_HI|SEVEN_CARD_STUD|SEVEN_CARD_STUD_HI_LO|RAZZ|FIVE_CARD_DRAW)\s (?P%(LS)s|)?(?P[.0-9]+)/ (%(LS)s)?(?P[.0-9]+) )? - """ % substitutions, re.MULTILINE|re.DOTALL|re.VERBOSE) #TODO: detect play money (identified by "Play money" rather than "Real money" and set currency accordingly + """ % substitutions, re.MULTILINE|re.DOTALL|re.VERBOSE) re_TailSplitHands = re.compile(u'(\*\*\*\*\*\sEnd\sof\shand\s[-A-Z\d]+.*\n)(?=\*)') re_Button = re.compile('Button: seat (?P