Merge branch 'master' of git://git.assembla.com/fpdboz.git

This commit is contained in:
Eric Blade 2010-11-26 09:14:25 -05:00
commit 5e04f32519
21 changed files with 830 additions and 126 deletions

View File

@ -133,8 +133,9 @@ or None if we fail to get the info """
self.info = {}
mg = m.groupdict()
print mg
limits = { 'No Limit':'nl', 'Limit':'fl' }
limits = { 'No Limit':'nl', 'No Limit ':'nl', 'Limit':'fl' }
games = { # base, category
'Holdem' : ('hold','holdem'),
'Holdem Tournament' : ('hold','holdem') }

View File

@ -55,6 +55,7 @@ import Card
import Charset
from Exceptions import *
import Configuration
import Filters
# Other library modules
@ -73,7 +74,7 @@ except ImportError:
use_numpy = False
DB_VERSION = 144
DB_VERSION = 145
# Variance created as sqlite has a bunch of undefined aggregate functions.
@ -291,8 +292,8 @@ class Database:
# vars for hand ids or dates fetched according to above config:
self.hand_1day_ago = 0 # max hand id more than 24 hrs earlier than now
self.date_ndays_ago = 'd000000' # date N days ago ('d' + YYMMDD)
self.h_date_ndays_ago = 'd000000' # date N days ago ('d' + YYMMDD) for hero
self.date_ndays_ago = 'd00000000' # date N days ago ('d' + YYMMDD)
self.h_date_ndays_ago = 'd00000000' # date N days ago ('d' + YYMMDD) for hero
self.date_nhands_ago = {} # dates N hands ago per player - not used yet
self.saveActions = False if self.import_options['saveActions'] == False else True
@ -690,20 +691,22 @@ class Database:
if row and row[0]:
self.hand_1day_ago = int(row[0])
d = timedelta(days=hud_days)
now = datetime.utcnow() - d
self.date_ndays_ago = "d%02d%02d%02d" % (now.year - 2000, now.month, now.day)
offset = strptime(Filters.Filters(self, self.config, self.sql).getDates()[0],"%Y-%m-%d %H:%M:%S").tm_hour
d = timedelta(days=h_hud_days)
d = timedelta(days=hud_days, hours=offset)
now = datetime.utcnow() - d
self.h_date_ndays_ago = "d%02d%02d%02d" % (now.year - 2000, now.month, now.day)
self.date_ndays_ago = "d%02d%02d%02d%02d" % (now.year - 2000, now.month, now.day, offset)
d = timedelta(days=h_hud_days, hours=offset)
now = datetime.utcnow() - d
self.h_date_ndays_ago = "d%02d%02d%02d%02d" % (now.year - 2000, now.month, now.day, offset)
def init_player_hud_stat_vars(self, playerid):
# not sure if this is workable, to be continued ...
try:
# self.date_nhands_ago is used for fetching stats for last n hands (hud_style = 'H')
# This option not used yet - needs to be called for each player :-(
self.date_nhands_ago[str(playerid)] = 'd000000'
self.date_nhands_ago[str(playerid)] = 'd00000000'
# should use aggregated version of query if appropriate
c.execute(self.sql.query['get_date_nhands_ago'], (self.hud_hands, playerid))
@ -771,11 +774,11 @@ class Database:
if hud_style == 'T':
stylekey = self.date_ndays_ago
elif hud_style == 'A':
stylekey = '0000000' # all stylekey values should be higher than this
stylekey = '000000000' # all stylekey values should be higher than this
elif hud_style == 'S':
stylekey = 'zzzzzzz' # all stylekey values should be lower than this
stylekey = 'zzzzzzzzz' # all stylekey values should be lower than this
else:
stylekey = '0000000'
stylekey = '000000000'
log.info('hud_style: %s' % hud_style)
#elif hud_style == 'H':
@ -784,11 +787,11 @@ class Database:
if h_hud_style == 'T':
h_stylekey = self.h_date_ndays_ago
elif h_hud_style == 'A':
h_stylekey = '0000000' # all stylekey values should be higher than this
h_stylekey = '000000000' # all stylekey values should be higher than this
elif h_hud_style == 'S':
h_stylekey = 'zzzzzzz' # all stylekey values should be lower than this
h_stylekey = 'zzzzzzzzz' # all stylekey values should be lower than this
else:
h_stylekey = '000000'
h_stylekey = '00000000'
log.info('h_hud_style: %s' % h_hud_style)
#elif h_hud_style == 'H':
@ -1824,11 +1827,11 @@ class Database:
"""Update cached statistics. If update fails because no record exists, do an insert."""
if self.use_date_in_hudcache:
styleKey = datetime.strftime(starttime, 'd%y%m%d')
#styleKey = "d%02d%02d%02d" % (hand_start_time.year-2000, hand_start_time.month, hand_start_time.day)
styleKey = datetime.strftime(starttime, 'd%y%m%d%H')
#styleKey = "d%02d%02d%02d%02d" % (hand_start_time.year-2000, hand_start_time.month, hand_start_time.day, hand_start_time.hour)
else:
# hard-code styleKey as 'A000000' (all-time cache, no key) for now
styleKey = 'A000000'
# hard-code styleKey as 'A00000000' (all-time cache, no key) for now
styleKey = 'A00000000'
update_hudcache = self.sql.query['update_hudcache']
update_hudcache = update_hudcache.replace('%s', self.sql.query['placeholder'])

View File

@ -50,11 +50,14 @@ import Database
import Filters
import Charset
DEBUG = False
class GuiSessionViewer (threading.Thread):
def __init__(self, config, querylist, mainwin, debug=True):
self.debug = debug
self.conf = config
self.sql = querylist
self.window = mainwin
self.liststore = None
@ -153,6 +156,28 @@ class GuiSessionViewer (threading.Thread):
# make sure Hand column is not displayed
#[x for x in self.columns if x[0] == 'hand'][0][1] = False
if DEBUG == False:
warning_string = """
Session Viewer is proof of concept code only, and contains many bugs.
Feel free to use the viewer, but there is no guarantee that the data is accurate.
If you are interested in developing the code further please contact us via the usual channels.
Thankyou
"""
self.warning_box(warning_string)
def warning_box(self, str, diatitle=_("FPDB WARNING")):
diaWarning = gtk.Dialog(title=diatitle, parent=self.window, flags=gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
label = gtk.Label(str)
diaWarning.vbox.add(label)
label.show()
response = diaWarning.run()
diaWarning.destroy()
return response
def get_vbox(self):
"""returns the vbox of this thread"""

205
pyfpdb/GuiStove.py Normal file
View File

@ -0,0 +1,205 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#Copyright 2008-2010 Steffen Schaumburg
#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU Affero General Public License as published by
#the Free Software Foundation, version 3 of the License.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU Affero General Public License
#along with this program. If not, see <http://www.gnu.org/licenses/>.
#In the "official" distribution you can find the license in agpl-3.0.txt.
import L10n
_ = L10n.get_translation()
import pygtk
pygtk.require('2.0')
import gtk
import os
import sys
import Charset
DEBUG = False
class GuiStove():
def __init__(self, config, parent, debug=True):
"""Constructor for GraphViewer"""
self.conf = config
self.parent = parent
self.mainHBox = gtk.HBox(False, 0)
# hierarchy: self.mainHBox / self.notebook
self.notebook = gtk.Notebook()
self.notebook.set_tab_pos(gtk.POS_TOP)
self.notebook.set_show_tabs(True)
self.notebook.set_show_border(True)
self.createFlopTab()
#self.createStudTab()
#self.createDrawTab()
self.mainHBox.add(self.notebook)
self.mainHBox.show_all()
if DEBUG == False:
warning_string = """
Stove is a GUI mockup of a EV calculation page, and completely non functional.
Unless you are interested in developing this feature, please ignore this page.
If you are interested in developing the code further see GuiStove.py and Stove.py
Thankyou
"""
self.warning_box(warning_string)
def warning_box(self, str, diatitle=_("FPDB WARNING")):
diaWarning = gtk.Dialog(title=diatitle, parent=self.parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
label = gtk.Label(str)
diaWarning.vbox.add(label)
label.show()
response = diaWarning.run()
diaWarning.destroy()
return response
def get_active_text(combobox):
model = combobox.get_model()
active = combobox.get_active()
if active < 0:
return None
return model[active][0]
def create_combo_box(self, strings):
combobox = gtk.combo_box_new_text()
for label in strings:
combobox.append_text(label)
combobox.set_active(0)
return combobox
def createFlopTab(self):
# hierarchy: hbox / ddbox / ddhbox / Label + flop_games_cb | label + players_cb
# / gamehbox / in_frame / table /
# / out_frame
tab_title = "Flop"
label = gtk.Label(tab_title)
ddbox = gtk.VBox(False, 0)
self.notebook.append_page(ddbox, label)
ddhbox = gtk.HBox(False, 0)
gamehbox = gtk.HBox(False, 0)
ddbox.add(ddhbox)
ddbox.add(gamehbox)
# Combo boxes in the top row
games = [ "Holdem", "Omaha", "Omaha 8", ]
players = [ "2", "3", "4", "5", "6", "7", "8", "9", "10" ]
flop_games_cb = self.create_combo_box(games)
players_cb = self.create_combo_box(players)
label = gtk.Label("Gametype:")
ddhbox.add(label)
ddhbox.add(flop_games_cb)
label = gtk.Label("Players:")
ddhbox.add(label)
ddhbox.add(players_cb)
# Frames for Stove input and output
in_frame = gtk.Frame("Input:")
out_frame = gtk.Frame("Output:")
gamehbox.add(in_frame)
gamehbox.add(out_frame)
outstring = """
No board given. Using Monte-Carlo simulation...
Enumerated 2053443 possible plays.
Your hand: (Ad Ac)
Against the range: {
AhAd, AhAs, AdAs, KhKd, KhKs,
KhKc, KdKs, KdKc, KsKc, QhQd,
QhQs, QhQc, QdQs, QdQc, QsQc,
JhJd, JhJs, JhJc, JdJs, JdJc,
JsJc
}
Win Lose Tie
69.91% 15.83% 14.26%
"""
label = gtk.Label(outstring)
out_frame.add(label)
# Input Frame
table = gtk.Table(4, 4, True)
label = gtk.Label("Board:")
board = gtk.Entry()
#board.connect("changed", self._some_function, arg)
btn1 = gtk.Button()
btn1.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
#btn.connect('clicked', self._some_function, arg)
table.attach(label, 0, 1, 0, 1, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK)
table.attach(board, 1, 2, 0, 1, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK)
table.attach(btn1, 2, 3, 0, 1, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK)
label = gtk.Label("Player1:")
board = gtk.Entry()
#board.connect("changed", self._some_function, arg)
btn2 = gtk.Button()
btn2.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
#btn.connect('clicked', self._some_function, arg)
btn3 = gtk.Button()
btn3.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
#btn.connect('clicked', self._some_function, arg)
table.attach(label, 0, 1, 1, 2, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK)
table.attach(board, 1, 2, 1, 2, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK)
table.attach(btn2, 2, 3, 1, 2, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK)
table.attach(btn3, 3, 4, 1, 2, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK)
label = gtk.Label("Player2:")
board = gtk.Entry()
#board.connect("changed", self._some_function, arg)
btn4 = gtk.Button()
btn4.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
#btn.connect('clicked', self._some_function, arg)
btn5 = gtk.Button()
btn5.set_image(gtk.image_new_from_stock(gtk.STOCK_INDEX, gtk.ICON_SIZE_BUTTON))
#btn.connect('clicked', self._some_function, arg)
table.attach(label, 0, 1, 2, 3, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK)
table.attach(board, 1, 2, 2, 3, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK)
table.attach(btn4, 2, 3, 2, 3, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK)
table.attach(btn5, 3, 4, 2, 3, xoptions=gtk.SHRINK, yoptions=gtk.SHRINK)
#table.attach(label, i, i+1, j, j+1,)
in_frame.add(table)
def get_vbox(self):
"""returns the vbox of this thread"""
return self.mainHBox
#end def get_vbox

69
pyfpdb/HUD_main.pyw Normal file → Executable file
View File

@ -24,9 +24,6 @@
Main for FreePokerTools HUD.
"""
# TODO allow window resizing
# TODO hud to echo, but ignore non numbers
# TODO no stat window for hero
# TODO things to add to config.xml
# Standard Library modules
import sys
@ -39,26 +36,21 @@ import traceback
import thread
import time
import string
import re
# pyGTK modules
import pygtk
import gtk
import gobject
# FreePokerTools modules
import Configuration
import Database
from HandHistoryConverter import getTableTitleRe
import Hud
# get the correct module for the current os
if os.name == 'posix':
import XTables as Tables
elif os.name == 'nt':
import WinTables as Tables
#import Tables
import Hud
import locale
lang = locale.getdefaultlocale()[0][0:2]
@ -79,7 +71,6 @@ else:
c = Configuration.Config(file=options.config, dbname=options.dbname)
log = Configuration.get_logger("logging.conf", "hud", log_dir=c.dir_log, log_file='HUD-log.txt')
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.
@ -144,14 +135,13 @@ class HUD_main(object):
pass
def client_destroyed(self, widget, hud): # call back for terminating the main eventloop
self.kill_hud(None, hud.table.name)
self.kill_hud(None, hud.table.key)
def game_changed(self, widget, hud):
print _("hud_main: Game changed.")
def table_changed(self, widget, hud):
print _("hud_main: Table changed.")
self.kill_hud(None, hud.table.name)
self.kill_hud(None, hud.table.key)
def destroy(self, *args): # call back for terminating the main eventloop
log.info(_("Terminating normally."))
@ -159,12 +149,24 @@ class HUD_main(object):
def kill_hud(self, event, table):
# called by an event in the HUD, to kill this specific HUD
# This method can be called by either gui or non-gui thread. It doesn't
# cost much to always do it in a thread-safe manner.
def idle():
gtk.gdk.threads_enter()
try:
if table in self.hud_dict:
self.hud_dict[table].kill()
self.hud_dict[table].main_window.destroy()
self.vb.remove(self.hud_dict[table].tablehudlabel)
del(self.hud_dict[table])
self.main_window.resize(1, 1)
except:
pass
finally:
gtk.gdk.threads_leave()
gobject.idle_add(idle)
def check_tables(self):
for hud in self.hud_dict.keys():
@ -178,19 +180,18 @@ class HUD_main(object):
gtk.gdk.threads_enter()
try:
table.gdkhandle = gtk.gdk.window_foreign_new(table.number)
newlabel = gtk.Label("%s - %s" % (table.site, table_name))
self.vb.add(newlabel)
newlabel.show()
self.main_window.resize_children()
self.hud_dict[table_name].tablehudlabel = newlabel
self.hud_dict[table_name].create(new_hand_id, self.config, stat_dict, cards)
for m in self.hud_dict[table_name].aux_windows:
self.hud_dict[table.key].tablehudlabel = newlabel
self.hud_dict[table.key].create(new_hand_id, self.config, stat_dict, cards)
for m in self.hud_dict[table.key].aux_windows:
m.create()
m.update_gui(new_hand_id)
self.hud_dict[table_name].update(new_hand_id, self.config)
self.hud_dict[table_name].reposition_windows()
self.hud_dict[table.key].update(new_hand_id, self.config)
self.hud_dict[table.key].reposition_windows()
except:
log.error("*** Exception in HUD_main::idle_func() *** " + str(sys.exc_info()))
for e in traceback.format_tb(sys.exc_info()[2]):
@ -199,21 +200,22 @@ class HUD_main(object):
gtk.gdk.threads_leave()
return False
self.hud_dict[table_name] = Hud.Hud(self, table, max, poker_game, self.config, self.db_connection)
self.hud_dict[table_name].table_name = table_name
self.hud_dict[table_name].stat_dict = stat_dict
self.hud_dict[table_name].cards = cards
self.hud_dict[table.key] = Hud.Hud(self, table, max, poker_game, self.config, self.db_connection)
self.hud_dict[table.key].table_name = table_name
self.hud_dict[table.key].stat_dict = stat_dict
self.hud_dict[table.key].cards = cards
table.hud = self.hud_dict[table.key]
# set agg_bb_mult so that aggregate_tour and aggregate_ring can be ignored,
# agg_bb_mult == 1 means no aggregation after these if statements:
if type == "tour" and self.hud_params['aggregate_tour'] == False:
self.hud_dict[table_name].hud_params['agg_bb_mult'] = 1
self.hud_dict[table.key].hud_params['agg_bb_mult'] = 1
elif type == "ring" and self.hud_params['aggregate_ring'] == False:
self.hud_dict[table_name].hud_params['agg_bb_mult'] = 1
self.hud_dict[table.key].hud_params['agg_bb_mult'] = 1
if type == "tour" and self.hud_params['h_aggregate_tour'] == False:
self.hud_dict[table_name].hud_params['h_agg_bb_mult'] = 1
self.hud_dict[table.key].hud_params['h_agg_bb_mult'] = 1
elif type == "ring" and self.hud_params['h_aggregate_ring'] == False:
self.hud_dict[table_name].hud_params['h_agg_bb_mult'] = 1
self.hud_dict[table.key].hud_params['h_agg_bb_mult'] = 1
# sqlcoder: I forget why these are set to true (aren't they ignored from now on?)
# but I think it's needed:
self.hud_params['aggregate_ring'] = True
@ -222,7 +224,7 @@ class HUD_main(object):
self.hud_params['aggregate_tour'] = True
self.hud_params['h_aggregate_tour'] = True
[aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[table_name].aux_windows]
[aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[table.key].aux_windows]
gobject.idle_add(idle_func)
def update_HUD(self, new_hand_id, table_name, config):
@ -268,6 +270,8 @@ class HUD_main(object):
self.destroy()
break # this thread is not always killed immediately with gtk.main_quit()
# This block cannot be hoisted outside the while loop, because it would
# cause a problem when auto importing into an empty db.
if not found:
for site in self.config.get_supported_sites():
result = self.db_connection.get_site_id(site)
@ -355,9 +359,10 @@ class HUD_main(object):
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 type == "tour":
# tablewindow.check_table_no(None)
# # Ray!! tablewindow::check_table_no expects a HUD as an argument!
if type == "tour":
self.hud_dict[temp_key].table.check_table_no(self.hud_dict[temp_key])
if __name__== "__main__":
# start the HUD_main object

View File

@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Copyright 2010 Chaz Littlejohn
@ -28,18 +28,21 @@ import Configuration
import Database
__ARCHIVE_PRE_HEADER_REGEX='^Hand #(\d+)\s*$|\*{20}\s#\s\d+\s\*+\s+'
re_SplitArchive = re.compile(__ARCHIVE_PRE_HEADER_REGEX)
re_SplitArchive = re.compile(__ARCHIVE_PRE_HEADER_REGEX, re.MULTILINE)
class IdentifySite:
def __init__(self, config, in_path = '-'):
self.in_path = in_path
self.config = config
self.db = Database.Database(config)
self.db = Database.Database(self.config)
self.sitelist = {}
self.filelist = {}
self.generateSiteList()
if os.path.isdir(self.in_path):
self.walkDirectory(self.in_path, self.sitelist)
else:
self.idSite(self.in_path, self.sitelist)
def generateSiteList(self):
"""Generates a ordered dictionary of site, filter and filter name for each site in hhcs"""
@ -80,7 +83,7 @@ class IdentifySite:
for kodec in self.__listof(obj.codepage):
try:
in_fh = codecs.open(file, 'r', kodec)
whole_file = in_fh.read()
whole_file = in_fh.read(2000)
in_fh.close()
if info[2] in ('OnGame', 'Winamax'):
@ -94,7 +97,7 @@ class IdentifySite:
if re_SplitArchive.search(whole_file):
archive = True
if m:
self.filelist[file] = [info[0]] + [info[1]] + [kodec] + [archive]
self.filelist[file] = [info[1]] + [kodec] + [archive]
break
except:
pass

View File

@ -415,9 +415,12 @@ class Aux_Seats(Aux_Window):
# Methods likely to be of use for any Seat_Window implementation
def destroy(self):
"""Destroy all of the seat windows."""
try:
for i in self.m_windows.keys():
self.m_windows[i].destroy()
del(self.m_windows[i])
except AttributeError:
pass
# Methods likely to be useful for mucked card windows (or similar) only
def hide(self):

View File

@ -59,6 +59,8 @@ def fpdb_options():
help=_("File to be split is a PokerStars or Full Tilt Poker archive file"))
parser.add_option("-n", "--numhands", dest="hands", default="100", type="int",
help=_("How many hands do you want saved to each file. Default is 100"))
parser.add_option("-w", "--workerid", dest="workerid", default="0", type="int",
help=_("Specifies the worker id running the script"))
(options, argv) = parser.parse_args()

View File

@ -298,7 +298,7 @@ class PokerStars(HandHistoryConverter):
if key == 'BUTTON':
hand.buttonpos = info[key]
if key == 'MAX':
hand.maxseats = int(info[key])
if info[key]: hand.maxseats = int(info[key])
if key == 'MIXED':
hand.mixed = self.mixes[info[key]] if info[key] is not None else None

View File

@ -1064,7 +1064,7 @@ class Sql:
activeSeats SMALLINT NOT NULL,
position CHAR(1),
tourneyTypeId SMALLINT UNSIGNED, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
styleKey CHAR(7) NOT NULL, /* 1st char is style (A/T/H/S), other 6 are the key */
styleKey CHAR(9) NOT NULL, /* 1st char is style (A/T/H/S), other 8 are the key */
HDs INT NOT NULL,
wonWhenSeenStreet1 FLOAT,
@ -1165,7 +1165,7 @@ class Sql:
activeSeats SMALLINT,
position CHAR(1),
tourneyTypeId INT, FOREIGN KEY (tourneyTypeId) REFERENCES TourneyTypes(id),
styleKey CHAR(7) NOT NULL, /* 1st char is style (A/T/H/S), other 6 are the key */
styleKey CHAR(9) NOT NULL, /* 1st char is style (A/T/H/S), other 8 are the key */
HDs INT,
wonWhenSeenStreet1 FLOAT,
@ -2047,7 +2047,7 @@ class Sql:
# gets a date, would need to use handsplayers (not hudcache) to get exact hand Id
if db_server == 'mysql':
self.query['get_date_nhands_ago'] = """
select concat( 'd', date_format(max(h.startTime), '%Y%m%d') )
select concat( 'd', date_format(max(h.startTime), '%Y%m%d%H') )
from (select hp.playerId
,coalesce(greatest(max(hp.handId)-%s,1),1) as maxminusx
from HandsPlayers hp
@ -2059,7 +2059,7 @@ class Sql:
"""
elif db_server == 'postgresql':
self.query['get_date_nhands_ago'] = """
select 'd' || to_char(max(h3.startTime), 'YYMMDD')
select 'd' || to_char(max(h3.startTime), 'YYMMDDHH')
from (select hp.playerId
,coalesce(greatest(max(hp.handId)-%s,1),1) as maxminusx
from HandsPlayers hp
@ -2071,7 +2071,7 @@ class Sql:
"""
elif db_server == 'sqlite': # untested guess at query:
self.query['get_date_nhands_ago'] = """
select 'd' || strftime(max(h3.startTime), 'YYMMDD')
select 'd' || strftime(max(h3.startTime), 'YYMMDDHH')
from (select hp.playerId
,coalesce(greatest(max(hp.handId)-%s,1),1) as maxminusx
from HandsPlayers hp
@ -3290,7 +3290,7 @@ class Sql:
else 'E'
end AS hc_position
<tourney_select_clause>
,date_format(h.startTime, 'd%y%m%d')
,date_format(h.startTime, 'd%y%m%d%H')
,count(1)
,sum(wonWhenSeenStreet1)
,sum(wonWhenSeenStreet2)
@ -3379,7 +3379,7 @@ class Sql:
,h.seats
,hc_position
<tourney_group_clause>
,date_format(h.startTime, 'd%y%m%d')
,date_format(h.startTime, 'd%y%m%d%H')
"""
elif db_server == 'postgresql':
self.query['rebuildHudCache'] = """
@ -3488,7 +3488,7 @@ class Sql:
else 'E'
end AS hc_position
<tourney_select_clause>
,'d' || to_char(h.startTime, 'YYMMDD')
,'d' || to_char(h.startTime, 'YYMMDDHH')
,count(1)
,sum(wonWhenSeenStreet1)
,sum(wonWhenSeenStreet2)
@ -3577,7 +3577,7 @@ class Sql:
,h.seats
,hc_position
<tourney_group_clause>
,to_char(h.startTime, 'YYMMDD')
,to_char(h.startTime, 'YYMMDDHH')
"""
else: # assume sqlite
self.query['rebuildHudCache'] = """
@ -3686,7 +3686,7 @@ class Sql:
else 'E'
end AS hc_position
<tourney_select_clause>
,'d' || substr(strftime('%Y%m%d', h.startTime),3,7)
,'d' || substr(strftime('%Y%m%d%H', h.startTime),3,9)
,count(1)
,sum(wonWhenSeenStreet1)
,sum(wonWhenSeenStreet2)
@ -3775,7 +3775,7 @@ class Sql:
,h.seats
,hc_position
<tourney_group_clause>
,'d' || substr(strftime('%Y%m%d', h.startTime),3,7)
,'d' || substr(strftime('%Y%m%d%H', h.startTime),3,9)
"""
self.query['insert_hudcache'] = """

View File

@ -1,19 +1,22 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#!/usr/bin/env python
#Copyright 2010 Chaz Littlejohn
#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.
# Copyright 2010, Chaz Littlejohn
#
#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.
# 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.
#
#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.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
########################################################################
import L10n
_ = L10n.get_translation()
@ -28,6 +31,7 @@ import Options
import Configuration
from Exceptions import *
from cStringIO import StringIO
import time
(options, argv) = Options.fpdb_options()
@ -37,7 +41,7 @@ codepage = ["utf-16", "utf-8", "cp1252"]
class SplitHandHistory:
def __init__(self, config, in_path = '-', out_path = None, hands = 100, filter = "PokerStarsToFpdb", archive = False):
def __init__(self, config, in_path = '-', out_path = None, hands = 100, filter = "PokerStarsToFpdb", archive = False, workerid = 0):
self.config = config
self.in_path = in_path
self.out_path = out_path
@ -50,22 +54,25 @@ class SplitHandHistory:
self.line_addendum = None
self.filedone = False
self.timestamp = str(time.time())
self.workerid = '%02d' % workerid
#Acquire re_SplitHands for this hh
filter_name = filter.replace("ToFpdb", "")
self.filter_name = filter.replace("ToFpdb", "")
mod = __import__(filter)
obj = getattr(mod, filter_name, None)
obj = getattr(mod, self.filter_name, None)
self.re_SplitHands = obj.re_SplitHands
#Determine line delimiter type if any
if self.re_SplitHands.match('\n\n'):
self.line_delimiter = '\n\n'
if self.re_SplitHands.match('\n\n\n'):
self.line_delimiter = '\n\n\n'
if self.re_SplitHands.match('\n\n'):
self.line_delimiter = '\n\n'
#Add new line addendum for sites which match SplitHand to next line as well
if filter_name == 'OnGame':
if self.filter_name == 'OnGame':
self.line_addendum = '*'
if filter_name == 'Carbon':
if self.filter_name == 'Carbon':
self.line_addendum = '<game'
#Open the gargantuan file
@ -75,6 +82,7 @@ class SplitHandHistory:
except IOError:
print _('File not found')
sys.exit(2)
self.kodec = kodec
#Split with do_hands_per_file if archive and paragraphs if a regular hh
if self.archive:
@ -105,9 +113,10 @@ class SplitHandHistory:
print _('Nope, will not work (fileno=%d)' % fileno)
sys.exit(2)
basename = os.path.splitext(os.path.basename(self.in_path))[0]
name = os.path.join(self.out_path, basename+'-%06d.txt' % fileno)
name = os.path.join(self.out_path, self.filter_name+'-'+basename+'_'+self.workerid+'_'+self.timestamp+'_%06d.txt' % fileno)
print '-> %s' % name
newfile = file(name, 'w')
os.chmod(name, 0775)
return newfile
#Archive Hand Splitter
@ -122,8 +131,11 @@ class SplitHandHistory:
except FpdbEndOfFile:
done = True
break
except UnicodeEncodeError:
print _('Absurd character done messed you up')
sys.exit(2)
except:
print _("Unexpected error processing file")
print _('Unexpected error processing file')
sys.exit(2)
n += 1
outfile.close()
@ -174,7 +186,7 @@ class SplitHandHistory:
l = infile.readline()
l = l.replace('\r\n', '\n')
outfile.write(l)
l = infile.readline()
l = infile.readline().encode(self.kodec)
while len(l) < 3:
l = infile.readline()
@ -182,7 +194,7 @@ class SplitHandHistory:
while len(l) > 2:
l = l.replace('\r\n', '\n')
outfile.write(l)
l = infile.readline()
l = infile.readline().encode(self.kodec)
outfile.write(self.line_delimiter)
return infile
@ -196,12 +208,18 @@ def main(argv=None):
if argv is None:
argv = sys.argv[1:]
if not options.filename:
options.filename = sys.argv[1]
if not options.config:
options.config = Configuration.Config(file = "HUD_config.test.xml")
options.config = sys.argv[2]
if sys.argv[3] == "True":
options.archive = True
if options.filename:
SplitHH = SplitHandHistory(options.config, options.filename, options.outpath, options.hands,
options.hhc, options.archive)
options.hhc, options.archive, options.workerid)
if __name__ == '__main__':
sys.exit(main())

View File

@ -9,6 +9,7 @@
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
#TODO: gettextify
import sys, random
import pokereval

View File

@ -116,6 +116,7 @@ class Table_Window(object):
self.config = config
self.site = site
self.hud = None # fill in later
if tournament is not None and table_number is not None:
self.tournament = int(tournament)
self.table = int(table_number)
@ -123,11 +124,13 @@ class Table_Window(object):
self.type = "tour"
table_kwargs = dict(tournament = self.tournament, table_number = self.table)
self.tableno_re = getTableNoRe(self.config, self.site, tournament = self.tournament)
self.key = tournament # used as key for the hud_dict in HUD_main
elif table_name is not None:
self.name = table_name
self.type = "cash"
self.tournament = None
table_kwargs = dict(table_name = table_name)
self.key = table_name
else:
return None
@ -135,6 +138,7 @@ class Table_Window(object):
self.search_string = getTableTitleRe(self.config, self.site, self.type, **table_kwargs)
self.find_table_parameters()
self.gdkhandle = gtk.gdk.window_foreign_new(self.number)
geo = self.get_geometry()
if geo is None: return None
self.width = geo['width']
@ -150,7 +154,7 @@ class Table_Window(object):
# __str__ method for testing
likely_attrs = ("number", "title", "site", "width", "height", "x", "y",
"tournament", "table", "gdkhandle", "window", "parent",
"game", "search_string", "tableno_re")
"key", "hud", "game", "search_string", "tableno_re")
temp = 'TableWindow object\n'
for a in likely_attrs:
if getattr(self, a, 0):
@ -191,7 +195,7 @@ class Table_Window(object):
if mo is not None:
#print "get_table_no: mo=",mo.groups()
return mo.group(1)
return int(mo.group(1))
return False
####################################################################
@ -256,7 +260,7 @@ class Table_Window(object):
if result != False and result != self.table:
self.table = result
if hud is not None:
hud.main_window.emit("table_changed", hud)
hud.parent.main_window.emit("table_changed", hud)
return True
def check_bad_words(self, title):

View File

@ -201,6 +201,7 @@ def main(argv=None):
walk_testfiles("regression-test-files/cash/iPoker/", compare, importer, iPokerErrors, "iPoker")
if sites['Winamax'] == True:
walk_testfiles("regression-test-files/cash/Winamax/", compare, importer, WinamaxErrors, "Winamax")
walk_testfiles("regression-test-files/tour/Winamax/", compare, importer, WinamaxErrors, "Winamax")
if sites['Win2day'] == True:
walk_testfiles("regression-test-files/cash/Win2day/", compare, importer, Win2dayErrors, "Win2day")

View File

@ -82,15 +82,26 @@ class Winamax(HandHistoryConverter):
# Winamax Poker - CashGame - HandId: #279823-223-1285031451 - Holdem no limit (0.02€/0.05€) - 2010/09/21 03:10:51 UTC
# Table: 'Charenton-le-Pont' 9-max (real money) Seat #5 is the button
re_HandInfo = re.compile(u"""
\s*Winamax\sPoker\s-\sCashGame\s-\sHandId:\s\#(?P<HID1>\d+)-(?P<HID2>\d+)-(?P<HID3>\d+).*\s
\s*Winamax\sPoker\s-\s
(?P<RING>CashGame)?
(?P<TOUR>Tournament\s
(?P<TOURNAME>.+)?\s
buyIn:\s(?P<BUYIN>(?P<BIAMT>[%(LS)s\d\,]+)?\s\+?\s(?P<BIRAKE>[%(LS)s\d\,]+)?\+?(?P<BOUNTY>[%(LS)s\d\.]+)?\s?(?P<TOUR_ISO>%(LEGAL_ISO)s)?|Gratuit|Ticket\suniquement)?\s
(level:\s(?P<LEVEL>\d+))?
.*)?
\s-\sHandId:\s\#(?P<HID1>\d+)-(?P<HID2>\d+)-(?P<HID3>\d+).*\s
(?P<GAME>Holdem|Omaha)\s
(?P<LIMIT>no\slimit|pot\slimit)\s
\(
(((%(LS)s)?(?P<ANTE>[.0-9]+)(%(LS)s)?)/)?
((%(LS)s)?(?P<SB>[.0-9]+)(%(LS)s)?)/
((%(LS)s)?(?P<BB>[.0-9]+)(%(LS)s)?)
\)\s-\s
(?P<DATETIME>.*)
Table:\s\'(?P<TABLE>[^']+)\'\s(?P<MAXPLAYER>\d+)\-max
Table:\s\'(?P<TABLE>[^(]+)
(.(?P<TOURNO>\d+).\#(?P<TABLENO>\d+))?.*
\'
\s(?P<MAXPLAYER>\d+)\-max
""" % substitutions, re.MULTILINE|re.DOTALL|re.VERBOSE)
re_TailSplitHands = re.compile(r'\n\s*\n')
@ -126,8 +137,8 @@ class Winamax(HandHistoryConverter):
self.re_PostSB = re.compile('%(PLYR)s posts small blind (%(CUR)s)?(?P<SB>[\.0-9]+)(%(CUR)s)?' % subst, re.MULTILINE)
self.re_PostBB = re.compile('%(PLYR)s posts big blind (%(CUR)s)?(?P<BB>[\.0-9]+)(%(CUR)s)?' % subst, re.MULTILINE)
self.re_DenySB = re.compile('(?P<PNAME>.*) deny SB' % subst, re.MULTILINE)
self.re_Antes = re.compile(r"^%(PLYR)s: posts the ante (%(CUR)s)?(?P<ANTE>[\.0-9]+)(%(CUR)s)?" % subst, re.MULTILINE)
self.re_BringIn = re.compile(r"^%(PLYR)s: brings[- ]in( low|) for (%(CUR)s)?(?P<BRINGIN>[\.0-9]+(%(CUR)s)?)" % subst, re.MULTILINE)
self.re_Antes = re.compile(r"^%(PLYR)s posts ante (%(CUR)s)?(?P<ANTE>[\.0-9]+)(%(CUR)s)?" % subst, re.MULTILINE)
self.re_BringIn = re.compile(r"^%(PLYR)s brings[- ]in( low|) for (%(CUR)s)?(?P<BRINGIN>[\.0-9]+(%(CUR)s)?)" % subst, re.MULTILINE)
self.re_PostBoth = re.compile('(?P<PNAME>.*): posts small \& big blind \( (%(CUR)s)?(?P<SBBB>[\.0-9]+)(%(CUR)s)?\)' % subst)
self.re_PostDead = re.compile('(?P<PNAME>.*) posts dead blind \((%(CUR)s)?(?P<DEAD>[\.0-9]+)(%(CUR)s)?\)' % subst, re.MULTILINE)
self.re_HeroCards = re.compile('Dealt\sto\s%(PLYR)s\s\[(?P<CARDS>.*)\]' % subst)
@ -144,6 +155,9 @@ class Winamax(HandHistoryConverter):
["ring", "hold", "fl"],
["ring", "hold", "nl"],
["ring", "hold", "pl"],
["tour", "hold", "fl"],
["tour", "hold", "nl"],
["tour", "hold", "pl"],
]
def determineGameType(self, handText):
@ -160,7 +174,11 @@ class Winamax(HandHistoryConverter):
mg = m.groupdict()
if mg.get('TOUR'):
info['type'] = 'tour'
elif mg.get('RING'):
info['type'] = 'ring'
info['currency'] = 'EUR'
if 'LIMIT' in mg:
@ -202,11 +220,62 @@ class Winamax(HandHistoryConverter):
hand.startTime = datetime.datetime.strptime(datetimestr, "%Y/%m/%d %H:%M:%S") # also timezone at end, e.g. " ET"
hand.startTime = HandHistoryConverter.changeTimezone(hand.startTime, "CET", "UTC")
if key == 'HID1':
hand.handid = "1%.4d%s%s"%(int(info['HID2']),info['HID1'],info['HID3'])
# Need to remove non-alphanumerics for MySQL
hand.handid = "1%.9d%s%s"%(int(info['HID2']),info['HID1'],info['HID3'])
if key == 'TOURNO':
hand.tourNo = info[key]
if key == 'TABLE':
hand.tablename = info[key]
if key == 'BUYIN':
if hand.tourNo!=None:
#print "DEBUG: info['BUYIN']: %s" % info['BUYIN']
#print "DEBUG: info['BIAMT']: %s" % info['BIAMT']
#print "DEBUG: info['BIRAKE']: %s" % info['BIRAKE']
#print "DEBUG: info['BOUNTY']: %s" % info['BOUNTY']
for k in ['BIAMT','BIRAKE']:
if k in info.keys() and info[k]:
info[k] = info[k].replace(',','.')
if info[key] == 'Freeroll':
hand.buyin = 0
hand.fee = 0
hand.buyinCurrency = "FREE"
else:
if info[key].find("$")!=-1:
hand.buyinCurrency="USD"
elif info[key].find(u"")!=-1:
hand.buyinCurrency="EUR"
elif info[key].find("FPP")!=-1:
hand.buyinCurrency="PSFP"
else:
#FIXME: handle other currencies, FPP, play money
raise FpdbParseError(_("failed to detect currency"))
info['BIAMT'] = info['BIAMT'].strip(u'$€FPP')
if hand.buyinCurrency!="PSFP":
if info['BOUNTY'] != None:
# There is a bounty, Which means we need to switch BOUNTY and BIRAKE values
tmp = info['BOUNTY']
info['BOUNTY'] = info['BIRAKE']
info['BIRAKE'] = tmp
info['BOUNTY'] = info['BOUNTY'].strip(u'$€') # Strip here where it isn't 'None'
hand.koBounty = int(100*Decimal(info['BOUNTY']))
hand.isKO = True
else:
hand.isKO = False
info['BIRAKE'] = info['BIRAKE'].strip(u'$€')
hand.buyin = int(100*Decimal(info['BIAMT']))
hand.fee = int(100*Decimal(info['BIRAKE']))
else:
hand.buyin = int(Decimal(info['BIAMT']))
hand.fee = 0
if key == 'LEVEL':
hand.level = info[key]
# TODO: These
hand.buttonpos = 1
hand.maxseats = 10 # Set to None - Hand.py will guessMaxSeats()

View File

@ -44,6 +44,10 @@ class Table(Table_Window):
def find_table_parameters(self):
# This is called by __init__(). Find the poker table window of interest,
# given the self.search_string. Then populate self.number, self.title,
# self.window, and self.parent (if required).
reg = '''
\s+(?P<XID>[\dxabcdef]+) # XID in hex
\s(?P<TITLE>.+): # window title
@ -53,12 +57,10 @@ class Table(Table_Window):
for listing in os.popen('xwininfo -root -tree').readlines():
if re.search(self.search_string, listing, re.I):
mo = re.match(reg, listing, re.VERBOSE)
# mo = re.match('\s+([\dxabcdef]+) (.+):\s\(\"([a-zA-Z0-9\-.]+)\".+ (\d+)x(\d+)\+\d+\+\d+ \+(\d+)\+(\d+)', listing)
title = re.sub('\"', '', mo.groupdict()["TITLE"])
if self.check_bad_words(title): continue
self.number = int( mo.groupdict()["XID"], 0 )
self.title = title
self.hud = None # specified later
break
if self.number is None:

View File

@ -116,6 +116,7 @@ import GuiAutoImport
import GuiGraphViewer
import GuiTourneyGraphViewer
import GuiSessionViewer
import GuiStove
import SQL
import Database
import Configuration
@ -778,6 +779,7 @@ class fpdb:
<menuitem action="tourneyviewer"/>
<menuitem action="posnstats"/>
<menuitem action="sessionstats"/>
<menuitem action="stove"/>
</menu>
<menu action="database">
<menuitem action="maintaindbs"/>
@ -814,6 +816,7 @@ class fpdb:
('hudConfigurator', None, _('_HUD Configurator'), _('<control>H'), 'HUD Configurator', self.diaHudConfigurator),
('graphs', None, _('_Graphs'), _('<control>G'), 'Graphs', self.tabGraphViewer),
('tourneygraphs', None, _('Tourney Graphs'), None, 'TourneyGraphs', self.tabTourneyGraphViewer),
('stove', None, _('Stove'), None, 'Stove', self.tabStove),
('ringplayerstats', None, _('Ring _Player Stats (tabulated view, not on pgsql)'), _('<control>P'), 'Ring Player Stats (tabulated view, not on pgsql)', self.tab_ring_player_stats),
('tourneyplayerstats', None, _('_Tourney Stats (tabulated view, not on pgsql)'), _('<control>T'), 'Tourney Stats (tabulated view, not on pgsql)', self.tab_tourney_player_stats),
('tourneyviewer', None, _('Tourney _Viewer'), None, 'Tourney Viewer)', self.tab_tourney_viewer_stats),
@ -1000,7 +1003,7 @@ class fpdb:
self.add_and_display_tab(bulk_tab, _("Bulk Import"))
def tab_tourney_import(self, widget, data=None):
"""opens a tab for bulk importing"""
"""opens a tab for bulk importing tournament summaries"""
new_import_thread = GuiTourneyImport.GuiTourneyImport(self.settings, self.config, self.sql, self.window)
self.threads.append(new_import_thread)
bulk_tab=new_import_thread.get_vbox()
@ -1078,6 +1081,13 @@ You can find the full license texts in agpl-3.0.txt, gpl-2.0.txt, gpl-3.0.txt an
gv_tab = new_gv_thread.get_vbox()
self.add_and_display_tab(gv_tab, _("Tourney Graphs"))
def tabStove(self, widget, data=None):
"""opens a tab for bulk importing tournament summaries"""
thread = GuiStove.GuiStove(self.config, self.window)
self.threads.append(thread)
tab = thread.get_vbox()
self.add_and_display_tab(tab, _("Stove"))
def __init__(self):
# no more than 1 process can this lock at a time:
self.lock = interlocks.InterProcessLock(name="fpdb_global_lock")

2
pyfpdb/interlocks.py Executable file → Normal file
View File

@ -108,7 +108,7 @@ class InterProcessLockFcntl(InterProcessLockBase):
self.lockfd = 0
try:
os.unlink(self.lock_file_name)
except IOError:
except OSError:
# We don't care about the existence of the file too much here. It's the flock() we care about,
# And that should just go away magically.
pass

View File

@ -0,0 +1,42 @@
PokerStars Game #2428142447: Hold'em Limit ($1/$2 USD) - 2005/08/26 16:12:22 ET
Table 'Teucer II' Seat #5 is the button
Seat 1: Frankson34 ($24 in chips)
Seat 2: webb22 ($64 in chips)
Seat 3: eric_mtx ($26 in chips)
Seat 4: sososolid ($147.75 in chips)
Seat 5: DRILHER ($48.25 in chips)
Seat 6: Naughtychic ($60 in chips)
Seat 7: Terps78 ($71.50 in chips)
Seat 8: ChazDazzle ($69.25 in chips)
Seat 9: alekos ($55 in chips)
Seat 10: BigNards84 ($64.25 in chips)
Naughtychic: posts small blind $0.50
Terps78: posts big blind $1
*** HOLE CARDS ***
Dealt to ChazDazzle [8c Kd]
ChazDazzle: folds
alekos: folds
BigNards84: raises $1 to $2
Frankson34: folds
webb22: folds
eric_mtx: folds
ChazDazzle leaves the table
sososolid: folds
DRILHER: folds
cdhender joins the table at seat #8
Naughtychic: folds
Terps78: folds
BigNards84 collected $2.50 from pot
BigNards84: doesn't show hand
*** SUMMARY ***
Total pot $2.50 | Rake $0
Seat 1: Frankson34 folded before Flop (didn't bet)
Seat 2: webb22 folded before Flop (didn't bet)
Seat 3: eric_mtx folded before Flop (didn't bet)
Seat 4: sososolid folded before Flop (didn't bet)
Seat 5: DRILHER (button) folded before Flop (didn't bet)
Seat 6: Naughtychic (small blind) folded before Flop
Seat 7: Terps78 (big blind) folded before Flop
Seat 8: ChazDazzle folded before Flop (didn't bet)
Seat 9: alekos folded before Flop (didn't bet)
Seat 10: BigNards84 collected ($2.50)

View File

@ -0,0 +1,310 @@
Winamax Poker - Tournament "No Limit Hold'em" buyIn: 0,90€ + 0,10€ level: 0 - HandId: #7959970263859201-1-1288800933 - Holdem no limit (10/20) - 2010/11/03 17:15:33 UTC
Table: 'No Limit Hold'em(1853325)#0' 10-max (real money) Seat #3 is the button
Seat 1: Player6 (1500)
Seat 2: Player3 (1500)
Seat 3: Player9 (1500)
Seat 4: Player1 (1500)
Seat 5: Player0 (1500)
Seat 6: Player7 (1500)
Seat 7: Player4 (1500)
Seat 8: Player2 (1500)
Seat 9: Player5 (1500)
Seat 10: Player8 (1500)
*** ANTE/BLINDS ***
Player1 posts small blind 10
Player0 posts big blind 20
Dealt to Player6 [Jd 7h]
*** PRE-FLOP ***
Player7 folds
Player4 folds
Player2 folds
Player5 calls 20
Player8 folds
Player6 calls 20
Player3 calls 20
Player9 calls 20
Player1 calls 10
Player0 checks
*** FLOP *** [Td 4c 5h]
Player1 checks
Player0 checks
Player5 checks
Player6 bets 80
Player3 calls 80
Player9 folds
Player1 folds
Player0 calls 80
Player5 folds
*** TURN *** [Td 4c 5h][3h]
Player0 checks
Player6 checks
Player3 checks
*** RIVER *** [Td 4c 5h 3h][Kc]
Player0 checks
Player6 bets 240
Player3 calls 240
Player0 folds
*** SHOW DOWN ***
Player6 shows [Jd 7h] (High card : King)
Player3 shows [Kd 4d] (Two pairs : Kings and 4)
Player3 collected 840 from pot
*** SUMMARY ***
Total pot 840 | No rake
Board: [Td 4c 5h 3h Kc]
Seat 1: Player6 showed [Jd 7h] and lost with High card : King
Seat 2: Player3 showed [Kd 4d] and won 840 with Two pairs : Kings and 4
Seat 3: Player9 (button) folded on the flop
Seat 4: Player1 (small blind) folded on the flop
Seat 5: Player0 (big blind) folded on the river
Seat 6: Player7 folded on the pre-flop
Seat 7: Player4 folded
Seat 8: Player2 folded on the pre-flop
Seat 9: Player5 folded on the flop
Seat 10: Player8 folded on the pre-flop
Winamax Poker - Tournament "No Limit Hold'em" buyIn: 0,90€ + 0,10€ level: 0 - HandId: #7959970263859201-2-1288801071 - Holdem no limit (10/20) - 2010/11/03 17:17:51 UTC
Table: 'No Limit Hold'em(1853325)#0' 10-max (real money) Seat #4 is the button
Seat 1: Player6 (1160)
Seat 2: Player3 (2000)
Seat 3: Player9 (1480)
Seat 4: Player1 (1480)
Seat 5: Player0 (1400)
Seat 6: Player7 (1500)
Seat 7: Player4 (1500)
Seat 8: Player2 (1500)
Seat 9: Player5 (1480)
Seat 10: Player8 (1500)
*** ANTE/BLINDS ***
Player0 posts small blind 10
Player7 posts big blind 20
Dealt to Player6 [7h 3s]
*** PRE-FLOP ***
Player4 folds
Player2 folds
Player5 calls 20
Player8 calls 20
Player6 folds
Player3 calls 20
Player9 folds
Player1 calls 20
Player0 calls 10
Player7 checks
*** FLOP *** [Jh 6h Qd]
Player0 checks
Player7 bets 20
Player5 calls 20
Player8 calls 20
Player3 folds
Player1 calls 20
Player0 calls 20
*** TURN *** [Jh 6h Qd][5s]
Player0 checks
Player7 checks
Player5 bets 220
Player8 folds
Player1 folds
Player0 folds
Player7 calls 220
*** RIVER *** [Jh 6h Qd 5s][3c]
Player7 checks
Player5 bets 660
Player7 folds
Player5 collected 1320 from pot
*** SUMMARY ***
Total pot 1.32k | No rake
Board: [Jh 6h Qd 5s 3c]
Seat 1: Player6 folded on the pre-flop
Seat 2: Player3 folded on the flop
Seat 3: Player9 folded on the pre-flop
Seat 4: Player1 (button) folded on the turn
Seat 5: Player0 (small blind) folded on the turn
Seat 6: Player7 (big blind) folded on the river
Seat 7: Player4 folded on the pre-flop
Seat 8: Player2 folded on the pre-flop
Seat 9: Player5 won 1320
Seat 10: Player8 folded on the turn
Winamax Poker - Tournament "No Limit Hold'em" buyIn: 0,90€ + 0,10€ level: 0 - HandId: #7959970263859201-3-1288801160 - Holdem no limit (10/20) - 2010/11/03 17:19:20 UTC
Table: 'No Limit Hold'em(1853325)#0' 10-max (real money) Seat #5 is the button
Seat 1: Player6 (1160)
Seat 2: Player3 (1980)
Seat 3: Player9 (1480)
Seat 4: Player1 (1440)
Seat 5: Player0 (1360)
Seat 6: Player7 (1240)
Seat 7: Player4 (1500)
Seat 8: Player2 (1500)
Seat 9: Player5 (1880)
Seat 10: Player8 (1460)
*** ANTE/BLINDS ***
Player7 posts small blind 10
Player4 posts big blind 20
Dealt to Player6 [4h 3d]
*** PRE-FLOP ***
Player2 folds
Player5 calls 20
Player8 calls 20
Player6 folds
Player3 folds
Player9 folds
Player1 calls 20
Player0 folds
Player7 raises 20 to 40
Player4 folds
Player5 calls 20
Player8 calls 20
Player1 calls 20
*** FLOP *** [Qd Kh 4s]
Player7 bets 1200 and is all-in
Player5 folds
Player8 folds
Player1 folds
Player7 collected 1380 from pot
*** SUMMARY ***
Total pot 1.38k | No rake
Board: [Qd Kh 4s]
Seat 1: Player6 folded on the pre-flop
Seat 2: Player3 folded on the pre-flop
Seat 3: Player9 folded on the pre-flop
Seat 4: Player1 folded on the flop
Seat 5: Player0 (button) folded on the pre-flop
Seat 6: Player7 (small blind) won 1380
Seat 7: Player4 (big blind) folded on the pre-flop
Seat 8: Player2 folded on the pre-flop
Seat 9: Player5 folded on the flop
Seat 10: Player8 folded on the flop
Winamax Poker - Tournament "No Limit Hold'em" buyIn: 0,90€ + 0,10€ level: 0 - HandId: #7959970263859201-4-1288801277 - Holdem no limit (10/20) - 2010/11/03 17:21:17 UTC
Table: 'No Limit Hold'em(1853325)#0' 10-max (real money) Seat #6 is the button
Seat 1: Player6 (1160)
Seat 2: Player3 (1980)
Seat 3: Player9 (1480)
Seat 4: Player1 (1400)
Seat 5: Player0 (1360)
Seat 6: Player7 (1380)
Seat 7: Player4 (1480)
Seat 8: Player2 (1500)
Seat 9: Player5 (1840)
Seat 10: Player8 (1420)
*** ANTE/BLINDS ***
Player4 posts small blind 10
Player2 posts big blind 20
Dealt to Player6 [Qc 7d]
*** PRE-FLOP ***
Player5 calls 20
Player8 folds
Player6 folds
Player3 folds
Player9 folds
Player1 calls 20
Player0 folds
Player7 calls 20
Player4 calls 10
Player2 checks
*** FLOP *** [9s 7h 5h]
Player4 checks
Player2 checks
Player5 checks
Player1 checks
Player7 checks
*** TURN *** [9s 7h 5h][Ts]
Player4 checks
Player2 checks
Player5 checks
Player1 checks
Player7 bets 20
Player4 calls 20
Player2 folds
Player5 folds
Player1 calls 20
*** RIVER *** [9s 7h 5h Ts][7s]
Player4 checks
Player1 checks
Player7 bets 160
Player4 folds
Player1 calls 160
*** SHOW DOWN ***
Player1 shows [4c 4d] (Two pairs : 7 and 4)
Player7 shows [4s As] (Flush Ace high)
Player7 collected 480 from pot
*** SUMMARY ***
Total pot 480 | No rake
Board: [9s 7h 5h Ts 7s]
Seat 1: Player6 folded on the pre-flop
Seat 2: Player3 folded on the pre-flop
Seat 3: Player9 folded on the pre-flop
Seat 4: Player1 showed [4c 4d] and lost with Two pairs : 7 and 4
Seat 5: Player0 folded on the pre-flop
Seat 6: Player7 (button) showed [4s As] and won 480 with Flush Ace high
Seat 7: Player4 (small blind) folded on the river
Seat 8: Player2 (big blind) folded on the turn
Seat 9: Player5 folded on the turn
Seat 10: Player8 folded on the pre-flop
Winamax Poker - Tournament "No Limit Hold'em" buyIn: 0,90€ + 0,10€ level: 1 - HandId: #7959970263859201-5-1288801360 - Holdem no limit (10/20) - 2010/11/03 17:22:40 UTC
Table: 'No Limit Hold'em(1853325)#0' 10-max (real money) Seat #7 is the button
Seat 1: Player6 (1160)
Seat 2: Player3 (1980)
Seat 3: Player9 (1480)
Seat 4: Player1 (1200)
Seat 5: Player0 (1360)
Seat 6: Player7 (1660)
Seat 7: Player4 (1440)
Seat 8: Player2 (1480)
Seat 9: Player5 (1820)
Seat 10: Player8 (1420)
*** ANTE/BLINDS ***
Player2 posts small blind 10
Player5 posts big blind 20
Dealt to Player6 [Kd Ah]
*** PRE-FLOP ***
Player8 calls 20
Player6 raises 70 to 90
Player3 folds
Player9 calls 90
Player1 calls 90
Player0 calls 90
Player7 calls 90
Player4 calls 90
Player2 folds
Player5 calls 70
Player8 calls 70
*** FLOP *** [2s 5h 3h]
Player5 checks
Player8 checks
Player6 bets 365
Player9 folds
Player1 folds
Player0 folds
Player7 calls 365
Player4 folds
Player5 folds
Player8 folds
*** TURN *** [2s 5h 3h][6d]
Player6 bets 705 and is all-in
Player7 calls 705
*** RIVER *** [2s 5h 3h 6d][5s]
*** SHOW DOWN ***
Player6 shows [Kd Ah] (One pair : 5)
Player7 shows [7d 7h] (Two pairs : 7 and 5)
Player7 collected 2870 from pot
*** SUMMARY ***
Total pot 2.87k | No rake
Board: [2s 5h 3h 6d 5s]
Seat 1: Player6 showed [Kd Ah] and lost with One pair : 5
Seat 2: Player3 folded on the pre-flop
Seat 3: Player9 folded on the flop
Seat 4: Player1 folded on the flop
Seat 5: Player0 folded on the flop
Seat 6: Player7 showed [7d 7h] and won 2870 with Two pairs : 7 and 5
Seat 7: Player4 (button) folded on the flop
Seat 8: Player2 (small blind) folded on the pre-flop
Seat 9: Player5 (big blind) folded on the flop
Seat 10: Player8 folded on the flop