diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..3d8ec313 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +# Variable definitions +VERSION = 0.12 +DATE = $(shell date +%Y%m%d) + +all: + @echo "Usage:" + @echo " make snapshot - Tags the repository with $(VERSION)-$(DATE) and creates a tarball from that" + +snapshot: + git tag $(VERSION)-$(DATE) + git archive --prefix=fpdb-$(VERSION)-$(DATE)/ $(VERSION)-$(DATE) | gzip -9 > ../fpdb-$(VERSION)-$(DATE).tar.gz diff --git a/pyfpdb/Anonymise.py b/pyfpdb/Anonymise.py new file mode 100644 index 00000000..32036b1e --- /dev/null +++ b/pyfpdb/Anonymise.py @@ -0,0 +1,37 @@ +import os +import re +import codecs +import Options +import HandHistoryConverter + +(options, argv) = Options.fpdb_options() + +filter = options.hhc + +filter_name = filter.replace("ToFpdb", "") + +mod = __import__(filter) +obj = getattr(mod, filter_name, None) + +hhc = obj(autostart=False) + +if os.path.exists(options.infile): + in_fh = codecs.open(options.infile, 'r', "utf8") + filecontents = in_fh.read() + in_fh.close() +else: + print "Could not find file %s" % options.infile + exit(1) + +m = hhc.re_PlayerInfo.finditer(filecontents) + +players = [] +for a in m: + players = players + [a.group('PNAME')] + +uniq = set(players) + +for i, name in enumerate(uniq, 1): + filecontents = filecontents.replace(name, 'Player%d' %i) + +print filecontents diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py old mode 100755 new mode 100644 index cd6ad298..36fdd2d2 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -58,7 +58,8 @@ class Database: PGSQL = 3 SQLITE = 4 - hero_hudstart_def = '1999-12-31' # default for length of Hero's stats in HUD + hero_hudstart_def = '1999-12-31' # default for length of Hero's stats in HUD + villain_hudstart_def = '1999-12-31' # default for length of Villain's stats in HUD # Data Structures for index and foreign key creation # drop_code is an int with possible values: 0 - don't drop for bulk import @@ -473,8 +474,9 @@ class Database: else: h_seats_min, h_seats_max = 0, 10 print "bad h_seats_style value:", h_seats_style - print "opp seats style", seats_style, "hero seats style", h_seats_style - print "opp seats:", seats_min, seats_max, " hero seats:", h_seats_min, h_seats_max + log.info("opp seats style %s %d %d hero seats style %s %d %d" + % (seats_style, seats_min, seats_max + ,h_seats_style, h_seats_min, h_seats_max) ) if hud_style == 'S' or h_hud_style == 'S': self.get_stats_from_hand_session(hand, stat_dict, hero_id @@ -1324,7 +1326,7 @@ class Database: self.dropAllForeignKeys() self.createAllForeignKeys() - def rebuild_hudcache(self, start=None): + def rebuild_hudcache(self, h_start=None, v_start=None): """clears hudcache and rebuilds from the individual handsplayers records""" try: @@ -1344,13 +1346,17 @@ class Database: if p_id: self.hero_ids[site_id] = int(p_id) - if start is None: - start = self.hero_hudstart_def + if h_start is None: + h_start = self.hero_hudstart_def + if v_start is None: + v_start = self.villain_hudstart_def if self.hero_ids == {}: where = "" else: - where = "where hp.playerId not in " + str(tuple(self.hero_ids.values())) \ - + " or h.handStart > '" + start + "'" + where = "where ( hp.playerId not in " + str(tuple(self.hero_ids.values())) \ + + " and h.handStart > '" + v_start + "')" \ + + " or ( hp.playerId in " + str(tuple(self.hero_ids.values())) \ + + " and h.handStart > '" + h_start + "')" rebuild_sql = self.sql.query['rebuildHudCache'].replace('', where) self.get_cursor().execute(self.sql.query['clearHudCache']) diff --git a/pyfpdb/DerivedStats.py b/pyfpdb/DerivedStats.py index c244f019..e4072d8a 100644 --- a/pyfpdb/DerivedStats.py +++ b/pyfpdb/DerivedStats.py @@ -149,6 +149,42 @@ class DerivedStats(): for i, card in enumerate(hcs[:7], 1): self.handsplayers[player[1]]['card%s' % i] = Card.encodeCard(card) + # position, + #Stud 3rd street card test + # denny501: brings in for $0.02 + # s0rrow: calls $0.02 + # TomSludge: folds + # Soroka69: calls $0.02 + # rdiezchang: calls $0.02 (Seat 8) + # u.pressure: folds (Seat 1) + # 123smoothie: calls $0.02 + # gashpor: calls $0.02 + # tourneyTypeId, + # startCards, + # street0_3BChance,street0_3BDone, + # otherRaisedStreet1-4 + # foldToOtherRaisedStreet1-4 + # stealAttemptChance,stealAttempted, + # foldBbToStealChance,foldedBbToSteal, + # foldSbToStealChance,foldedSbToSteal, + # foldToStreet1-4CBChance, foldToStreet1-4CBDone, + # street1-4CheckCallRaiseChance, street1-4CheckCallRaiseDone, + + # Additional stats + # 3betSB, 3betBB + # Squeeze, Ratchet? + + + def getPosition(hand, seat): + """Returns position value like 'B', 'S', 0, 1, ...""" + # Flop/Draw games with blinds + # Need a better system??? + # -2 BB - B (all) + # -1 SB - S (all) + # 0 Button + # 1 Cutoff + # 2 Hijack + def assembleHudCache(self, hand): pass @@ -195,8 +231,9 @@ class DerivedStats(): pas = set.union(self.pfba(actions) - self.pfba(actions, l=('folds',)), alliners) self.hands['playersAtShowdown'] = len(pas) - for player in pas: - self.handsplayers[player]['sawShowdown'] = True + if self.hands['playersAtShowdown'] > 1: + for player in pas: + self.handsplayers[player]['sawShowdown'] = True def streetXRaises(self, hand): # self.actions[street] is a list of all actions in a tuple, contining the action as the second element diff --git a/pyfpdb/GuiGraphViewer.py b/pyfpdb/GuiGraphViewer.py index 76c80f2e..9daa940f 100644 --- a/pyfpdb/GuiGraphViewer.py +++ b/pyfpdb/GuiGraphViewer.py @@ -196,7 +196,10 @@ class GuiGraphViewer (threading.Thread): self.ax.plot(green, color='green', label='Hands: %d\nProfit: $%.2f' %(len(green), green[-1])) self.ax.plot(blue, color='blue', label='Showdown: $%.2f' %(blue[-1])) self.ax.plot(red, color='red', label='Non-showdown: $%.2f' %(red[-1])) - self.ax.legend(loc='best', fancybox=True, shadow=True, prop=FontProperties(size='smaller')) + if sys.version[0:3] == '2.5': + self.ax.legend(loc='best', shadow=True, prop=FontProperties(size='smaller')) + else: + self.ax.legend(loc='best', fancybox=True, shadow=True, prop=FontProperties(size='smaller')) self.graphBox.add(self.canvas) diff --git a/pyfpdb/GuiLogView.py b/pyfpdb/GuiLogView.py new file mode 100755 index 00000000..3b7b8aa6 --- /dev/null +++ b/pyfpdb/GuiLogView.py @@ -0,0 +1,175 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +#Copyright 2008 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 in the docs folder of the package. + + +import mmap + +import pygtk +pygtk.require('2.0') +import gtk +import gobject +import pango + +import Configuration + +log = Configuration.get_logger("logging.conf", "logview") + +MAX_LINES = 100000 + +class GuiLogView: + + def __init__(self, config, mainwin, vbox): + self.config = config + self.main_window = mainwin + self.vbox = vbox + gtk.Widget.set_size_request(self.vbox, 700, 400); + + self.liststore = gtk.ListStore(str, str, str, str, gobject.TYPE_BOOLEAN) # date, module, level, text + + # this is how to add a filter: + # + # # Creation of the filter, from the model + # filter = self.liststore.filter_new() + # filter.set_visible_column(1) + # + # # The TreeView gets the filter as model + # self.listview = gtk.TreeView(filter) + + self.listview = gtk.TreeView(model=self.liststore) + self.listview.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_NONE) + self.listcols = [] + + scrolledwindow = gtk.ScrolledWindow() + scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + scrolledwindow.add(self.listview) + self.vbox.pack_start(scrolledwindow, expand=True, fill=True, padding=0) + + refreshbutton = gtk.Button("Refresh") + refreshbutton.connect("clicked", self.refresh, None) + self.vbox.pack_start(refreshbutton, False, False, 3) + refreshbutton.show() + + self.listview.show() + scrolledwindow.show() + self.vbox.show() + + col = self.addColumn("Date/Time", 0) + col = self.addColumn("Module", 1) + col = self.addColumn("Level", 2) + col = self.addColumn("Text", 3) + + self.loadLog() + self.vbox.show_all() + + def addColumn(self, title, n): + col = gtk.TreeViewColumn(title) + self.listview.append_column(col) + cRender = gtk.CellRendererText() + cRender.set_property("wrap-mode", pango.WRAP_WORD_CHAR) + col.pack_start(cRender, True) + col.add_attribute(cRender, 'text', n) + col.set_max_width(1000) + col.set_spacing(0) # no effect + self.listcols.append(col) + col.set_clickable(True) + col.connect("clicked", self.sortCols, n) + return(col) + + def loadLog(self): + + #self.configStore = gtk.TreeStore(gobject.TYPE_PYOBJECT, gobject.TYPE_STRING, gobject.TYPE_STRING) + #self.configView = gtk.TreeView(self.configStore) + #self.configView.set_enable_tree_lines(True) + self.liststore.clear() + self.listcols = [] + + # count number of lines in file + f = open('logging.out', "r+") + buf = mmap.mmap(f.fileno(), 0) + readline = buf.readline + lines = 0 + while readline(): + lines += 1 + f.close() + + startline = 0 + if lines > MAX_LINES: + # only display from startline if log file is large + startline = lines - MAX_LINES + + f = open('logging.out', "r+") + buf = mmap.mmap(f.fileno(), 0) + readline = buf.readline + l = 0 + line = readline() + while line: + # eg line: + # 2009-12-02 15:23:21,716 - config DEBUG config logger initialised + l = l + 1 + if l > startline and len(line) > 49: + iter = self.liststore.append( (line[0:23], line[26:32], line[39:46], line[48:].strip(), True) ) + line = readline() + f.close() + + def sortCols(self, col, n): + try: + if not col.get_sort_indicator() or col.get_sort_order() == gtk.SORT_ASCENDING: + col.set_sort_order(gtk.SORT_DESCENDING) + else: + col.set_sort_order(gtk.SORT_ASCENDING) + self.liststore.set_sort_column_id(n, col.get_sort_order()) + #self.liststore.set_sort_func(n, self.sortnums, (n,grid)) + for i in xrange(len(self.listcols)): + self.listcols[i].set_sort_indicator(False) + self.listcols[n].set_sort_indicator(True) + # use this listcols[col].set_sort_indicator(True) + # to turn indicator off for other cols + except: + err = traceback.extract_tb(sys.exc_info()[2]) + print "***sortCols error: " + str(sys.exc_info()[1]) + print "\n".join( [e[0]+':'+str(e[1])+" "+e[2] for e in err] ) + + def refresh(self, widget, data): + self.loadLog() + + + +if __name__=="__main__": + + config = Configuration.Config() + + win = gtk.Window(gtk.WINDOW_TOPLEVEL) + win.set_title("Test Log Viewer") + win.set_border_width(1) + win.set_default_size(600, 500) + win.set_resizable(True) + + dia = gtk.Dialog("Log Viewer", + win, + gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, + (gtk.STOCK_CLOSE, gtk.RESPONSE_OK)) + dia.set_default_size(500, 500) + log = GuiLogView(config, win, dia.vbox) + response = dia.run() + if response == gtk.RESPONSE_ACCEPT: + pass + dia.destroy() + + + + diff --git a/pyfpdb/HUD_config.test.xml b/pyfpdb/HUD_config.test.xml index 52905a70..1a5f77fa 100644 --- a/pyfpdb/HUD_config.test.xml +++ b/pyfpdb/HUD_config.test.xml @@ -574,7 +574,7 @@ Left-Drag to Move" - + diff --git a/pyfpdb/HUD_main.py b/pyfpdb/HUD_main.py index 108b89c7..62025018 100755 --- a/pyfpdb/HUD_main.py +++ b/pyfpdb/HUD_main.py @@ -63,6 +63,9 @@ elif os.name == 'nt': import Hud +log = Configuration.get_logger("logging.conf") + + class HUD_main(object): """A main() object to own both the read_stdin thread and the gui.""" # This class mainly provides state for controlling the multiple HUDs. @@ -192,6 +195,8 @@ class HUD_main(object): while 1: # wait for a new hand number on stdin new_hand_id = sys.stdin.readline() + t0 = time.time() + t1 = t2 = t3 = t4 = t5 = t6 = t0 new_hand_id = string.rstrip(new_hand_id) if new_hand_id == "": # blank line means quit self.destroy() @@ -206,6 +211,7 @@ class HUD_main(object): print "db error: skipping %s" % new_hand_id sys.stderr.write("Database error: could not find hand %s.\n" % new_hand_id) continue + t1 = time.time() if type == "tour": # hand is from a tournament temp_key = tour_number @@ -215,6 +221,12 @@ class HUD_main(object): # Update an existing HUD if temp_key in self.hud_dict: # get stats using hud's specific params and get cards + self.db_connection.init_hud_stat_vars( self.hud_dict[temp_key].hud_params['hud_days'] + , self.hud_dict[temp_key].hud_params['h_hud_days']) + t2 = time.time() + stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_dict[temp_key].hud_params + ,self.hero_ids[site_id], num_seats) + t3 = time.time() try: self.db_connection.init_hud_stat_vars( self.hud_dict[temp_key].hud_params['hud_days'] , self.hud_dict[temp_key].hud_params['h_hud_days']) @@ -238,8 +250,10 @@ class HUD_main(object): else: # get stats using default params--also get cards self.db_connection.init_hud_stat_vars( self.hud_params['hud_days'], self.hud_params['h_hud_days'] ) + t4 = time.time() stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_params ,self.hero_ids[site_id], num_seats) + t5 = time.time() cards = self.db_connection.get_cards(new_hand_id) comm_cards = self.db_connection.get_common_cards(new_hand_id) if comm_cards != {}: # stud! @@ -263,6 +277,9 @@ class HUD_main(object): else: sys.stderr.write('Table "%s" no longer exists\n' % table_name) + t6 = time.time() + log.info("HUD_main.read_stdin: hand read in %4.3f seconds (%4.3f,%4.3f,%4.3f,%4.3f,%4.3f,%4.3f)" + % (t6-t0,t1-t0,t2-t0,t3-t0,t4-t0,t5-t0,t6-t0)) self.db_connection.connection.rollback() if __name__== "__main__": diff --git a/pyfpdb/Hand.py b/pyfpdb/Hand.py index efa9c0b6..9ff78249 100644 --- a/pyfpdb/Hand.py +++ b/pyfpdb/Hand.py @@ -54,6 +54,7 @@ class Hand(object): self.starttime = 0 self.handText = handText self.handid = 0 + self.dbid_hands = 0 self.tablename = "" self.hero = "" self.maxseats = None @@ -218,8 +219,8 @@ db: a connected fpdb_db object""" # seats TINYINT NOT NULL, hh['seats'] = len(sqlids) - handid = db.storeHand(hh) - db.storeHandsPlayers(handid, sqlids, self.stats.getHandsPlayers()) + self.dbid_hands = db.storeHand(hh) + db.storeHandsPlayers(self.dbid_hands, sqlids, self.stats.getHandsPlayers()) # HandsActions - all actions for all players for all streets - self.actions # HudCache data can be generated from HandsActions (HandsPlayers?) # Tourneys ? diff --git a/pyfpdb/HandHistoryConverter.py b/pyfpdb/HandHistoryConverter.py index 41b7b3d0..27bb9b1a 100644 --- a/pyfpdb/HandHistoryConverter.py +++ b/pyfpdb/HandHistoryConverter.py @@ -71,6 +71,8 @@ follow : whether to tail -f the input""" self.out_path = out_path self.processedHands = [] + self.numHands = 0 + self.numErrors = 0 # Tourney object used to store TourneyInfo when called to deal with a Summary file self.tourney = None @@ -135,17 +137,17 @@ Otherwise, finish at EOF. return try: - numHands = 0 - numErrors = 0 + self.numHands = 0 + self.numErrors = 0 if self.follow: #TODO: See how summary files can be handled on the fly (here they should be rejected as before) log.info("Tailing '%s'" % self.in_path) for handText in self.tailHands(): try: self.processHand(handText) - numHands += 1 + self.numHands += 1 except FpdbParseError, e: - numErrors += 1 + self.numErrors += 1 log.warning("Failed to convert hand %s" % e.hid) log.warning("Exception msg: '%s'" % str(e)) log.debug(handText) @@ -160,13 +162,13 @@ Otherwise, finish at EOF. try: self.processedHands.append(self.processHand(handText)) except FpdbParseError, e: - numErrors += 1 + self.numErrors += 1 log.warning("Failed to convert hand %s" % e.hid) log.warning("Exception msg: '%s'" % str(e)) log.debug(handText) - numHands = len(handsList) + self.numHands = len(handsList) endtime = time.time() - log.info("Read %d hands (%d failed) in %.3f seconds" % (numHands, numErrors, endtime - starttime)) + log.info("Read %d hands (%d failed) in %.3f seconds" % (self.numHands, self.numErrors, endtime - starttime)) else: self.parsedObjectType = "Summary" summaryParsingStatus = self.readSummaryInfo(handsList) diff --git a/pyfpdb/Hud.py b/pyfpdb/Hud.py index c9420a8a..b61c17aa 100644 --- a/pyfpdb/Hud.py +++ b/pyfpdb/Hud.py @@ -173,26 +173,26 @@ class Hud: item = gtk.CheckMenuItem(' All Levels') self.aggMenu.append(item) item.connect("activate", self.set_aggregation, ('P',10000)) - setattr(self, 'h_aggBBmultItem10000', item) - # + setattr(self, 'h_aggBBmultItem10000', item) + # item = gtk.MenuItem('For #Seats:') self.aggMenu.append(item) - # + # item = gtk.CheckMenuItem(' Any Number') self.aggMenu.append(item) item.connect("activate", self.set_seats_style, ('P','A')) setattr(self, 'h_seatsStyleOptionA', item) - # + # item = gtk.CheckMenuItem(' Custom') self.aggMenu.append(item) item.connect("activate", self.set_seats_style, ('P','C')) - setattr(self, 'h_seatsStyleOptionC', item) - # + setattr(self, 'h_seatsStyleOptionC', item) + # item = gtk.CheckMenuItem(' Exact') self.aggMenu.append(item) item.connect("activate", self.set_seats_style, ('P','E')) - setattr(self, 'h_seatsStyleOptionE', item) - # + setattr(self, 'h_seatsStyleOptionE', item) + # item = gtk.MenuItem('Since:') self.aggMenu.append(item) # @@ -242,26 +242,26 @@ class Hud: item = gtk.CheckMenuItem(' All Levels') self.aggMenu.append(item) item.connect("activate", self.set_aggregation, ('O',10000)) - setattr(self, 'aggBBmultItem10000', item) - # + setattr(self, 'aggBBmultItem10000', item) + # item = gtk.MenuItem('For #Seats:') self.aggMenu.append(item) - # + # item = gtk.CheckMenuItem(' Any Number') self.aggMenu.append(item) item.connect("activate", self.set_seats_style, ('O','A')) setattr(self, 'seatsStyleOptionA', item) - # + # item = gtk.CheckMenuItem(' Custom') self.aggMenu.append(item) item.connect("activate", self.set_seats_style, ('O','C')) - setattr(self, 'seatsStyleOptionC', item) - # + setattr(self, 'seatsStyleOptionC', item) + # item = gtk.CheckMenuItem(' Exact') self.aggMenu.append(item) item.connect("activate", self.set_seats_style, ('O','E')) - setattr(self, 'seatsStyleOptionE', item) - # + setattr(self, 'seatsStyleOptionE', item) + # item = gtk.MenuItem('Since:') self.aggMenu.append(item) # @@ -358,7 +358,7 @@ class Hud: def change_max_seats(self, widget): if self.max != widget.ms: - print 'change_max_seats', widget.ms + #print 'change_max_seats', widget.ms self.max = widget.ms try: self.kill() @@ -402,7 +402,7 @@ class Hud: else: param = 'seats_style' prefix = '' - + if style == 'A' and getattr(self, prefix+'seatsStyleOptionA').get_active(): self.hud_params[param] = 'A' getattr(self, prefix+'seatsStyleOptionC').set_active(False) @@ -678,7 +678,7 @@ class Stat_Window: return True def kill_popup(self, popup): - print "remove popup", popup + #print "remove popup", popup self.popups.remove(popup) popup.window.destroy() diff --git a/pyfpdb/Options.py b/pyfpdb/Options.py index 9859e7d2..ab226124 100644 --- a/pyfpdb/Options.py +++ b/pyfpdb/Options.py @@ -36,8 +36,11 @@ def fpdb_options(): action="store_true", help="Indicates program was restarted with a different path (only allowed once).") parser.add_option("-i", "--infile", - dest="config", default=None, + dest="infile", default="Slartibartfast", help="Input file") + parser.add_option("-k", "--konverter", + dest="hhc", default="PokerStarsToFpdb", + help="Module name for Hand History Converter") (options, argv) = parser.parse_args() return (options, argv) diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index eb9296ef..5a0d1965 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -1317,6 +1317,7 @@ class Sql: 1.25 would be a config value so user could change it) */ GROUP BY hc.PlayerId, hp.seatNo, p.name + ORDER BY hc.PlayerId, hp.seatNo, p.name """ # same as above except stats are aggregated for all blind/limit levels @@ -1418,6 +1419,7 @@ class Sql: ) ) GROUP BY hc.PlayerId, p.name + ORDER BY hc.PlayerId, p.name """ # NOTES on above cursor: # - Do NOT include %s inside query in a comment - the db api thinks diff --git a/pyfpdb/fpdb.py b/pyfpdb/fpdb.py index d5f4faec..9085c4f5 100755 --- a/pyfpdb/fpdb.py +++ b/pyfpdb/fpdb.py @@ -37,14 +37,20 @@ if os.name == 'nt' and sys.version[0:3] not in ('2.5', '2.6') and '-r' not in sy os.execvpe('python.exe', ('python.exe', 'fpdb.py', '-r'), os.environ) # first arg is ignored (name of program being run) else: print "\npython 2.5 not found, please install python 2.5 or 2.6 for fpdb\n" - exit + raw_input("Press ENTER to continue.") + exit() else: pass #print "debug - not changing path" if os.name == 'nt': - import win32api - import win32con + try: + import win32api + import win32con + except ImportError: + print "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/" + raw_input("Press ENTER to continue.") + exit() print "Python " + sys.version[0:3] + '...\n' @@ -60,16 +66,23 @@ if not options.errorsToConsole: errorFile = open('fpdb-error-log.txt', 'w', 0) sys.stderr = errorFile -import logging +#import logging +import logging, logging.config -import pygtk -pygtk.require('2.0') -import gtk +try: + import pygtk + pygtk.require('2.0') + import gtk +except: + print "Unable to load PYGTK modules required for GUI. Please install PyCairo, PyGObject, and PyGTK from www.pygtk.org." + raw_input("Press ENTER to continue.") + exit() import interlocks import GuiPrefs +import GuiLogView import GuiBulkImport import GuiPlayerStats import GuiPositionalStats @@ -85,6 +98,8 @@ import Exceptions VERSION = "0.12" +log = Configuration.get_logger("logging.conf", "fpdb") + class fpdb: def tab_clicked(self, widget, tab_name): """called when a tab button is clicked to activate that tab""" @@ -115,7 +130,7 @@ class fpdb: self.pages.append(new_page) self.tabs.append(event_box) self.tab_names.append(new_tab_name) - + #self.nb.append_page(new_page, gtk.Label(new_tab_name)) self.nb.append_page(page, event_box) self.nb_tabs.append(new_tab_name) @@ -135,12 +150,12 @@ class fpdb: self.nb.set_current_page(tab_no) def create_custom_tab(self, text, nb): - #create a custom tab for notebook containing a + #create a custom tab for notebook containing a #label and a button with STOCK_ICON eventBox = gtk.EventBox() tabBox = gtk.HBox(False, 2) tabLabel = gtk.Label(text) - tabBox.pack_start(tabLabel, False) + tabBox.pack_start(tabLabel, False) eventBox.add(tabBox) if nb.get_n_pages() > 0: @@ -157,7 +172,7 @@ class fpdb: return eventBox def add_icon_to_button(self, button): - iconBox = gtk.HBox(False, 0) + iconBox = gtk.HBox(False, 0) image = gtk.Image() image.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_SMALL_TOOLBAR) gtk.Button.set_relief(button, gtk.RELIEF_NONE) @@ -168,8 +183,8 @@ class fpdb: iconBox.pack_start(image, True, False, 0) button.add(iconBox) iconBox.show() - return - + return + # Remove a page from the notebook def remove_tab(self, button, data): (nb, text) = data @@ -183,7 +198,7 @@ class fpdb: #print " removing page", page del self.nb_tabs[page] nb.remove_page(page) - # Need to refresh the widget -- + # Need to refresh the widget -- # This forces the widget to redraw itself. #nb.queue_draw_area(0,0,-1,-1) needed or not?? @@ -196,14 +211,17 @@ class fpdb: def dia_about(self, widget, data=None): #self.warning_box("About FPDB:\n\nFPDB was originally created by a guy named Steffen, sometime in 2008, \nand is mostly worked on these days by people named Eratosthenes, s0rrow, _mt, EricBlade, sqlcoder, and other strange people.\n\n", "ABOUT FPDB") dia = gtk.AboutDialog() - dia.set_name("FPDB") + dia.set_name("Free Poker Database (FPDB)") dia.set_version(VERSION) - dia.set_copyright("2008-2009, Steffen, Eratosthenes, s0rrow, EricBlade, _mt, sqlcoder, and others") + dia.set_copyright("2008-2010, Steffen, Eratosthenes, s0rrow, EricBlade, _mt, sqlcoder, Bostik, and others") dia.set_comments("GTK AboutDialog comments here") dia.set_license("GPL v3") dia.set_website("http://fpdb.sourceforge.net/") - dia.set_authors("Steffen, Eratosthenes, s0rrow, EricBlade, _mt, and others") + dia.set_authors(['Steffen', 'Eratosthenes', 's0rrow', + 'EricBlade', '_mt', 'and others']) dia.set_program_name("FPDB") + dia.set_authors("Steffen, Eratosthenes, s0rrow, EricBlade, _mt, sqlcoder, Bostik, and others") + dia.set_program_name("Free Poker Database (FPDB)") dia.run() dia.destroy() @@ -334,27 +352,48 @@ class fpdb: diastring = "Please confirm that you want to re-create the HUD cache." self.dia_confirm.format_secondary_text(diastring) - hb = gtk.HBox(True, 1) + hb1 = gtk.HBox(True, 1) + self.h_start_date = gtk.Entry(max=12) + self.h_start_date.set_text( self.db.get_hero_hudcache_start() ) + lbl = gtk.Label(" Hero's cache starts: ") + btn = gtk.Button() + btn.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)) + btn.connect('clicked', self.__calendar_dialog, self.h_start_date) + + hb1.pack_start(lbl, expand=True, padding=3) + hb1.pack_start(self.h_start_date, expand=True, padding=2) + hb1.pack_start(btn, expand=False, padding=3) + self.dia_confirm.vbox.add(hb1) + hb1.show_all() + + hb2 = gtk.HBox(True, 1) self.start_date = gtk.Entry(max=12) self.start_date.set_text( self.db.get_hero_hudcache_start() ) - lbl = gtk.Label(" Hero's cache starts: ") + lbl = gtk.Label(" Villains' cache starts: ") btn = gtk.Button() btn.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON)) btn.connect('clicked', self.__calendar_dialog, self.start_date) - hb.pack_start(lbl, expand=True, padding=3) - hb.pack_start(self.start_date, expand=True, padding=2) - hb.pack_start(btn, expand=False, padding=3) - self.dia_confirm.vbox.add(hb) - hb.show_all() + hb2.pack_start(lbl, expand=True, padding=3) + hb2.pack_start(self.start_date, expand=True, padding=2) + hb2.pack_start(btn, expand=False, padding=3) + self.dia_confirm.vbox.add(hb2) + hb2.show_all() response = self.dia_confirm.run() - self.dia_confirm.destroy() if response == gtk.RESPONSE_YES: - self.db.rebuild_hudcache( self.start_date.get_text() ) + lbl = gtk.Label(" Rebuilding HUD Cache ... ") + self.dia_confirm.vbox.add(lbl) + lbl.show() + while gtk.events_pending(): + gtk.main_iteration_do(False) + + self.db.rebuild_hudcache( self.h_start_date.get_text(), self.start_date.get_text() ) elif response == gtk.RESPONSE_NO: print 'User cancelled rebuilding hud cache' + self.dia_confirm.destroy() + self.release_global_lock() def dia_rebuild_indexes(self, widget, data=None): @@ -368,16 +407,53 @@ class fpdb: self.dia_confirm.format_secondary_text(diastring) response = self.dia_confirm.run() - self.dia_confirm.destroy() if response == gtk.RESPONSE_YES: + lbl = gtk.Label(" Rebuilding Indexes ... ") + self.dia_confirm.vbox.add(lbl) + lbl.show() + while gtk.events_pending(): + gtk.main_iteration_do(False) self.db.rebuild_indexes() + + lbl.set_text(" Cleaning Database ... ") + while gtk.events_pending(): + gtk.main_iteration_do(False) self.db.vacuumDB() + + lbl.set_text(" Analyzing Database ... ") + while gtk.events_pending(): + gtk.main_iteration_do(False) self.db.analyzeDB() elif response == gtk.RESPONSE_NO: print 'User cancelled rebuilding db indexes' + self.dia_confirm.destroy() + self.release_global_lock() + def dia_logs(self, widget, data=None): + lock_set = False + if self.obtain_global_lock(): + lock_set = True + + dia = gtk.Dialog(title="Log Messages" + ,parent=None + ,flags=0 + ,buttons=(gtk.STOCK_CLOSE,gtk.RESPONSE_OK)) + logviewer = GuiLogView.GuiLogView(self.config, self.window, dia.vbox) + response = dia.run() + if response == gtk.RESPONSE_ACCEPT: + pass + dia.destroy() + + if lock_set: + self.release_global_lock() + + def addLogText(self, text): + end_iter = self.logbuffer.get_end_iter() + self.logbuffer.insert(end_iter, text) + self.logview.scroll_to_mark(self.logbuffer.get_insert(), 0) + def __calendar_dialog(self, widget, entry): self.dia_confirm.set_modal(False) d = gtk.Window(gtk.WINDOW_TOPLEVEL) @@ -397,10 +473,13 @@ class fpdb: d.show_all() def __get_dates(self): - t1 = self.start_date.get_text() + t1 = self.h_start_date.get_text() if t1 == '': t1 = '1970-01-01' - return (t1) + t2 = self.start_date.get_text() + if t2 == '': + t2 = '1970-01-01' + return (t1, t2) def __get_date(self, widget, calendar, entry, win): # year and day are correct, month is 0..11 @@ -477,6 +556,7 @@ class fpdb: + @@ -518,6 +598,7 @@ class fpdb: ('stats', None, '_Statistics (todo)', None, 'View Database Statistics', self.dia_database_stats), ('help', None, '_Help'), ('Abbrev', None, '_Abbrevations (todo)', None, 'List of Abbrevations', self.tab_abbreviations), + ('Logs', None, '_Log Messages', None, 'Log and Debug Messages', self.dia_logs), ('About', None, 'A_bout', None, 'About the program', self.dia_about), ('License', None, '_License and Copying (todo)', None, 'License and Copying', self.dia_licensing), ]) @@ -557,7 +638,7 @@ class fpdb: self.warning_box("MySQL Server reports: Access denied. Are your permissions set correctly?") exit() except Exceptions.FpdbMySQLNoDatabase: - msg = "MySQL client reports: 2002 error. Unable to connect - Please check that the MySQL service has been started" + msg = "MySQL client reports: 2002 or 2003 error. Unable to connect - Please check that the MySQL service has been started" self.warning_box(msg) exit @@ -752,7 +833,6 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt") sys.stderr.write("fpdb starting ...") def window_state_event_cb(self, window, event): - print "window_state_event", event if event.changed_mask & gtk.gdk.WINDOW_STATE_ICONIFIED: # -20 = GWL_EXSTYLE can't find it in the pywin32 libs #bits = win32api.GetWindowLong(self.window.window.handle, -20) @@ -835,6 +915,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt") gtk.main() return 0 + if __name__ == "__main__": me = fpdb() me.main() diff --git a/pyfpdb/fpdb_db.py b/pyfpdb/fpdb_db.py index 8a0ec54e..405a142c 100644 --- a/pyfpdb/fpdb_db.py +++ b/pyfpdb/fpdb_db.py @@ -106,7 +106,7 @@ class fpdb_db: except MySQLdb.Error, ex: if ex.args[0] == 1045: raise FpdbMySQLAccessDenied(ex.args[0], ex.args[1]) - elif ex.args[0] == 2002: + elif ex.args[0] == 2002 or ex.args[0] == 2003: # 2002 is no unix socket, 2003 is no tcp socket raise FpdbMySQLNoDatabase(ex.args[0], ex.args[1]) else: print "*** WARNING UNKNOWN MYSQL ERROR", ex diff --git a/pyfpdb/fpdb_import.py b/pyfpdb/fpdb_import.py index 19bf18d1..760e1f01 100644 --- a/pyfpdb/fpdb_import.py +++ b/pyfpdb/fpdb_import.py @@ -21,7 +21,7 @@ import os # todo: remove this once import_dir is in fpdb_import import sys -from time import time, strftime, sleep +from time import time, strftime, sleep, clock import traceback import math import datetime @@ -101,6 +101,8 @@ class Importer: self.NEWIMPORT = Configuration.NEWIMPORT + clock() # init clock in windows + #Set functions def setCallHud(self, value): self.callHud = value @@ -359,10 +361,15 @@ class Importer: # print "file",counter," updated", os.path.basename(file), stat_info.st_size, self.updatedsize[file], stat_info.st_mtime, self.updatedtime[file] try: if not os.path.isdir(file): - self.caller.addText("\n"+file) + self.caller.addText("\n"+os.path.basename(file)) except KeyError: # TODO: What error happens here? pass - self.import_file_dict(self.database, file, self.filelist[file][0], self.filelist[file][1], None) + (stored, duplicates, partial, errors, ttime) = self.import_file_dict(self.database, file, self.filelist[file][0], self.filelist[file][1], None) + try: + if not os.path.isdir(file): + self.caller.addText(" %d stored, %d duplicates, %d partial, %d errors (time = %f)" % (stored, duplicates, partial, errors, ttime)) + except KeyError: # TODO: Again, what error happens here? fix when we find out .. + pass self.updatedsize[file] = stat_info.st_size self.updatedtime[file] = time() else: @@ -393,7 +400,7 @@ class Importer: if os.path.isdir(file): self.addToDirList[file] = [site] + [filter] - return + return (0,0,0,0,0) conv = None (stored, duplicates, partial, errors, ttime) = (0, 0, 0, 0, 0) @@ -427,8 +434,17 @@ class Importer: self.pos_in_file[file] = hhc.getLastCharacterRead() for hand in handlist: + #try, except duplicates here? #hand.prepInsert() hand.insert(self.database) + if self.callHud and hand.dbid_hands != 0: + #print "DEBUG: call to HUD: handsId: %s" % hand.dbid_hands + #pipe the Hands.id out to the HUD + # print "fpdb_import: sending hand to hud", handsId, "pipe =", self.caller.pipe_to_hud + self.caller.pipe_to_hud.stdin.write("%s" % (hand.dbid_hands) + os.linesep) + + errors = getattr(hhc, 'numErrors') + stored = getattr(hhc, 'numHands') else: # conversion didn't work # TODO: appropriate response? @@ -472,10 +488,13 @@ class Importer: self.pos_in_file[file] = inputFile.tell() inputFile.close() + x = clock() (stored, duplicates, partial, errors, ttime, handsId) = self.import_fpdb_lines(db, self.lines, starttime, file, site, q) db.commit() - ttime = time() - starttime + y = clock() + ttime = y - x + #ttime = time() - starttime if q is None: log.info("Total stored: %(stored)d\tduplicates:%(duplicates)d\terrors:%(errors)d\ttime:%(ttime)s" % locals()) @@ -554,7 +573,11 @@ class Importer: #print "call to HUD here. handsId:",handsId #pipe the Hands.id out to the HUD # print "fpdb_import: sending hand to hud", handsId, "pipe =", self.caller.pipe_to_hud - self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep) + try: + self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep) + except IOError: # hud closed + self.callHud = False + pass # continue import without hud except Exceptions.DuplicateError: duplicates += 1 db.rollback() diff --git a/pyfpdb/fpdb_simple.py b/pyfpdb/fpdb_simple.py index aaf74772..aa9421f6 100644 --- a/pyfpdb/fpdb_simple.py +++ b/pyfpdb/fpdb_simple.py @@ -1,5 +1,5 @@ #!/usr/bin/python - + #Copyright 2008 Steffen Jobbagy-Felso #This program is free software: you can redistribute it and/or modify #it under the terms of the GNU Affero General Public License as published by @@ -14,13 +14,13 @@ #along with this program. If not, see . #In the "official" distribution you can find the license in #agpl-3.0.txt in the docs folder of the package. - + #This file contains simple functions for fpdb #Aiming to eventually remove this module, functions will move to, eg: #fpdb_db db create/re-create/management/etc #Hands or related files for saving hands to db, etc - + import datetime import time import re @@ -29,7 +29,7 @@ from Exceptions import * import locale import Card - + PS = 1 FTP = 2 @@ -52,7 +52,7 @@ def checkPositions(positions): raise FpdbError("invalid position '"+p+"' found in checkPositions") ### RHH modified to allow for "position 9" here (pos==9 is when you're a dead hand before the BB ### eric - position 8 could be valid - if only one blind is posted, but there's still 10 people, ie a sitout is present, and the small is dead... - + def classifyLines(hand, category, lineTypes, lineStreets): """ makes a list of classifications for each line for further processing manipulates passed arrays """ @@ -69,7 +69,7 @@ def classifyLines(hand, category, lineTypes, lineStreets): elif i == 0: lineTypes.append("header") elif line.startswith("Table '"): - lineTypes.append("table") + lineTypes.append("table") elif line.startswith("Seat ") and ( ("in chips" in line) or "($" in line): lineTypes.append("name") elif isActionLine(line): @@ -84,7 +84,7 @@ def classifyLines(hand, category, lineTypes, lineStreets): elif line.startswith("*** TURN *** ["): lineTypes.append("cards") currentStreet="turn" - elif line.startswith("*** RIVER *** ["): + elif line.startswith("*** RIVER *** ["): lineTypes.append("cards") currentStreet="river" elif line.startswith("*** 3"): @@ -115,7 +115,7 @@ def classifyLines(hand, category, lineTypes, lineStreets): else: raise FpdbError("unrecognised linetype in:"+hand[i]) lineStreets.append(currentStreet) - + def convert3B4B(category, limit_type, actionTypes, actionAmounts): """calculates the actual bet amounts in the given amount array and changes it accordingly.""" for i in xrange(len(actionTypes)): @@ -130,7 +130,7 @@ def convert3B4B(category, limit_type, actionTypes, actionAmounts): amount2 = actionAmounts[bets[betNo][0]][bets[betNo][1]][bets[betNo][2]] amount1 = actionAmounts[bets[betNo-1][0]][bets[betNo-1][1]][bets[betNo-1][2]] actionAmounts[bets[betNo][0]][bets[betNo][1]][bets[betNo][2]] = amount2 - amount1 - + def convertBlindBet(actionTypes, actionAmounts): """ Corrects the bet amount if the player had to pay blinds """ i = 0#setting street to pre-flop @@ -140,14 +140,14 @@ def convertBlindBet(actionTypes, actionAmounts): for k in xrange(len(actionTypes[i][j])): if actionTypes[i][j][k] == "blind": blinds.append((i,j,k)) - + if blinds and actionTypes[i][j][k] == "bet": bets.append((i,j,k)) if len(bets) == 1: blind_amount=actionAmounts[blinds[0][0]][blinds[0][1]][blinds[0][2]] bet_amount=actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]] actionAmounts[bets[0][0]][bets[0][1]][bets[0][2]] = bet_amount - blind_amount - + #converts the strings in the given array to ints (changes the passed array, no returning). see table design for conversion details #todo: make this use convertCardValuesBoard def convertCardValues(arr): @@ -156,14 +156,14 @@ def convertCardValues(arr): # a 0-card is one in a stud game that we did not see or was not shown card_map = { 0: 0, "2": 2, "3" : 3, "4" : 4, "5" : 5, "6" : 6, "7" : 7, "8" : 8, "9" : 9, "T" : 10, "J" : 11, "Q" : 12, "K" : 13, "A" : 14} - + def convertCardValuesBoard(arr): """ converts the strings in the given array to ints (changes the passed array, no returning). see table design for conversion details """ for i in xrange(len(arr)): arr[i] = card_map[arr[i]] - + def createArrays(category, seats, card_values, card_suits, antes, winnings, rakes, action_types, allIns, action_amounts, actionNos, actionTypeByNo): @@ -174,10 +174,10 @@ def createArrays(category, seats, card_values, card_suits, antes, winnings, antes.append(0) winnings.append(0) rakes.append(0) - + streetCount = 4 if (category == "holdem" or category == "omahahi" or category == "omahahilo") else 5 - + for i in xrange(streetCount): #build the first dimension array, for streets action_types.append([]) allIns.append([]) @@ -199,13 +199,13 @@ def createArrays(category, seats, card_values, card_suits, antes, winnings, # else: # raise FpdbError("invalid category") #end def createArrays - + def fill_board_cards(board_values, board_suits): """ fill up the two board card arrays """ while len(board_values) < 5: board_values.append(0) board_suits.append("x") - + def fillCardArrays(player_count, base, category, card_values, card_suits): """fills up the two card arrays""" if category == "holdem": @@ -216,13 +216,13 @@ def fillCardArrays(player_count, base, category, card_values, card_suits): cardCount = 7 else: raise FpdbError("invalid category:", category) - + for i in xrange(player_count): while len(card_values[i]) < cardCount: card_values[i].append(0) card_suits[i].append("x") #end def fillCardArrays - + #filters out a player that folded before paying ante or blinds. This should be called #before calling the actual hand parser. manipulates hand, no return. def filterAnteBlindFold(hand): @@ -233,7 +233,7 @@ def filterAnteBlindFold(hand): for i, line in enumerate(hand): if line.startswith("*** 3") or line.startswith("*** HOLE"): pre3rd = hand[0:i] - + foldeeName = None for line in pre3rd: if line.endswith("folds") or line.endswith("is sitting out") or line.endswith(" stands up"): #found ante fold or timeout @@ -249,24 +249,24 @@ def filterAnteBlindFold(hand): pos1 = line.find(": ") + 2 pos2 = line.find(" (") foldeeName = line[pos1:pos2] - + if foldeeName is not None: #print "filterAnteBlindFold, foldeeName:",foldeeName for i, line in enumerate(hand): if foldeeName in line: hand[i] = None - + return [line for line in hand if line] def stripEOLspaces(str): return str.rstrip() - + def filterCrap(hand, isTourney): """ removes useless lines as well as trailing spaces """ #remove trailing spaces at end of line hand = [line.rstrip() for line in hand] - + #general variable position word filter/string filter for i in xrange(len(hand)): if hand[i].startswith("Board ["): @@ -347,10 +347,10 @@ def filterCrap(hand, isTourney): hand[i] = False # python docs say this is identical to filter(None, list) # which removes all false items from the passed list (hand) - hand = [line for line in hand if line] - + hand = [line for line in hand if line] + return hand - + def float2int(string): """ takes a poker float (including , for thousand seperator) and converts it to an int """ @@ -358,11 +358,11 @@ def float2int(string): pos = string.find(",") if pos != -1: #remove , the thousand seperator string = "%s%s" % (string[0:pos], string[pos+1:]) - + pos = string.find(".") if pos != -1: #remove decimal point string = "%s%s" % (string[0:pos], string[pos+1:]) - + result = int(string) if pos == -1: #no decimal point - was in full dollars - need to multiply with 100 result *= 100 @@ -372,7 +372,7 @@ ActionLines = ( "calls $", ": calls ", "brings in for", "completes it to", "posts small blind", "posts the small blind", "posts big blind", "posts the big blind", "posts small & big blinds", "posts $", "posts a dead", "bets $", ": bets ", " raises") - + def isActionLine(line): if line.endswith("folds"): return True @@ -383,44 +383,44 @@ def isActionLine(line): # searches for each member of ActionLines being in line, returns true # on first match .. neat func - return any(x for x in ActionLines if x in line) - + return any(x for x in ActionLines if x in line) + def isAlreadyInDB(db, gametypeID, siteHandNo): c = db.get_cursor() c.execute(db.sql.query['isAlreadyInDB'], (gametypeID, siteHandNo)) result = c.fetchall() if len(result) >= 1: raise DuplicateError ("dupl") - + def isRebuyOrAddon(topline): """isRebuyOrAddon not implemented yet""" return False - + #returns whether the passed topline indicates a tournament or not def isTourney(topline): return "Tournament" in topline - + WinLines = ( "wins the pot", "ties for the ", "wins side pot", "wins the low main pot", "wins the high main pot", "wins the low", "wins the high pot", "wins the high side pot", "wins the main pot", "wins the side pot", "collected" ) def isWinLine(line): """ returns boolean whether the passed line is a win line """ - return any(x for x in WinLines if x in line) - + return any(x for x in WinLines if x in line) + #returns the amount of cash/chips put into the put in the given action line def parseActionAmount(line, atype, isTourney): #if (line.endswith(" and is all-in")): # line=line[:-14] #elif (line.endswith(", and is all in")): # line=line[:-15] - - #ideally we should recognise this as an all-in if category is capXl + + #ideally we should recognise this as an all-in if category is capXl if line.endswith(", and is capped"): line=line[:-15] if line.endswith(" and is capped"): line=line[:-14] - + if atype == "fold" or atype == "check": amount = 0 elif atype == "unbet": @@ -443,12 +443,12 @@ def parseActionAmount(line, atype, isTourney): #print "pos:",pos #print "pos of 20:", line.find("20") amount = int(line[pos:]) - + if atype == "unbet": amount *= -1 return amount #end def parseActionAmount - + #doesnt return anything, simply changes the passed arrays action_types and # action_amounts. For stud this expects numeric streets (3-7), for # holdem/omaha it expects predeal, preflop, flop, turn or river @@ -461,25 +461,25 @@ def parseActionLine(base, isTourney, line, street, playerIDs, names, action_type street = 2 elif street == "river": street = 3 - + nextActionNo = 0 for player in xrange(len(actionNos[street])): for count in xrange(len(actionNos[street][player])): if actionNos[street][player][count]>=nextActionNo: nextActionNo=actionNos[street][player][count]+1 - + (line, allIn) = goesAllInOnThisLine(line) atype = parseActionType(line) playerno = recognisePlayerNo(line, names, atype) amount = parseActionAmount(line, atype, isTourney) - + action_types[street][playerno].append(atype) allIns[street][playerno].append(allIn) action_amounts[street][playerno].append(amount) actionNos[street][playerno].append(nextActionNo) tmp=(playerIDs[playerno], atype) actionTypeByNo[street].append(tmp) - + def goesAllInOnThisLine(line): """returns whether the player went all-in on this line and removes the all-in text from the line.""" isAllIn = False @@ -490,20 +490,20 @@ def goesAllInOnThisLine(line): line = line[:-15] isAllIn = True return (line, isAllIn) - + #returns the action type code (see table design) of the given action line -ActionTypes = { 'brings in for' :"blind", +ActionTypes = { 'brings in for' :"blind", ' posts $' :"blind", - ' posts a dead ' :"blind", - ' posts the small blind of $' :"blind", + ' posts a dead ' :"blind", + ' posts the small blind of $' :"blind", ': posts big blind ' :"blind", - ': posts small blind ' :"blind", - ' posts the big blind of $' :"blind", + ': posts small blind ' :"blind", + ' posts the big blind of $' :"blind", ': posts small & big blinds $' :"blind", ': posts small blind $' :"blind", - 'calls' :"call", - 'completes it to' :"bet", - ' bets' :"bet", + 'calls' :"call", + 'completes it to' :"bet", + ' bets' :"bet", ' raises' :"bet" } def parseActionType(line): @@ -516,9 +516,9 @@ def parseActionType(line): else: for x in ActionTypes: if x in line: - return ActionTypes[x] + return ActionTypes[x] raise FpdbError ("failed to recognise actiontype in parseActionLine in: "+line) - + #parses the ante out of the given line and checks which player paid it, updates antes accordingly. def parseAnteLine(line, isTourney, names, antes): for i, name in enumerate(names): @@ -534,19 +534,19 @@ def parseAnteLine(line, isTourney, names, antes): pos1 = line.rfind("ante") + 5 pos2 = line.find(" ", pos1) antes[i] += int(line[pos1:pos2]) - + #returns the buyin of a tourney in cents def parseBuyin(topline): pos1 = topline.find("$")+1 pos2 = topline.find("+") return float2int(topline[pos1:pos2]) - + #parses a card line and changes the passed arrays accordingly #todo: reorganise this messy method def parseCardLine(category, street, line, names, cardValues, cardSuits, boardValues, boardSuits): if line.startswith("Dealt to") or " shows [" in line or "mucked [" in line: playerNo = recognisePlayerNo(line, names, "card") #anything but unbet will be ok for that string - + pos = line.rfind("[")+1 if category == "holdem": for i in (pos, pos+3): @@ -554,7 +554,7 @@ def parseCardLine(category, street, line, names, cardValues, cardSuits, boardVal cardSuits[playerNo].append(line[i+1:i+2]) if len(cardValues[playerNo]) != 2: if (cardValues[playerNo][0] == cardValues[playerNo][2] and - cardSuits[playerNo][1] == cardSuits[playerNo][3]): + cardSuits[playerNo][1] == cardSuits[playerNo][3]): cardValues[playerNo]=cardValues[playerNo][0:2] cardSuits[playerNo]=cardSuits[playerNo][0:2] else: @@ -617,7 +617,7 @@ def parseCardLine(category, street, line, names, cardValues, cardSuits, boardVal #print boardValues else: raise FpdbError ("unrecognised line:"+line) - + def parseCashesAndSeatNos(lines): """parses the startCashes and seatNos of each player out of the given lines and returns them as a dictionary of two arrays""" cashes = [] @@ -625,21 +625,21 @@ def parseCashesAndSeatNos(lines): for i in xrange (len(lines)): pos2=lines[i].find(":") seatNos.append(int(lines[i][5:pos2])) - + pos1=lines[i].rfind("($")+2 if pos1==1: #for tourneys - it's 1 instead of -1 due to adding 2 above pos1=lines[i].rfind("(")+1 pos2=lines[i].find(" in chips") cashes.append(float2int(lines[i][pos1:pos2])) return {'startCashes':cashes, 'seatNos':seatNos} - + #returns the buyin of a tourney in cents def parseFee(topline): pos1=topline.find("$")+1 pos1=topline.find("$",pos1)+1 pos2=topline.find(" ", pos1) return float2int(topline[pos1:pos2]) - + #returns a datetime object with the starttime indicated in the given topline def parseHandStartTime(topline): #convert x:13:35 to 0x:13:35 @@ -650,7 +650,7 @@ def parseHandStartTime(topline): topline = "%s0%s" % (topline[0:pos+1], topline[pos+1:]) break counter += 1 - + isUTC=False if topline.find("UTC")!=-1: pos1 = topline.find("-")+2 @@ -669,12 +669,12 @@ def parseHandStartTime(topline): rexx = '(?P[0-9]{4})\/(?P[0-9]{2})\/(?P[0-9]{2})[\- ]+(?P
[0-9]+):(?P[0-9]+):(?P[0-9]+)' m = re.search(rexx,tmp) result = datetime.datetime(int(m.group('YEAR')), int(m.group('MON')), int(m.group('DAY')), int(m.group('HR')), int(m.group('MIN')), int(m.group('SEC'))) - + if not isUTC: #these use US ET result += datetime.timedelta(hours=5) - + return result - + #parses the names out of the given lines and returns them as an array def findName(line): pos1 = line.find(":") + 2 @@ -683,11 +683,11 @@ def findName(line): def parseNames(lines): return [findName(line) for line in lines] - + def parsePositions(hand, names): positions = [-1 for i in names] sb, bb = -1, -1 - + for line in hand: if sb == -1 and "small blind" in line and "dead small blind" not in line: sb = line @@ -703,7 +703,7 @@ def parsePositions(hand, names): sbExists = False if bb != -1: bb = recognisePlayerNo(bb, names, "bet") - + # print "sb = ", sb, "bb = ", bb if bb == sb: # if big and small are same, then don't duplicate the small sbExists = False @@ -716,7 +716,7 @@ def parsePositions(hand, names): #fill up rest of array arraypos = sb - 1 if sbExists else bb - 1 - + distFromBtn=0 while arraypos >= 0 and arraypos != bb: #print "parsePositions first while, arraypos:",arraypos,"positions:",positions @@ -732,7 +732,7 @@ def parsePositions(hand, names): i -= 1 ### RHH - Changed to set the null seats before BB to "9" i = sb - 1 if sbExists else bb - 1 - + while positions[i] < 0: positions[i]=9 i-=1 @@ -750,19 +750,19 @@ def parsePositions(hand, names): raise FpdbError ("failed to read positions") # print str(positions), "\n" return positions - + #simply parses the rake amount and returns it as an int def parseRake(line): pos = line.find("Rake")+6 rake = float2int(line[pos:]) return rake - + def parseSiteHandNo(topline): """returns the hand no assigned by the poker site""" pos1 = topline.find("#")+1 pos2 = topline.find(":") return topline[pos1:pos2] - + def parseTableLine(base, line): """returns a dictionary with maxSeats and tableName""" pos1=line.find('\'')+1 @@ -773,14 +773,14 @@ def parseTableLine(base, line): #print "seats:",line[pos3:pos4] return {'maxSeats':int(line[pos3:pos4]), 'tableName':line[pos1:pos2]} #end def parseTableLine - + #returns the hand no assigned by the poker site def parseTourneyNo(topline): pos1 = topline.find("Tournament #")+12 pos2 = topline.find(",", pos1) #print "parseTourneyNo pos1:",pos1," pos2:",pos2, " result:",topline[pos1:pos2] return topline[pos1:pos2] - + #parses a win/collect line. manipulates the passed array winnings, no explicit return def parseWinLine(line, names, winnings, isTourney): #print "parseWinLine: line:",line @@ -795,7 +795,7 @@ def parseWinLine(line, names, winnings, isTourney): pos1 = line.rfind("$") + 1 pos2 = line.find(" ", pos1) winnings[i] += float2int(line[pos1:pos2]) - + #returns the category (as per database) string for the given line def recogniseCategory(line): if "Razz" in line: @@ -814,12 +814,12 @@ def recogniseCategory(line): return "studhilo" else: raise FpdbError("failed to recognise category, line:"+line) - + #returns the int for the gametype_id for the given line def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, category, isTourney):#todo: this method is messy #if (topline.find("HORSE")!=-1): # raise FpdbError("recogniseGametypeID: HORSE is not yet supported.") - + #note: the below variable names small_bet and big_bet are misleading, in NL/PL they mean small/big blind if isTourney: type = "tour" @@ -835,27 +835,27 @@ def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, c pos1 = topline.find("$")+1 pos2 = topline.find("/$") small_bet = float2int(topline[pos1:pos2]) - + pos1 = pos2+2 if isTourney: pos1 -= 1 pos2 = topline.find(")") - + if pos2 <= pos1: pos2 = topline.find(")", pos1) - + if isTourney: big_bet = int(topline[pos1:pos2]) else: big_bet = float2int(topline[pos1:pos2]) - + if 'No Limit' in topline: limit_type = "nl" if 'Cap No' not in topline else "cn" elif 'Pot Limit' in topline: limit_type = "pl" if 'Cap Pot' not in topline else "cp" else: limit_type = "fl" - + #print "recogniseGametypeID small_bet/blind:",small_bet,"big bet/blind:", big_bet,"limit type:",limit_type if limit_type == "fl": cursor.execute(db.sql.query['getGametypeFL'], (site_id, type, category, @@ -870,7 +870,7 @@ def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, c #ret=result[0] #print "recgt1 ret=",ret #print "tried SELECTing gametypes.id, result:",result - + try: len(result) except TypeError: @@ -878,14 +878,14 @@ def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, c base="hold" else: base="stud" - + if category=="holdem" or category=="omahahi" or category=="studhi": hiLo='h' elif category=="razz": hiLo='l' else: hiLo='s' - + if (limit_type=="fl"): big_blind=small_bet if base=="hold": @@ -901,17 +901,17 @@ def recogniseGametypeID(backend, db, cursor, topline, smallBlindLine, site_id, c small_blind=0 result = db.insertGameTypes( (site_id, type, base, category, limit_type, hiLo ,small_blind, big_blind, small_bet, big_bet) ) - #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s + #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s #AND limitType=%s AND smallBet=%s AND bigBet=%s", (site_id, type, category, limit_type, small_bet, big_bet)) else: result = db.insertGameTypes( (site_id, type, base, category, limit_type, hiLo ,small_bet, big_bet, 0, 0) )#remember, for these bet means blind #cursor.execute ("SELECT id FROM Gametypes WHERE siteId=%s AND type=%s AND category=%s #AND limitType=%s AND smallBlind=%s AND bigBlind=%s", (site_id, type, category, limit_type, small_bet, big_bet)) - + return result[0] #end def recogniseGametypeID - + def recogniseTourneyTypeId(db, siteId, tourneySiteId, buyin, fee, knockout, rebuyOrAddon): ret = -1 cursor = db.get_cursor() @@ -920,32 +920,32 @@ def recogniseTourneyTypeId(db, siteId, tourneySiteId, buyin, fee, knockout, rebu #TODO: When the summary file will be dumped to BD, if the tourney is already in, Buy-In/Fee may need an update (e.g. creation of a new type and link to the Tourney) cursor.execute (db.sql.query['getTourneyTypeIdByTourneyNo'].replace('%s', db.sql.query['placeholder']), (tourneySiteId, siteId)) result = cursor.fetchone() - + try: len(result) ret = result[0] except: - cursor.execute( """SELECT id FROM TourneyTypes - WHERE siteId=%s AND buyin=%s AND fee=%s + cursor.execute( """SELECT id FROM TourneyTypes + WHERE siteId=%s AND buyin=%s AND fee=%s AND knockout=%s AND rebuyOrAddon=%s""".replace('%s', db.sql.query['placeholder']) , (siteId, buyin, fee, knockout, rebuyOrAddon) ) result = cursor.fetchone() #print "tried selecting tourneytypes.id, result:", result - + try: len(result) ret = result[0] except TypeError:#this means we need to create a new entry #print "insert new tourneytype record ..." try: - cursor.execute( """INSERT INTO TourneyTypes (siteId, buyin, fee, knockout, rebuyOrAddon) + cursor.execute( """INSERT INTO TourneyTypes (siteId, buyin, fee, knockout, rebuyOrAddon) VALUES (%s, %s, %s, %s, %s)""".replace('%s', db.sql.query['placeholder']) , (siteId, buyin, fee, knockout, rebuyOrAddon) ) ret = db.get_last_insert_id(cursor) except: #print "maybe tourneytype was created since select, try selecting again ..." - cursor.execute( """SELECT id FROM TourneyTypes - WHERE siteId=%s AND buyin=%s AND fee=%s + cursor.execute( """SELECT id FROM TourneyTypes + WHERE siteId=%s AND buyin=%s AND fee=%s AND knockout=%s AND rebuyOrAddon=%s""".replace('%s', db.sql.query['placeholder']) , (siteId, buyin, fee, knockout, rebuyOrAddon) ) result = cursor.fetchone() @@ -956,12 +956,12 @@ def recogniseTourneyTypeId(db, siteId, tourneySiteId, buyin, fee, knockout, rebu print "Failed to find or insert TourneyTypes record" ret = -1 # failed to find or insert record #print "tried selecting tourneytypes.id again, result:", result - + #print "recogniseTourneyTypeId: returning", ret return ret #end def recogniseTourneyTypeId - - + + #recognises the name in the given line and returns its array position in the given array def recognisePlayerNo(line, names, atype): #print "recogniseplayerno, names:",names @@ -981,7 +981,7 @@ def recognisePlayerNo(line, names, atype): tmp=line[9:] else: tmp=line[8:] - + if (tmp.startswith(encodedName)): return (i) else: @@ -990,8 +990,8 @@ def recognisePlayerNo(line, names, atype): #if we're here we mustve failed raise FpdbError ("failed to recognise player in: "+line+" atype:"+atype) #end def recognisePlayerNo - - + + #removes trailing \n from the given array def removeTrailingEOL(arr): for i in xrange(len(arr)): @@ -1001,7 +1001,7 @@ def removeTrailingEOL(arr): #print "arr[i] after removetrailingEOL:", arr[i] return arr #end def removeTrailingEOL - + #splits the rake according to the proportion of pot won. manipulates the second passed array. def splitRake(winnings, rakes, totalRake): winnercnt=0 @@ -1020,7 +1020,7 @@ def splitRake(winnings, rakes, totalRake): winPortion=winnings[i]/totalWin rakes[i]=totalRake*winPortion #end def splitRake - + def generateHudCacheData(player_ids, base, category, action_types, allIns, actionTypeByNo ,winnings, totalWinnings, positions, actionTypes, actionAmounts, antes): """calculates data for the HUD during import. IMPORTANT: if you change this method make @@ -1050,12 +1050,12 @@ sure to also change the following storage method and table_viewer.prepare_data i foldToOtherRaisedStreet3=[] foldToOtherRaisedStreet4=[] wonWhenSeenStreet1=[] - + wonAtSD=[] stealAttemptChance=[] stealAttempted=[] hudDataPositions=[] - + street0Calls=[] street1Calls=[] street2Calls=[] @@ -1071,7 +1071,7 @@ sure to also change the following storage method and table_viewer.prepare_data i #street2Raises=[] #street3Raises=[] #street4Raises=[] - + # Summary figures for hand table: result={} result['playersVpi']=0 @@ -1090,13 +1090,13 @@ sure to also change the following storage method and table_viewer.prepare_data i result['street3Pot']=0 result['street4Pot']=0 result['showdownPot']=0 - + firstPfRaiseByNo=-1 firstPfRaiserId=-1 firstPfRaiserNo=-1 firstPfCallByNo=-1 firstPfCallerId=-1 - + for i, action in enumerate(actionTypeByNo[0]): if action[1] == "bet": firstPfRaiseByNo = i @@ -1116,7 +1116,7 @@ sure to also change the following storage method and table_viewer.prepare_data i if firstPfRaiseByNo < firstPfCallByNo or firstPfCallByNo == -1: firstPlayId = firstPfRaiserId - + cutoffId=-1 buttonId=-1 sbId=-1 @@ -1131,9 +1131,9 @@ sure to also change the following storage method and table_viewer.prepare_data i sbId = player_ids[player] if pos == 'B': bbId = player_ids[player] - + someoneStole=False - + #run a loop for each player preparing the actual values that will be commited to SQL for player in xrange(len(player_ids)): #set default values @@ -1177,7 +1177,7 @@ sure to also change the following storage method and table_viewer.prepare_data i #myStreet2Raises=0 #myStreet3Raises=0 #myStreet4Raises=0 - + #calculate VPIP and PFR street=0 heroPfRaiseCount=0 @@ -1186,14 +1186,14 @@ sure to also change the following storage method and table_viewer.prepare_data i myStreet0Aggr = True if currentAction == "bet" or currentAction == "call": myStreet0VPI = True - + if myStreet0VPI: result['playersVpi'] += 1 myStreet0Calls = action_types[street][player].count('call') myStreet0Bets = action_types[street][player].count('bet') # street0Raises = action_types[street][player].count('raise') bet count includes raises for now result['street0Raises'] += myStreet0Bets - + #PF3BChance and PF3B pfFold=-1 pfRaise=-1 @@ -1208,7 +1208,7 @@ sure to also change the following storage method and table_viewer.prepare_data i myStreet0_3BChance = True if pfRaise > firstPfRaiseByNo: myStreet0_3BDone = True - + #steal calculations if base=="hold": if len(player_ids)>=3: # no point otherwise # was 5, use 3 to match pokertracker definition @@ -1235,44 +1235,40 @@ sure to also change the following storage method and table_viewer.prepare_data i myStealAttemptChance=True if positions[player]=='B': pass - + if myStealAttempted: someoneStole=True - - + + #calculate saw* values - isAllIn = False - if any(i for i in allIns[0][player]): - isAllIn = True - if (len(action_types[1][player])>0 or isAllIn): + isAllIn = any(i for i in allIns[0][player]) + if isAllIn or len(action_types[1][player]) > 0: myStreet1Seen = True - - if any(i for i in allIns[1][player]): - isAllIn = True - if (len(action_types[2][player])>0 or isAllIn): - myStreet2Seen = True - - if any(i for i in allIns[2][player]): - isAllIn = True - if (len(action_types[3][player])>0 or isAllIn): - myStreet3Seen = True - + + if not isAllIn: + isAllIn = any(i for i in allIns[1][player]) + elif len(action_types[2][player]) > 0: + if all(actiontype != "fold" for actiontype in action_types[1][player]): + myStreet2Seen = True + + if not isAllIn: + isAllAin = any(i for i in allIns[2][player]) + elif len(action_types[3][player]) > 0: + if all(actiontype != "fold" for actiontype in action_types[2][player]): + myStreet3Seen = True + #print "base:", base - if base=="hold": - mySawShowdown = True - if any(actiontype == "fold" for actiontype in action_types[3][player]): - mySawShowdown = False + if base == "hold": + mySawShowdown = not any(actiontype == "fold" for actiontype in action_types[3][player]) else: #print "in else" - if any(i for i in allIns[3][player]): - isAllIn = True - if (len(action_types[4][player])>0 or isAllIn): + if not isAllIn: + isAllIn = any(i for i in allIns[3][player]) + elif len(action_types[4][player]) > 0: #print "in if" myStreet4Seen = True - - mySawShowdown = True - if any(actiontype == "fold" for actiontype in action_types[4][player]): - mySawShowdown = False + + mySawShowdown = not any(actiontype == "fold" for actiontype in action_types[4][player]) if myStreet1Seen: result['playersAtStreet1'] += 1 @@ -1284,101 +1280,93 @@ sure to also change the following storage method and table_viewer.prepare_data i result['playersAtStreet4'] += 1 if mySawShowdown: result['playersAtShowdown'] += 1 - + #flop stuff - street=1 + street = 1 if myStreet1Seen: - if any(actiontype == "bet" for actiontype in action_types[street][player]): - myStreet1Aggr = True - + myStreet1Aggr = any(actiontype == "bet" for actiontype in action_types[street][player]) myStreet1Calls = action_types[street][player].count('call') myStreet1Bets = action_types[street][player].count('bet') # street1Raises = action_types[street][player].count('raise') bet count includes raises for now result['street1Raises'] += myStreet1Bets - + for otherPlayer in xrange(len(player_ids)): - if player==otherPlayer: + if player == otherPlayer: pass else: for countOther in xrange(len(action_types[street][otherPlayer])): - if action_types[street][otherPlayer][countOther]=="bet": - myOtherRaisedStreet1=True + if action_types[street][otherPlayer][countOther] == "bet": + myOtherRaisedStreet1 = True for countOtherFold in xrange(len(action_types[street][player])): - if action_types[street][player][countOtherFold]=="fold": - myFoldToOtherRaisedStreet1=True - + if action_types[street][player][countOtherFold] == "fold": + myFoldToOtherRaisedStreet1 = True + #turn stuff - copy of flop with different vars - street=2 + street = 2 if myStreet2Seen: - if any(actiontype == "bet" for actiontype in action_types[street][player]): - myStreet2Aggr = True - + myStreet2Aggr = any(actiontype == "bet" for actiontype in action_types[street][player]) myStreet2Calls = action_types[street][player].count('call') myStreet2Bets = action_types[street][player].count('bet') # street2Raises = action_types[street][player].count('raise') bet count includes raises for now result['street2Raises'] += myStreet2Bets - + for otherPlayer in xrange(len(player_ids)): - if player==otherPlayer: + if player == otherPlayer: pass else: for countOther in xrange(len(action_types[street][otherPlayer])): - if action_types[street][otherPlayer][countOther]=="bet": - myOtherRaisedStreet2=True + if action_types[street][otherPlayer][countOther] == "bet": + myOtherRaisedStreet2 = True for countOtherFold in xrange(len(action_types[street][player])): - if action_types[street][player][countOtherFold]=="fold": - myFoldToOtherRaisedStreet2=True - + if action_types[street][player][countOtherFold] == "fold": + myFoldToOtherRaisedStreet2 = True + #river stuff - copy of flop with different vars - street=3 + street = 3 if myStreet3Seen: - if any(actiontype == "bet" for actiontype in action_types[street][player]): - myStreet3Aggr = True - + myStreet3Aggr = any(actiontype == "bet" for actiontype in action_types[street][player]) myStreet3Calls = action_types[street][player].count('call') myStreet3Bets = action_types[street][player].count('bet') # street3Raises = action_types[street][player].count('raise') bet count includes raises for now result['street3Raises'] += myStreet3Bets - + for otherPlayer in xrange(len(player_ids)): - if player==otherPlayer: + if player == otherPlayer: pass else: for countOther in xrange(len(action_types[street][otherPlayer])): - if action_types[street][otherPlayer][countOther]=="bet": - myOtherRaisedStreet3=True + if action_types[street][otherPlayer][countOther] == "bet": + myOtherRaisedStreet3 = True for countOtherFold in xrange(len(action_types[street][player])): - if action_types[street][player][countOtherFold]=="fold": - myFoldToOtherRaisedStreet3=True - + if action_types[street][player][countOtherFold] == "fold": + myFoldToOtherRaisedStreet3 = True + #stud river stuff - copy of flop with different vars - street=4 + street = 4 if myStreet4Seen: - if any(actiontype == "bet" for actiontype in action_types[street][player]): - myStreet4Aggr=True - + myStreet4Aggr = any(actiontype == "bet" for actiontype in action_types[street][player]) myStreet4Calls = action_types[street][player].count('call') myStreet4Bets = action_types[street][player].count('bet') # street4Raises = action_types[street][player].count('raise') bet count includes raises for now result['street4Raises'] += myStreet4Bets - + for otherPlayer in xrange(len(player_ids)): - if player==otherPlayer: + if player == otherPlayer: pass else: for countOther in xrange(len(action_types[street][otherPlayer])): - if action_types[street][otherPlayer][countOther]=="bet": - myOtherRaisedStreet4=True + if action_types[street][otherPlayer][countOther] == "bet": + myOtherRaisedStreet4 = True for countOtherFold in xrange(len(action_types[street][player])): - if action_types[street][player][countOtherFold]=="fold": - myFoldToOtherRaisedStreet4=True - + if action_types[street][player][countOtherFold] == "fold": + myFoldToOtherRaisedStreet4 = True + if winnings[player] != 0: if myStreet1Seen: myWonWhenSeenStreet1 = winnings[player] / float(totalWinnings) if mySawShowdown: - myWonAtSD=myWonWhenSeenStreet1 - + myWonAtSD = myWonWhenSeenStreet1 + #add each value to the appropriate array street0VPI.append(myStreet0VPI) street0Aggr.append(myStreet0Aggr) @@ -1443,7 +1431,7 @@ sure to also change the following storage method and table_viewer.prepare_data i #street2Raises.append(myStreet2Raises) #street3Raises.append(myStreet3Raises) #street4Raises.append(myStreet4Raises) - + #add each array to the to-be-returned dictionary result['street0VPI']=street0VPI result['street0Aggr']=street0Aggr @@ -1454,7 +1442,7 @@ sure to also change the following storage method and table_viewer.prepare_data i result['street3Seen']=street3Seen result['street4Seen']=street4Seen result['sawShowdown']=sawShowdown - + result['street1Aggr']=street1Aggr result['otherRaisedStreet1']=otherRaisedStreet1 result['foldToOtherRaisedStreet1']=foldToOtherRaisedStreet1 @@ -1486,7 +1474,7 @@ sure to also change the following storage method and table_viewer.prepare_data i #result['street2Raises']=street2Raises #result['street3Raises']=street3Raises #result['street4Raises']=street4Raises - + #now the various steal values foldBbToStealChance=[] foldedBbToSteal=[] @@ -1497,7 +1485,7 @@ sure to also change the following storage method and table_viewer.prepare_data i myFoldedBbToSteal=False myFoldSbToStealChance=False myFoldedSbToSteal=False - + if base=="hold": if someoneStole and (positions[player]=='B' or positions[player]=='S') and firstPfRaiserId!=player_ids[player]: street=0 @@ -1510,8 +1498,8 @@ sure to also change the following storage method and table_viewer.prepare_data i myFoldSbToStealChance=True if action_types[street][player][count]=="fold": myFoldedSbToSteal=True - - + + foldBbToStealChance.append(myFoldBbToStealChance) foldedBbToSteal.append(myFoldedBbToSteal) foldSbToStealChance.append(myFoldSbToStealChance) @@ -1520,7 +1508,7 @@ sure to also change the following storage method and table_viewer.prepare_data i result['foldedBbToSteal']=foldedBbToSteal result['foldSbToStealChance']=foldSbToStealChance result['foldedSbToSteal']=foldedSbToSteal - + #now CB street1CBChance=[] street1CBDone=[] @@ -1528,18 +1516,18 @@ sure to also change the following storage method and table_viewer.prepare_data i for player in xrange(len(player_ids)): myStreet1CBChance=False myStreet1CBDone=False - + if street0VPI[player]: myStreet1CBChance=True if street1Aggr[player]: myStreet1CBDone=True didStreet1CB.append(player_ids[player]) - + street1CBChance.append(myStreet1CBChance) street1CBDone.append(myStreet1CBDone) result['street1CBChance']=street1CBChance result['street1CBDone']=street1CBDone - + #now 2B street2CBChance=[] street2CBDone=[] @@ -1547,18 +1535,18 @@ sure to also change the following storage method and table_viewer.prepare_data i for player in xrange(len(player_ids)): myStreet2CBChance=False myStreet2CBDone=False - + if street1CBDone[player]: myStreet2CBChance=True if street2Aggr[player]: myStreet2CBDone=True didStreet2CB.append(player_ids[player]) - + street2CBChance.append(myStreet2CBChance) street2CBDone.append(myStreet2CBDone) result['street2CBChance']=street2CBChance result['street2CBDone']=street2CBDone - + #now 3B street3CBChance=[] street3CBDone=[] @@ -1566,18 +1554,18 @@ sure to also change the following storage method and table_viewer.prepare_data i for player in xrange(len(player_ids)): myStreet3CBChance=False myStreet3CBDone=False - + if street2CBDone[player]: myStreet3CBChance=True if street3Aggr[player]: myStreet3CBDone=True didStreet3CB.append(player_ids[player]) - + street3CBChance.append(myStreet3CBChance) street3CBDone.append(myStreet3CBDone) result['street3CBChance']=street3CBChance result['street3CBDone']=street3CBDone - + #and 4B street4CBChance=[] street4CBDone=[] @@ -1585,21 +1573,21 @@ sure to also change the following storage method and table_viewer.prepare_data i for player in xrange(len(player_ids)): myStreet4CBChance=False myStreet4CBDone=False - + if street3CBDone[player]: myStreet4CBChance=True if street4Aggr[player]: myStreet4CBDone=True didStreet4CB.append(player_ids[player]) - + street4CBChance.append(myStreet4CBChance) street4CBDone.append(myStreet4CBDone) result['street4CBChance']=street4CBChance result['street4CBDone']=street4CBDone - - + + result['position']=hudDataPositions - + foldToStreet1CBChance=[] foldToStreet1CBDone=[] foldToStreet2CBChance=[] @@ -1608,40 +1596,40 @@ sure to also change the following storage method and table_viewer.prepare_data i foldToStreet3CBDone=[] foldToStreet4CBChance=[] foldToStreet4CBDone=[] - + for player in xrange(len(player_ids)): myFoldToStreet1CBChance=False myFoldToStreet1CBDone=False foldToStreet1CBChance.append(myFoldToStreet1CBChance) foldToStreet1CBDone.append(myFoldToStreet1CBDone) - + myFoldToStreet2CBChance=False myFoldToStreet2CBDone=False foldToStreet2CBChance.append(myFoldToStreet2CBChance) foldToStreet2CBDone.append(myFoldToStreet2CBDone) - + myFoldToStreet3CBChance=False myFoldToStreet3CBDone=False foldToStreet3CBChance.append(myFoldToStreet3CBChance) foldToStreet3CBDone.append(myFoldToStreet3CBDone) - + myFoldToStreet4CBChance=False myFoldToStreet4CBDone=False foldToStreet4CBChance.append(myFoldToStreet4CBChance) foldToStreet4CBDone.append(myFoldToStreet4CBDone) - + if len(didStreet1CB)>=1: generateFoldToCB(1, player_ids, didStreet1CB, street1CBDone, foldToStreet1CBChance, foldToStreet1CBDone, actionTypeByNo) - + if len(didStreet2CB)>=1: generateFoldToCB(2, player_ids, didStreet2CB, street2CBDone, foldToStreet2CBChance, foldToStreet2CBDone, actionTypeByNo) - + if len(didStreet3CB)>=1: generateFoldToCB(3, player_ids, didStreet3CB, street3CBDone, foldToStreet3CBChance, foldToStreet3CBDone, actionTypeByNo) - + if len(didStreet4CB)>=1: generateFoldToCB(4, player_ids, didStreet4CB, street4CBDone, foldToStreet4CBChance, foldToStreet4CBDone, actionTypeByNo) - + result['foldToStreet1CBChance']=foldToStreet1CBChance result['foldToStreet1CBDone']=foldToStreet1CBDone result['foldToStreet2CBChance']=foldToStreet2CBChance @@ -1650,10 +1638,10 @@ sure to also change the following storage method and table_viewer.prepare_data i result['foldToStreet3CBDone']=foldToStreet3CBDone result['foldToStreet4CBChance']=foldToStreet4CBChance result['foldToStreet4CBDone']=foldToStreet4CBDone - - + + totalProfit=[] - + street1CheckCallRaiseChance=[] street1CheckCallRaiseDone=[] street2CheckCallRaiseChance=[] @@ -1672,7 +1660,7 @@ sure to also change the following storage method and table_viewer.prepare_data i #for j in xrange(len(actionTypes[i])): #iterate through names (using pl loop above) for k in xrange(len(actionTypes[i][pl])): #iterate through individual actions of that player on that street myTotalProfit -= actionAmounts[i][pl][k] - + myStreet1CheckCallRaiseChance=False myStreet1CheckCallRaiseDone=False myStreet2CheckCallRaiseChance=False @@ -1681,11 +1669,11 @@ sure to also change the following storage method and table_viewer.prepare_data i myStreet3CheckCallRaiseDone=False myStreet4CheckCallRaiseChance=False myStreet4CheckCallRaiseDone=False - + #print "myTotalProfit=", myTotalProfit totalProfit.append(myTotalProfit) #print "totalProfit[]=", totalProfit - + street1CheckCallRaiseChance.append(myStreet1CheckCallRaiseChance) street1CheckCallRaiseDone.append(myStreet1CheckCallRaiseDone) street2CheckCallRaiseChance.append(myStreet2CheckCallRaiseChance) @@ -1694,10 +1682,10 @@ sure to also change the following storage method and table_viewer.prepare_data i street3CheckCallRaiseDone.append(myStreet3CheckCallRaiseDone) street4CheckCallRaiseChance.append(myStreet4CheckCallRaiseChance) street4CheckCallRaiseDone.append(myStreet4CheckCallRaiseDone) - + result['totalProfit']=totalProfit #print "res[totalProfit]=", result['totalProfit'] - + result['street1CheckCallRaiseChance']=street1CheckCallRaiseChance result['street1CheckCallRaiseDone']=street1CheckCallRaiseDone result['street2CheckCallRaiseChance']=street2CheckCallRaiseChance @@ -1708,7 +1696,7 @@ sure to also change the following storage method and table_viewer.prepare_data i result['street4CheckCallRaiseDone']=street4CheckCallRaiseDone return result #end def generateHudCacheData - + def generateFoldToCB(street, playerIDs, didStreetCB, streetCBDone, foldToStreetCBChance, foldToStreetCBDone, actionTypeByNo): """fills the passed foldToStreetCB* arrays appropriately depending on the given street""" #print "beginning of generateFoldToCB, street:", street, "len(actionTypeByNo):", len(actionTypeByNo) @@ -1720,7 +1708,7 @@ def generateFoldToCB(street, playerIDs, didStreetCB, streetCBDone, foldToStreetC if player==actionTypeByNo[street][action][0] and firstCBReaction==0: firstCBReaction=action+1 break - + for action in actionTypeByNo[street][firstCBReaction:]: for player in xrange(len(playerIDs)): if playerIDs[player]==action[0]: diff --git a/pyfpdb/logging.conf b/pyfpdb/logging.conf index 124b509d..1b54b453 100644 --- a/pyfpdb/logging.conf +++ b/pyfpdb/logging.conf @@ -11,6 +11,18 @@ keys=fileFormatter,stderrFormatter level=INFO handlers=consoleHandler,fileHandler +[logger_fpdb] +level=INFO +handlers=consoleHandler,fileHandler +qualname=fpdb +propagate=0 + +[logger_logview] +level=INFO +handlers=consoleHandler,fileHandler +qualname=logview +propagate=0 + [logger_parser] level=INFO handlers=consoleHandler,fileHandler @@ -24,7 +36,7 @@ qualname=importer propagate=0 [logger_config] -level=DEBUG +level=INFO handlers=consoleHandler,fileHandler qualname=config propagate=0 diff --git a/pyfpdb/regression-test-files/cash/Betfair/Flop/PLO-6max-USD-0.05-0.10-200909.All.in.river.splitpot.txt b/pyfpdb/regression-test-files/cash/Betfair/Flop/PLO-6max-USD-0.05-0.10-200909.All.in.river.splitpot.txt new file mode 100644 index 00000000..c4685742 --- /dev/null +++ b/pyfpdb/regression-test-files/cash/Betfair/Flop/PLO-6max-USD-0.05-0.10-200909.All.in.river.splitpot.txt @@ -0,0 +1,55 @@ +***** Betfair Poker Hand History for Game 100000000 ***** +PL $0.05/$0.10 Omaha - Sunday, October 18, 20:00:00 GMT 2009 +Table Death 1 6-max (Real Money) +Seat 2 is the button +Total number of active players : 6 +Seat 1: Player6 ( $1 ) +Seat 2: Player3 ( $9.38 ) +Seat 3: Player2 ( $2.82 ) +Seat 4: Player4 ( $4.13 ) +Seat 5: Player5 ( $28.77 ) +Seat 6: Player1 ( $6.46 ) +Player2 posts small blind [$0.05] +Player4 posts big blind [$0.10] +Player6 posts big blind [$0.10] +** Dealing down cards ** +Dealt to Player6 [ 7c, 6c, 5h, Jh ] +Player5 folds +Player1 calls [$0.10] +Player6 checks +Player3 calls [$0.10] +Player2 raises to [$0.30] +Player4 calls [$0.20] +Player1 calls [$0.20] +Player6 goes all-in +Player6 raises to [$1] +Player3 calls [$0.90] +Player2 calls [$0.70] +Player4 calls [$0.70] +Player1 calls [$0.70] +** Dealing Flop ** [ 4d, 5d, 6d ] +Player2 checks +Player4 checks +Player1 checks +Player3 checks +** Dealing Turn ** [ 3s ] +Player2 checks +Player4 bets [$0.10] +Player1 calls [$0.10] +Player3 folds +Player2 folds +** Dealing River ** [ 4c ] +Player4 goes all-in +Player4 bets [$3.03] +Player1 calls [$3.03] +** Showdown ** +Player6 shows [ 7c, 6c, 5h, Jh ] a straight, Seven to Three +Player4 shows [ 7d, 8c, 3d, 6h ] a straight flush, Seven to Three +Player1 shows [ 3h, 4h, Td, 4s ] four of a kind, Fours +** Hand Conclusion ** +Player4 wins $6.26 from side pot #1 with a straight flush, Seven to Three +Player4 wins $4.44 from main pot with a straight flush, Seven to Three +************ Game 100000000 ends ************ + + + diff --git a/pyfpdb/regression-test-files/cash/Stars/Flop/NLHE-6max-USD-0.05-0.10-200912.Stats-comparision.txt b/pyfpdb/regression-test-files/cash/Stars/Flop/NLHE-6max-USD-0.05-0.10-200912.Stats-comparision.txt new file mode 100644 index 00000000..5f140759 --- /dev/null +++ b/pyfpdb/regression-test-files/cash/Stars/Flop/NLHE-6max-USD-0.05-0.10-200912.Stats-comparision.txt @@ -0,0 +1,43 @@ +PokerStars Game #36185273365: Hold'em No Limit ($0.05/$0.10 USD) - 2009/12/03 9:16:10 ET +Table 'Eurynome IV' 6-max Seat #3 is the button +Seat 1: s0rrow ($16.10 in chips) +Seat 2: chrisbiz ($9.45 in chips) +Seat 3: papajohn77 ($6.55 in chips) +Seat 4: WSOFish ($21.05 in chips) +Seat 5: drefron ($10 in chips) +Seat 6: garegerret ($10.60 in chips) +WSOFish: posts small blind $0.05 +drefron: posts big blind $0.10 +*** HOLE CARDS *** +Dealt to s0rrow [5s As] +garegerret: folds +s0rrow: raises $0.20 to $0.30 +chrisbiz: calls $0.30 +papajohn77: folds +WSOFish: folds +drefron: folds +*** FLOP *** [8c 4c 4d] +s0rrow: checks +chrisbiz: bets $0.40 +s0rrow: raises $1 to $1.40 +chrisbiz: calls $1 +*** TURN *** [8c 4c 4d] [Kc] +s0rrow: bets $3.20 +chrisbiz: calls $3.20 +*** RIVER *** [8c 4c 4d Kc] [2s] +s0rrow: bets $11.20 and is all-in +chrisbiz: folds +Uncalled bet ($11.20) returned to s0rrow +s0rrow collected $9.50 from pot +*** SUMMARY *** +Total pot $9.95 | Rake $0.45 +Board [8c 4c 4d Kc 2s] +Seat 1: s0rrow collected ($9.50) +Seat 2: chrisbiz folded on the River +Seat 3: papajohn77 (button) folded before Flop (didn't bet) +Seat 4: WSOFish (small blind) folded before Flop +Seat 5: drefron (big blind) folded before Flop +Seat 6: garegerret folded before Flop (didn't bet) + + + diff --git a/pyfpdb/regression-test-files/cash/Stars/Flop/PLO8-6max-USD-0.01-0.02-200911.txt b/pyfpdb/regression-test-files/cash/Stars/Flop/PLO8-6max-USD-0.01-0.02-200911.txt new file mode 100644 index 00000000..fb96f3f9 --- /dev/null +++ b/pyfpdb/regression-test-files/cash/Stars/Flop/PLO8-6max-USD-0.01-0.02-200911.txt @@ -0,0 +1,602 @@ +PokerStars Game #35874998500: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:36:51 ET +Table 'Gaby II' 6-max Seat #3 is the button +Seat 1: EricSteph261 ($11.27 in chips) +Seat 2: UnderMeSensi ($3.33 in chips) +Seat 3: supermeXXX ($1.19 in chips) +Seat 4: xgz520 ($1.81 in chips) +Seat 5: s0rrow ($3 in chips) +Seat 6: tiger48475 ($5 in chips) +xgz520: posts small blind $0.01 +s0rrow: posts big blind $0.02 +*** HOLE CARDS *** +Dealt to s0rrow [2h 2c 3s 9h] +tiger48475: folds +EricSteph261: folds +UnderMeSensi: raises $0.05 to $0.07 +supermeXXX: folds +xgz520: folds +s0rrow: calls $0.05 +*** FLOP *** [Jd 5c Kc] +s0rrow: checks +UnderMeSensi: checks +*** TURN *** [Jd 5c Kc] [4c] +s0rrow: checks +UnderMeSensi: bets $0.08 +s0rrow: calls $0.08 +*** RIVER *** [Jd 5c Kc 4c] [Th] +s0rrow: checks +UnderMeSensi: bets $0.31 +EricSteph261 is sitting out +s0rrow: folds +Uncalled bet ($0.31) returned to UnderMeSensi +UnderMeSensi collected $0.31 from pot +UnderMeSensi: doesn't show hand +*** SUMMARY *** +Total pot $0.31 | Rake $0 +Board [Jd 5c Kc 4c Th] +Seat 1: EricSteph261 folded before Flop (didn't bet) +Seat 2: UnderMeSensi collected ($0.31) +Seat 3: supermeXXX (button) folded before Flop (didn't bet) +Seat 4: xgz520 (small blind) folded before Flop +Seat 5: s0rrow (big blind) folded on the River +Seat 6: tiger48475 folded before Flop (didn't bet) + + + +PokerStars Game #35875026976: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:37:39 ET +Table 'Gaby II' 6-max Seat #4 is the button +Seat 2: UnderMeSensi ($3.49 in chips) +Seat 3: supermeXXX ($1.19 in chips) +Seat 4: xgz520 ($1.80 in chips) +Seat 5: s0rrow ($2.85 in chips) +Seat 6: tiger48475 ($5 in chips) +s0rrow: posts small blind $0.01 +tiger48475: posts big blind $0.02 +*** HOLE CARDS *** +Dealt to s0rrow [4d 3s 8d Jd] +UnderMeSensi: raises $0.05 to $0.07 +supermeXXX: folds +xgz520: folds +s0rrow: folds +tiger48475: folds +Uncalled bet ($0.05) returned to UnderMeSensi +xgz520 leaves the table +UnderMeSensi collected $0.05 from pot +UnderMeSensi: doesn't show hand +*** SUMMARY *** +Total pot $0.05 | Rake $0 +Seat 2: UnderMeSensi collected ($0.05) +Seat 3: supermeXXX folded before Flop (didn't bet) +Seat 4: xgz520 (button) folded before Flop (didn't bet) +Seat 5: s0rrow (small blind) folded before Flop +Seat 6: tiger48475 (big blind) folded before Flop + + + +PokerStars Game #35875034981: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:37:53 ET +Table 'Gaby II' 6-max Seat #5 is the button +Seat 2: UnderMeSensi ($3.52 in chips) +Seat 3: supermeXXX ($1.19 in chips) +Seat 5: s0rrow ($2.84 in chips) +Seat 6: tiger48475 ($5 in chips) +tiger48475: posts small blind $0.01 +UnderMeSensi: posts big blind $0.02 +*** HOLE CARDS *** +Dealt to s0rrow [Qh 6c Th 9c] +supermeXXX: raises $0.04 to $0.06 +s0rrow: calls $0.06 +tiger48475: folds +UnderMeSensi: calls $0.04 +*** FLOP *** [5h 4d 2d] +UnderMeSensi: checks +supermeXXX: bets $0.10 +s0rrow: folds +UnderMeSensi: calls $0.10 +*** TURN *** [5h 4d 2d] [Jd] +UnderMeSensi: checks +supermeXXX: checks +*** RIVER *** [5h 4d 2d Jd] [6h] +UnderMeSensi: checks +supermeXXX: checks +*** SHOW DOWN *** +UnderMeSensi: shows [7c 6s 7h As] (HI: a pair of Sevens; LO: 6,5,4,2,A) +supermeXXX: shows [Ah 2h Kh 2s] (HI: three of a kind, Deuces; LO: 6,5,4,2,A) +supermeXXX collected $0.20 from pot +UnderMeSensi collected $0.10 from pot +supermeXXX collected $0.09 from pot +*** SUMMARY *** +Total pot $0.39 | Rake $0 +Board [5h 4d 2d Jd 6h] +Seat 2: UnderMeSensi (big blind) showed [7c 6s 7h As] and won ($0.10) with HI: a pair of Sevens; LO: 6,5,4,2,A +Seat 3: supermeXXX showed [Ah 2h Kh 2s] and won ($0.29) with HI: three of a kind, Deuces; LO: 6,5,4,2,A +Seat 5: s0rrow (button) folded on the Flop +Seat 6: tiger48475 (small blind) folded before Flop + + + +PokerStars Game #35875059163: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:38:34 ET +Table 'Gaby II' 6-max Seat #6 is the button +Seat 2: UnderMeSensi ($3.46 in chips) +Seat 3: supermeXXX ($1.32 in chips) +Seat 5: s0rrow ($2.78 in chips) +Seat 6: tiger48475 ($5 in chips) +UnderMeSensi: posts small blind $0.01 +supermeXXX: posts big blind $0.02 +*** HOLE CARDS *** +Dealt to s0rrow [Ts Qs 9d 7c] +s0rrow: raises $0.04 to $0.06 +tiger48475: folds +UnderMeSensi: calls $0.05 +diyi69 joins the table at seat #4 +supermeXXX: folds +*** FLOP *** [3h Ah 5d] +UnderMeSensi: checks +s0rrow: checks +*** TURN *** [3h Ah 5d] [Kc] +UnderMeSensi: checks +s0rrow: bets $0.14 +UnderMeSensi: folds +Uncalled bet ($0.14) returned to s0rrow +s0rrow collected $0.14 from pot +*** SUMMARY *** +Total pot $0.14 | Rake $0 +Board [3h Ah 5d Kc] +Seat 2: UnderMeSensi (small blind) folded on the Turn +Seat 3: supermeXXX (big blind) folded before Flop +Seat 5: s0rrow collected ($0.14) +Seat 6: tiger48475 (button) folded before Flop (didn't bet) + + + +PokerStars Game #35875079294: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:39:09 ET +Table 'Gaby II' 6-max Seat #2 is the button +Seat 2: UnderMeSensi ($3.40 in chips) +Seat 3: supermeXXX ($1.30 in chips) +Seat 4: diyi69 ($1 in chips) +Seat 5: s0rrow ($2.86 in chips) +Seat 6: tiger48475 ($5 in chips) +supermeXXX: posts small blind $0.01 +diyi69: posts big blind $0.02 +*** HOLE CARDS *** +Dealt to s0rrow [8s 6d 7s 2s] +s0rrow: folds +tiger48475: folds +UnderMeSensi: folds +supermeXXX: calls $0.01 +diyi69 has timed out +diyi69: checks +*** FLOP *** [As Js 5h] +supermeXXX: bets $0.04 +diyi69 has timed out +diyi69: folds +Uncalled bet ($0.04) returned to supermeXXX +diyi69 is sitting out +supermeXXX collected $0.04 from pot +*** SUMMARY *** +Total pot $0.04 | Rake $0 +Board [As Js 5h] +Seat 2: UnderMeSensi (button) folded before Flop (didn't bet) +Seat 3: supermeXXX (small blind) collected ($0.04) +Seat 4: diyi69 (big blind) folded on the Flop +Seat 5: s0rrow folded before Flop (didn't bet) +Seat 6: tiger48475 folded before Flop (didn't bet) + + + +PokerStars Game #35875131707: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:40:40 ET +Table 'Gaby II' 6-max Seat #3 is the button +Seat 2: UnderMeSensi ($3.40 in chips) +Seat 3: supermeXXX ($1.32 in chips) +Seat 5: s0rrow ($2.86 in chips) +Seat 6: tiger48475 ($5 in chips) +s0rrow: posts small blind $0.01 +tiger48475: posts big blind $0.02 +*** HOLE CARDS *** +Dealt to s0rrow [7c As 4d 4h] +UnderMeSensi: calls $0.02 +supermeXXX: folds +s0rrow: calls $0.01 +tiger48475: checks +*** FLOP *** [Ks 9d Ts] +s0rrow: checks +tiger48475: bets $0.06 +UnderMeSensi: calls $0.06 +s0rrow: folds +*** TURN *** [Ks 9d Ts] [7h] +tiger48475: checks +EricSteph261 has returned +UnderMeSensi: checks +*** RIVER *** [Ks 9d Ts 7h] [4s] +tiger48475: checks +UnderMeSensi: bets $0.10 +tiger48475: folds +Uncalled bet ($0.10) returned to UnderMeSensi +UnderMeSensi collected $0.18 from pot +UnderMeSensi: doesn't show hand +*** SUMMARY *** +Total pot $0.18 | Rake $0 +Board [Ks 9d Ts 7h 4s] +Seat 2: UnderMeSensi collected ($0.18) +Seat 3: supermeXXX (button) folded before Flop (didn't bet) +Seat 5: s0rrow (small blind) folded on the Flop +Seat 6: tiger48475 (big blind) folded on the River + + + +PokerStars Game #35875159084: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:41:27 ET +Table 'Gaby II' 6-max Seat #5 is the button +Seat 1: EricSteph261 ($11.27 in chips) +Seat 2: UnderMeSensi ($3.50 in chips) +Seat 3: supermeXXX ($1.32 in chips) +Seat 5: s0rrow ($2.84 in chips) +Seat 6: tiger48475 ($5 in chips) +tiger48475: posts small blind $0.01 +EricSteph261: posts big blind $0.02 +*** HOLE CARDS *** +Dealt to s0rrow [Jc 3h 2s Qc] +UnderMeSensi: calls $0.02 +supermeXXX: calls $0.02 +s0rrow: raises $0.08 to $0.10 +tiger48475: folds +EricSteph261: folds +UnderMeSensi: calls $0.08 +supermeXXX: folds +*** FLOP *** [Ac 5s Js] +UnderMeSensi: checks +s0rrow: bets $0.20 +UnderMeSensi: calls $0.20 +*** TURN *** [Ac 5s Js] [8c] +UnderMeSensi: checks +s0rrow: bets $0.50 +UnderMeSensi: calls $0.50 +*** RIVER *** [Ac 5s Js 8c] [Jd] +UnderMeSensi: bets $1.60 +s0rrow: calls $1.60 +*** SHOW DOWN *** +UnderMeSensi: shows [7s 9s Jh 3c] (HI: three of a kind, Jacks; LO: 8,7,5,3,A) +s0rrow: shows [Jc 3h 2s Qc] (HI: three of a kind, Jacks - Ace+Queen kicker; LO: 8,5,3,2,A) +s0rrow collected $2.33 from pot +s0rrow collected $2.32 from pot +*** SUMMARY *** +Total pot $4.85 | Rake $0.20 +Board [Ac 5s Js 8c Jd] +Seat 1: EricSteph261 (big blind) folded before Flop +Seat 2: UnderMeSensi showed [7s 9s Jh 3c] and lost with HI: three of a kind, Jacks; LO: 8,7,5,3,A +Seat 3: supermeXXX folded before Flop +Seat 5: s0rrow (button) showed [Jc 3h 2s Qc] and won ($4.65) with HI: three of a kind, Jacks; LO: 8,5,3,2,A +Seat 6: tiger48475 (small blind) folded before Flop + + + +PokerStars Game #35875194885: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:42:28 ET +Table 'Gaby II' 6-max Seat #6 is the button +Seat 1: EricSteph261 ($11.25 in chips) +Seat 2: UnderMeSensi ($1.10 in chips) +Seat 3: supermeXXX ($1.30 in chips) +Seat 5: s0rrow ($5.09 in chips) +Seat 6: tiger48475 ($5 in chips) +EricSteph261: posts small blind $0.01 +UnderMeSensi: posts big blind $0.02 +*** HOLE CARDS *** +Dealt to s0rrow [7s 3c 3h 8d] +supermeXXX: folds +s0rrow: raises $0.02 to $0.04 +tiger48475: calls $0.04 +EricSteph261: calls $0.03 +UnderMeSensi: calls $0.02 +*** FLOP *** [8c 3s 4s] +EricSteph261: checks +UnderMeSensi: checks +s0rrow: bets $0.14 +tiger48475: folds +EricSteph261: folds +UnderMeSensi: folds +Uncalled bet ($0.14) returned to s0rrow +s0rrow collected $0.16 from pot +*** SUMMARY *** +Total pot $0.16 | Rake $0 +Board [8c 3s 4s] +Seat 1: EricSteph261 (small blind) folded on the Flop +Seat 2: UnderMeSensi (big blind) folded on the Flop +Seat 3: supermeXXX folded before Flop (didn't bet) +Seat 5: s0rrow collected ($0.16) +Seat 6: tiger48475 (button) folded on the Flop + + + +PokerStars Game #35875219121: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:43:08 ET +Table 'Gaby II' 6-max Seat #1 is the button +Seat 1: EricSteph261 ($11.21 in chips) +Seat 2: UnderMeSensi ($1.06 in chips) +Seat 3: supermeXXX ($1.30 in chips) +Seat 5: s0rrow ($5.21 in chips) +Seat 6: tiger48475 ($5 in chips) +UnderMeSensi: posts small blind $0.01 +supermeXXX: posts big blind $0.02 +*** HOLE CARDS *** +Dealt to s0rrow [Ks Qd Kd Kc] +s0rrow: raises $0.04 to $0.06 +tiger48475: folds +EricSteph261: calls $0.06 +UnderMeSensi: calls $0.05 +supermeXXX: calls $0.04 +*** FLOP *** [2d Jh 5h] +UnderMeSensi: checks +supermeXXX: checks +s0rrow: checks +EricSteph261: checks +*** TURN *** [2d Jh 5h] [Js] +UnderMeSensi: checks +supermeXXX: checks +s0rrow: checks +EricSteph261: checks +*** RIVER *** [2d Jh 5h Js] [7s] +UnderMeSensi: checks +supermeXXX: checks +s0rrow: checks +EricSteph261: checks +*** SHOW DOWN *** +UnderMeSensi: shows [5d 6c As 9d] (HI: two pair, Jacks and Fives; LO: 7,6,5,2,A) +supermeXXX: shows [6s Th 7c Ac] (HI: two pair, Jacks and Sevens; LO: 7,6,5,2,A) +s0rrow: shows [Ks Qd Kd Kc] (HI: two pair, Kings and Jacks) +EricSteph261: shows [4s 9c 3d 2c] (HI: two pair, Jacks and Deuces; LO: 7,5,4,3,2) +s0rrow collected $0.12 from pot +EricSteph261 collected $0.12 from pot +*** SUMMARY *** +Total pot $0.24 | Rake $0 +Board [2d Jh 5h Js 7s] +Seat 1: EricSteph261 (button) showed [4s 9c 3d 2c] and won ($0.12) with HI: two pair, Jacks and Deuces; LO: 7,5,4,3,2 +Seat 2: UnderMeSensi (small blind) showed [5d 6c As 9d] and lost with HI: two pair, Jacks and Fives; LO: 7,6,5,2,A +Seat 3: supermeXXX (big blind) showed [6s Th 7c Ac] and lost with HI: two pair, Jacks and Sevens; LO: 7,6,5,2,A +Seat 5: s0rrow showed [Ks Qd Kd Kc] and won ($0.12) with HI: two pair, Kings and Jacks +Seat 6: tiger48475 folded before Flop (didn't bet) + + + +PokerStars Game #35875246335: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:43:54 ET +Table 'Gaby II' 6-max Seat #2 is the button +Seat 1: EricSteph261 ($11.27 in chips) +Seat 2: UnderMeSensi ($1 in chips) +Seat 3: supermeXXX ($1.24 in chips) +Seat 5: s0rrow ($5.27 in chips) +Seat 6: tiger48475 ($5 in chips) +supermeXXX: posts small blind $0.01 +s0rrow: posts big blind $0.02 +*** HOLE CARDS *** +Dealt to s0rrow [Jd Kc 6h Jc] +tiger48475: folds +EricSteph261: calls $0.02 +UnderMeSensi is disconnected +UnderMeSensi has timed out while disconnected +UnderMeSensi: folds +UnderMeSensi is sitting out +supermeXXX: calls $0.01 +s0rrow: checks +*** FLOP *** [8d 7s Qh] +supermeXXX: bets $0.02 +s0rrow: folds +EricSteph261: calls $0.02 +*** TURN *** [8d 7s Qh] [As] +supermeXXX: bets $0.04 +EricSteph261: calls $0.04 +*** RIVER *** [8d 7s Qh As] [5d] +supermeXXX: checks +EricSteph261: checks +*** SHOW DOWN *** +supermeXXX: shows [Kh Qd 9s Th] (HI: a pair of Queens) +EricSteph261: shows [Jh 2d 5s 6c] (HI: a pair of Fives; LO: 7,6,5,2,A) +supermeXXX collected $0.09 from pot +EricSteph261 collected $0.09 from pot +*** SUMMARY *** +Total pot $0.18 | Rake $0 +Board [8d 7s Qh As 5d] +Seat 1: EricSteph261 showed [Jh 2d 5s 6c] and won ($0.09) with HI: a pair of Fives; LO: 7,6,5,2,A +Seat 2: UnderMeSensi (button) folded before Flop (didn't bet) +Seat 3: supermeXXX (small blind) showed [Kh Qd 9s Th] and won ($0.09) with HI: a pair of Queens +Seat 5: s0rrow (big blind) folded on the Flop +Seat 6: tiger48475 folded before Flop (didn't bet) + + + +PokerStars Game #35875293439: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:45:14 ET +Table 'Gaby II' 6-max Seat #3 is the button +Seat 1: EricSteph261 ($11.28 in chips) +Seat 3: supermeXXX ($1.25 in chips) +Seat 5: s0rrow ($5.25 in chips) +Seat 6: tiger48475 ($5 in chips) +s0rrow: posts small blind $0.01 +tiger48475: posts big blind $0.02 +*** HOLE CARDS *** +Dealt to s0rrow [9c 8h 8s 3c] +EricSteph261: calls $0.02 +supermeXXX: calls $0.02 +s0rrow: calls $0.01 +tiger48475: checks +*** FLOP *** [Ah 2d Qc] +s0rrow: checks +tiger48475: checks +EricSteph261: checks +supermeXXX: checks +*** TURN *** [Ah 2d Qc] [3d] +s0rrow: checks +tiger48475: checks +EricSteph261: checks +supermeXXX: checks +*** RIVER *** [Ah 2d Qc 3d] [6s] +s0rrow: checks +tiger48475: checks +EricSteph261: checks +supermeXXX: checks +*** SHOW DOWN *** +s0rrow: shows [9c 8h 8s 3c] (HI: a pair of Eights; LO: 8,6,3,2,A) +tiger48475: shows [3s 5s Ts Th] (HI: a pair of Tens; LO: 6,5,3,2,A) +EricSteph261: shows [As Ks Jh 7h] (HI: a pair of Aces; LO: 7,6,3,2,A) +supermeXXX: mucks hand +EricSteph261 collected $0.04 from pot +tiger48475 collected $0.04 from pot +*** SUMMARY *** +Total pot $0.08 | Rake $0 +Board [Ah 2d Qc 3d 6s] +Seat 1: EricSteph261 showed [As Ks Jh 7h] and won ($0.04) with HI: a pair of Aces; LO: 7,6,3,2,A +Seat 3: supermeXXX (button) mucked [9h 9s 4c Kc] +Seat 5: s0rrow (small blind) showed [9c 8h 8s 3c] and lost with HI: a pair of Eights; LO: 8,6,3,2,A +Seat 6: tiger48475 (big blind) showed [3s 5s Ts Th] and won ($0.04) with HI: a pair of Tens; LO: 6,5,3,2,A + + + +PokerStars Game #35875328026: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:46:13 ET +Table 'Gaby II' 6-max Seat #5 is the button +Seat 1: EricSteph261 ($11.30 in chips) +Seat 3: supermeXXX ($1.23 in chips) +Seat 5: s0rrow ($5.23 in chips) +Seat 6: tiger48475 ($5.02 in chips) +tiger48475: posts small blind $0.01 +EricSteph261: posts big blind $0.02 +*** HOLE CARDS *** +Dealt to s0rrow [Qd 6h 8s 6c] +supermeXXX: calls $0.02 +s0rrow: folds +tiger48475: calls $0.01 +EricSteph261: checks +*** FLOP *** [Kc Ac 5s] +tiger48475: checks +EricSteph261: checks +supermeXXX: checks +*** TURN *** [Kc Ac 5s] [3h] +tiger48475: checks +EricSteph261: checks +supermeXXX: checks +*** RIVER *** [Kc Ac 5s 3h] [Qh] +tiger48475: bets $0.06 +EricSteph261: folds +EricSteph261 is sitting out +supermeXXX: folds +Uncalled bet ($0.06) returned to tiger48475 +tiger48475 collected $0.06 from pot +*** SUMMARY *** +Total pot $0.06 | Rake $0 +Board [Kc Ac 5s 3h Qh] +Seat 1: EricSteph261 (big blind) folded on the River +Seat 3: supermeXXX folded on the River +Seat 5: s0rrow (button) folded before Flop (didn't bet) +Seat 6: tiger48475 (small blind) collected ($0.06) + + + +PokerStars Game #35875356253: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:47:00 ET +Table 'Gaby II' 6-max Seat #6 is the button +Seat 3: supermeXXX ($1.21 in chips) +Seat 5: s0rrow ($5.23 in chips) +Seat 6: tiger48475 ($5.06 in chips) +supermeXXX: posts small blind $0.01 +s0rrow: posts big blind $0.02 +*** HOLE CARDS *** +Dealt to s0rrow [8h Jd 5d 8d] +tiger48475: folds +supermeXXX: calls $0.01 +s0rrow: checks +*** FLOP *** [Ks 9s 6c] +supermeXXX: bets $0.02 +s0rrow: calls $0.02 +*** TURN *** [Ks 9s 6c] [Qc] +supermeXXX: bets $0.02 +s0rrow: calls $0.02 +*** RIVER *** [Ks 9s 6c Qc] [Ad] +supermeXXX: checks +s0rrow: checks +*** SHOW DOWN *** +supermeXXX: shows [Tc 7d 8c 3s] (HI: high card Ace) +s0rrow: shows [8h Jd 5d 8d] (HI: a pair of Eights) +s0rrow collected $0.12 from pot +No low hand qualified +*** SUMMARY *** +Total pot $0.12 | Rake $0 +Board [Ks 9s 6c Qc Ad] +Seat 3: supermeXXX (small blind) showed [Tc 7d 8c 3s] and lost with HI: high card Ace +Seat 5: s0rrow (big blind) showed [8h Jd 5d 8d] and won ($0.12) with HI: a pair of Eights +Seat 6: tiger48475 (button) folded before Flop (didn't bet) + + + +PokerStars Game #35875379792: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:47:39 ET +Table 'Gaby II' 6-max Seat #3 is the button +Seat 3: supermeXXX ($1.15 in chips) +Seat 5: s0rrow ($5.29 in chips) +Seat 6: tiger48475 ($5.06 in chips) +s0rrow: posts small blind $0.01 +tiger48475: posts big blind $0.02 +*** HOLE CARDS *** +Dealt to s0rrow [9c 5h 3s Th] +supermeXXX: calls $0.02 +s0rrow: calls $0.01 +tiger48475: checks +*** FLOP *** [Jc 3h Jd] +s0rrow: checks +tiger48475: checks +supermeXXX: checks +*** TURN *** [Jc 3h Jd] [6d] +s0rrow: checks +tiger48475: bets $0.06 +supermeXXX: folds +EricSteph261 has returned +s0rrow: calls $0.06 +*** RIVER *** [Jc 3h Jd 6d] [5c] +s0rrow: checks +tiger48475: bets $0.14 +s0rrow: folds +Uncalled bet ($0.14) returned to tiger48475 +tiger48475 collected $0.18 from pot +*** SUMMARY *** +Total pot $0.18 | Rake $0 +Board [Jc 3h Jd 6d 5c] +Seat 3: supermeXXX (button) folded on the Turn +Seat 5: s0rrow (small blind) folded on the River +Seat 6: tiger48475 (big blind) collected ($0.18) + + + +PokerStars Game #35875409365: Omaha Hi/Lo Pot Limit ($0.01/$0.02 USD) - 2009/11/26 10:48:29 ET +Table 'Gaby II' 6-max Seat #5 is the button +Seat 1: EricSteph261 ($11.28 in chips) +Seat 3: supermeXXX ($1.13 in chips) +Seat 5: s0rrow ($5.21 in chips) +Seat 6: tiger48475 ($5.16 in chips) +tiger48475: posts small blind $0.01 +EricSteph261: posts big blind $0.02 +*** HOLE CARDS *** +Dealt to s0rrow [6h 3c Th 2s] +supermeXXX: calls $0.02 +s0rrow: calls $0.02 +tiger48475: calls $0.01 +EricSteph261 has timed out +EricSteph261: checks +*** FLOP *** [9d 5s Jh] +tiger48475: bets $0.06 +EricSteph261 has timed out +EricSteph261: folds +EricSteph261 is sitting out +supermeXXX: calls $0.06 +s0rrow: calls $0.06 +*** TURN *** [9d 5s Jh] [Ks] +tiger48475: checks +supermeXXX: bets $0.10 +s0rrow: folds +tiger48475: calls $0.10 +*** RIVER *** [9d 5s Jh Ks] [9s] +tiger48475: checks +supermeXXX: checks +*** SHOW DOWN *** +tiger48475: shows [6s 9h 9c Ad] (HI: four of a kind, Nines) +supermeXXX: mucks hand +tiger48475 collected $0.46 from pot +No low hand qualified +*** SUMMARY *** +Total pot $0.46 | Rake $0 +Board [9d 5s Jh Ks 9s] +Seat 1: EricSteph261 (big blind) folded on the Flop +Seat 3: supermeXXX mucked [Qd Tc 5h Ts] +Seat 5: s0rrow (button) folded on the Turn +Seat 6: tiger48475 (small blind) showed [6s 9h 9c Ad] and won ($0.46) with HI: four of a kind, Nines + + + diff --git a/pyfpdb/regression-test-files/cash/Stars/Stud/7-StudHL-USD-0.04-0.08-200911.Cardtest.txt b/pyfpdb/regression-test-files/cash/Stars/Stud/7-StudHL-USD-0.04-0.08-200911.Cardtest.txt new file mode 100644 index 00000000..0ffdcc3d --- /dev/null +++ b/pyfpdb/regression-test-files/cash/Stars/Stud/7-StudHL-USD-0.04-0.08-200911.Cardtest.txt @@ -0,0 +1,96 @@ +PokerStars Game #35874676388: 7 Card Stud Hi/Lo Limit ($0.04/$0.08 USD) - 2009/11/26 10:27:46 ET +Table 'Dawn II' 8-max +Seat 1: u.pressure ($11.17 in chips) +Seat 2: 123smoothie ($0.99 in chips) +Seat 3: gashpor ($1.40 in chips) +Seat 4: denny501 ($0.71 in chips) +Seat 5: s0rrow ($1.52 in chips) +Seat 6: TomSludge ($1.58 in chips) +Seat 7: Soroka69 ($0.83 in chips) +Seat 8: rdiezchang ($2.05 in chips) +u.pressure: posts the ante $0.01 +123smoothie: posts the ante $0.01 +gashpor: posts the ante $0.01 +denny501: posts the ante $0.01 +s0rrow: posts the ante $0.01 +TomSludge: posts the ante $0.01 +Soroka69: posts the ante $0.01 +rdiezchang: posts the ante $0.01 +*** 3rd STREET *** +Dealt to u.pressure [Td] +Dealt to 123smoothie [4c] +Dealt to gashpor [5d] +Dealt to denny501 [2c] +Dealt to s0rrow [7c 3s 5h] +Dealt to TomSludge [8s] +Dealt to Soroka69 [7d] +Dealt to rdiezchang [Ad] +denny501: brings in for $0.02 +s0rrow: calls $0.02 +TomSludge: folds +Soroka69: calls $0.02 +rdiezchang: calls $0.02 +u.pressure: folds +123smoothie: calls $0.02 +gashpor: calls $0.02 +*** 4th STREET *** +Dealt to 123smoothie [4c] [3c] +Dealt to gashpor [5d] [Qd] +Dealt to denny501 [2c] [7s] +Dealt to s0rrow [7c 3s 5h] [Qc] +Dealt to Soroka69 [7d] [5s] +Dealt to rdiezchang [Ad] [Js] +rdiezchang: checks +123smoothie: checks +gashpor: checks +denny501: folds +denny501 leaves the table +s0rrow: checks +Soroka69: checks +*** 5th STREET *** +Dealt to 123smoothie [4c 3c] [9s] +Dealt to gashpor [5d Qd] [Jd] +Dealt to s0rrow [7c 3s 5h Qc] [Kc] +Dealt to Soroka69 [7d 5s] [5c] +Dealt to rdiezchang [Ad Js] [Ts] +LainaRahat joins the table at seat #4 +Soroka69: checks +rdiezchang: checks +123smoothie: checks +gashpor: bets $0.08 +s0rrow: calls $0.08 +Soroka69: calls $0.08 +rdiezchang: folds +123smoothie: folds +*** 6th STREET *** +Dealt to gashpor [5d Qd Jd] [9d] +Dealt to s0rrow [7c 3s 5h Qc Kc] [6d] +Dealt to Soroka69 [7d 5s 5c] [2s] +Soroka69: checks +gashpor: bets $0.08 +s0rrow: calls $0.08 +Soroka69: calls $0.08 +*** RIVER *** +Dealt to s0rrow [7c 3s 5h Qc Kc 6d] [4d] +Soroka69: checks +gashpor: bets $0.08 +s0rrow: calls $0.08 +Soroka69: folds +*** SHOW DOWN *** +gashpor: shows [4h 3d 5d Qd Jd 9d 6h] (HI: a flush, Queen high) +s0rrow: shows [7c 3s 5h Qc Kc 6d 4d] (HI: a straight, Three to Seven; LO: 7,6,5,4,3) +gashpor collected $0.40 from pot +s0rrow collected $0.40 from pot +*** SUMMARY *** +Total pot $0.84 | Rake $0.04 +Seat 1: u.pressure folded on the 3rd Street (didn't bet) +Seat 2: 123smoothie folded on the 5th Street +Seat 3: gashpor showed [4h 3d 5d Qd Jd 9d 6h] and won ($0.40) with HI: a flush, Queen high +Seat 4: denny501 folded on the 4th Street +Seat 5: s0rrow showed [7c 3s 5h Qc Kc 6d 4d] and won ($0.40) with HI: a straight, Three to Seven; LO: 7,6,5,4,3 +Seat 6: TomSludge folded on the 3rd Street (didn't bet) +Seat 7: Soroka69 folded on the River +Seat 8: rdiezchang folded on the 5th Street + + + diff --git a/pyfpdb/test1.py b/pyfpdb/test1.py new file mode 100755 index 00000000..76bde20e --- /dev/null +++ b/pyfpdb/test1.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +"""test1.py + +Test if python is working. +""" +# Copyright 2008, Ray E. Barker +# +# 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 sys + +print "\npython is working!" +print "\npress return to finish" + +sys.stdin.readline() diff --git a/pyfpdb/test2.py b/pyfpdb/test2.py new file mode 100755 index 00000000..c52d0a6c --- /dev/null +++ b/pyfpdb/test2.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python +"""test2.py + +Test if gtk is working. +""" +# Copyright 2008, Ray E. Barker +# +# 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 sys + +try: + import pygtk + pygtk.require('2.0') + import gtk + + + win = gtk.Window(gtk.WINDOW_TOPLEVEL) + win.set_title("Test GTK") + win.set_border_width(1) + win.set_default_size(600, 500) + win.set_resizable(True) + #win.show() + + dia = gtk.Dialog("Test GTK", + win, + gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, + (gtk.STOCK_CLOSE, gtk.RESPONSE_OK)) + dia.set_default_size(500, 300) + + l = gtk.Label("GTK is working!") + dia.vbox.add(l) + l.show() + + response = dia.run() + if response == gtk.RESPONSE_ACCEPT: + pass + dia.destroy() + +except: + print "\nError:", sys.exc_info() + print "\npress return to finish" + sys.stdin.readline() diff --git a/pyfpdb/test_Betfair.py b/pyfpdb/test_Betfair.py index 50949e93..7c979882 100644 --- a/pyfpdb/test_Betfair.py +++ b/pyfpdb/test_Betfair.py @@ -1,21 +1,34 @@ # -*- coding: utf-8 -*- import BetfairToFpdb +from Hand import * import py +import Configuration +import Database +import SQL +import fpdb_import -def checkGameInfo(hhc, header, info): - assert hhc.determineGameType(header) == info +config = Configuration.Config(file = "HUD_config.test.xml") +db = Database.Database(config) +sql = SQL.Sql(db_server = 'sqlite') -def testGameInfo(): - hhc = BetfairToFpdb.Betfair(autostart=False) - pairs = ( - (u"""***** Betfair Poker Hand History for Game 472386869 ***** -NL $0.02/$0.04 Texas Hold'em - Sunday, January 25, 10:10:42 GMT 2009 -Table Rookie 191 6-max (Real Money) -Seat 1 is the button -Total number of active players : 6""", - {'type':'ring', 'base':"hold", 'category':'holdem', 'limitType':'nl', 'sb':'0.02', 'bb':'0.04', 'currency':'USD'}), - ) +settings = {} +settings.update(config.get_db_parameters()) +settings.update(config.get_tv_parameters()) +settings.update(config.get_import_parameters()) +settings.update(config.get_default_paths()) - for (header, info) in pairs: - yield checkGameInfo, hhc, header, info +def testFlopImport(): + db.recreate_tables() + importer = fpdb_import.Importer(False, settings, config) + importer.setDropIndexes("don't drop") + importer.setFailOnError(True) + importer.setThreads(-1) + importer.addBulkImportImportFileOrDir( + """regression-test-files/cash/Betfair/Flop/PLO-6max-USD-0.05-0.10-200909.All.in.river.splitpot.txt""", site="Betfair") + importer.setCallHud(False) + (stored, dups, partial, errs, ttime) = importer.runImport() + importer.clearFileList() + + # Should actually do some testing here + assert 1 == 1 diff --git a/pyfpdb/test_PokerStars.py b/pyfpdb/test_PokerStars.py index 6c97c2d4..e3e45c35 100644 --- a/pyfpdb/test_PokerStars.py +++ b/pyfpdb/test_PokerStars.py @@ -74,12 +74,45 @@ def testFlopImport(): # """regression-test-files/tour/Stars/Flop/NLHE-USD-MTT-5r-200710.txt""", site="PokerStars") importer.addBulkImportImportFileOrDir( """regression-test-files/cash/Stars/Flop/PLO8-6max-USD-0.01-0.02-200911.txt""", site="PokerStars") + #HID - 36185273365 + # Besides the horrible play it contains lots of useful cases + # Preflop: raise, then 3bet chance for seat 2 + # Flop: Checkraise by hero, 4bet chance not taken by villain + # Turn: Turn continuation bet by hero, called + # River: hero (continuation bets?) all-in and is not called + importer.addBulkImportImportFileOrDir( + """regression-test-files/cash/Stars/Flop/NLHE-6max-USD-0.05-0.10-200912.Stats-comparision.txt""", site="PokerStars") importer.setCallHud(False) (stored, dups, partial, errs, ttime) = importer.runImport() + print "DEBUG: stored: %s dups: %s partial: %s errs: %s ttime: %s" %(stored, dups, partial, errs, ttime) importer.clearFileList() - # Should actually do some testing here - assert 1 == 1 + col = { 'sawShowdown': 2 + } + + q = """SELECT + s.name, + p.name, + hp.sawShowdown +FROM + Hands as h, + Sites as s, + Gametypes as g, + HandsPlayers as hp, + Players as p +WHERE + h.siteHandNo = 36185273365 +and g.id = h.gametypeid +and hp.handid = h.id +and p.id = hp.playerid +and s.id = p.siteid""" + c = db.get_cursor() + c.execute(q) + result = c.fetchall() + for row, data in enumerate(result): + print "DEBUG: result[%s]: %s" %(row, result[row]) + # Assert if any sawShowdown = True + assert result[row][col['sawShowdown']] == 0 def testStudImport(): db.recreate_tables()