Merge own master

This commit is contained in:
Mika Bostrom 2009-12-10 06:46:09 +02:00
commit fcf14f9100
26 changed files with 1658 additions and 333 deletions

11
Makefile Normal file
View File

@ -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

37
pyfpdb/Anonymise.py Normal file
View File

@ -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

22
pyfpdb/Database.py Executable file → Normal file
View File

@ -58,7 +58,8 @@ class Database:
PGSQL = 3 PGSQL = 3
SQLITE = 4 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 # Data Structures for index and foreign key creation
# drop_code is an int with possible values: 0 - don't drop for bulk import # drop_code is an int with possible values: 0 - don't drop for bulk import
@ -473,8 +474,9 @@ class Database:
else: else:
h_seats_min, h_seats_max = 0, 10 h_seats_min, h_seats_max = 0, 10
print "bad h_seats_style value:", h_seats_style print "bad h_seats_style value:", h_seats_style
print "opp seats style", seats_style, "hero seats style", h_seats_style log.info("opp seats style %s %d %d hero seats style %s %d %d"
print "opp seats:", seats_min, seats_max, " hero seats:", h_seats_min, h_seats_max % (seats_style, seats_min, seats_max
,h_seats_style, h_seats_min, h_seats_max) )
if hud_style == 'S' or h_hud_style == 'S': if hud_style == 'S' or h_hud_style == 'S':
self.get_stats_from_hand_session(hand, stat_dict, hero_id self.get_stats_from_hand_session(hand, stat_dict, hero_id
@ -1324,7 +1326,7 @@ class Database:
self.dropAllForeignKeys() self.dropAllForeignKeys()
self.createAllForeignKeys() 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""" """clears hudcache and rebuilds from the individual handsplayers records"""
try: try:
@ -1344,13 +1346,17 @@ class Database:
if p_id: if p_id:
self.hero_ids[site_id] = int(p_id) self.hero_ids[site_id] = int(p_id)
if start is None: if h_start is None:
start = self.hero_hudstart_def h_start = self.hero_hudstart_def
if v_start is None:
v_start = self.villain_hudstart_def
if self.hero_ids == {}: if self.hero_ids == {}:
where = "" where = ""
else: else:
where = "where hp.playerId not in " + str(tuple(self.hero_ids.values())) \ where = "where ( hp.playerId not in " + str(tuple(self.hero_ids.values())) \
+ " or h.handStart > '" + start + "'" + " 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_clause>', where) rebuild_sql = self.sql.query['rebuildHudCache'].replace('<where_clause>', where)
self.get_cursor().execute(self.sql.query['clearHudCache']) self.get_cursor().execute(self.sql.query['clearHudCache'])

View File

@ -149,6 +149,42 @@ class DerivedStats():
for i, card in enumerate(hcs[:7], 1): for i, card in enumerate(hcs[:7], 1):
self.handsplayers[player[1]]['card%s' % i] = Card.encodeCard(card) 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): def assembleHudCache(self, hand):
pass pass
@ -195,8 +231,9 @@ class DerivedStats():
pas = set.union(self.pfba(actions) - self.pfba(actions, l=('folds',)), alliners) pas = set.union(self.pfba(actions) - self.pfba(actions, l=('folds',)), alliners)
self.hands['playersAtShowdown'] = len(pas) self.hands['playersAtShowdown'] = len(pas)
for player in pas: if self.hands['playersAtShowdown'] > 1:
self.handsplayers[player]['sawShowdown'] = True for player in pas:
self.handsplayers[player]['sawShowdown'] = True
def streetXRaises(self, hand): def streetXRaises(self, hand):
# self.actions[street] is a list of all actions in a tuple, contining the action as the second element # self.actions[street] is a list of all actions in a tuple, contining the action as the second element

View File

@ -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(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(blue, color='blue', label='Showdown: $%.2f' %(blue[-1]))
self.ax.plot(red, color='red', label='Non-showdown: $%.2f' %(red[-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) self.graphBox.add(self.canvas)

175
pyfpdb/GuiLogView.py Executable file
View File

@ -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 <http://www.gnu.org/licenses/>.
#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()

View File

@ -574,7 +574,7 @@ Left-Drag to Move"
</hhcs> </hhcs>
<supported_databases> <supported_databases>
<database db_ip="localhost" db_name=":memory:" db_pass="fpdb" db_server="sqlite" db_user="fpdb"/> <database db_ip="localhost" db_name="fpdb" db_pass="fpdb" db_server="sqlite" db_user="fpdb"/>
</supported_databases> </supported_databases>
</FreePokerToolsConfig> </FreePokerToolsConfig>

View File

@ -63,6 +63,9 @@ elif os.name == 'nt':
import Hud import Hud
log = Configuration.get_logger("logging.conf")
class HUD_main(object): class HUD_main(object):
"""A main() object to own both the read_stdin thread and the gui.""" """A main() object to own both the read_stdin thread and the gui."""
# This class mainly provides state for controlling the multiple HUDs. # This class mainly provides state for controlling the multiple HUDs.
@ -159,10 +162,10 @@ class HUD_main(object):
# function idle_func() to be run by the gui thread, at its leisure. # function idle_func() to be run by the gui thread, at its leisure.
def idle_func(): def idle_func():
gtk.gdk.threads_enter() gtk.gdk.threads_enter()
self.hud_dict[table_name].update(new_hand_id, config) try:
self.hud_dict[table_name].update(new_hand_id, config)
# The HUD could get destroyed in the above call ^^, which leaves us with a KeyError here vv # The HUD could get destroyed in the above call ^^, which leaves us with a KeyError here vv
# if we ever get an error we need to expect ^^ then we need to handle it vv - Eric # if we ever get an error we need to expect ^^ then we need to handle it vv - Eric
try:
[aw.update_gui(new_hand_id) for aw in self.hud_dict[table_name].aux_windows] [aw.update_gui(new_hand_id) for aw in self.hud_dict[table_name].aux_windows]
except KeyError: except KeyError:
pass pass
@ -192,6 +195,8 @@ class HUD_main(object):
while 1: # wait for a new hand number on stdin while 1: # wait for a new hand number on stdin
new_hand_id = sys.stdin.readline() new_hand_id = sys.stdin.readline()
t0 = time.time()
t1 = t2 = t3 = t4 = t5 = t6 = t0
new_hand_id = string.rstrip(new_hand_id) new_hand_id = string.rstrip(new_hand_id)
if new_hand_id == "": # blank line means quit if new_hand_id == "": # blank line means quit
self.destroy() self.destroy()
@ -206,6 +211,7 @@ class HUD_main(object):
print "db error: skipping %s" % new_hand_id print "db error: skipping %s" % new_hand_id
sys.stderr.write("Database error: could not find hand %s.\n" % new_hand_id) sys.stderr.write("Database error: could not find hand %s.\n" % new_hand_id)
continue continue
t1 = time.time()
if type == "tour": # hand is from a tournament if type == "tour": # hand is from a tournament
temp_key = tour_number temp_key = tour_number
@ -215,6 +221,12 @@ class HUD_main(object):
# Update an existing HUD # Update an existing HUD
if temp_key in self.hud_dict: if temp_key in self.hud_dict:
# get stats using hud's specific params and get cards # 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: try:
self.db_connection.init_hud_stat_vars( self.hud_dict[temp_key].hud_params['hud_days'] 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']) , self.hud_dict[temp_key].hud_params['h_hud_days'])
@ -238,8 +250,10 @@ class HUD_main(object):
else: else:
# get stats using default params--also get cards # 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'] ) 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 stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_params
,self.hero_ids[site_id], num_seats) ,self.hero_ids[site_id], num_seats)
t5 = time.time()
cards = self.db_connection.get_cards(new_hand_id) cards = self.db_connection.get_cards(new_hand_id)
comm_cards = self.db_connection.get_common_cards(new_hand_id) comm_cards = self.db_connection.get_common_cards(new_hand_id)
if comm_cards != {}: # stud! if comm_cards != {}: # stud!
@ -263,6 +277,9 @@ class HUD_main(object):
else: else:
sys.stderr.write('Table "%s" no longer exists\n' % table_name) 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() self.db_connection.connection.rollback()
if __name__== "__main__": if __name__== "__main__":

View File

@ -54,6 +54,7 @@ class Hand(object):
self.starttime = 0 self.starttime = 0
self.handText = handText self.handText = handText
self.handid = 0 self.handid = 0
self.dbid_hands = 0
self.tablename = "" self.tablename = ""
self.hero = "" self.hero = ""
self.maxseats = None self.maxseats = None
@ -218,8 +219,8 @@ db: a connected fpdb_db object"""
# seats TINYINT NOT NULL, # seats TINYINT NOT NULL,
hh['seats'] = len(sqlids) hh['seats'] = len(sqlids)
handid = db.storeHand(hh) self.dbid_hands = db.storeHand(hh)
db.storeHandsPlayers(handid, sqlids, self.stats.getHandsPlayers()) db.storeHandsPlayers(self.dbid_hands, sqlids, self.stats.getHandsPlayers())
# HandsActions - all actions for all players for all streets - self.actions # HandsActions - all actions for all players for all streets - self.actions
# HudCache data can be generated from HandsActions (HandsPlayers?) # HudCache data can be generated from HandsActions (HandsPlayers?)
# Tourneys ? # Tourneys ?

View File

@ -71,6 +71,8 @@ follow : whether to tail -f the input"""
self.out_path = out_path self.out_path = out_path
self.processedHands = [] self.processedHands = []
self.numHands = 0
self.numErrors = 0
# Tourney object used to store TourneyInfo when called to deal with a Summary file # Tourney object used to store TourneyInfo when called to deal with a Summary file
self.tourney = None self.tourney = None
@ -135,17 +137,17 @@ Otherwise, finish at EOF.
return return
try: try:
numHands = 0 self.numHands = 0
numErrors = 0 self.numErrors = 0
if self.follow: if self.follow:
#TODO: See how summary files can be handled on the fly (here they should be rejected as before) #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) log.info("Tailing '%s'" % self.in_path)
for handText in self.tailHands(): for handText in self.tailHands():
try: try:
self.processHand(handText) self.processHand(handText)
numHands += 1 self.numHands += 1
except FpdbParseError, e: except FpdbParseError, e:
numErrors += 1 self.numErrors += 1
log.warning("Failed to convert hand %s" % e.hid) log.warning("Failed to convert hand %s" % e.hid)
log.warning("Exception msg: '%s'" % str(e)) log.warning("Exception msg: '%s'" % str(e))
log.debug(handText) log.debug(handText)
@ -160,13 +162,13 @@ Otherwise, finish at EOF.
try: try:
self.processedHands.append(self.processHand(handText)) self.processedHands.append(self.processHand(handText))
except FpdbParseError, e: except FpdbParseError, e:
numErrors += 1 self.numErrors += 1
log.warning("Failed to convert hand %s" % e.hid) log.warning("Failed to convert hand %s" % e.hid)
log.warning("Exception msg: '%s'" % str(e)) log.warning("Exception msg: '%s'" % str(e))
log.debug(handText) log.debug(handText)
numHands = len(handsList) self.numHands = len(handsList)
endtime = time.time() 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: else:
self.parsedObjectType = "Summary" self.parsedObjectType = "Summary"
summaryParsingStatus = self.readSummaryInfo(handsList) summaryParsingStatus = self.readSummaryInfo(handsList)

View File

@ -173,26 +173,26 @@ class Hud:
item = gtk.CheckMenuItem(' All Levels') item = gtk.CheckMenuItem(' All Levels')
self.aggMenu.append(item) self.aggMenu.append(item)
item.connect("activate", self.set_aggregation, ('P',10000)) item.connect("activate", self.set_aggregation, ('P',10000))
setattr(self, 'h_aggBBmultItem10000', item) setattr(self, 'h_aggBBmultItem10000', item)
# #
item = gtk.MenuItem('For #Seats:') item = gtk.MenuItem('For #Seats:')
self.aggMenu.append(item) self.aggMenu.append(item)
# #
item = gtk.CheckMenuItem(' Any Number') item = gtk.CheckMenuItem(' Any Number')
self.aggMenu.append(item) self.aggMenu.append(item)
item.connect("activate", self.set_seats_style, ('P','A')) item.connect("activate", self.set_seats_style, ('P','A'))
setattr(self, 'h_seatsStyleOptionA', item) setattr(self, 'h_seatsStyleOptionA', item)
# #
item = gtk.CheckMenuItem(' Custom') item = gtk.CheckMenuItem(' Custom')
self.aggMenu.append(item) self.aggMenu.append(item)
item.connect("activate", self.set_seats_style, ('P','C')) item.connect("activate", self.set_seats_style, ('P','C'))
setattr(self, 'h_seatsStyleOptionC', item) setattr(self, 'h_seatsStyleOptionC', item)
# #
item = gtk.CheckMenuItem(' Exact') item = gtk.CheckMenuItem(' Exact')
self.aggMenu.append(item) self.aggMenu.append(item)
item.connect("activate", self.set_seats_style, ('P','E')) item.connect("activate", self.set_seats_style, ('P','E'))
setattr(self, 'h_seatsStyleOptionE', item) setattr(self, 'h_seatsStyleOptionE', item)
# #
item = gtk.MenuItem('Since:') item = gtk.MenuItem('Since:')
self.aggMenu.append(item) self.aggMenu.append(item)
# #
@ -242,26 +242,26 @@ class Hud:
item = gtk.CheckMenuItem(' All Levels') item = gtk.CheckMenuItem(' All Levels')
self.aggMenu.append(item) self.aggMenu.append(item)
item.connect("activate", self.set_aggregation, ('O',10000)) item.connect("activate", self.set_aggregation, ('O',10000))
setattr(self, 'aggBBmultItem10000', item) setattr(self, 'aggBBmultItem10000', item)
# #
item = gtk.MenuItem('For #Seats:') item = gtk.MenuItem('For #Seats:')
self.aggMenu.append(item) self.aggMenu.append(item)
# #
item = gtk.CheckMenuItem(' Any Number') item = gtk.CheckMenuItem(' Any Number')
self.aggMenu.append(item) self.aggMenu.append(item)
item.connect("activate", self.set_seats_style, ('O','A')) item.connect("activate", self.set_seats_style, ('O','A'))
setattr(self, 'seatsStyleOptionA', item) setattr(self, 'seatsStyleOptionA', item)
# #
item = gtk.CheckMenuItem(' Custom') item = gtk.CheckMenuItem(' Custom')
self.aggMenu.append(item) self.aggMenu.append(item)
item.connect("activate", self.set_seats_style, ('O','C')) item.connect("activate", self.set_seats_style, ('O','C'))
setattr(self, 'seatsStyleOptionC', item) setattr(self, 'seatsStyleOptionC', item)
# #
item = gtk.CheckMenuItem(' Exact') item = gtk.CheckMenuItem(' Exact')
self.aggMenu.append(item) self.aggMenu.append(item)
item.connect("activate", self.set_seats_style, ('O','E')) item.connect("activate", self.set_seats_style, ('O','E'))
setattr(self, 'seatsStyleOptionE', item) setattr(self, 'seatsStyleOptionE', item)
# #
item = gtk.MenuItem('Since:') item = gtk.MenuItem('Since:')
self.aggMenu.append(item) self.aggMenu.append(item)
# #
@ -358,7 +358,7 @@ class Hud:
def change_max_seats(self, widget): def change_max_seats(self, widget):
if self.max != widget.ms: if self.max != widget.ms:
print 'change_max_seats', widget.ms #print 'change_max_seats', widget.ms
self.max = widget.ms self.max = widget.ms
try: try:
self.kill() self.kill()
@ -402,7 +402,7 @@ class Hud:
else: else:
param = 'seats_style' param = 'seats_style'
prefix = '' prefix = ''
if style == 'A' and getattr(self, prefix+'seatsStyleOptionA').get_active(): if style == 'A' and getattr(self, prefix+'seatsStyleOptionA').get_active():
self.hud_params[param] = 'A' self.hud_params[param] = 'A'
getattr(self, prefix+'seatsStyleOptionC').set_active(False) getattr(self, prefix+'seatsStyleOptionC').set_active(False)
@ -678,7 +678,7 @@ class Stat_Window:
return True return True
def kill_popup(self, popup): def kill_popup(self, popup):
print "remove popup", popup #print "remove popup", popup
self.popups.remove(popup) self.popups.remove(popup)
popup.window.destroy() popup.window.destroy()

View File

@ -36,8 +36,11 @@ def fpdb_options():
action="store_true", action="store_true",
help="Indicates program was restarted with a different path (only allowed once).") help="Indicates program was restarted with a different path (only allowed once).")
parser.add_option("-i", "--infile", parser.add_option("-i", "--infile",
dest="config", default=None, dest="infile", default="Slartibartfast",
help="Input file") help="Input file")
parser.add_option("-k", "--konverter",
dest="hhc", default="PokerStarsToFpdb",
help="Module name for Hand History Converter")
(options, argv) = parser.parse_args() (options, argv) = parser.parse_args()
return (options, argv) return (options, argv)

View File

@ -1317,6 +1317,7 @@ class Sql:
1.25 would be a config value so user could change it) 1.25 would be a config value so user could change it)
*/ */
GROUP BY hc.PlayerId, hp.seatNo, p.name 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 # same as above except stats are aggregated for all blind/limit levels
@ -1418,6 +1419,7 @@ class Sql:
) )
) )
GROUP BY hc.PlayerId, p.name GROUP BY hc.PlayerId, p.name
ORDER BY hc.PlayerId, p.name
""" """
# NOTES on above cursor: # NOTES on above cursor:
# - Do NOT include %s inside query in a comment - the db api thinks # - Do NOT include %s inside query in a comment - the db api thinks

View File

@ -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) os.execvpe('python.exe', ('python.exe', 'fpdb.py', '-r'), os.environ) # first arg is ignored (name of program being run)
else: else:
print "\npython 2.5 not found, please install python 2.5 or 2.6 for fpdb\n" 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: else:
pass pass
#print "debug - not changing path" #print "debug - not changing path"
if os.name == 'nt': if os.name == 'nt':
import win32api try:
import win32con 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' print "Python " + sys.version[0:3] + '...\n'
@ -60,16 +66,23 @@ if not options.errorsToConsole:
errorFile = open('fpdb-error-log.txt', 'w', 0) errorFile = open('fpdb-error-log.txt', 'w', 0)
sys.stderr = errorFile sys.stderr = errorFile
import logging #import logging
import logging, logging.config
import pygtk try:
pygtk.require('2.0') import pygtk
import gtk 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 interlocks
import GuiPrefs import GuiPrefs
import GuiLogView
import GuiBulkImport import GuiBulkImport
import GuiPlayerStats import GuiPlayerStats
import GuiPositionalStats import GuiPositionalStats
@ -85,6 +98,8 @@ import Exceptions
VERSION = "0.12" VERSION = "0.12"
log = Configuration.get_logger("logging.conf", "fpdb")
class fpdb: class fpdb:
def tab_clicked(self, widget, tab_name): def tab_clicked(self, widget, tab_name):
"""called when a tab button is clicked to activate that tab""" """called when a tab button is clicked to activate that tab"""
@ -115,7 +130,7 @@ class fpdb:
self.pages.append(new_page) self.pages.append(new_page)
self.tabs.append(event_box) self.tabs.append(event_box)
self.tab_names.append(new_tab_name) self.tab_names.append(new_tab_name)
#self.nb.append_page(new_page, gtk.Label(new_tab_name)) #self.nb.append_page(new_page, gtk.Label(new_tab_name))
self.nb.append_page(page, event_box) self.nb.append_page(page, event_box)
self.nb_tabs.append(new_tab_name) self.nb_tabs.append(new_tab_name)
@ -135,12 +150,12 @@ class fpdb:
self.nb.set_current_page(tab_no) self.nb.set_current_page(tab_no)
def create_custom_tab(self, text, nb): 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 #label and a button with STOCK_ICON
eventBox = gtk.EventBox() eventBox = gtk.EventBox()
tabBox = gtk.HBox(False, 2) tabBox = gtk.HBox(False, 2)
tabLabel = gtk.Label(text) tabLabel = gtk.Label(text)
tabBox.pack_start(tabLabel, False) tabBox.pack_start(tabLabel, False)
eventBox.add(tabBox) eventBox.add(tabBox)
if nb.get_n_pages() > 0: if nb.get_n_pages() > 0:
@ -157,7 +172,7 @@ class fpdb:
return eventBox return eventBox
def add_icon_to_button(self, button): def add_icon_to_button(self, button):
iconBox = gtk.HBox(False, 0) iconBox = gtk.HBox(False, 0)
image = gtk.Image() image = gtk.Image()
image.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_SMALL_TOOLBAR) image.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_SMALL_TOOLBAR)
gtk.Button.set_relief(button, gtk.RELIEF_NONE) gtk.Button.set_relief(button, gtk.RELIEF_NONE)
@ -168,8 +183,8 @@ class fpdb:
iconBox.pack_start(image, True, False, 0) iconBox.pack_start(image, True, False, 0)
button.add(iconBox) button.add(iconBox)
iconBox.show() iconBox.show()
return return
# Remove a page from the notebook # Remove a page from the notebook
def remove_tab(self, button, data): def remove_tab(self, button, data):
(nb, text) = data (nb, text) = data
@ -183,7 +198,7 @@ class fpdb:
#print " removing page", page #print " removing page", page
del self.nb_tabs[page] del self.nb_tabs[page]
nb.remove_page(page) nb.remove_page(page)
# Need to refresh the widget -- # Need to refresh the widget --
# This forces the widget to redraw itself. # This forces the widget to redraw itself.
#nb.queue_draw_area(0,0,-1,-1) needed or not?? #nb.queue_draw_area(0,0,-1,-1) needed or not??
@ -196,15 +211,17 @@ class fpdb:
def dia_about(self, widget, data=None): 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") #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 = gtk.AboutDialog()
dia.set_name("FPDB") dia.set_name("Free Poker Database (FPDB)")
dia.set_version(VERSION) 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_comments("GTK AboutDialog comments here")
dia.set_license("GPL v3") dia.set_license("GPL v3")
dia.set_website("http://fpdb.sourceforge.net/") dia.set_website("http://fpdb.sourceforge.net/")
dia.set_authors(['Steffen', 'Eratosthenes', 's0rrow', dia.set_authors(['Steffen', 'Eratosthenes', 's0rrow',
'EricBlade', '_mt', 'and others']) 'EricBlade', '_mt', 'and others'])
dia.set_program_name("FPDB") 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.run()
dia.destroy() dia.destroy()
@ -335,27 +352,48 @@ class fpdb:
diastring = "Please confirm that you want to re-create the HUD cache." diastring = "Please confirm that you want to re-create the HUD cache."
self.dia_confirm.format_secondary_text(diastring) 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 = gtk.Entry(max=12)
self.start_date.set_text( self.db.get_hero_hudcache_start() ) 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 = gtk.Button()
btn.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_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) btn.connect('clicked', self.__calendar_dialog, self.start_date)
hb.pack_start(lbl, expand=True, padding=3) hb2.pack_start(lbl, expand=True, padding=3)
hb.pack_start(self.start_date, expand=True, padding=2) hb2.pack_start(self.start_date, expand=True, padding=2)
hb.pack_start(btn, expand=False, padding=3) hb2.pack_start(btn, expand=False, padding=3)
self.dia_confirm.vbox.add(hb) self.dia_confirm.vbox.add(hb2)
hb.show_all() hb2.show_all()
response = self.dia_confirm.run() response = self.dia_confirm.run()
self.dia_confirm.destroy()
if response == gtk.RESPONSE_YES: 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: elif response == gtk.RESPONSE_NO:
print 'User cancelled rebuilding hud cache' print 'User cancelled rebuilding hud cache'
self.dia_confirm.destroy()
self.release_global_lock() self.release_global_lock()
def dia_rebuild_indexes(self, widget, data=None): def dia_rebuild_indexes(self, widget, data=None):
@ -369,16 +407,53 @@ class fpdb:
self.dia_confirm.format_secondary_text(diastring) self.dia_confirm.format_secondary_text(diastring)
response = self.dia_confirm.run() response = self.dia_confirm.run()
self.dia_confirm.destroy()
if response == gtk.RESPONSE_YES: 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() self.db.rebuild_indexes()
lbl.set_text(" Cleaning Database ... ")
while gtk.events_pending():
gtk.main_iteration_do(False)
self.db.vacuumDB() self.db.vacuumDB()
lbl.set_text(" Analyzing Database ... ")
while gtk.events_pending():
gtk.main_iteration_do(False)
self.db.analyzeDB() self.db.analyzeDB()
elif response == gtk.RESPONSE_NO: elif response == gtk.RESPONSE_NO:
print 'User cancelled rebuilding db indexes' print 'User cancelled rebuilding db indexes'
self.dia_confirm.destroy()
self.release_global_lock() 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): def __calendar_dialog(self, widget, entry):
self.dia_confirm.set_modal(False) self.dia_confirm.set_modal(False)
d = gtk.Window(gtk.WINDOW_TOPLEVEL) d = gtk.Window(gtk.WINDOW_TOPLEVEL)
@ -398,10 +473,13 @@ class fpdb:
d.show_all() d.show_all()
def __get_dates(self): def __get_dates(self):
t1 = self.start_date.get_text() t1 = self.h_start_date.get_text()
if t1 == '': if t1 == '':
t1 = '1970-01-01' 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): def __get_date(self, widget, calendar, entry, win):
# year and day are correct, month is 0..11 # year and day are correct, month is 0..11
@ -478,6 +556,7 @@ class fpdb:
</menu> </menu>
<menu action="help"> <menu action="help">
<menuitem action="Abbrev"/> <menuitem action="Abbrev"/>
<menuitem action="Logs"/>
<separator/> <separator/>
<menuitem action="About"/> <menuitem action="About"/>
<menuitem action="License"/> <menuitem action="License"/>
@ -519,6 +598,7 @@ class fpdb:
('stats', None, '_Statistics (todo)', None, 'View Database Statistics', self.dia_database_stats), ('stats', None, '_Statistics (todo)', None, 'View Database Statistics', self.dia_database_stats),
('help', None, '_Help'), ('help', None, '_Help'),
('Abbrev', None, '_Abbrevations (todo)', None, 'List of Abbrevations', self.tab_abbreviations), ('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), ('About', None, 'A_bout', None, 'About the program', self.dia_about),
('License', None, '_License and Copying (todo)', None, 'License and Copying', self.dia_licensing), ('License', None, '_License and Copying (todo)', None, 'License and Copying', self.dia_licensing),
]) ])
@ -558,7 +638,7 @@ class fpdb:
self.warning_box("MySQL Server reports: Access denied. Are your permissions set correctly?") self.warning_box("MySQL Server reports: Access denied. Are your permissions set correctly?")
exit() exit()
except Exceptions.FpdbMySQLNoDatabase: 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) self.warning_box(msg)
exit exit
@ -753,7 +833,6 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
sys.stderr.write("fpdb starting ...") sys.stderr.write("fpdb starting ...")
def window_state_event_cb(self, window, event): def window_state_event_cb(self, window, event):
print "window_state_event", event
if event.changed_mask & gtk.gdk.WINDOW_STATE_ICONIFIED: if event.changed_mask & gtk.gdk.WINDOW_STATE_ICONIFIED:
# -20 = GWL_EXSTYLE can't find it in the pywin32 libs # -20 = GWL_EXSTYLE can't find it in the pywin32 libs
#bits = win32api.GetWindowLong(self.window.window.handle, -20) #bits = win32api.GetWindowLong(self.window.window.handle, -20)
@ -836,6 +915,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
gtk.main() gtk.main()
return 0 return 0
if __name__ == "__main__": if __name__ == "__main__":
me = fpdb() me = fpdb()
me.main() me.main()

View File

@ -106,7 +106,7 @@ class fpdb_db:
except MySQLdb.Error, ex: except MySQLdb.Error, ex:
if ex.args[0] == 1045: if ex.args[0] == 1045:
raise FpdbMySQLAccessDenied(ex.args[0], ex.args[1]) 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]) raise FpdbMySQLNoDatabase(ex.args[0], ex.args[1])
else: else:
print "*** WARNING UNKNOWN MYSQL ERROR", ex print "*** WARNING UNKNOWN MYSQL ERROR", ex

View File

@ -21,7 +21,7 @@
import os # todo: remove this once import_dir is in fpdb_import import os # todo: remove this once import_dir is in fpdb_import
import sys import sys
from time import time, strftime, sleep from time import time, strftime, sleep, clock
import traceback import traceback
import math import math
import datetime import datetime
@ -101,6 +101,8 @@ class Importer:
self.NEWIMPORT = Configuration.NEWIMPORT self.NEWIMPORT = Configuration.NEWIMPORT
clock() # init clock in windows
#Set functions #Set functions
def setCallHud(self, value): def setCallHud(self, value):
self.callHud = 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] # print "file",counter," updated", os.path.basename(file), stat_info.st_size, self.updatedsize[file], stat_info.st_mtime, self.updatedtime[file]
try: try:
if not os.path.isdir(file): 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? except KeyError: # TODO: What error happens here?
pass 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.updatedsize[file] = stat_info.st_size
self.updatedtime[file] = time() self.updatedtime[file] = time()
else: else:
@ -393,7 +400,7 @@ class Importer:
if os.path.isdir(file): if os.path.isdir(file):
self.addToDirList[file] = [site] + [filter] self.addToDirList[file] = [site] + [filter]
return return (0,0,0,0,0)
conv = None conv = None
(stored, duplicates, partial, errors, ttime) = (0, 0, 0, 0, 0) (stored, duplicates, partial, errors, ttime) = (0, 0, 0, 0, 0)
@ -427,8 +434,17 @@ class Importer:
self.pos_in_file[file] = hhc.getLastCharacterRead() self.pos_in_file[file] = hhc.getLastCharacterRead()
for hand in handlist: for hand in handlist:
#try, except duplicates here?
#hand.prepInsert() #hand.prepInsert()
hand.insert(self.database) 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: else:
# conversion didn't work # conversion didn't work
# TODO: appropriate response? # TODO: appropriate response?
@ -472,10 +488,13 @@ class Importer:
self.pos_in_file[file] = inputFile.tell() self.pos_in_file[file] = inputFile.tell()
inputFile.close() inputFile.close()
x = clock()
(stored, duplicates, partial, errors, ttime, handsId) = self.import_fpdb_lines(db, self.lines, starttime, file, site, q) (stored, duplicates, partial, errors, ttime, handsId) = self.import_fpdb_lines(db, self.lines, starttime, file, site, q)
db.commit() db.commit()
ttime = time() - starttime y = clock()
ttime = y - x
#ttime = time() - starttime
if q is None: if q is None:
log.info("Total stored: %(stored)d\tduplicates:%(duplicates)d\terrors:%(errors)d\ttime:%(ttime)s" % locals()) 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 #print "call to HUD here. handsId:",handsId
#pipe the Hands.id out to the HUD #pipe the Hands.id out to the HUD
# print "fpdb_import: sending hand to hud", handsId, "pipe =", self.caller.pipe_to_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: except Exceptions.DuplicateError:
duplicates += 1 duplicates += 1
db.rollback() db.rollback()

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,18 @@ keys=fileFormatter,stderrFormatter
level=INFO level=INFO
handlers=consoleHandler,fileHandler 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] [logger_parser]
level=INFO level=INFO
handlers=consoleHandler,fileHandler handlers=consoleHandler,fileHandler
@ -24,7 +36,7 @@ qualname=importer
propagate=0 propagate=0
[logger_config] [logger_config]
level=DEBUG level=INFO
handlers=consoleHandler,fileHandler handlers=consoleHandler,fileHandler
qualname=config qualname=config
propagate=0 propagate=0

View File

@ -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 ************

View File

@ -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)

View File

@ -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

View File

@ -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

29
pyfpdb/test1.py Executable file
View File

@ -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()

57
pyfpdb/test2.py Executable file
View File

@ -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()

View File

@ -1,21 +1,34 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import BetfairToFpdb import BetfairToFpdb
from Hand import *
import py import py
import Configuration
import Database
import SQL
import fpdb_import
def checkGameInfo(hhc, header, info): config = Configuration.Config(file = "HUD_config.test.xml")
assert hhc.determineGameType(header) == info db = Database.Database(config)
sql = SQL.Sql(db_server = 'sqlite')
def testGameInfo(): settings = {}
hhc = BetfairToFpdb.Betfair(autostart=False) settings.update(config.get_db_parameters())
pairs = ( settings.update(config.get_tv_parameters())
(u"""***** Betfair Poker Hand History for Game 472386869 ***** settings.update(config.get_import_parameters())
NL $0.02/$0.04 Texas Hold'em - Sunday, January 25, 10:10:42 GMT 2009 settings.update(config.get_default_paths())
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'}),
)
for (header, info) in pairs: def testFlopImport():
yield checkGameInfo, hhc, header, info 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

View File

@ -74,12 +74,45 @@ def testFlopImport():
# """regression-test-files/tour/Stars/Flop/NLHE-USD-MTT-5r-200710.txt""", site="PokerStars") # """regression-test-files/tour/Stars/Flop/NLHE-USD-MTT-5r-200710.txt""", site="PokerStars")
importer.addBulkImportImportFileOrDir( importer.addBulkImportImportFileOrDir(
"""regression-test-files/cash/Stars/Flop/PLO8-6max-USD-0.01-0.02-200911.txt""", site="PokerStars") """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) importer.setCallHud(False)
(stored, dups, partial, errs, ttime) = importer.runImport() (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() importer.clearFileList()
# Should actually do some testing here col = { 'sawShowdown': 2
assert 1 == 1 }
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(): def testStudImport():
db.recreate_tables() db.recreate_tables()