Merge branch 'master' of git://git.assembla.com/fpdboz
This commit is contained in:
commit
45eccb0697
|
@ -10,7 +10,8 @@ Architecture: all
|
||||||
Section: games
|
Section: games
|
||||||
Priority: extra
|
Priority: extra
|
||||||
Depends: ${python:Depends}, python-gtk2, python-matplotlib,
|
Depends: ${python:Depends}, python-gtk2, python-matplotlib,
|
||||||
python-support, mysql-server | postgresql | python-pysqlite2,
|
python-support, python-xlib,
|
||||||
|
mysql-server | postgresql | python-pysqlite2,
|
||||||
python-psycopg2 | python-mysqldb
|
python-psycopg2 | python-mysqldb
|
||||||
Suggests: wine
|
Suggests: wine
|
||||||
Description: free poker database with HUD
|
Description: free poker database with HUD
|
||||||
|
|
|
@ -26,7 +26,7 @@ except:
|
||||||
diaSQLLibMissing = gtk.Dialog(title="Fatal Error - SQL interface library missing", parent=None, flags=0, buttons=(gtk.STOCK_QUIT,gtk.RESPONSE_OK))
|
diaSQLLibMissing = gtk.Dialog(title="Fatal Error - SQL interface library missing", parent=None, flags=0, buttons=(gtk.STOCK_QUIT,gtk.RESPONSE_OK))
|
||||||
|
|
||||||
print "Please note that the CLI importer only works with MySQL, if you use PostgreSQL this error is expected."
|
print "Please note that the CLI importer only works with MySQL, if you use PostgreSQL this error is expected."
|
||||||
|
|
||||||
import fpdb_import
|
import fpdb_import
|
||||||
import fpdb_db
|
import fpdb_db
|
||||||
|
|
||||||
|
@ -36,9 +36,9 @@ if __name__ == "__main__":
|
||||||
parser.add_option("-c", "--handCount", default="0", type="int",
|
parser.add_option("-c", "--handCount", default="0", type="int",
|
||||||
help="Number of hands to import (default 0 means unlimited)")
|
help="Number of hands to import (default 0 means unlimited)")
|
||||||
parser.add_option("-d", "--database", default="fpdb", help="The MySQL database to use (default fpdb)")
|
parser.add_option("-d", "--database", default="fpdb", help="The MySQL database to use (default fpdb)")
|
||||||
parser.add_option("-e", "--errorFile", default="failed.txt",
|
parser.add_option("-e", "--errorFile", default="failed.txt",
|
||||||
help="File to store failed hands into. (default: failed.txt) Not implemented.")
|
help="File to store failed hands into. (default: failed.txt) Not implemented.")
|
||||||
parser.add_option("-f", "--inputFile", "--file", "--inputfile", default="stdin",
|
parser.add_option("-f", "--inputFile", "--file", "--inputfile", default="stdin",
|
||||||
help="The file you want to import (remember to use quotes if necessary)")
|
help="The file you want to import (remember to use quotes if necessary)")
|
||||||
parser.add_option("-m", "--minPrint", "--status", default="50", type="int",
|
parser.add_option("-m", "--minPrint", "--status", default="50", type="int",
|
||||||
help="How often to print a one-line status report (0 means never, default is 50)")
|
help="How often to print a one-line status report (0 means never, default is 50)")
|
||||||
|
@ -51,8 +51,8 @@ if __name__ == "__main__":
|
||||||
parser.add_option("-x", "--failOnError", action="store_true",
|
parser.add_option("-x", "--failOnError", action="store_true",
|
||||||
help="If this option is passed it quits when it encounters any error")
|
help="If this option is passed it quits when it encounters any error")
|
||||||
|
|
||||||
(options, sys.argv) = parser.parse_args()
|
(options, argv) = parser.parse_args()
|
||||||
|
|
||||||
settings={'callFpdbHud':False, 'db-backend':2}
|
settings={'callFpdbHud':False, 'db-backend':2}
|
||||||
settings['db-host']=options.server
|
settings['db-host']=options.server
|
||||||
settings['db-user']=options.user
|
settings['db-user']=options.user
|
||||||
|
|
|
@ -6,17 +6,17 @@ Handles HUD configuration files.
|
||||||
"""
|
"""
|
||||||
# Copyright 2008, 2009, Ray E. Barker
|
# Copyright 2008, 2009, Ray E. Barker
|
||||||
|
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
@ -37,32 +37,117 @@ from xml.dom.minidom import Node
|
||||||
import logging, logging.config
|
import logging, logging.config
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
|
|
||||||
try: # local path
|
##############################################################################
|
||||||
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf"))
|
# Functions for finding config files and setting up logging
|
||||||
except ConfigParser.NoSectionError: # debian package path
|
# Also used in other modules that use logging.
|
||||||
logging.config.fileConfig('/usr/share/python-fpdb/logging.conf')
|
|
||||||
|
|
||||||
log = logging.getLogger("config")
|
def get_default_config_path():
|
||||||
log.debug("config logger initialised")
|
"""Returns the path where the fpdb config file _should_ be stored."""
|
||||||
|
if os.name == 'posix':
|
||||||
|
config_path = os.path.join(os.path.expanduser("~"), '.fpdb')
|
||||||
|
elif os.name == 'nt':
|
||||||
|
config_path = os.path.join(os.environ["APPDATA"], 'fpdb')
|
||||||
|
else: config_path = False
|
||||||
|
return config_path
|
||||||
|
|
||||||
def fix_tf(x, default = True):
|
def get_exec_path():
|
||||||
# The xml parser doesn't translate "True" to True. Therefore, we never get
|
"""Returns the path to the fpdb.(py|exe) file we are executing"""
|
||||||
# True or False from the parser only "True" or "False". So translate the
|
if hasattr(sys, "frozen"): # compiled by py2exe
|
||||||
# string to the python boolean representation.
|
return os.path.dirname(sys.executable)
|
||||||
if x == "1" or x == 1 or string.lower(x) == "true" or string.lower(x) == "t":
|
else:
|
||||||
|
pathname = os.path.dirname(sys.argv[0])
|
||||||
|
return os.path.abspath(pathname)
|
||||||
|
|
||||||
|
def get_config(file_name, fallback = True):
|
||||||
|
"""Looks in cwd and in self.default_config_path for a config file."""
|
||||||
|
config_path = os.path.join(get_exec_path(), file_name)
|
||||||
|
# print "config_path=", config_path
|
||||||
|
if os.path.exists(config_path): # there is a file in the cwd
|
||||||
|
return config_path # so we use it
|
||||||
|
else: # no file in the cwd, look where it should be in the first place
|
||||||
|
config_path = os.path.join(get_default_config_path(), file_name)
|
||||||
|
# print "config path 2=", config_path
|
||||||
|
if os.path.exists(config_path):
|
||||||
|
return config_path
|
||||||
|
|
||||||
|
# No file found
|
||||||
|
if not fallback:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# OK, fall back to the .example file, should be in the start dir
|
||||||
|
if os.path.exists(file_name + ".example"):
|
||||||
|
try:
|
||||||
|
shutil.copyfile(file_name + ".example", file_name)
|
||||||
|
print "No %s found, using %s.example.\n" % (file_name, file_name)
|
||||||
|
print "A %s file has been created. You will probably have to edit it." % file_name
|
||||||
|
sys.stderr.write("No %s found, using %s.example.\n" % (file_name, file_name) )
|
||||||
|
except:
|
||||||
|
print "No %s found, cannot fall back. Exiting.\n" % file_name
|
||||||
|
sys.stderr.write("No %s found, cannot fall back. Exiting.\n" % file_name)
|
||||||
|
sys.exit()
|
||||||
|
return file_name
|
||||||
|
|
||||||
|
def get_logger(file_name, config = "config", fallback = False):
|
||||||
|
conf = get_config(file_name, fallback = fallback)
|
||||||
|
if conf:
|
||||||
|
try:
|
||||||
|
logging.config.fileConfig(conf)
|
||||||
|
log = logging.getLogger(config)
|
||||||
|
log.debug("%s logger initialised" % config)
|
||||||
|
return log
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
log = logging.basicConfig()
|
||||||
|
log = logging.getLogger()
|
||||||
|
log.debug("config logger initialised")
|
||||||
|
return log
|
||||||
|
|
||||||
|
# find a logging.conf file and set up logging
|
||||||
|
log = get_logger("logging.conf")
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# application wide consts
|
||||||
|
|
||||||
|
APPLICATION_NAME_SHORT = 'fpdb'
|
||||||
|
APPLICATION_VERSION = 'xx.xx.xx'
|
||||||
|
|
||||||
|
DIR_SELF = os.path.dirname(get_exec_path())
|
||||||
|
#TODO: imo no good idea to place 'database' in parent dir
|
||||||
|
DIR_DATABASES = os.path.join(os.path.dirname(DIR_SELF), 'database')
|
||||||
|
|
||||||
|
DATABASE_TYPE_POSTGRESQL = 'postgresql'
|
||||||
|
DATABASE_TYPE_SQLITE = 'sqlite'
|
||||||
|
DATABASE_TYPE_MYSQL = 'mysql'
|
||||||
|
DATABASE_TYPES = (
|
||||||
|
DATABASE_TYPE_POSTGRESQL,
|
||||||
|
DATABASE_TYPE_SQLITE,
|
||||||
|
DATABASE_TYPE_MYSQL,
|
||||||
|
)
|
||||||
|
|
||||||
|
NEWIMPORT = False
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
def string_to_bool(string, default=True):
|
||||||
|
"""converts a string representation of a boolean value to boolean True or False
|
||||||
|
@param string: (str) the string to convert
|
||||||
|
@param default: value to return if the string can not be converted to a boolean value
|
||||||
|
"""
|
||||||
|
string = string.lower()
|
||||||
|
if string in ('1', 'true', 't'):
|
||||||
return True
|
return True
|
||||||
if x == "0" or x == 0 or string.lower(x) == "false" or string.lower(x) == "f":
|
elif string in ('0', 'false', 'f'):
|
||||||
return False
|
return False
|
||||||
return default
|
return default
|
||||||
|
|
||||||
class Layout:
|
class Layout:
|
||||||
def __init__(self, node):
|
def __init__(self, node):
|
||||||
|
|
||||||
self.max = int( node.getAttribute('max') )
|
self.max = int( node.getAttribute('max') )
|
||||||
if node.hasAttribute('fav_seat'): self.fav_seat = int( node.getAttribute('fav_seat') )
|
if node.hasAttribute('fav_seat'): self.fav_seat = int( node.getAttribute('fav_seat') )
|
||||||
self.width = int( node.getAttribute('width') )
|
self.width = int( node.getAttribute('width') )
|
||||||
self.height = int( node.getAttribute('height') )
|
self.height = int( node.getAttribute('height') )
|
||||||
|
|
||||||
self.location = []
|
self.location = []
|
||||||
self.location = map(lambda x: None, range(self.max+1)) # fill array with max seats+1 empty entries
|
self.location = map(lambda x: None, range(self.max+1)) # fill array with max seats+1 empty entries
|
||||||
|
|
||||||
|
@ -81,7 +166,7 @@ class Layout:
|
||||||
temp = temp + " Locations = "
|
temp = temp + " Locations = "
|
||||||
for i in range(1, len(self.location)):
|
for i in range(1, len(self.location)):
|
||||||
temp = temp + "(%d,%d)" % self.location[i]
|
temp = temp + "(%d,%d)" % self.location[i]
|
||||||
|
|
||||||
return temp + "\n"
|
return temp + "\n"
|
||||||
|
|
||||||
class Site:
|
class Site:
|
||||||
|
@ -91,27 +176,27 @@ class Site:
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
return os.path.abspath(path)
|
return os.path.abspath(path)
|
||||||
return path
|
return path
|
||||||
|
|
||||||
self.site_name = node.getAttribute("site_name")
|
self.site_name = node.getAttribute("site_name")
|
||||||
self.table_finder = node.getAttribute("table_finder")
|
self.table_finder = node.getAttribute("table_finder")
|
||||||
self.screen_name = node.getAttribute("screen_name")
|
self.screen_name = node.getAttribute("screen_name")
|
||||||
self.site_path = normalizePath(node.getAttribute("site_path"))
|
self.site_path = normalizePath(node.getAttribute("site_path"))
|
||||||
self.HH_path = normalizePath(node.getAttribute("HH_path"))
|
self.HH_path = normalizePath(node.getAttribute("HH_path"))
|
||||||
self.decoder = node.getAttribute("decoder")
|
self.decoder = node.getAttribute("decoder")
|
||||||
self.hudopacity = node.getAttribute("hudopacity")
|
self.hudopacity = node.getAttribute("hudopacity")
|
||||||
self.hudbgcolor = node.getAttribute("bgcolor")
|
self.hudbgcolor = node.getAttribute("bgcolor")
|
||||||
self.hudfgcolor = node.getAttribute("fgcolor")
|
self.hudfgcolor = node.getAttribute("fgcolor")
|
||||||
self.converter = node.getAttribute("converter")
|
self.converter = node.getAttribute("converter")
|
||||||
self.aux_window = node.getAttribute("aux_window")
|
self.aux_window = node.getAttribute("aux_window")
|
||||||
self.font = node.getAttribute("font")
|
self.font = node.getAttribute("font")
|
||||||
self.font_size = node.getAttribute("font_size")
|
self.font_size = node.getAttribute("font_size")
|
||||||
self.use_frames = node.getAttribute("use_frames")
|
self.use_frames = node.getAttribute("use_frames")
|
||||||
self.enabled = fix_tf(node.getAttribute("enabled"), default = True)
|
self.enabled = string_to_bool(node.getAttribute("enabled"), default=True)
|
||||||
self.xpad = node.getAttribute("xpad")
|
self.xpad = node.getAttribute("xpad")
|
||||||
self.ypad = node.getAttribute("ypad")
|
self.ypad = node.getAttribute("ypad")
|
||||||
self.layout = {}
|
self.layout = {}
|
||||||
|
|
||||||
print "Loading site", self.site_name
|
print "Loading site", self.site_name
|
||||||
|
|
||||||
for layout_node in node.getElementsByTagName('layout'):
|
for layout_node in node.getElementsByTagName('layout'):
|
||||||
lo = Layout(layout_node)
|
lo = Layout(layout_node)
|
||||||
|
@ -124,7 +209,7 @@ class Site:
|
||||||
self.hudopacity = 1.0 if self.hudopacity == "" else float(self.hudopacity)
|
self.hudopacity = 1.0 if self.hudopacity == "" else float(self.hudopacity)
|
||||||
|
|
||||||
if self.use_frames == "": self.use_frames = False
|
if self.use_frames == "": self.use_frames = False
|
||||||
if self.font == "": self.font = "Sans"
|
if self.font == "": self.font = "Sans"
|
||||||
if self.hudbgcolor == "": self.hudbgcolor = "#000000"
|
if self.hudbgcolor == "": self.hudbgcolor = "#000000"
|
||||||
if self.hudfgcolor == "": self.hudfgcolor = "#FFFFFF"
|
if self.hudfgcolor == "": self.hudfgcolor = "#FFFFFF"
|
||||||
|
|
||||||
|
@ -136,27 +221,27 @@ class Site:
|
||||||
value = getattr(self, key)
|
value = getattr(self, key)
|
||||||
if callable(value): continue
|
if callable(value): continue
|
||||||
temp = temp + ' ' + key + " = " + str(value) + "\n"
|
temp = temp + ' ' + key + " = " + str(value) + "\n"
|
||||||
|
|
||||||
for layout in self.layout:
|
for layout in self.layout:
|
||||||
temp = temp + "%s" % self.layout[layout]
|
temp = temp + "%s" % self.layout[layout]
|
||||||
|
|
||||||
return temp
|
return temp
|
||||||
|
|
||||||
class Stat:
|
class Stat:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
temp = " stat_name = %s, row = %d, col = %d, tip = %s, click = %s, popup = %s\n" % (self.stat_name, self.row, self.col, self.tip, self.click, self.popup)
|
temp = " stat_name = %s, row = %d, col = %d, tip = %s, click = %s, popup = %s\n" % (self.stat_name, self.row, self.col, self.tip, self.click, self.popup)
|
||||||
return temp
|
return temp
|
||||||
|
|
||||||
class Game:
|
class Game:
|
||||||
def __init__(self, node):
|
def __init__(self, node):
|
||||||
self.game_name = node.getAttribute("game_name")
|
self.game_name = node.getAttribute("game_name")
|
||||||
self.rows = int( node.getAttribute("rows") )
|
self.rows = int( node.getAttribute("rows") )
|
||||||
self.cols = int( node.getAttribute("cols") )
|
self.cols = int( node.getAttribute("cols") )
|
||||||
self.xpad = node.getAttribute("xpad")
|
self.xpad = node.getAttribute("xpad")
|
||||||
self.ypad = node.getAttribute("ypad")
|
self.ypad = node.getAttribute("ypad")
|
||||||
|
|
||||||
# Defaults
|
# Defaults
|
||||||
if self.xpad == "": self.xpad = 1
|
if self.xpad == "": self.xpad = 1
|
||||||
|
@ -170,21 +255,21 @@ class Game:
|
||||||
aux_list[i] = aux_list[i].strip()
|
aux_list[i] = aux_list[i].strip()
|
||||||
self.aux = aux_list
|
self.aux = aux_list
|
||||||
|
|
||||||
self.stats = {}
|
self.stats = {}
|
||||||
for stat_node in node.getElementsByTagName('stat'):
|
for stat_node in node.getElementsByTagName('stat'):
|
||||||
stat = Stat()
|
stat = Stat()
|
||||||
stat.stat_name = stat_node.getAttribute("stat_name")
|
stat.stat_name = stat_node.getAttribute("stat_name")
|
||||||
stat.row = int( stat_node.getAttribute("row") )
|
stat.row = int( stat_node.getAttribute("row") )
|
||||||
stat.col = int( stat_node.getAttribute("col") )
|
stat.col = int( stat_node.getAttribute("col") )
|
||||||
stat.tip = stat_node.getAttribute("tip")
|
stat.tip = stat_node.getAttribute("tip")
|
||||||
stat.click = stat_node.getAttribute("click")
|
stat.click = stat_node.getAttribute("click")
|
||||||
stat.popup = stat_node.getAttribute("popup")
|
stat.popup = stat_node.getAttribute("popup")
|
||||||
stat.hudprefix = stat_node.getAttribute("hudprefix")
|
stat.hudprefix = stat_node.getAttribute("hudprefix")
|
||||||
stat.hudsuffix = stat_node.getAttribute("hudsuffix")
|
stat.hudsuffix = stat_node.getAttribute("hudsuffix")
|
||||||
stat.hudcolor = stat_node.getAttribute("hudcolor")
|
stat.hudcolor = stat_node.getAttribute("hudcolor")
|
||||||
|
|
||||||
self.stats[stat.stat_name] = stat
|
self.stats[stat.stat_name] = stat
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
temp = "Game = " + self.game_name + "\n"
|
temp = "Game = " + self.game_name + "\n"
|
||||||
temp = temp + " rows = %d\n" % self.rows
|
temp = temp + " rows = %d\n" % self.rows
|
||||||
|
@ -192,24 +277,23 @@ class Game:
|
||||||
temp = temp + " xpad = %d\n" % self.xpad
|
temp = temp + " xpad = %d\n" % self.xpad
|
||||||
temp = temp + " ypad = %d\n" % self.ypad
|
temp = temp + " ypad = %d\n" % self.ypad
|
||||||
temp = temp + " aux = %s\n" % self.aux
|
temp = temp + " aux = %s\n" % self.aux
|
||||||
|
|
||||||
for stat in self.stats.keys():
|
for stat in self.stats.keys():
|
||||||
temp = temp + "%s" % self.stats[stat]
|
temp = temp + "%s" % self.stats[stat]
|
||||||
|
|
||||||
return temp
|
return temp
|
||||||
|
|
||||||
class Database:
|
class Database:
|
||||||
def __init__(self, node):
|
def __init__(self, node):
|
||||||
self.db_name = node.getAttribute("db_name")
|
self.db_name = node.getAttribute("db_name")
|
||||||
self.db_server = node.getAttribute("db_server")
|
self.db_server = node.getAttribute("db_server").lower()
|
||||||
self.db_ip = node.getAttribute("db_ip")
|
self.db_ip = node.getAttribute("db_ip")
|
||||||
self.db_user = node.getAttribute("db_user")
|
self.db_user = node.getAttribute("db_user")
|
||||||
self.db_type = node.getAttribute("db_type")
|
|
||||||
self.db_pass = node.getAttribute("db_pass")
|
self.db_pass = node.getAttribute("db_pass")
|
||||||
self.db_selected = fix_tf(node.getAttribute("default"),"False")
|
self.db_selected = string_to_bool(node.getAttribute("default"), default=False)
|
||||||
log.debug("Database db_name:'%(name)s' db_server:'%(server)s' db_ip:'%(ip)s' db_user:'%(user)s' db_type:'%(type)s' db_pass (not logged) selected:'%(sel)s'" \
|
log.debug("Database db_name:'%(name)s' db_server:'%(server)s' db_ip:'%(ip)s' db_user:'%(user)s' db_pass (not logged) selected:'%(sel)s'" \
|
||||||
% { 'name':self.db_name, 'server':self.db_server, 'ip':self.db_ip, 'user':self.db_user, 'type':self.db_type, 'sel':self.db_selected} )
|
% { 'name':self.db_name, 'server':self.db_server, 'ip':self.db_ip, 'user':self.db_user, 'sel':self.db_selected} )
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
temp = 'Database = ' + self.db_name + '\n'
|
temp = 'Database = ' + self.db_name + '\n'
|
||||||
for key in dir(self):
|
for key in dir(self):
|
||||||
|
@ -244,7 +328,7 @@ class Aux_window:
|
||||||
|
|
||||||
class HHC:
|
class HHC:
|
||||||
def __init__(self, node):
|
def __init__(self, node):
|
||||||
self.site = node.getAttribute("site")
|
self.site = node.getAttribute("site")
|
||||||
self.converter = node.getAttribute("converter")
|
self.converter = node.getAttribute("converter")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -254,10 +338,10 @@ class HHC:
|
||||||
class Popup:
|
class Popup:
|
||||||
def __init__(self, node):
|
def __init__(self, node):
|
||||||
self.name = node.getAttribute("pu_name")
|
self.name = node.getAttribute("pu_name")
|
||||||
self.pu_stats = []
|
self.pu_stats = []
|
||||||
for stat_node in node.getElementsByTagName('pu_stat'):
|
for stat_node in node.getElementsByTagName('pu_stat'):
|
||||||
self.pu_stats.append(stat_node.getAttribute("pu_stat_name"))
|
self.pu_stats.append(stat_node.getAttribute("pu_stat_name"))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
temp = "Popup = " + self.name + "\n"
|
temp = "Popup = " + self.name + "\n"
|
||||||
for stat in self.pu_stats:
|
for stat in self.pu_stats:
|
||||||
|
@ -267,32 +351,32 @@ class Popup:
|
||||||
class Import:
|
class Import:
|
||||||
def __init__(self, node):
|
def __init__(self, node):
|
||||||
self.node = node
|
self.node = node
|
||||||
self.interval = node.getAttribute("interval")
|
self.interval = node.getAttribute("interval")
|
||||||
self.callFpdbHud = node.getAttribute("callFpdbHud")
|
self.callFpdbHud = node.getAttribute("callFpdbHud")
|
||||||
self.hhArchiveBase = node.getAttribute("hhArchiveBase")
|
self.hhArchiveBase = node.getAttribute("hhArchiveBase")
|
||||||
self.saveActions = fix_tf(node.getAttribute("saveActions"), True)
|
self.saveActions = string_to_bool(node.getAttribute("saveActions"), default=True)
|
||||||
self.fastStoreHudCache = fix_tf(node.getAttribute("fastStoreHudCache"), False)
|
self.fastStoreHudCache = string_to_bool(node.getAttribute("fastStoreHudCache"), default=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return " interval = %s\n callFpdbHud = %s\n hhArchiveBase = %s\n saveActions = %s\n fastStoreHudCache = %s\n" \
|
return " interval = %s\n callFpdbHud = %s\n hhArchiveBase = %s\n saveActions = %s\n fastStoreHudCache = %s\n" \
|
||||||
% (self.interval, self.callFpdbHud, self.hhArchiveBase, self.saveActions, self.fastStoreHudCache)
|
% (self.interval, self.callFpdbHud, self.hhArchiveBase, self.saveActions, self.fastStoreHudCache)
|
||||||
|
|
||||||
class HudUI:
|
class HudUI:
|
||||||
def __init__(self, node):
|
def __init__(self, node):
|
||||||
self.node = node
|
self.node = node
|
||||||
self.label = node.getAttribute('label')
|
self.label = node.getAttribute('label')
|
||||||
#
|
#
|
||||||
self.aggregate_ring = fix_tf(node.getAttribute('aggregate_ring_game_stats'))
|
self.hud_style = node.getAttribute('stat_range')
|
||||||
self.aggregate_tour = fix_tf(node.getAttribute('aggregate_tourney_stats'))
|
self.hud_days = node.getAttribute('stat_days')
|
||||||
self.hud_style = node.getAttribute('stat_aggregation_range')
|
self.aggregate_ring = string_to_bool(node.getAttribute('aggregate_ring_game_stats'))
|
||||||
self.hud_days = node.getAttribute('aggregation_days')
|
self.aggregate_tour = string_to_bool(node.getAttribute('aggregate_tourney_stats'))
|
||||||
self.agg_bb_mult = node.getAttribute('aggregation_level_multiplier')
|
self.agg_bb_mult = node.getAttribute('aggregation_level_multiplier')
|
||||||
#
|
#
|
||||||
self.h_aggregate_ring = fix_tf(node.getAttribute('aggregate_hero_ring_game_stats'))
|
self.h_hud_style = node.getAttribute('hero_stat_range')
|
||||||
self.h_aggregate_tour = fix_tf(node.getAttribute('aggregate_hero_tourney_stats'))
|
self.h_hud_days = node.getAttribute('hero_stat_days')
|
||||||
self.h_hud_style = node.getAttribute('hero_stat_aggregation_range')
|
self.h_aggregate_ring = string_to_bool(node.getAttribute('aggregate_hero_ring_game_stats'))
|
||||||
self.h_hud_days = node.getAttribute('hero_aggregation_days')
|
self.h_aggregate_tour = string_to_bool(node.getAttribute('aggregate_hero_tourney_stats'))
|
||||||
self.h_agg_bb_mult = node.getAttribute('hero_aggregation_level_multiplier')
|
self.h_agg_bb_mult = node.getAttribute('hero_aggregation_level_multiplier')
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -301,12 +385,12 @@ class HudUI:
|
||||||
|
|
||||||
class Tv:
|
class Tv:
|
||||||
def __init__(self, node):
|
def __init__(self, node):
|
||||||
self.combinedStealFold = node.getAttribute("combinedStealFold")
|
self.combinedStealFold = string_to_bool(node.getAttribute("combinedStealFold"), default=True)
|
||||||
self.combined2B3B = node.getAttribute("combined2B3B")
|
self.combined2B3B = string_to_bool(node.getAttribute("combined2B3B"), default=True)
|
||||||
self.combinedPostflop = node.getAttribute("combinedPostflop")
|
self.combinedPostflop = string_to_bool(node.getAttribute("combinedPostflop"), default=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return (" combinedStealFold = %s\n combined2B3B = %s\n combinedPostflop = %s\n" %
|
return (" combinedStealFold = %s\n combined2B3B = %s\n combinedPostflop = %s\n" %
|
||||||
(self.combinedStealFold, self.combined2B3B, self.combinedPostflop) )
|
(self.combinedStealFold, self.combined2B3B, self.combinedPostflop) )
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
@ -315,7 +399,7 @@ class Config:
|
||||||
# "file" is a path to an xml file with the fpdb/HUD configuration
|
# "file" is a path to an xml file with the fpdb/HUD configuration
|
||||||
# we check the existence of "file" and try to recover if it doesn't exist
|
# we check the existence of "file" and try to recover if it doesn't exist
|
||||||
|
|
||||||
self.default_config_path = self.get_default_config_path()
|
# self.default_config_path = self.get_default_config_path()
|
||||||
if file is not None: # config file path passed in
|
if file is not None: # config file path passed in
|
||||||
file = os.path.expanduser(file)
|
file = os.path.expanduser(file)
|
||||||
if not os.path.exists(file):
|
if not os.path.exists(file):
|
||||||
|
@ -323,31 +407,15 @@ class Config:
|
||||||
sys.stderr.write("Configuration file %s not found. Using defaults." % (file))
|
sys.stderr.write("Configuration file %s not found. Using defaults." % (file))
|
||||||
file = None
|
file = None
|
||||||
|
|
||||||
if file is None: # configuration file path not passed or invalid
|
if file is None: file = get_config("HUD_config.xml")
|
||||||
file = self.find_config() #Look for a config file in the normal places
|
|
||||||
|
|
||||||
if file is None: # no config file in the normal places
|
|
||||||
file = self.find_example_config() #Look for an example file to edit
|
|
||||||
|
|
||||||
if file is None: # that didn't work either, just die
|
|
||||||
print "No HUD_config_xml found after looking in current directory and "+self.default_config_path+"\nExiting"
|
|
||||||
sys.stderr.write("No HUD_config_xml found after looking in current directory and "+self.default_config_path+"\nExiting")
|
|
||||||
print "press enter to continue"
|
|
||||||
sys.stdin.readline()
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
# Parse even if there was no real config file found and we are using the example
|
# Parse even if there was no real config file found and we are using the example
|
||||||
# If using the example, we'll edit it later
|
# If using the example, we'll edit it later
|
||||||
# sc 2009/10/04 Example already copied to main filename, is this ok?
|
|
||||||
log.info("Reading configuration file %s" % file)
|
log.info("Reading configuration file %s" % file)
|
||||||
if os.sep in file:
|
print "\nReading configuration file %s\n" % file
|
||||||
print "\nReading configuration file %s\n" % file
|
|
||||||
else:
|
|
||||||
print "\nReading configuration file %s" % file
|
|
||||||
print "in %s\n" % os.getcwd()
|
|
||||||
try:
|
try:
|
||||||
doc = xml.dom.minidom.parse(file)
|
doc = xml.dom.minidom.parse(file)
|
||||||
except:
|
except:
|
||||||
log.error("Error parsing %s. See error log file." % (file))
|
log.error("Error parsing %s. See error log file." % (file))
|
||||||
traceback.print_exc(file=sys.stderr)
|
traceback.print_exc(file=sys.stderr)
|
||||||
print "press enter to continue"
|
print "press enter to continue"
|
||||||
|
@ -358,10 +426,13 @@ class Config:
|
||||||
self.file = file
|
self.file = file
|
||||||
self.supported_sites = {}
|
self.supported_sites = {}
|
||||||
self.supported_games = {}
|
self.supported_games = {}
|
||||||
self.supported_databases = {}
|
self.supported_databases = {} # databaseName --> Database instance
|
||||||
self.aux_windows = {}
|
self.aux_windows = {}
|
||||||
self.hhcs = {}
|
self.hhcs = {}
|
||||||
self.popup_windows = {}
|
self.popup_windows = {}
|
||||||
|
self.db_selected = None # database the user would like to use
|
||||||
|
self.tv = None
|
||||||
|
|
||||||
|
|
||||||
# s_sites = doc.getElementsByTagName("supported_sites")
|
# s_sites = doc.getElementsByTagName("supported_sites")
|
||||||
for site_node in doc.getElementsByTagName("site"):
|
for site_node in doc.getElementsByTagName("site"):
|
||||||
|
@ -372,37 +443,34 @@ class Config:
|
||||||
for game_node in doc.getElementsByTagName("game"):
|
for game_node in doc.getElementsByTagName("game"):
|
||||||
game = Game(node = game_node)
|
game = Game(node = game_node)
|
||||||
self.supported_games[game.game_name] = game
|
self.supported_games[game.game_name] = game
|
||||||
|
|
||||||
|
# parse databases defined by user in the <supported_databases> section
|
||||||
|
# the user may select the actual database to use via commandline or by setting the selected="bool"
|
||||||
|
# attribute of the tag. if no database is explicitely selected, we use the first one we come across
|
||||||
# s_dbs = doc.getElementsByTagName("supported_databases")
|
# s_dbs = doc.getElementsByTagName("supported_databases")
|
||||||
# select database from those defined in config by:
|
#TODO: do we want to take all <database> tags or all <database> tags contained in <supported_databases>
|
||||||
# 1) command line option
|
# ..this may break stuff for some users. so leave it unchanged for now untill there is a decission
|
||||||
# or 2) selected="True" in config element
|
|
||||||
# or 3) just choose the first we come across
|
|
||||||
for db_node in doc.getElementsByTagName("database"):
|
for db_node in doc.getElementsByTagName("database"):
|
||||||
try:
|
db = Database(node=db_node)
|
||||||
db = Database(node = db_node)
|
if db.db_name in self.supported_databases:
|
||||||
except:
|
raise ValueError("Database names must be unique")
|
||||||
raise FpdbError("Unable to create database object")
|
if self.db_selected is None or db.db_selected:
|
||||||
else:
|
self.db_selected = db.db_name
|
||||||
if db.db_name in self.supported_databases:
|
self.supported_databases[db.db_name] = db
|
||||||
raise FpdbError("Database names must be unique")
|
#TODO: if the user may passes '' (empty string) as database name via command line, his choice is ignored
|
||||||
# If there is only one Database node, or none are marked
|
# ..when we parse the xml we allow for ''. there has to be a decission if to allow '' or not
|
||||||
# default, use first
|
|
||||||
if not self.supported_databases:
|
|
||||||
self.db_selected = db.db_name
|
|
||||||
self.supported_databases[db.db_name] = db
|
|
||||||
if db.db_selected:
|
|
||||||
self.db_selected = db.db_name
|
|
||||||
|
|
||||||
if dbname and dbname in self.supported_databases:
|
if dbname and dbname in self.supported_databases:
|
||||||
self.db_selected = dbname
|
self.db_selected = dbname
|
||||||
|
#NOTE: fpdb can not handle the case when no database is defined in xml, so we throw an exception for now
|
||||||
|
if self.db_selected is None:
|
||||||
|
raise ValueError('There must be at least one database defined')
|
||||||
|
|
||||||
# s_dbs = doc.getElementsByTagName("mucked_windows")
|
# s_dbs = doc.getElementsByTagName("mucked_windows")
|
||||||
for aw_node in doc.getElementsByTagName("aw"):
|
for aw_node in doc.getElementsByTagName("aw"):
|
||||||
aw = Aux_window(node = aw_node)
|
aw = Aux_window(node = aw_node)
|
||||||
self.aux_windows[aw.name] = aw
|
self.aux_windows[aw.name] = aw
|
||||||
|
|
||||||
# s_dbs = doc.getElementsByTagName("mucked_windows")
|
# s_dbs = doc.getElementsByTagName("mucked_windows")
|
||||||
for hhc_node in doc.getElementsByTagName("hhc"):
|
for hhc_node in doc.getElementsByTagName("hhc"):
|
||||||
hhc = HHC(node = hhc_node)
|
hhc = HHC(node = hhc_node)
|
||||||
self.hhcs[hhc.site] = hhc
|
self.hhcs[hhc.site] = hhc
|
||||||
|
@ -421,8 +489,7 @@ class Config:
|
||||||
self.ui = hui
|
self.ui = hui
|
||||||
|
|
||||||
for tv_node in doc.getElementsByTagName("tv"):
|
for tv_node in doc.getElementsByTagName("tv"):
|
||||||
tv = Tv(node = tv_node)
|
self.tv = Tv(node = tv_node)
|
||||||
self.tv = tv
|
|
||||||
|
|
||||||
db = self.get_db_parameters()
|
db = self.get_db_parameters()
|
||||||
if db['db-password'] == 'YOUR MYSQL PASSWORD':
|
if db['db-password'] == 'YOUR MYSQL PASSWORD':
|
||||||
|
@ -432,36 +499,14 @@ class Config:
|
||||||
else:
|
else:
|
||||||
df_parms = self.read_default_conf(df_file)
|
df_parms = self.read_default_conf(df_file)
|
||||||
self.set_db_parameters(db_name = 'fpdb', db_ip = df_parms['db-host'],
|
self.set_db_parameters(db_name = 'fpdb', db_ip = df_parms['db-host'],
|
||||||
db_user = df_parms['db-user'],
|
db_user = df_parms['db-user'],
|
||||||
db_pass = df_parms['db-password'])
|
db_pass = df_parms['db-password'])
|
||||||
self.save(file=os.path.join(self.default_config_path, "HUD_config.xml"))
|
self.save(file=os.path.join(self.default_config_path, "HUD_config.xml"))
|
||||||
|
|
||||||
print ""
|
print ""
|
||||||
|
|
||||||
def set_hhArchiveBase(self, path):
|
def set_hhArchiveBase(self, path):
|
||||||
self.imp.node.setAttribute("hhArchiveBase", path)
|
self.imp.node.setAttribute("hhArchiveBase", path)
|
||||||
|
|
||||||
def find_config(self):
|
|
||||||
"""Looks in cwd and in self.default_config_path for a config file."""
|
|
||||||
if os.path.exists('HUD_config.xml'): # there is a HUD_config in the cwd
|
|
||||||
file = 'HUD_config.xml' # so we use it
|
|
||||||
else: # no HUD_config in the cwd, look where it should be in the first place
|
|
||||||
config_path = os.path.join(self.default_config_path, 'HUD_config.xml')
|
|
||||||
if os.path.exists(config_path):
|
|
||||||
file = config_path
|
|
||||||
else:
|
|
||||||
file = None
|
|
||||||
return file
|
|
||||||
|
|
||||||
def get_default_config_path(self):
|
|
||||||
"""Returns the path where the fpdb config file _should_ be stored."""
|
|
||||||
if os.name == 'posix':
|
|
||||||
config_path = os.path.join(os.path.expanduser("~"), '.fpdb')
|
|
||||||
elif os.name == 'nt':
|
|
||||||
config_path = os.path.join(os.environ["APPDATA"], 'fpdb')
|
|
||||||
else: config_path = None
|
|
||||||
return config_path
|
|
||||||
|
|
||||||
|
|
||||||
def find_default_conf(self):
|
def find_default_conf(self):
|
||||||
if os.name == 'posix':
|
if os.name == 'posix':
|
||||||
|
@ -476,29 +521,8 @@ class Config:
|
||||||
file = None
|
file = None
|
||||||
return file
|
return file
|
||||||
|
|
||||||
def read_default_conf(self, file):
|
def get_doc(self):
|
||||||
parms = {}
|
return self.doc
|
||||||
with open(file, "r") as fh:
|
|
||||||
for line in fh:
|
|
||||||
line = string.strip(line)
|
|
||||||
(key, value) = line.split('=')
|
|
||||||
parms[key] = value
|
|
||||||
return parms
|
|
||||||
|
|
||||||
def find_example_config(self):
|
|
||||||
if os.path.exists('HUD_config.xml.example'): # there is a HUD_config in the cwd
|
|
||||||
file = 'HUD_config.xml' # so we use it
|
|
||||||
try:
|
|
||||||
shutil.copyfile(file+'.example', file)
|
|
||||||
except:
|
|
||||||
file = ''
|
|
||||||
print "No HUD_config.xml found, using HUD_config.xml.example.\n", \
|
|
||||||
"A HUD_config.xml has been created. You will probably have to edit it."
|
|
||||||
sys.stderr.write("No HUD_config.xml found, using HUD_config.xml.example.\n" + \
|
|
||||||
"A HUD_config.xml has been created. You will probably have to edit it.")
|
|
||||||
else:
|
|
||||||
file = None
|
|
||||||
return file
|
|
||||||
|
|
||||||
def get_site_node(self, site):
|
def get_site_node(self, site):
|
||||||
for site_node in self.doc.getElementsByTagName("site"):
|
for site_node in self.doc.getElementsByTagName("site"):
|
||||||
|
@ -518,7 +542,7 @@ class Config:
|
||||||
|
|
||||||
def get_layout_node(self, site_node, layout):
|
def get_layout_node(self, site_node, layout):
|
||||||
for layout_node in site_node.getElementsByTagName("layout"):
|
for layout_node in site_node.getElementsByTagName("layout"):
|
||||||
if layout_node.getAttribute("max") is None:
|
if layout_node.getAttribute("max") is None:
|
||||||
return None
|
return None
|
||||||
if int( layout_node.getAttribute("max") ) == int( layout ):
|
if int( layout_node.getAttribute("max") ) == int( layout ):
|
||||||
return layout_node
|
return layout_node
|
||||||
|
@ -534,13 +558,11 @@ class Config:
|
||||||
return location_node
|
return location_node
|
||||||
|
|
||||||
def save(self, file = None):
|
def save(self, file = None):
|
||||||
if file is not None:
|
if file is None:
|
||||||
with open(file, 'w') as f:
|
file = self.file
|
||||||
self.doc.writexml(f)
|
shutil.move(file, file+".backup")
|
||||||
else:
|
with open(file, 'w') as f:
|
||||||
shutil.move(self.file, self.file+".backup")
|
self.doc.writexml(f)
|
||||||
with open(self.file, 'w') as f:
|
|
||||||
self.doc.writexml(f)
|
|
||||||
|
|
||||||
def edit_layout(self, site_name, max, width = None, height = None,
|
def edit_layout(self, site_name, max, width = None, height = None,
|
||||||
fav_seat = None, locations = None):
|
fav_seat = None, locations = None):
|
||||||
|
@ -571,6 +593,13 @@ class Config:
|
||||||
else:
|
else:
|
||||||
self.aux_windows[aux_name].layout[max].location[i] = ( locations[i][0], locations[i][1] )
|
self.aux_windows[aux_name].layout[max].location[i] = ( locations[i][0], locations[i][1] )
|
||||||
|
|
||||||
|
#NOTE: we got a nice Database class, so why map it again here?
|
||||||
|
# user input validation should be done when initializing the Database class. this allows to give appropriate feddback when something goes wrong
|
||||||
|
# try ..except is evil here. it swallows all kinds of errors. dont do this
|
||||||
|
# naming database types 2, 3, 4 on the fly is no good idea. i see this all over the code. better use some globally defined consts (see DATABASE_TYPE_*)
|
||||||
|
# i would like to drop this method entirely and replace it by get_selected_database() or better get_active_database(), returning one of our Database instances
|
||||||
|
# thus we can drop self.db_selected (holding database name) entirely and replace it with self._active_database = Database, avoiding to define the same
|
||||||
|
# thing multiple times
|
||||||
def get_db_parameters(self):
|
def get_db_parameters(self):
|
||||||
db = {}
|
db = {}
|
||||||
name = self.db_selected
|
name = self.db_selected
|
||||||
|
@ -590,20 +619,18 @@ class Config:
|
||||||
try: db['db-server'] = self.supported_databases[name].db_server
|
try: db['db-server'] = self.supported_databases[name].db_server
|
||||||
except: pass
|
except: pass
|
||||||
|
|
||||||
try: db['db-type'] = self.supported_databases[name].db_type
|
if self.supported_databases[name].db_server== DATABASE_TYPE_MYSQL:
|
||||||
except: pass
|
|
||||||
|
|
||||||
if string.lower(self.supported_databases[name].db_server) == 'mysql':
|
|
||||||
db['db-backend'] = 2
|
db['db-backend'] = 2
|
||||||
elif string.lower(self.supported_databases[name].db_server) == 'postgresql':
|
elif self.supported_databases[name].db_server== DATABASE_TYPE_POSTGRESQL:
|
||||||
db['db-backend'] = 3
|
db['db-backend'] = 3
|
||||||
elif string.lower(self.supported_databases[name].db_server) == 'sqlite':
|
elif self.supported_databases[name].db_server== DATABASE_TYPE_SQLITE:
|
||||||
db['db-backend'] = 4
|
db['db-backend'] = 4
|
||||||
else: db['db-backend'] = None # this is big trouble
|
else:
|
||||||
|
raise ValueError('Unsupported database backend: %s' % self.supported_databases[name].db_server)
|
||||||
return db
|
return db
|
||||||
|
|
||||||
def set_db_parameters(self, db_name = 'fpdb', db_ip = None, db_user = None,
|
def set_db_parameters(self, db_name = 'fpdb', db_ip = None, db_user = None,
|
||||||
db_pass = None, db_server = None, db_type = None):
|
db_pass = None, db_server = None):
|
||||||
db_node = self.get_db_node(db_name)
|
db_node = self.get_db_node(db_name)
|
||||||
if db_node != None:
|
if db_node != None:
|
||||||
if db_ip is not None: db_node.setAttribute("db_ip", db_ip)
|
if db_ip is not None: db_node.setAttribute("db_ip", db_ip)
|
||||||
|
@ -618,7 +645,7 @@ class Config:
|
||||||
if db_server is not None: self.supported_databases[db_name].dp_server = db_server
|
if db_server is not None: self.supported_databases[db_name].dp_server = db_server
|
||||||
if db_type is not None: self.supported_databases[db_name].dp_type = db_type
|
if db_type is not None: self.supported_databases[db_name].dp_type = db_type
|
||||||
return
|
return
|
||||||
|
|
||||||
def getDefaultSite(self):
|
def getDefaultSite(self):
|
||||||
"Returns first enabled site or None"
|
"Returns first enabled site or None"
|
||||||
for site_name,site in self.supported_sites.iteritems():
|
for site_name,site in self.supported_sites.iteritems():
|
||||||
|
@ -627,79 +654,88 @@ class Config:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_tv_parameters(self):
|
def get_tv_parameters(self):
|
||||||
tv = {}
|
if self.tv is not None:
|
||||||
try: tv['combinedStealFold'] = self.tv.combinedStealFold
|
return {
|
||||||
except: tv['combinedStealFold'] = True
|
'combinedStealFold': self.tv.combinedStealFold,
|
||||||
|
'combined2B3B': self.tv.combined2B3B,
|
||||||
try: tv['combined2B3B'] = self.tv.combined2B3B
|
'combinedPostflop': self.tv.combinedPostflop
|
||||||
except: tv['combined2B3B'] = True
|
}
|
||||||
|
return {}
|
||||||
try: tv['combinedPostflop'] = self.tv.combinedPostflop
|
|
||||||
except: tv['combinedPostflop'] = True
|
|
||||||
return tv
|
|
||||||
|
|
||||||
# Allow to change the menu appearance
|
# Allow to change the menu appearance
|
||||||
def get_hud_ui_parameters(self):
|
def get_hud_ui_parameters(self):
|
||||||
hui = {}
|
hui = {}
|
||||||
|
|
||||||
default_text = 'FPDB Menu - Right click\nLeft-Drag to Move'
|
default_text = 'FPDB Menu - Right click\nLeft-Drag to Move'
|
||||||
try:
|
try:
|
||||||
hui['label'] = self.ui.label
|
hui['label'] = self.ui.label
|
||||||
if self.ui.label == '': # Empty menu label is a big no-no
|
if self.ui.label == '': # Empty menu label is a big no-no
|
||||||
hui['label'] = default_text
|
hui['label'] = default_text
|
||||||
except:
|
except:
|
||||||
hui['label'] = default_text
|
hui['label'] = default_text
|
||||||
|
|
||||||
|
try: hui['hud_style'] = self.ui.hud_style
|
||||||
|
except: hui['hud_style'] = 'A' # default is show stats for All-time, also S(session) and T(ime)
|
||||||
|
|
||||||
|
try: hui['hud_days'] = int(self.ui.hud_days)
|
||||||
|
except: hui['hud_days'] = 90
|
||||||
|
|
||||||
try: hui['aggregate_ring'] = self.ui.aggregate_ring
|
try: hui['aggregate_ring'] = self.ui.aggregate_ring
|
||||||
except: hui['aggregate_ring'] = False
|
except: hui['aggregate_ring'] = False
|
||||||
|
|
||||||
try: hui['aggregate_tour'] = self.ui.aggregate_tour
|
try: hui['aggregate_tour'] = self.ui.aggregate_tour
|
||||||
except: hui['aggregate_tour'] = True
|
except: hui['aggregate_tour'] = True
|
||||||
|
|
||||||
try: hui['hud_style'] = self.ui.hud_style
|
try: hui['agg_bb_mult'] = self.ui.agg_bb_mult
|
||||||
except: hui['hud_style'] = 'A'
|
except: hui['agg_bb_mult'] = 1
|
||||||
|
|
||||||
try: hui['hud_days'] = int(self.ui.hud_days)
|
try: hui['seats_style'] = self.ui.seats_style
|
||||||
except: hui['hud_days'] = 90
|
except: hui['seats_style'] = 'A' # A / C / E, use A(ll) / C(ustom) / E(xact) seat numbers
|
||||||
|
|
||||||
try: hui['agg_bb_mult'] = self.ui.agg_bb_mult
|
try: hui['seats_cust_nums'] = self.ui.seats_cust_nums
|
||||||
except: hui['agg_bb_mult'] = 1
|
except: hui['seats_cust_nums'] = ['n/a', 'n/a', (2,2), (3,4), (3,5), (4,6), (5,7), (6,8), (7,9), (8,10), (8,10)]
|
||||||
|
|
||||||
# Hero specific
|
# Hero specific
|
||||||
|
|
||||||
|
try: hui['h_hud_style'] = self.ui.h_hud_style
|
||||||
|
except: hui['h_hud_style'] = 'S'
|
||||||
|
|
||||||
|
try: hui['h_hud_days'] = int(self.ui.h_hud_days)
|
||||||
|
except: hui['h_hud_days'] = 30
|
||||||
|
|
||||||
try: hui['h_aggregate_ring'] = self.ui.h_aggregate_ring
|
try: hui['h_aggregate_ring'] = self.ui.h_aggregate_ring
|
||||||
except: hui['h_aggregate_ring'] = False
|
except: hui['h_aggregate_ring'] = False
|
||||||
|
|
||||||
try: hui['h_aggregate_tour'] = self.ui.h_aggregate_tour
|
try: hui['h_aggregate_tour'] = self.ui.h_aggregate_tour
|
||||||
except: hui['h_aggregate_tour'] = True
|
except: hui['h_aggregate_tour'] = True
|
||||||
|
|
||||||
try: hui['h_hud_style'] = self.ui.h_hud_style
|
|
||||||
except: hui['h_hud_style'] = 'S'
|
|
||||||
|
|
||||||
try: hui['h_hud_days'] = int(self.ui.h_hud_days)
|
|
||||||
except: hui['h_hud_days'] = 30
|
|
||||||
|
|
||||||
try: hui['h_agg_bb_mult'] = self.ui.h_agg_bb_mult
|
try: hui['h_agg_bb_mult'] = self.ui.h_agg_bb_mult
|
||||||
except: hui['h_agg_bb_mult'] = 1
|
except: hui['h_agg_bb_mult'] = 1
|
||||||
|
|
||||||
|
try: hui['h_seats_style'] = self.ui.h_seats_style
|
||||||
|
except: hui['h_seats_style'] = 'A' # A / C / E, use A(ll) / C(ustom) / E(xact) seat numbers
|
||||||
|
|
||||||
|
try: hui['h_seats_cust_nums'] = self.ui.h_seats_cust_nums
|
||||||
|
except: hui['h_seats_cust_nums'] = ['n/a', 'n/a', (2,2), (3,4), (3,5), (4,6), (5,7), (6,8), (7,9), (8,10), (8,10)]
|
||||||
|
|
||||||
return hui
|
return hui
|
||||||
|
|
||||||
|
|
||||||
def get_import_parameters(self):
|
def get_import_parameters(self):
|
||||||
imp = {}
|
imp = {}
|
||||||
try: imp['callFpdbHud'] = self.imp.callFpdbHud
|
try: imp['callFpdbHud'] = self.imp.callFpdbHud
|
||||||
except: imp['callFpdbHud'] = True
|
except: imp['callFpdbHud'] = True
|
||||||
|
|
||||||
try: imp['interval'] = self.imp.interval
|
try: imp['interval'] = self.imp.interval
|
||||||
except: imp['interval'] = 10
|
except: imp['interval'] = 10
|
||||||
|
|
||||||
try: imp['hhArchiveBase'] = self.imp.hhArchiveBase
|
try: imp['hhArchiveBase'] = self.imp.hhArchiveBase
|
||||||
except: imp['hhArchiveBase'] = "~/.fpdb/HandHistories/"
|
except: imp['hhArchiveBase'] = "~/.fpdb/HandHistories/"
|
||||||
|
|
||||||
try: imp['saveActions'] = self.imp.saveActions
|
try: imp['saveActions'] = self.imp.saveActions
|
||||||
except: imp['saveActions'] = True
|
except: imp['saveActions'] = True
|
||||||
|
|
||||||
try: imp['fastStoreHudCache'] = self.imp.fastStoreHudCache
|
try: imp['fastStoreHudCache'] = self.imp.fastStoreHudCache
|
||||||
except: imp['fastStoreHudCache'] = True
|
except: imp['fastStoreHudCache'] = True
|
||||||
return imp
|
return imp
|
||||||
|
|
||||||
|
@ -710,10 +746,10 @@ class Config:
|
||||||
path = os.path.expanduser(self.supported_sites[site].HH_path)
|
path = os.path.expanduser(self.supported_sites[site].HH_path)
|
||||||
assert(os.path.isdir(path) or os.path.isfile(path)) # maybe it should try another site?
|
assert(os.path.isdir(path) or os.path.isfile(path)) # maybe it should try another site?
|
||||||
paths['hud-defaultPath'] = paths['bulkImport-defaultPath'] = path
|
paths['hud-defaultPath'] = paths['bulkImport-defaultPath'] = path
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
paths['hud-defaultPath'] = paths['bulkImport-defaultPath'] = "** ERROR DEFAULT PATH IN CONFIG DOES NOT EXIST **"
|
paths['hud-defaultPath'] = paths['bulkImport-defaultPath'] = "** ERROR DEFAULT PATH IN CONFIG DOES NOT EXIST **"
|
||||||
return paths
|
return paths
|
||||||
|
|
||||||
def get_frames(self, site = "PokerStars"):
|
def get_frames(self, site = "PokerStars"):
|
||||||
if site not in self.supported_sites: return False
|
if site not in self.supported_sites: return False
|
||||||
return self.supported_sites[site].use_frames == True
|
return self.supported_sites[site].use_frames == True
|
||||||
|
@ -733,74 +769,70 @@ class Config:
|
||||||
else:
|
else:
|
||||||
colors['hudfgcolor'] = self.supported_sites[site].hudfgcolor
|
colors['hudfgcolor'] = self.supported_sites[site].hudfgcolor
|
||||||
return colors
|
return colors
|
||||||
|
|
||||||
def get_default_font(self, site = 'PokerStars'):
|
|
||||||
(font, font_size) = ("Sans", "8")
|
|
||||||
if site not in self.supported_sites:
|
|
||||||
return ("Sans", "8")
|
|
||||||
if self.supported_sites[site].font == "":
|
|
||||||
font = "Sans"
|
|
||||||
else:
|
|
||||||
font = self.supported_sites[site].font
|
|
||||||
|
|
||||||
if self.supported_sites[site].font_size == "":
|
def get_default_font(self, site='PokerStars'):
|
||||||
font_size = "8"
|
font = "Sans"
|
||||||
else:
|
font_size = "8"
|
||||||
font_size = self.supported_sites[site].font_size
|
site = self.supported_sites.get(site, None)
|
||||||
return (font, font_size)
|
if site is not None:
|
||||||
|
if site.font:
|
||||||
|
font = site.font
|
||||||
|
if site.font_size:
|
||||||
|
font_size = site.font_size
|
||||||
|
return font, font_size
|
||||||
|
|
||||||
def get_locations(self, site = "PokerStars", max = "8"):
|
def get_locations(self, site_name="PokerStars", max=8):
|
||||||
|
site = self.supported_sites.get(site_name, None)
|
||||||
try:
|
if site is not None:
|
||||||
locations = self.supported_sites[site].layout[max].location
|
location = site.layout.get(max, None)
|
||||||
except:
|
if location is not None:
|
||||||
locations = ( ( 0, 0), (684, 61), (689, 239), (692, 346),
|
return location.location
|
||||||
(586, 393), (421, 440), (267, 440), ( 0, 361),
|
return (
|
||||||
( 0, 280), (121, 280), ( 46, 30) )
|
( 0, 0), (684, 61), (689, 239), (692, 346),
|
||||||
return locations
|
(586, 393), (421, 440), (267, 440), ( 0, 361),
|
||||||
|
( 0, 280), (121, 280), ( 46, 30)
|
||||||
|
)
|
||||||
|
|
||||||
def get_aux_locations(self, aux = "mucked", max = "9"):
|
def get_aux_locations(self, aux = "mucked", max = "9"):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
locations = self.aux_windows[aux].layout[max].location
|
locations = self.aux_windows[aux].layout[max].location
|
||||||
except:
|
except:
|
||||||
locations = ( ( 0, 0), (684, 61), (689, 239), (692, 346),
|
locations = ( ( 0, 0), (684, 61), (689, 239), (692, 346),
|
||||||
(586, 393), (421, 440), (267, 440), ( 0, 361),
|
(586, 393), (421, 440), (267, 440), ( 0, 361),
|
||||||
( 0, 280), (121, 280), ( 46, 30) )
|
( 0, 280), (121, 280), ( 46, 30) )
|
||||||
return locations
|
return locations
|
||||||
|
|
||||||
def get_supported_sites(self, all = False):
|
def get_supported_sites(self, all=False):
|
||||||
"""Returns the list of supported sites."""
|
"""Returns the list of supported sites."""
|
||||||
the_sites = []
|
if all:
|
||||||
for site in self.supported_sites.keys():
|
return self.supported_sites.keys()
|
||||||
params = self.get_site_parameters(site)
|
else:
|
||||||
if all or params['enabled']:
|
return [site_name for (site_name, site) in self.supported_sites.items() if site.enabled]
|
||||||
the_sites.append(site)
|
|
||||||
return the_sites
|
|
||||||
|
|
||||||
def get_site_parameters(self, site):
|
def get_site_parameters(self, site):
|
||||||
"""Returns a dict of the site parameters for the specified site"""
|
"""Returns a dict of the site parameters for the specified site"""
|
||||||
parms = {}
|
parms = {}
|
||||||
parms["converter"] = self.supported_sites[site].converter
|
parms["converter"] = self.supported_sites[site].converter
|
||||||
parms["decoder"] = self.supported_sites[site].decoder
|
parms["decoder"] = self.supported_sites[site].decoder
|
||||||
parms["hudbgcolor"] = self.supported_sites[site].hudbgcolor
|
parms["hudbgcolor"] = self.supported_sites[site].hudbgcolor
|
||||||
parms["hudfgcolor"] = self.supported_sites[site].hudfgcolor
|
parms["hudfgcolor"] = self.supported_sites[site].hudfgcolor
|
||||||
parms["hudopacity"] = self.supported_sites[site].hudopacity
|
parms["hudopacity"] = self.supported_sites[site].hudopacity
|
||||||
parms["screen_name"] = self.supported_sites[site].screen_name
|
parms["screen_name"] = self.supported_sites[site].screen_name
|
||||||
parms["site_path"] = self.supported_sites[site].site_path
|
parms["site_path"] = self.supported_sites[site].site_path
|
||||||
parms["table_finder"] = self.supported_sites[site].table_finder
|
parms["table_finder"] = self.supported_sites[site].table_finder
|
||||||
parms["HH_path"] = self.supported_sites[site].HH_path
|
parms["HH_path"] = self.supported_sites[site].HH_path
|
||||||
parms["site_name"] = self.supported_sites[site].site_name
|
parms["site_name"] = self.supported_sites[site].site_name
|
||||||
parms["aux_window"] = self.supported_sites[site].aux_window
|
parms["aux_window"] = self.supported_sites[site].aux_window
|
||||||
parms["font"] = self.supported_sites[site].font
|
parms["font"] = self.supported_sites[site].font
|
||||||
parms["font_size"] = self.supported_sites[site].font_size
|
parms["font_size"] = self.supported_sites[site].font_size
|
||||||
parms["enabled"] = self.supported_sites[site].enabled
|
parms["enabled"] = self.supported_sites[site].enabled
|
||||||
parms["xpad"] = self.supported_sites[site].xpad
|
parms["xpad"] = self.supported_sites[site].xpad
|
||||||
parms["ypad"] = self.supported_sites[site].ypad
|
parms["ypad"] = self.supported_sites[site].ypad
|
||||||
return parms
|
return parms
|
||||||
|
|
||||||
def set_site_parameters(self, site_name, converter = None, decoder = None,
|
def set_site_parameters(self, site_name, converter = None, decoder = None,
|
||||||
hudbgcolor = None, hudfgcolor = None,
|
hudbgcolor = None, hudfgcolor = None,
|
||||||
hudopacity = None, screen_name = None,
|
hudopacity = None, screen_name = None,
|
||||||
site_path = None, table_finder = None,
|
site_path = None, table_finder = None,
|
||||||
HH_path = None, enabled = None,
|
HH_path = None, enabled = None,
|
||||||
|
@ -824,10 +856,7 @@ class Config:
|
||||||
|
|
||||||
def get_aux_windows(self):
|
def get_aux_windows(self):
|
||||||
"""Gets the list of mucked window formats in the configuration."""
|
"""Gets the list of mucked window formats in the configuration."""
|
||||||
mw = []
|
return self.aux_windows.keys()
|
||||||
for w in self.aux_windows.keys():
|
|
||||||
mw.append(w)
|
|
||||||
return mw
|
|
||||||
|
|
||||||
def get_aux_parameters(self, name):
|
def get_aux_parameters(self, name):
|
||||||
"""Gets a dict of mucked window parameters from the named mw."""
|
"""Gets a dict of mucked window parameters from the named mw."""
|
||||||
|
@ -841,17 +870,17 @@ class Config:
|
||||||
|
|
||||||
return param
|
return param
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_game_parameters(self, name):
|
def get_game_parameters(self, name):
|
||||||
"""Get the configuration parameters for the named game."""
|
"""Get the configuration parameters for the named game."""
|
||||||
param = {}
|
param = {}
|
||||||
if self.supported_games.has_key(name):
|
if self.supported_games.has_key(name):
|
||||||
param['game_name'] = self.supported_games[name].game_name
|
param['game_name'] = self.supported_games[name].game_name
|
||||||
param['rows'] = self.supported_games[name].rows
|
param['rows'] = self.supported_games[name].rows
|
||||||
param['cols'] = self.supported_games[name].cols
|
param['cols'] = self.supported_games[name].cols
|
||||||
param['xpad'] = self.supported_games[name].xpad
|
param['xpad'] = self.supported_games[name].xpad
|
||||||
param['ypad'] = self.supported_games[name].ypad
|
param['ypad'] = self.supported_games[name].ypad
|
||||||
param['aux'] = self.supported_games[name].aux
|
param['aux'] = self.supported_games[name].aux
|
||||||
return param
|
return param
|
||||||
|
|
||||||
def get_supported_games(self):
|
def get_supported_games(self):
|
||||||
|
@ -867,7 +896,7 @@ class Config:
|
||||||
|
|
||||||
if __name__== "__main__":
|
if __name__== "__main__":
|
||||||
c = Config()
|
c = Config()
|
||||||
|
|
||||||
print "\n----------- SUPPORTED SITES -----------"
|
print "\n----------- SUPPORTED SITES -----------"
|
||||||
for s in c.supported_sites.keys():
|
for s in c.supported_sites.keys():
|
||||||
print c.supported_sites[s]
|
print c.supported_sites[s]
|
||||||
|
@ -894,7 +923,7 @@ if __name__== "__main__":
|
||||||
for w in c.hhcs.keys():
|
for w in c.hhcs.keys():
|
||||||
print c.hhcs[w]
|
print c.hhcs[w]
|
||||||
print "----------- END HAND HISTORY CONVERTERS -----------"
|
print "----------- END HAND HISTORY CONVERTERS -----------"
|
||||||
|
|
||||||
print "\n----------- POPUP WINDOW FORMATS -----------"
|
print "\n----------- POPUP WINDOW FORMATS -----------"
|
||||||
for w in c.popup_windows.keys():
|
for w in c.popup_windows.keys():
|
||||||
print c.popup_windows[w]
|
print c.popup_windows[w]
|
||||||
|
@ -910,9 +939,9 @@ if __name__== "__main__":
|
||||||
|
|
||||||
c.edit_layout("PokerStars", 6, locations=( (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6) ))
|
c.edit_layout("PokerStars", 6, locations=( (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6) ))
|
||||||
c.save(file="testout.xml")
|
c.save(file="testout.xml")
|
||||||
|
|
||||||
print "db = ", c.get_db_parameters()
|
print "db = ", c.get_db_parameters()
|
||||||
# print "tv = ", c.get_tv_parameters()
|
# print "tv = ", c.get_tv_parameters()
|
||||||
# print "imp = ", c.get_import_parameters()
|
# print "imp = ", c.get_import_parameters()
|
||||||
print "paths = ", c.get_default_paths("PokerStars")
|
print "paths = ", c.get_default_paths("PokerStars")
|
||||||
print "colors = ", c.get_default_colors("PokerStars")
|
print "colors = ", c.get_default_colors("PokerStars")
|
||||||
|
@ -921,7 +950,7 @@ if __name__== "__main__":
|
||||||
print c.get_aux_parameters(mw)
|
print c.get_aux_parameters(mw)
|
||||||
|
|
||||||
print "mucked locations =", c.get_aux_locations('mucked', 9)
|
print "mucked locations =", c.get_aux_locations('mucked', 9)
|
||||||
# c.edit_aux_layout('mucked', 9, locations = [(487, 113), (555, 469), (572, 276), (522, 345),
|
# c.edit_aux_layout('mucked', 9, locations = [(487, 113), (555, 469), (572, 276), (522, 345),
|
||||||
# (333, 354), (217, 341), (150, 273), (150, 169), (230, 115)])
|
# (333, 354), (217, 341), (150, 273), (150, 169), (230, 115)])
|
||||||
# print "mucked locations =", c.get_aux_locations('mucked', 9)
|
# print "mucked locations =", c.get_aux_locations('mucked', 9)
|
||||||
|
|
||||||
|
@ -933,4 +962,14 @@ if __name__== "__main__":
|
||||||
for game in c.get_supported_games():
|
for game in c.get_supported_games():
|
||||||
print c.get_game_parameters(game)
|
print c.get_game_parameters(game)
|
||||||
|
|
||||||
|
for hud_param, value in c.get_hud_ui_parameters().iteritems():
|
||||||
|
print "hud param %s = %s" % (hud_param, value)
|
||||||
|
|
||||||
print "start up path = ", c.execution_path("")
|
print "start up path = ", c.execution_path("")
|
||||||
|
|
||||||
|
try:
|
||||||
|
from xml.dom.ext import PrettyPrint
|
||||||
|
for site_node in c.doc.getElementsByTagName("site"):
|
||||||
|
PrettyPrint(site_node, stream=sys.stdout, encoding="utf-8")
|
||||||
|
except:
|
||||||
|
print "xml.dom.ext needs PyXML to be installed!"
|
||||||
|
|
|
@ -21,6 +21,11 @@ Create and manage the database objects.
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
|
# ToDo: - rebuild indexes / vacuum option
|
||||||
|
# - check speed of get_stats_from_hand() - add log info
|
||||||
|
# - check size of db, seems big? (mysql)
|
||||||
|
# - investigate size of mysql db (200K for just 7K hands? 2GB for 140K hands?)
|
||||||
|
|
||||||
# postmaster -D /var/lib/pgsql/data
|
# postmaster -D /var/lib/pgsql/data
|
||||||
|
|
||||||
# Standard Library modules
|
# Standard Library modules
|
||||||
|
@ -45,16 +50,7 @@ import Card
|
||||||
import Tourney
|
import Tourney
|
||||||
from Exceptions import *
|
from Exceptions import *
|
||||||
|
|
||||||
import logging, logging.config
|
log = Configuration.get_logger("logging.conf")
|
||||||
import ConfigParser
|
|
||||||
|
|
||||||
try: # local path
|
|
||||||
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf"))
|
|
||||||
except ConfigParser.NoSectionError: # debian package path
|
|
||||||
logging.config.fileConfig('/usr/share/python-fpdb/logging.conf')
|
|
||||||
|
|
||||||
log = logging.getLogger('db')
|
|
||||||
|
|
||||||
|
|
||||||
class Database:
|
class Database:
|
||||||
|
|
||||||
|
@ -78,14 +74,9 @@ class Database:
|
||||||
indexes = [
|
indexes = [
|
||||||
[ ] # no db with index 0
|
[ ] # no db with index 0
|
||||||
, [ ] # no db with index 1
|
, [ ] # no db with index 1
|
||||||
, [ # indexes for mysql (list index 2)
|
, [ # indexes for mysql (list index 2) (foreign keys not here, in next data structure)
|
||||||
# {'tab':'Players', 'col':'name', 'drop':0} unique indexes not dropped
|
# {'tab':'Players', 'col':'name', 'drop':0} unique indexes not dropped
|
||||||
# {'tab':'Hands', 'col':'siteHandNo', 'drop':0} unique indexes not dropped
|
# {'tab':'Hands', 'col':'siteHandNo', 'drop':0} unique indexes not dropped
|
||||||
{'tab':'Hands', 'col':'gametypeId', 'drop':0} # mct 22/3/09
|
|
||||||
, {'tab':'HandsPlayers', 'col':'handId', 'drop':0} # not needed, handled by fk
|
|
||||||
, {'tab':'HandsPlayers', 'col':'playerId', 'drop':0} # not needed, handled by fk
|
|
||||||
, {'tab':'HandsPlayers', 'col':'tourneyTypeId', 'drop':0}
|
|
||||||
, {'tab':'HandsPlayers', 'col':'tourneysPlayersId', 'drop':0}
|
|
||||||
#, {'tab':'Tourneys', 'col':'siteTourneyNo', 'drop':0} unique indexes not dropped
|
#, {'tab':'Tourneys', 'col':'siteTourneyNo', 'drop':0} unique indexes not dropped
|
||||||
]
|
]
|
||||||
, [ # indexes for postgres (list index 3)
|
, [ # indexes for postgres (list index 3)
|
||||||
|
@ -126,6 +117,8 @@ class Database:
|
||||||
{'fktab':'Hands', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
|
{'fktab':'Hands', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
|
||||||
, {'fktab':'HandsPlayers', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1}
|
, {'fktab':'HandsPlayers', 'fkcol':'handId', 'rtab':'Hands', 'rcol':'id', 'drop':1}
|
||||||
, {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1}
|
, {'fktab':'HandsPlayers', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':1}
|
||||||
|
, {'fktab':'HandsPlayers', 'fkcol':'tourneyTypeId', 'rtab':'TourneyTypes', 'rcol':'id', 'drop':1}
|
||||||
|
, {'fktab':'HandsPlayers', 'fkcol':'tourneysPlayersId','rtab':'TourneysPlayers','rcol':'id', 'drop':1}
|
||||||
, {'fktab':'HandsActions', 'fkcol':'handsPlayerId', 'rtab':'HandsPlayers', 'rcol':'id', 'drop':1}
|
, {'fktab':'HandsActions', 'fkcol':'handsPlayerId', 'rtab':'HandsPlayers', 'rcol':'id', 'drop':1}
|
||||||
, {'fktab':'HudCache', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
|
, {'fktab':'HudCache', 'fkcol':'gametypeId', 'rtab':'Gametypes', 'rcol':'id', 'drop':1}
|
||||||
, {'fktab':'HudCache', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':0}
|
, {'fktab':'HudCache', 'fkcol':'playerId', 'rtab':'Players', 'rcol':'id', 'drop':0}
|
||||||
|
@ -205,7 +198,7 @@ class Database:
|
||||||
|
|
||||||
# where possible avoid creating new SQL instance by using the global one passed in
|
# where possible avoid creating new SQL instance by using the global one passed in
|
||||||
if sql is None:
|
if sql is None:
|
||||||
self.sql = SQL.Sql(type = self.type, db_server = self.db_server)
|
self.sql = SQL.Sql(db_server = self.db_server)
|
||||||
else:
|
else:
|
||||||
self.sql = sql
|
self.sql = sql
|
||||||
|
|
||||||
|
@ -249,7 +242,6 @@ class Database:
|
||||||
|
|
||||||
db_params = c.get_db_parameters()
|
db_params = c.get_db_parameters()
|
||||||
self.import_options = c.get_import_parameters()
|
self.import_options = c.get_import_parameters()
|
||||||
self.type = db_params['db-type']
|
|
||||||
self.backend = db_params['db-backend']
|
self.backend = db_params['db-backend']
|
||||||
self.db_server = db_params['db-server']
|
self.db_server = db_params['db-server']
|
||||||
self.database = db_params['db-databaseName']
|
self.database = db_params['db-databaseName']
|
||||||
|
@ -441,21 +433,53 @@ class Database:
|
||||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||||
print "*** Database Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
print "*** Database Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||||
|
|
||||||
|
# is get_stats_from_hand slow?
|
||||||
def get_stats_from_hand( self, hand, type # type is "ring" or "tour"
|
def get_stats_from_hand( self, hand, type # type is "ring" or "tour"
|
||||||
, hud_params = {'aggregate_tour':False, 'aggregate_ring':False, 'hud_style':'A', 'hud_days':30, 'agg_bb_mult':100
|
, hud_params = {'hud_style':'A', 'agg_bb_mult':1000
|
||||||
,'h_aggregate_tour':False, 'h_aggregate_ring':False, 'h_hud_style':'S', 'h_hud_days':30, 'h_agg_bb_mult':100}
|
,'seats_style':'A', 'seats_cust_nums':['n/a', 'n/a', (2,2), (3,4), (3,5), (4,6), (5,7), (6,8), (7,9), (8,10), (8,10)]
|
||||||
|
,'h_hud_style':'S', 'h_agg_bb_mult':1000
|
||||||
|
,'h_seats_style':'A', 'h_seats_cust_nums':['n/a', 'n/a', (2,2), (3,4), (3,5), (4,6), (5,7), (6,8), (7,9), (8,10), (8,10)]
|
||||||
|
}
|
||||||
, hero_id = -1
|
, hero_id = -1
|
||||||
|
, num_seats = 6
|
||||||
):
|
):
|
||||||
aggregate = hud_params['aggregate_tour'] if type == "tour" else hud_params['aggregate_ring']
|
|
||||||
hud_style = hud_params['hud_style']
|
hud_style = hud_params['hud_style']
|
||||||
agg_bb_mult = hud_params['agg_bb_mult'] if aggregate else 1
|
agg_bb_mult = hud_params['agg_bb_mult']
|
||||||
h_aggregate = hud_params['h_aggregate_tour'] if type == "tour" else hud_params['h_aggregate_ring']
|
seats_style = hud_params['seats_style']
|
||||||
|
seats_cust_nums = hud_params['seats_cust_nums']
|
||||||
h_hud_style = hud_params['h_hud_style']
|
h_hud_style = hud_params['h_hud_style']
|
||||||
h_agg_bb_mult = hud_params['h_agg_bb_mult'] if h_aggregate else 1
|
h_agg_bb_mult = hud_params['h_agg_bb_mult']
|
||||||
|
h_seats_style = hud_params['h_seats_style']
|
||||||
|
h_seats_cust_nums = hud_params['h_seats_cust_nums']
|
||||||
|
|
||||||
stat_dict = {}
|
stat_dict = {}
|
||||||
|
|
||||||
|
if seats_style == 'A':
|
||||||
|
seats_min, seats_max = 0, 10
|
||||||
|
elif seats_style == 'C':
|
||||||
|
seats_min, seats_max = seats_cust_nums[num_seats][0], seats_cust_nums[num_seats][1]
|
||||||
|
elif seats_style == 'E':
|
||||||
|
seats_min, seats_max = num_seats, num_seats
|
||||||
|
else:
|
||||||
|
seats_min, seats_max = 0, 10
|
||||||
|
print "bad seats_style value:", seats_style
|
||||||
|
|
||||||
|
if h_seats_style == 'A':
|
||||||
|
h_seats_min, h_seats_max = 0, 10
|
||||||
|
elif h_seats_style == 'C':
|
||||||
|
h_seats_min, h_seats_max = h_seats_cust_nums[num_seats][0], h_seats_cust_nums[num_seats][1]
|
||||||
|
elif h_seats_style == 'E':
|
||||||
|
h_seats_min, h_seats_max = num_seats, num_seats
|
||||||
|
else:
|
||||||
|
h_seats_min, h_seats_max = 0, 10
|
||||||
|
print "bad h_seats_style value:", h_seats_style
|
||||||
|
print "opp seats style", seats_style, "hero seats style", h_seats_style
|
||||||
|
print "opp seats:", seats_min, seats_max, " hero seats:", h_seats_min, h_seats_max
|
||||||
|
|
||||||
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, hud_style, h_hud_style)
|
self.get_stats_from_hand_session(hand, stat_dict, hero_id
|
||||||
|
,hud_style, seats_min, seats_max
|
||||||
|
,h_hud_style, h_seats_min, h_seats_max)
|
||||||
|
|
||||||
if hud_style == 'S' and h_hud_style == 'S':
|
if hud_style == 'S' and h_hud_style == 'S':
|
||||||
return stat_dict
|
return stat_dict
|
||||||
|
@ -466,6 +490,10 @@ class Database:
|
||||||
stylekey = '0000000' # all stylekey values should be higher than this
|
stylekey = '0000000' # all stylekey values should be higher than this
|
||||||
elif hud_style == 'S':
|
elif hud_style == 'S':
|
||||||
stylekey = 'zzzzzzz' # all stylekey values should be lower than this
|
stylekey = 'zzzzzzz' # all stylekey values should be lower than this
|
||||||
|
else:
|
||||||
|
stylekey = '0000000'
|
||||||
|
log.info('hud_style: %s' % hud_style)
|
||||||
|
|
||||||
#elif hud_style == 'H':
|
#elif hud_style == 'H':
|
||||||
# stylekey = date_nhands_ago needs array by player here ...
|
# stylekey = date_nhands_ago needs array by player here ...
|
||||||
|
|
||||||
|
@ -475,16 +503,17 @@ class Database:
|
||||||
h_stylekey = '0000000' # all stylekey values should be higher than this
|
h_stylekey = '0000000' # all stylekey values should be higher than this
|
||||||
elif h_hud_style == 'S':
|
elif h_hud_style == 'S':
|
||||||
h_stylekey = 'zzzzzzz' # all stylekey values should be lower than this
|
h_stylekey = 'zzzzzzz' # all stylekey values should be lower than this
|
||||||
|
else:
|
||||||
|
h_stylekey = '000000'
|
||||||
|
log.info('h_hud_style: %s' % h_hud_style)
|
||||||
|
|
||||||
#elif h_hud_style == 'H':
|
#elif h_hud_style == 'H':
|
||||||
# h_stylekey = date_nhands_ago needs array by player here ...
|
# h_stylekey = date_nhands_ago needs array by player here ...
|
||||||
|
|
||||||
#if aggregate: always use aggregate query now: use agg_bb_mult of 1 for no aggregation:
|
|
||||||
query = 'get_stats_from_hand_aggregated'
|
query = 'get_stats_from_hand_aggregated'
|
||||||
subs = (hand, hero_id, stylekey, agg_bb_mult, agg_bb_mult, hero_id, h_stylekey, h_agg_bb_mult, h_agg_bb_mult)
|
subs = (hand
|
||||||
#print "agg query subs:", subs
|
,hero_id, stylekey, agg_bb_mult, agg_bb_mult, seats_min, seats_max # hero params
|
||||||
#else:
|
,hero_id, h_stylekey, h_agg_bb_mult, h_agg_bb_mult, h_seats_min, h_seats_max) # villain params
|
||||||
# query = 'get_stats_from_hand'
|
|
||||||
# subs = (hand, stylekey)
|
|
||||||
|
|
||||||
#print "get stats: hud style =", hud_style, "query =", query, "subs =", subs
|
#print "get stats: hud style =", hud_style, "query =", query, "subs =", subs
|
||||||
c = self.connection.cursor()
|
c = self.connection.cursor()
|
||||||
|
@ -504,12 +533,15 @@ class Database:
|
||||||
return stat_dict
|
return stat_dict
|
||||||
|
|
||||||
# uses query on handsplayers instead of hudcache to get stats on just this session
|
# uses query on handsplayers instead of hudcache to get stats on just this session
|
||||||
def get_stats_from_hand_session(self, hand, stat_dict, hero_id, hud_style, h_hud_style):
|
def get_stats_from_hand_session(self, hand, stat_dict, hero_id
|
||||||
|
,hud_style, seats_min, seats_max
|
||||||
|
,h_hud_style, h_seats_min, h_seats_max):
|
||||||
"""Get stats for just this session (currently defined as any play in the last 24 hours - to
|
"""Get stats for just this session (currently defined as any play in the last 24 hours - to
|
||||||
be improved at some point ...)
|
be improved at some point ...)
|
||||||
h_hud_style and hud_style params indicate whether to get stats for hero and/or others
|
h_hud_style and hud_style params indicate whether to get stats for hero and/or others
|
||||||
- only fetch heros stats if h_hud_style == 'S',
|
- only fetch heros stats if h_hud_style == 'S',
|
||||||
and only fetch others stats if hud_style == 'S'
|
and only fetch others stats if hud_style == 'S'
|
||||||
|
seats_min/max params give seats limits, only include stats if between these values
|
||||||
"""
|
"""
|
||||||
|
|
||||||
query = self.sql.query['get_stats_from_hand_session']
|
query = self.sql.query['get_stats_from_hand_session']
|
||||||
|
@ -518,7 +550,8 @@ class Database:
|
||||||
else:
|
else:
|
||||||
query = query.replace("<signed>", '')
|
query = query.replace("<signed>", '')
|
||||||
|
|
||||||
subs = (self.hand_1day_ago, hand)
|
subs = (self.hand_1day_ago, hand, hero_id, seats_min, seats_max
|
||||||
|
, hero_id, h_seats_min, h_seats_max)
|
||||||
c = self.get_cursor()
|
c = self.get_cursor()
|
||||||
|
|
||||||
# now get the stats
|
# now get the stats
|
||||||
|
@ -533,6 +566,7 @@ class Database:
|
||||||
# Loop through stats adding them to appropriate stat_dict:
|
# Loop through stats adding them to appropriate stat_dict:
|
||||||
while row:
|
while row:
|
||||||
playerid = row[0]
|
playerid = row[0]
|
||||||
|
seats = row[1]
|
||||||
if (playerid == hero_id and h_hud_style == 'S') or (playerid != hero_id and hud_style == 'S'):
|
if (playerid == hero_id and h_hud_style == 'S') or (playerid != hero_id and hud_style == 'S'):
|
||||||
for name, val in zip(colnames, row):
|
for name, val in zip(colnames, row):
|
||||||
if not playerid in stat_dict:
|
if not playerid in stat_dict:
|
||||||
|
@ -544,7 +578,7 @@ class Database:
|
||||||
stat_dict[playerid][name.lower()] += val
|
stat_dict[playerid][name.lower()] += val
|
||||||
n += 1
|
n += 1
|
||||||
if n >= 10000: break # todo: don't think this is needed so set nice and high
|
if n >= 10000: break # todo: don't think this is needed so set nice and high
|
||||||
# for now - comment out or remove?
|
# prevents infinite loop so leave for now - comment out or remove?
|
||||||
row = c.fetchone()
|
row = c.fetchone()
|
||||||
else:
|
else:
|
||||||
log.error("ERROR: query %s result does not have player_id as first column" % (query,))
|
log.error("ERROR: query %s result does not have player_id as first column" % (query,))
|
||||||
|
@ -1134,9 +1168,9 @@ class Database:
|
||||||
print "dropping mysql index ", idx['tab'], idx['col']
|
print "dropping mysql index ", idx['tab'], idx['col']
|
||||||
try:
|
try:
|
||||||
self.get_cursor().execute( "alter table %s drop index %s"
|
self.get_cursor().execute( "alter table %s drop index %s"
|
||||||
, (idx['tab'],idx['col']) )
|
, (idx['tab'], idx['col']) )
|
||||||
except:
|
except:
|
||||||
pass
|
print " drop idx failed: " + str(sys.exc_info())
|
||||||
elif self.backend == self.PGSQL:
|
elif self.backend == self.PGSQL:
|
||||||
print "dropping pg index ", idx['tab'], idx['col']
|
print "dropping pg index ", idx['tab'], idx['col']
|
||||||
# mod to use tab_col for index name?
|
# mod to use tab_col for index name?
|
||||||
|
@ -1144,13 +1178,119 @@ class Database:
|
||||||
self.get_cursor().execute( "drop index %s_%s_idx"
|
self.get_cursor().execute( "drop index %s_%s_idx"
|
||||||
% (idx['tab'],idx['col']) )
|
% (idx['tab'],idx['col']) )
|
||||||
except:
|
except:
|
||||||
pass
|
print " drop idx failed: " + str(sys.exc_info())
|
||||||
else:
|
else:
|
||||||
print "Only MySQL and Postgres supported so far"
|
print "Only MySQL and Postgres supported so far"
|
||||||
return -1
|
return -1
|
||||||
if self.backend == self.PGSQL:
|
if self.backend == self.PGSQL:
|
||||||
self.connection.set_isolation_level(1) # go back to normal isolation level
|
self.connection.set_isolation_level(1) # go back to normal isolation level
|
||||||
#end def dropAllIndexes
|
#end def dropAllIndexes
|
||||||
|
|
||||||
|
def createAllForeignKeys(self):
|
||||||
|
"""Create foreign keys"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
if self.backend == self.PGSQL:
|
||||||
|
self.connection.set_isolation_level(0) # allow table/index operations to work
|
||||||
|
c = self.get_cursor()
|
||||||
|
except:
|
||||||
|
print " set_isolation_level failed: " + str(sys.exc_info())
|
||||||
|
|
||||||
|
for fk in self.foreignKeys[self.backend]:
|
||||||
|
if self.backend == self.MYSQL_INNODB:
|
||||||
|
c.execute("SELECT constraint_name " +
|
||||||
|
"FROM information_schema.KEY_COLUMN_USAGE " +
|
||||||
|
#"WHERE REFERENCED_TABLE_SCHEMA = 'fpdb'
|
||||||
|
"WHERE 1=1 " +
|
||||||
|
"AND table_name = %s AND column_name = %s " +
|
||||||
|
"AND referenced_table_name = %s " +
|
||||||
|
"AND referenced_column_name = %s ",
|
||||||
|
(fk['fktab'], fk['fkcol'], fk['rtab'], fk['rcol']) )
|
||||||
|
cons = c.fetchone()
|
||||||
|
#print "afterbulk: cons=", cons
|
||||||
|
if cons:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print "creating fk ", fk['fktab'], fk['fkcol'], "->", fk['rtab'], fk['rcol']
|
||||||
|
try:
|
||||||
|
c.execute("alter table " + fk['fktab'] + " add foreign key ("
|
||||||
|
+ fk['fkcol'] + ") references " + fk['rtab'] + "("
|
||||||
|
+ fk['rcol'] + ")")
|
||||||
|
except:
|
||||||
|
print " create fk failed: " + str(sys.exc_info())
|
||||||
|
elif self.backend == self.PGSQL:
|
||||||
|
print "creating fk ", fk['fktab'], fk['fkcol'], "->", fk['rtab'], fk['rcol']
|
||||||
|
try:
|
||||||
|
c.execute("alter table " + fk['fktab'] + " add constraint "
|
||||||
|
+ fk['fktab'] + '_' + fk['fkcol'] + '_fkey'
|
||||||
|
+ " foreign key (" + fk['fkcol']
|
||||||
|
+ ") references " + fk['rtab'] + "(" + fk['rcol'] + ")")
|
||||||
|
except:
|
||||||
|
print " create fk failed: " + str(sys.exc_info())
|
||||||
|
else:
|
||||||
|
print "Only MySQL and Postgres supported so far"
|
||||||
|
|
||||||
|
try:
|
||||||
|
if self.backend == self.PGSQL:
|
||||||
|
self.connection.set_isolation_level(1) # go back to normal isolation level
|
||||||
|
except:
|
||||||
|
print " set_isolation_level failed: " + str(sys.exc_info())
|
||||||
|
#end def createAllForeignKeys
|
||||||
|
|
||||||
|
def dropAllForeignKeys(self):
|
||||||
|
"""Drop all standalone indexes (i.e. not including primary keys or foreign keys)
|
||||||
|
using list of indexes in indexes data structure"""
|
||||||
|
# maybe upgrade to use data dictionary?? (but take care to exclude PK and FK)
|
||||||
|
if self.backend == self.PGSQL:
|
||||||
|
self.connection.set_isolation_level(0) # allow table/index operations to work
|
||||||
|
c = self.get_cursor()
|
||||||
|
|
||||||
|
for fk in self.foreignKeys[self.backend]:
|
||||||
|
if self.backend == self.MYSQL_INNODB:
|
||||||
|
c.execute("SELECT constraint_name " +
|
||||||
|
"FROM information_schema.KEY_COLUMN_USAGE " +
|
||||||
|
#"WHERE REFERENCED_TABLE_SCHEMA = 'fpdb'
|
||||||
|
"WHERE 1=1 " +
|
||||||
|
"AND table_name = %s AND column_name = %s " +
|
||||||
|
"AND referenced_table_name = %s " +
|
||||||
|
"AND referenced_column_name = %s ",
|
||||||
|
(fk['fktab'], fk['fkcol'], fk['rtab'], fk['rcol']) )
|
||||||
|
cons = c.fetchone()
|
||||||
|
#print "preparebulk find fk: cons=", cons
|
||||||
|
if cons:
|
||||||
|
print "dropping mysql fk", cons[0], fk['fktab'], fk['fkcol']
|
||||||
|
try:
|
||||||
|
c.execute("alter table " + fk['fktab'] + " drop foreign key " + cons[0])
|
||||||
|
except:
|
||||||
|
print " drop failed: " + str(sys.exc_info())
|
||||||
|
elif self.backend == self.PGSQL:
|
||||||
|
# DON'T FORGET TO RECREATE THEM!!
|
||||||
|
print "dropping pg fk", fk['fktab'], fk['fkcol']
|
||||||
|
try:
|
||||||
|
# try to lock table to see if index drop will work:
|
||||||
|
# hmmm, tested by commenting out rollback in grapher. lock seems to work but
|
||||||
|
# then drop still hangs :-( does work in some tests though??
|
||||||
|
# will leave code here for now pending further tests/enhancement ...
|
||||||
|
c.execute( "lock table %s in exclusive mode nowait" % (fk['fktab'],) )
|
||||||
|
#print "after lock, status:", c.statusmessage
|
||||||
|
#print "alter table %s drop constraint %s_%s_fkey" % (fk['fktab'], fk['fktab'], fk['fkcol'])
|
||||||
|
try:
|
||||||
|
c.execute("alter table %s drop constraint %s_%s_fkey" % (fk['fktab'], fk['fktab'], fk['fkcol']))
|
||||||
|
print "dropped pg fk pg fk %s_%s_fkey, continuing ..." % (fk['fktab'], fk['fkcol'])
|
||||||
|
except:
|
||||||
|
if "does not exist" not in str(sys.exc_value):
|
||||||
|
print "warning: drop pg fk %s_%s_fkey failed: %s, continuing ..." \
|
||||||
|
% (fk['fktab'], fk['fkcol'], str(sys.exc_value).rstrip('\n') )
|
||||||
|
except:
|
||||||
|
print "warning: constraint %s_%s_fkey not dropped: %s, continuing ..." \
|
||||||
|
% (fk['fktab'],fk['fkcol'], str(sys.exc_value).rstrip('\n'))
|
||||||
|
else:
|
||||||
|
print "Only MySQL and Postgres supported so far"
|
||||||
|
|
||||||
|
if self.backend == self.PGSQL:
|
||||||
|
self.connection.set_isolation_level(1) # go back to normal isolation level
|
||||||
|
#end def dropAllForeignKeys
|
||||||
|
|
||||||
|
|
||||||
def fillDefaultData(self):
|
def fillDefaultData(self):
|
||||||
c = self.get_cursor()
|
c = self.get_cursor()
|
||||||
|
@ -1178,6 +1318,12 @@ class Database:
|
||||||
|
|
||||||
#end def fillDefaultData
|
#end def fillDefaultData
|
||||||
|
|
||||||
|
def rebuild_indexes(self, start=None):
|
||||||
|
self.dropAllIndexes()
|
||||||
|
self.createAllIndexes()
|
||||||
|
self.dropAllForeignKeys()
|
||||||
|
self.createAllForeignKeys()
|
||||||
|
|
||||||
def rebuild_hudcache(self, start=None):
|
def rebuild_hudcache(self, start=None):
|
||||||
"""clears hudcache and rebuilds from the individual handsplayers records"""
|
"""clears hudcache and rebuilds from the individual handsplayers records"""
|
||||||
|
|
||||||
|
@ -1260,7 +1406,7 @@ class Database:
|
||||||
except:
|
except:
|
||||||
print "Error during analyze:", str(sys.exc_value)
|
print "Error during analyze:", str(sys.exc_value)
|
||||||
elif self.backend == self.PGSQL:
|
elif self.backend == self.PGSQL:
|
||||||
self.connection.set_isolation_level(0) # allow vacuum to work
|
self.connection.set_isolation_level(0) # allow analyze to work
|
||||||
try:
|
try:
|
||||||
self.get_cursor().execute(self.sql.query['analyze'])
|
self.get_cursor().execute(self.sql.query['analyze'])
|
||||||
except:
|
except:
|
||||||
|
@ -1271,6 +1417,25 @@ class Database:
|
||||||
print "Analyze took %.1f seconds" % (atime,)
|
print "Analyze took %.1f seconds" % (atime,)
|
||||||
#end def analyzeDB
|
#end def analyzeDB
|
||||||
|
|
||||||
|
def vacuumDB(self):
|
||||||
|
"""Do whatever the DB can offer to update index/table statistics"""
|
||||||
|
stime = time()
|
||||||
|
if self.backend == self.MYSQL_INNODB:
|
||||||
|
try:
|
||||||
|
self.get_cursor().execute(self.sql.query['vacuum'])
|
||||||
|
except:
|
||||||
|
print "Error during vacuum:", str(sys.exc_value)
|
||||||
|
elif self.backend == self.PGSQL:
|
||||||
|
self.connection.set_isolation_level(0) # allow vacuum to work
|
||||||
|
try:
|
||||||
|
self.get_cursor().execute(self.sql.query['vacuum'])
|
||||||
|
except:
|
||||||
|
print "Error during vacuum:", str(sys.exc_value)
|
||||||
|
self.connection.set_isolation_level(1) # go back to normal isolation level
|
||||||
|
self.commit()
|
||||||
|
atime = time() - stime
|
||||||
|
print "Vacuum took %.1f seconds" % (atime,)
|
||||||
|
#end def analyzeDB
|
||||||
|
|
||||||
# Start of Hand Writing routines. Idea is to provide a mixture of routines to store Hand data
|
# Start of Hand Writing routines. Idea is to provide a mixture of routines to store Hand data
|
||||||
# however the calling prog requires. Main aims:
|
# however the calling prog requires. Main aims:
|
||||||
|
@ -1352,7 +1517,9 @@ class Database:
|
||||||
|
|
||||||
q = q.replace('%s', self.sql.query['placeholder'])
|
q = q.replace('%s', self.sql.query['placeholder'])
|
||||||
|
|
||||||
self.cursor.execute(q, (
|
c = self.get_cursor()
|
||||||
|
|
||||||
|
c.execute(q, (
|
||||||
p['tableName'],
|
p['tableName'],
|
||||||
p['gameTypeId'],
|
p['gameTypeId'],
|
||||||
p['siteHandNo'],
|
p['siteHandNo'],
|
||||||
|
@ -1383,7 +1550,7 @@ class Database:
|
||||||
p['street4Pot'],
|
p['street4Pot'],
|
||||||
p['showdownPot']
|
p['showdownPot']
|
||||||
))
|
))
|
||||||
return self.get_last_insert_id(self.cursor)
|
return self.get_last_insert_id(c)
|
||||||
# def storeHand
|
# def storeHand
|
||||||
|
|
||||||
def storeHandsPlayers(self, hid, pids, pdata):
|
def storeHandsPlayers(self, hid, pids, pdata):
|
||||||
|
@ -1394,11 +1561,47 @@ class Database:
|
||||||
pids[p],
|
pids[p],
|
||||||
pdata[p]['startCash'],
|
pdata[p]['startCash'],
|
||||||
pdata[p]['seatNo'],
|
pdata[p]['seatNo'],
|
||||||
|
pdata[p]['card1'],
|
||||||
|
pdata[p]['card2'],
|
||||||
|
pdata[p]['card3'],
|
||||||
|
pdata[p]['card4'],
|
||||||
|
pdata[p]['card5'],
|
||||||
|
pdata[p]['card6'],
|
||||||
|
pdata[p]['card7'],
|
||||||
|
pdata[p]['winnings'],
|
||||||
|
pdata[p]['rake'],
|
||||||
|
pdata[p]['totalProfit'],
|
||||||
|
pdata[p]['street0VPI'],
|
||||||
|
pdata[p]['street1Seen'],
|
||||||
|
pdata[p]['street2Seen'],
|
||||||
|
pdata[p]['street3Seen'],
|
||||||
|
pdata[p]['street4Seen'],
|
||||||
|
pdata[p]['sawShowdown'],
|
||||||
|
pdata[p]['wonAtSD'],
|
||||||
pdata[p]['street0Aggr'],
|
pdata[p]['street0Aggr'],
|
||||||
pdata[p]['street1Aggr'],
|
pdata[p]['street1Aggr'],
|
||||||
pdata[p]['street2Aggr'],
|
pdata[p]['street2Aggr'],
|
||||||
pdata[p]['street3Aggr'],
|
pdata[p]['street3Aggr'],
|
||||||
pdata[p]['street4Aggr']
|
pdata[p]['street4Aggr'],
|
||||||
|
pdata[p]['street1CBChance'],
|
||||||
|
pdata[p]['street2CBChance'],
|
||||||
|
pdata[p]['street3CBChance'],
|
||||||
|
pdata[p]['street4CBChance'],
|
||||||
|
pdata[p]['street1CBDone'],
|
||||||
|
pdata[p]['street2CBDone'],
|
||||||
|
pdata[p]['street3CBDone'],
|
||||||
|
pdata[p]['street4CBDone'],
|
||||||
|
pdata[p]['wonWhenSeenStreet1'],
|
||||||
|
pdata[p]['street0Calls'],
|
||||||
|
pdata[p]['street1Calls'],
|
||||||
|
pdata[p]['street2Calls'],
|
||||||
|
pdata[p]['street3Calls'],
|
||||||
|
pdata[p]['street4Calls'],
|
||||||
|
pdata[p]['street0Bets'],
|
||||||
|
pdata[p]['street1Bets'],
|
||||||
|
pdata[p]['street2Bets'],
|
||||||
|
pdata[p]['street3Bets'],
|
||||||
|
pdata[p]['street4Bets'],
|
||||||
) )
|
) )
|
||||||
|
|
||||||
q = """INSERT INTO HandsPlayers (
|
q = """INSERT INTO HandsPlayers (
|
||||||
|
@ -1406,35 +1609,65 @@ class Database:
|
||||||
playerId,
|
playerId,
|
||||||
startCash,
|
startCash,
|
||||||
seatNo,
|
seatNo,
|
||||||
|
card1,
|
||||||
|
card2,
|
||||||
|
card3,
|
||||||
|
card4,
|
||||||
|
card5,
|
||||||
|
card6,
|
||||||
|
card7,
|
||||||
|
winnings,
|
||||||
|
rake,
|
||||||
|
totalProfit,
|
||||||
|
street0VPI,
|
||||||
|
street1Seen,
|
||||||
|
street2Seen,
|
||||||
|
street3Seen,
|
||||||
|
street4Seen,
|
||||||
|
sawShowdown,
|
||||||
|
wonAtSD,
|
||||||
street0Aggr,
|
street0Aggr,
|
||||||
street1Aggr,
|
street1Aggr,
|
||||||
street2Aggr,
|
street2Aggr,
|
||||||
street3Aggr,
|
street3Aggr,
|
||||||
street4Aggr
|
street4Aggr,
|
||||||
|
street1CBChance,
|
||||||
|
street2CBChance,
|
||||||
|
street3CBChance,
|
||||||
|
street4CBChance,
|
||||||
|
street1CBDone,
|
||||||
|
street2CBDone,
|
||||||
|
street3CBDone,
|
||||||
|
street4CBDone,
|
||||||
|
wonWhenSeenStreet1,
|
||||||
|
street0Calls,
|
||||||
|
street1Calls,
|
||||||
|
street2Calls,
|
||||||
|
street3Calls,
|
||||||
|
street4Calls,
|
||||||
|
street0Bets,
|
||||||
|
street1Bets,
|
||||||
|
street2Bets,
|
||||||
|
street3Bets,
|
||||||
|
street4Bets
|
||||||
)
|
)
|
||||||
VALUES (
|
VALUES (
|
||||||
%s, %s, %s, %s, %s,
|
%s, %s, %s, %s, %s,
|
||||||
%s, %s, %s, %s
|
%s, %s, %s, %s, %s,
|
||||||
|
%s, %s, %s, %s, %s,
|
||||||
|
%s, %s, %s, %s, %s,
|
||||||
|
%s, %s, %s, %s, %s,
|
||||||
|
%s, %s, %s, %s, %s,
|
||||||
|
%s, %s, %s, %s, %s,
|
||||||
|
%s, %s, %s, %s, %s,
|
||||||
|
%s, %s, %s, %s, %s
|
||||||
)"""
|
)"""
|
||||||
|
|
||||||
# position,
|
# position,
|
||||||
# tourneyTypeId,
|
# tourneyTypeId,
|
||||||
# card1,
|
|
||||||
# card2,
|
|
||||||
# card3,
|
|
||||||
# card4,
|
|
||||||
# startCards,
|
# startCards,
|
||||||
# winnings,
|
|
||||||
# rake,
|
|
||||||
# totalProfit,
|
|
||||||
# street0VPI,
|
|
||||||
# street0_3BChance,
|
# street0_3BChance,
|
||||||
# street0_3BDone,
|
# street0_3BDone,
|
||||||
# street1Seen,
|
|
||||||
# street2Seen,
|
|
||||||
# street3Seen,
|
|
||||||
# street4Seen,
|
|
||||||
# sawShowdown,
|
|
||||||
# otherRaisedStreet1,
|
# otherRaisedStreet1,
|
||||||
# otherRaisedStreet2,
|
# otherRaisedStreet2,
|
||||||
# otherRaisedStreet3,
|
# otherRaisedStreet3,
|
||||||
|
@ -1443,22 +1676,12 @@ class Database:
|
||||||
# foldToOtherRaisedStreet2,
|
# foldToOtherRaisedStreet2,
|
||||||
# foldToOtherRaisedStreet3,
|
# foldToOtherRaisedStreet3,
|
||||||
# foldToOtherRaisedStreet4,
|
# foldToOtherRaisedStreet4,
|
||||||
# wonWhenSeenStreet1,
|
|
||||||
# wonAtSD,
|
|
||||||
# stealAttemptChance,
|
# stealAttemptChance,
|
||||||
# stealAttempted,
|
# stealAttempted,
|
||||||
# foldBbToStealChance,
|
# foldBbToStealChance,
|
||||||
# foldedBbToSteal,
|
# foldedBbToSteal,
|
||||||
# foldSbToStealChance,
|
# foldSbToStealChance,
|
||||||
# foldedSbToSteal,
|
# foldedSbToSteal,
|
||||||
# street1CBChance,
|
|
||||||
# street1CBDone,
|
|
||||||
# street2CBChance,
|
|
||||||
# street2CBDone,
|
|
||||||
# street3CBChance,
|
|
||||||
# street3CBDone,
|
|
||||||
# street4CBChance,
|
|
||||||
# street4CBDone,
|
|
||||||
# foldToStreet1CBChance,
|
# foldToStreet1CBChance,
|
||||||
# foldToStreet1CBDone,
|
# foldToStreet1CBDone,
|
||||||
# foldToStreet2CBChance,
|
# foldToStreet2CBChance,
|
||||||
|
@ -1475,21 +1698,13 @@ class Database:
|
||||||
# street3CheckCallRaiseDone,
|
# street3CheckCallRaiseDone,
|
||||||
# street4CheckCallRaiseChance,
|
# street4CheckCallRaiseChance,
|
||||||
# street4CheckCallRaiseDone,
|
# street4CheckCallRaiseDone,
|
||||||
# street0Calls,
|
|
||||||
# street1Calls,
|
|
||||||
# street2Calls,
|
|
||||||
# street3Calls,
|
|
||||||
# street4Calls,
|
|
||||||
# street0Bets,
|
|
||||||
# street1Bets,
|
|
||||||
# street2Bets,
|
|
||||||
# street3Bets,
|
|
||||||
# street4Bets
|
|
||||||
|
|
||||||
q = q.replace('%s', self.sql.query['placeholder'])
|
q = q.replace('%s', self.sql.query['placeholder'])
|
||||||
|
|
||||||
#print "DEBUG: inserts: %s" %inserts
|
#print "DEBUG: inserts: %s" %inserts
|
||||||
self.cursor.executemany(q, inserts)
|
#print "DEBUG: q: %s" % q
|
||||||
|
c = self.get_cursor()
|
||||||
|
c.executemany(q, inserts)
|
||||||
|
|
||||||
def storeHudCacheNew(self, gid, pid, hc):
|
def storeHudCacheNew(self, gid, pid, hc):
|
||||||
q = """INSERT INTO HudCache (
|
q = """INSERT INTO HudCache (
|
||||||
|
@ -1631,6 +1846,15 @@ class Database:
|
||||||
# street4CheckCallRaiseChance,
|
# street4CheckCallRaiseChance,
|
||||||
# street4CheckCallRaiseDone)
|
# street4CheckCallRaiseDone)
|
||||||
|
|
||||||
|
def isDuplicate(self, gametypeID, siteHandNo):
|
||||||
|
dup = False
|
||||||
|
c = self.get_cursor()
|
||||||
|
c.execute(self.sql.query['isAlreadyInDB'], (gametypeID, siteHandNo))
|
||||||
|
result = c.fetchall()
|
||||||
|
if len(result) > 0:
|
||||||
|
dup = True
|
||||||
|
return dup
|
||||||
|
|
||||||
def getGameTypeId(self, siteid, game):
|
def getGameTypeId(self, siteid, game):
|
||||||
c = self.get_cursor()
|
c = self.get_cursor()
|
||||||
#FIXME: Fixed for NL at the moment
|
#FIXME: Fixed for NL at the moment
|
||||||
|
@ -1670,6 +1894,13 @@ class Database:
|
||||||
q = "SELECT name, id FROM Players WHERE siteid=%s and name=%s"
|
q = "SELECT name, id FROM Players WHERE siteid=%s and name=%s"
|
||||||
q = q.replace('%s', self.sql.query['placeholder'])
|
q = q.replace('%s', self.sql.query['placeholder'])
|
||||||
|
|
||||||
|
#NOTE/FIXME?: MySQL has ON DUPLICATE KEY UPDATE
|
||||||
|
#Usage:
|
||||||
|
# INSERT INTO `tags` (`tag`, `count`)
|
||||||
|
# VALUES ($tag, 1)
|
||||||
|
# ON DUPLICATE KEY UPDATE `count`=`count`+1;
|
||||||
|
|
||||||
|
|
||||||
#print "DEBUG: name: %s site: %s" %(name, site_id)
|
#print "DEBUG: name: %s site: %s" %(name, site_id)
|
||||||
|
|
||||||
c.execute (q, (site_id, name))
|
c.execute (q, (site_id, name))
|
||||||
|
@ -2684,14 +2915,14 @@ class HandToWrite:
|
||||||
if __name__=="__main__":
|
if __name__=="__main__":
|
||||||
c = Configuration.Config()
|
c = Configuration.Config()
|
||||||
|
|
||||||
db_connection = Database(c, 'fpdb', 'holdem') # mysql fpdb holdem
|
db_connection = Database(c) # mysql fpdb holdem
|
||||||
# db_connection = Database(c, 'fpdb-p', 'test') # mysql fpdb holdem
|
# db_connection = Database(c, 'fpdb-p', 'test') # mysql fpdb holdem
|
||||||
# db_connection = Database(c, 'PTrackSv2', 'razz') # mysql razz
|
# db_connection = Database(c, 'PTrackSv2', 'razz') # mysql razz
|
||||||
# db_connection = Database(c, 'ptracks', 'razz') # postgres
|
# db_connection = Database(c, 'ptracks', 'razz') # postgres
|
||||||
print "database connection object = ", db_connection.connection
|
print "database connection object = ", db_connection.connection
|
||||||
print "database type = ", db_connection.type
|
# db_connection.recreate_tables()
|
||||||
|
db_connection.dropAllIndexes()
|
||||||
db_connection.recreate_tables()
|
db_connection.createAllIndexes()
|
||||||
|
|
||||||
h = db_connection.get_last_hand()
|
h = db_connection.get_last_hand()
|
||||||
print "last hand = ", h
|
print "last hand = ", h
|
||||||
|
@ -2704,18 +2935,12 @@ if __name__=="__main__":
|
||||||
for p in stat_dict.keys():
|
for p in stat_dict.keys():
|
||||||
print p, " ", stat_dict[p]
|
print p, " ", stat_dict[p]
|
||||||
|
|
||||||
#print "nutOmatics stats:"
|
|
||||||
#stat_dict = db_connection.get_stats_from_hand(h, "ring")
|
|
||||||
#for p in stat_dict.keys():
|
|
||||||
# print p, " ", stat_dict[p]
|
|
||||||
|
|
||||||
print "cards =", db_connection.get_cards(u'1')
|
print "cards =", db_connection.get_cards(u'1')
|
||||||
db_connection.close_connection
|
db_connection.close_connection
|
||||||
|
|
||||||
print "press enter to continue"
|
print "press enter to continue"
|
||||||
sys.stdin.readline()
|
sys.stdin.readline()
|
||||||
|
|
||||||
|
|
||||||
#Code borrowed from http://push.cx/2008/caching-dictionaries-in-python-vs-ruby
|
#Code borrowed from http://push.cx/2008/caching-dictionaries-in-python-vs-ruby
|
||||||
class LambdaDict(dict):
|
class LambdaDict(dict):
|
||||||
def __init__(self, l):
|
def __init__(self, l):
|
||||||
|
|
|
@ -1,28 +1,85 @@
|
||||||
|
"""Database manager
|
||||||
|
|
||||||
|
@todo: (gtk) how to validate user input in gtk.Dialog? as soon as the user clicks ok the dialog is dead. we use a while loop as workaround. not nice
|
||||||
|
@todo: (fpdb) we need the application name 'fpdb' from somewhere to put it in dialog titles
|
||||||
|
@todo: (fpdb) config object should be initialized globally and accessible from all modules via Configuration.py
|
||||||
|
|
||||||
|
@todo: (all dialogs) save/restore size and pos
|
||||||
|
|
||||||
|
@todo: (WidgetDatabaseManager) give database status meaningful colors
|
||||||
|
@todo: (WidgetDatabaseManager) implement database purging
|
||||||
|
@todo: (WidgetDatabaseManager) implement database export
|
||||||
|
@todo: (WidgetDatabaseManager) what to do on database doubleclick?
|
||||||
|
@todo: (WidgetDatabaseManager) context menu for database tree
|
||||||
|
@todo: (WidgetDatabaseManager) initializing/validating databases may take a while. how to give feedback?
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import pygtk
|
import pygtk
|
||||||
pygtk.require('2.0')
|
pygtk.require('2.0')
|
||||||
import gtk
|
import gtk
|
||||||
|
import gobject
|
||||||
|
|
||||||
#*******************************************************************************************************
|
#*******************************************************************************************************
|
||||||
class DatabaseManager(object):
|
class DatabaseManager(gobject.GObject):
|
||||||
DatabaseTypes = {}
|
DatabaseTypes = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_fpdb(klass, data, defaultDatabaseType=None):
|
def from_fpdb(klass, data, defaultDatabaseType=None):
|
||||||
#TODO: parse whatever data is
|
|
||||||
#TODO: sort out unsupported databases passed by user and log
|
#NOTE: if no databases are present in config fpdb fails with
|
||||||
databases = (
|
# Traceback (most recent call last):
|
||||||
DatabaseTypeSqLite(name='myDb'),
|
# File "/home/me2/Scr/Repos/fpdb-mme/pyfpdb/DatabaseManager.py", line 783, in <module>
|
||||||
DatabaseTypeSqLite(name='myDb2'),
|
# databaseManager = DatabaseManager.from_fpdb('', defaultDatabaseType=DatabaseTypeSqLite)
|
||||||
|
# File "/home/me2/Scr/Repos/fpdb-mme/pyfpdb/DatabaseManager.py", line 36, in from_fpdb
|
||||||
)
|
# config = Configuration.Config(file=options.config, dbname=options.dbname)
|
||||||
|
# File "/home/me2/Scr/Repos/fpdb-mme/pyfpdb/Configuration.py", line 436, in __init__
|
||||||
|
# db = self.get_db_parameters()
|
||||||
|
# File "/home/me2/Scr/Repos/fpdb-mme/pyfpdb/Configuration.py", line 583, in get_db_parameters
|
||||||
|
# name = self.db_selected
|
||||||
|
# AttributeError: Config instance has no attribute 'db_selected'
|
||||||
|
import sys
|
||||||
|
import Options
|
||||||
|
import Configuration
|
||||||
|
#NOTE: fpdb should perform this globally
|
||||||
|
(options, argv) = Options.fpdb_options()
|
||||||
|
config = Configuration.Config(file=options.config, dbname=options.dbname)
|
||||||
|
#TODO: handle no database present
|
||||||
|
defaultDatabaseName = config.get_db_parameters().get('db-databaseName', None)
|
||||||
|
#TODO: fpdb stores databases in no particular order. this has to be fixed somehow
|
||||||
|
databases = []
|
||||||
|
for name, fpdbDatabase in config.supported_databases.items():
|
||||||
|
databaseKlass = klass.DatabaseTypes.get(fpdbDatabase.db_server, None)
|
||||||
|
#NOTE: Config does not seem to validate user input, so anything may end up here
|
||||||
|
if databaseKlass is None:
|
||||||
|
raise ValueError('Unknown databasetype: %s' % fpdbDatabase.db_server)
|
||||||
|
|
||||||
|
database = databaseKlass()
|
||||||
|
if database.Type == 'sqlite':
|
||||||
|
database.name = fpdbDatabase.db_name
|
||||||
|
database.file = fpdbDatabase.db_server
|
||||||
|
else:
|
||||||
|
database.name = fpdbDatabase.db_name
|
||||||
|
database.host = fpdbDatabase.db_server
|
||||||
|
#NOTE: fpdbDatabase.db_ip is no is a string
|
||||||
|
database.port = int(fpdbDatabase.db_ip)
|
||||||
|
database.user = fpdbDatabase.db_user
|
||||||
|
database.password = fpdbDatabase.db_pass
|
||||||
|
databases.append(database)
|
||||||
|
|
||||||
return klass(databases=databases, defaultDatabaseType=defaultDatabaseType)
|
return klass(databases=databases, defaultDatabaseType=defaultDatabaseType)
|
||||||
|
|
||||||
|
def to_fpdb(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, databases=None, defaultDatabaseType=None):
|
def __init__(self, databases=None, defaultDatabaseType=None):
|
||||||
|
gobject.GObject.__init__(self)
|
||||||
|
|
||||||
self._defaultDatabaseType = defaultDatabaseType
|
self._defaultDatabaseType = defaultDatabaseType
|
||||||
self._databases = [] if databases is None else list(databases)
|
self._databases = [] if databases is None else list(databases)
|
||||||
|
self._activeDatabase = None
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return iter(self._databases)
|
return iter(self._databases)
|
||||||
def set_default_database_type(self, databaseType):
|
def set_default_database_type(self, databaseType):
|
||||||
|
@ -31,7 +88,7 @@ class DatabaseManager(object):
|
||||||
return self._defaultDatabaseType
|
return self._defaultDatabaseType
|
||||||
def database_from_id(self, idDatabase):
|
def database_from_id(self, idDatabase):
|
||||||
for database in self._databases:
|
for database in self._databases:
|
||||||
if idDatabase == id(database):
|
if idDatabase == self.database_id(database):
|
||||||
return database
|
return database
|
||||||
def database_id(self, database):
|
def database_id(self, database):
|
||||||
return id(database)
|
return id(database)
|
||||||
|
@ -41,8 +98,26 @@ class DatabaseManager(object):
|
||||||
self._databases.append(database)
|
self._databases.append(database)
|
||||||
def remove_database(self, database):
|
def remove_database(self, database):
|
||||||
self._databases.remove(database)
|
self._databases.remove(database)
|
||||||
def init_database(self, database):
|
|
||||||
pass
|
def activate_database(self, database):
|
||||||
|
if self._activeDatabase is not None:
|
||||||
|
self._activeDatabase.status = self._activeDatabase.StatusInactive
|
||||||
|
#TODO: finalize database
|
||||||
|
self.emit('database-deactivated', self.database_id(self._activeDatabase) )
|
||||||
|
|
||||||
|
database.status = database.StatusActive
|
||||||
|
#TODO: activate database
|
||||||
|
self._activeDatabase = database
|
||||||
|
self.emit('database-activated', self.database_id(database) )
|
||||||
|
|
||||||
|
def active_database(self):
|
||||||
|
return self._activeDatabase
|
||||||
|
|
||||||
|
# register DatabaseManager signals
|
||||||
|
gobject.type_register(DatabaseManager)
|
||||||
|
gobject.signal_new('database-activated', DatabaseManager, gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (int, ))
|
||||||
|
gobject.signal_new('database-deactivated', DatabaseManager, gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (int, ))
|
||||||
|
gobject.signal_new('database-error', DatabaseManager, gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (int, ))
|
||||||
|
|
||||||
class DatabaseTypeMeta(type):
|
class DatabaseTypeMeta(type):
|
||||||
def __new__(klass, name, bases, kws):
|
def __new__(klass, name, bases, kws):
|
||||||
|
@ -56,10 +131,25 @@ class DatabaseTypeMeta(type):
|
||||||
class DatabaseTypeBase(object):
|
class DatabaseTypeBase(object):
|
||||||
__metaclass__ = DatabaseTypeMeta
|
__metaclass__ = DatabaseTypeMeta
|
||||||
Type = None
|
Type = None
|
||||||
Params = ()
|
StatusActive = 'active'
|
||||||
|
StatusInactive = 'inactive'
|
||||||
|
StatusError = 'error' #TODO: not implemented
|
||||||
|
|
||||||
|
#TODO: not happy with returning error string. just being too lazy to impl dozens of error codes for later translation
|
||||||
|
def init_new_database(self):
|
||||||
|
"""initializes a new empty database
|
||||||
|
@return: (str) error if something goes wrong, None otherwise
|
||||||
|
"""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def validate_database(self):
|
||||||
|
"""checks if the database is valid
|
||||||
|
@return: (str) error if something goes wrong, None otherwise
|
||||||
|
"""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
class DatabaseTypePostgres(DatabaseTypeBase):
|
class DatabaseTypePostgres(DatabaseTypeBase):
|
||||||
Type = 'postgres'
|
Type = 'postgresql'
|
||||||
@classmethod
|
@classmethod
|
||||||
def display_name(klass):
|
def display_name(klass):
|
||||||
return 'Postgres'
|
return 'Postgres'
|
||||||
|
@ -70,6 +160,15 @@ class DatabaseTypePostgres(DatabaseTypeBase):
|
||||||
self.user = user
|
self.user = user
|
||||||
self.password = password
|
self.password = password
|
||||||
self.database = database
|
self.database = database
|
||||||
|
self.status = self.StatusInactive
|
||||||
|
|
||||||
|
#TODO: implement
|
||||||
|
def init_new_database(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
#TODO: implement
|
||||||
|
def validate_database(self):
|
||||||
|
pass
|
||||||
|
|
||||||
class DatabaseTypeMysql(DatabaseTypeBase):
|
class DatabaseTypeMysql(DatabaseTypeBase):
|
||||||
Type = 'mysql'
|
Type = 'mysql'
|
||||||
|
@ -83,6 +182,16 @@ class DatabaseTypeMysql(DatabaseTypeBase):
|
||||||
self.user = user
|
self.user = user
|
||||||
self.password = password
|
self.password = password
|
||||||
self.database = database
|
self.database = database
|
||||||
|
self.status = self.StatusInactive
|
||||||
|
|
||||||
|
#TODO: implement
|
||||||
|
def init_new_database(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
#TODO: implement
|
||||||
|
def validate_database(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DatabaseTypeSqLite(DatabaseTypeBase):
|
class DatabaseTypeSqLite(DatabaseTypeBase):
|
||||||
Type = 'sqlite'
|
Type = 'sqlite'
|
||||||
|
@ -92,7 +201,26 @@ class DatabaseTypeSqLite(DatabaseTypeBase):
|
||||||
def __init__(self, name='', host='', file='', database='fpdb'):
|
def __init__(self, name='', host='', file='', database='fpdb'):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.file = file
|
self.file = file
|
||||||
self.database = database
|
self.status = self.StatusInactive
|
||||||
|
|
||||||
|
def init_new_database(self):
|
||||||
|
# make shure all attrs are specified
|
||||||
|
if not self.file:
|
||||||
|
return 'no database file specified'
|
||||||
|
# create file if necessary (this will truncate file if it exists)
|
||||||
|
try:
|
||||||
|
open(self.file, 'w').close()
|
||||||
|
except IOError:
|
||||||
|
return 'can not write file'
|
||||||
|
|
||||||
|
#TODO: init tables (...)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_database(self):
|
||||||
|
pass
|
||||||
|
#TODO: check if tables (...) exist
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#TODO: how do we want to handle unsupported database types?
|
#TODO: how do we want to handle unsupported database types?
|
||||||
# ..uncomment to remove unsupported database types
|
# ..uncomment to remove unsupported database types
|
||||||
|
@ -104,35 +232,49 @@ class DatabaseTypeSqLite(DatabaseTypeBase):
|
||||||
#except ImportError: del DatabaseManager.DatabaseTypes['sqlite']
|
#except ImportError: del DatabaseManager.DatabaseTypes['sqlite']
|
||||||
|
|
||||||
#***************************************************************************************************************************
|
#***************************************************************************************************************************
|
||||||
|
#TODO: there is no title (on linux), wtf?
|
||||||
|
def DialogError(parent=None, msg=''):
|
||||||
|
dlg = gtk.MessageDialog(
|
||||||
|
parent=parent,
|
||||||
|
flags=gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
type=gtk.MESSAGE_ERROR,
|
||||||
|
buttons=gtk.BUTTONS_OK,
|
||||||
|
message_format=msg,
|
||||||
|
)
|
||||||
|
dlg.run()
|
||||||
|
dlg.destroy()
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
#TODO: derrive from gtk.VBox?
|
#TODO: derrive from gtk.VBox?
|
||||||
class WidgetDatabaseProperties(gtk.VBox):
|
class WidgetDatabaseProperties(gtk.VBox):
|
||||||
|
|
||||||
ModeNew = 0
|
ModeNew = 0
|
||||||
ModeEdit = 1
|
ModeEdit = 1
|
||||||
ModeAdd = 2
|
ModeAdd = 2
|
||||||
|
|
||||||
class SqLiteFileChooserButton(gtk.HBox):
|
class SqLiteFileChooserButton(gtk.HBox):
|
||||||
#NOTE: for some weird reason it is impossible to let the user choose a non exiting filename with gtk.FileChooserButton, so impl our own on the fly
|
#NOTE: for some weird reason it is impossible to let the user choose a non exiting filename with gtk.FileChooserButton, so impl our own on the fly
|
||||||
def __init__(self, widgetDatabaseProperties, parentWidget):
|
def __init__(self, widgetDatabaseProperties, parentWidget):
|
||||||
gtk.HBox.__init__(self)
|
gtk.HBox.__init__(self)
|
||||||
self.set_homogeneous(False)
|
self.set_homogeneous(False)
|
||||||
|
|
||||||
self.parentWidget = parentWidget
|
self.parentWidget = parentWidget
|
||||||
self.widgetDatabaseProperties = widgetDatabaseProperties
|
self.widgetDatabaseProperties = widgetDatabaseProperties
|
||||||
self.entry = gtk.Entry()
|
self.entry = gtk.Entry()
|
||||||
self.button = gtk.Button('...')
|
self.button = gtk.Button('...')
|
||||||
self.button.connect('clicked', self.on_button_clicked)
|
self.button.connect('clicked', self.on_button_clicked)
|
||||||
|
|
||||||
# layout widgets
|
# layout widgets
|
||||||
self.pack_start(self.entry, True, True)
|
self.pack_start(self.entry, True, True)
|
||||||
self.pack_start(self.button, False, False)
|
self.pack_start(self.button, False, False)
|
||||||
|
|
||||||
def get_filename(self):
|
def get_filename(self):
|
||||||
return self.entry.get_text()
|
return self.entry.get_text()
|
||||||
|
|
||||||
def set_filename(self, name):
|
def set_filename(self, name):
|
||||||
self.entry.set_text(name)
|
self.entry.set_text(name)
|
||||||
|
|
||||||
def on_button_clicked(self, button):
|
def on_button_clicked(self, button):
|
||||||
if self.widgetDatabaseProperties.mode == WidgetDatabaseProperties.ModeAdd:
|
if self.widgetDatabaseProperties.mode == WidgetDatabaseProperties.ModeAdd:
|
||||||
action = gtk.FILE_CHOOSER_ACTION_OPEN
|
action = gtk.FILE_CHOOSER_ACTION_OPEN
|
||||||
|
@ -141,13 +283,13 @@ class WidgetDatabaseProperties(gtk.VBox):
|
||||||
else:
|
else:
|
||||||
raise ValueError('unsupported dialog mode')
|
raise ValueError('unsupported dialog mode')
|
||||||
dlg = gtk.FileChooserDialog(
|
dlg = gtk.FileChooserDialog(
|
||||||
title='Choose an exiting database file or type in name of a new one',
|
title='Choose an exiting database file or type in name of a new one',
|
||||||
parent=self.parentWidget,
|
parent=self.parentWidget,
|
||||||
action=action,
|
action=action,
|
||||||
buttons=(
|
buttons=(
|
||||||
gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
|
gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
|
||||||
gtk.STOCK_OK, gtk.RESPONSE_OK,
|
gtk.STOCK_OK, gtk.RESPONSE_OK,
|
||||||
),
|
),
|
||||||
backend=None
|
backend=None
|
||||||
)
|
)
|
||||||
dlg.set_default_response(gtk.RESPONSE_OK)
|
dlg.set_default_response(gtk.RESPONSE_OK)
|
||||||
|
@ -156,9 +298,9 @@ class WidgetDatabaseProperties(gtk.VBox):
|
||||||
fileName = dlg.get_filename()
|
fileName = dlg.get_filename()
|
||||||
self.set_filename(fileName)
|
self.set_filename(fileName)
|
||||||
dlg.destroy()
|
dlg.destroy()
|
||||||
|
|
||||||
|
|
||||||
|
#TODO: bit ugly this thingy. try to find a better way to map database attrs to gtk widgets
|
||||||
class FieldWidget(object):
|
class FieldWidget(object):
|
||||||
def __init__(self, text='', attrDatabase='', widget=None, attrGet=None, attrSet=None, defaultValue=None, canEdit=False, tooltip=''):
|
def __init__(self, text='', attrDatabase='', widget=None, attrGet=None, attrSet=None, defaultValue=None, canEdit=False, tooltip=''):
|
||||||
"""
|
"""
|
||||||
|
@ -168,15 +310,15 @@ class WidgetDatabaseProperties(gtk.VBox):
|
||||||
self._attrDatabase = attrDatabase
|
self._attrDatabase = attrDatabase
|
||||||
self._widget = widget
|
self._widget = widget
|
||||||
self._defaultValue = defaultValue
|
self._defaultValue = defaultValue
|
||||||
self._attrGetter=None,
|
self._attrGetter=None,
|
||||||
self._attrGet = attrGet
|
self._attrGet = attrGet
|
||||||
self._attrSet = attrSet
|
self._attrSet = attrSet
|
||||||
self._canEdit = canEdit
|
self._canEdit = canEdit
|
||||||
|
|
||||||
self._label.set_tooltip_text(tooltip)
|
self._label.set_tooltip_text(tooltip)
|
||||||
self._widget.set_tooltip_text(tooltip)
|
self._widget.set_tooltip_text(tooltip)
|
||||||
|
|
||||||
def widget(self):
|
def widget(self):
|
||||||
return self._widget
|
return self._widget
|
||||||
def label(self):
|
def label(self):
|
||||||
return self._label
|
return self._label
|
||||||
|
@ -193,10 +335,10 @@ class WidgetDatabaseProperties(gtk.VBox):
|
||||||
setattr(database, self._attrDatabase, getattr(self._widget, self._attrGet)() )
|
setattr(database, self._attrDatabase, getattr(self._widget, self._attrGet)() )
|
||||||
def reset_value(self):
|
def reset_value(self):
|
||||||
getattr(self._widget, self._attrSet)(self._defaultValue)
|
getattr(self._widget, self._attrSet)(self._defaultValue)
|
||||||
|
|
||||||
def __init__(self, databaseManager, database, mode=ModeEdit, parentWidget=None):
|
def __init__(self, databaseManager, database, mode=ModeEdit, parentWidget=None):
|
||||||
gtk.VBox.__init__(self)
|
gtk.VBox.__init__(self)
|
||||||
|
|
||||||
self.databaseManager = databaseManager
|
self.databaseManager = databaseManager
|
||||||
self.database = database
|
self.database = database
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
|
@ -204,76 +346,76 @@ class WidgetDatabaseProperties(gtk.VBox):
|
||||||
self.fieldWidgets = (
|
self.fieldWidgets = (
|
||||||
self.FieldWidget(
|
self.FieldWidget(
|
||||||
text='Name:',
|
text='Name:',
|
||||||
attrDatabase='name',
|
attrDatabase='name',
|
||||||
widget=gtk.Entry(),
|
widget=gtk.Entry(),
|
||||||
defaultValue='',
|
defaultValue='',
|
||||||
attrGet='get_text',
|
attrGet='get_text',
|
||||||
attrSet='set_text',
|
attrSet='set_text',
|
||||||
canEdit=True,
|
canEdit=True,
|
||||||
tooltip='Any name you like to name the database '
|
tooltip='Any name you like to name the database '
|
||||||
),
|
),
|
||||||
self.FieldWidget(
|
self.FieldWidget(
|
||||||
text='Db:',
|
text='File:',
|
||||||
attrDatabase='database',
|
attrDatabase='file',
|
||||||
widget=gtk.Entry(),
|
widget=self.SqLiteFileChooserButton(self, self.parentWidget),
|
||||||
defaultValue='',
|
defaultValue='',
|
||||||
attrGet='get_text',
|
attrGet='get_filename',
|
||||||
attrSet='set_text',
|
attrSet='set_filename',
|
||||||
canEdit=False,
|
canEdit=False,
|
||||||
tooltip='Name of the database to create'
|
|
||||||
),
|
|
||||||
self.FieldWidget(
|
|
||||||
text='File:',
|
|
||||||
attrDatabase='file',
|
|
||||||
widget=self.SqLiteFileChooserButton(self, self.parentWidget),
|
|
||||||
defaultValue='',
|
|
||||||
attrGet='get_filename',
|
|
||||||
attrSet='set_filename',
|
|
||||||
canEdit=False,
|
|
||||||
tooltip='Fully qualified path of the file to hold the database '
|
tooltip='Fully qualified path of the file to hold the database '
|
||||||
),
|
),
|
||||||
self.FieldWidget(
|
self.FieldWidget(
|
||||||
text='Host:',
|
text='Host:',
|
||||||
attrDatabase='host',
|
attrDatabase='host',
|
||||||
widget=gtk.Entry(),
|
widget=gtk.Entry(),
|
||||||
defaultValue='',
|
defaultValue='',
|
||||||
attrGet='get_text',
|
attrGet='get_text',
|
||||||
attrSet='set_text',
|
attrSet='set_text',
|
||||||
canEdit=False,
|
canEdit=False,
|
||||||
tooltip='Host the database is located at'
|
tooltip='Host the database is located at'
|
||||||
),
|
),
|
||||||
self.FieldWidget(
|
self.FieldWidget(
|
||||||
text='Port:',
|
text='Port:',
|
||||||
attrDatabase='port',
|
attrDatabase='port',
|
||||||
widget=gtk.SpinButton(adjustment=gtk.Adjustment(value=0, lower=0, upper=999999, step_incr=1, page_incr=10) ),
|
widget=gtk.SpinButton(adjustment=gtk.Adjustment(value=0, lower=0, upper=999999, step_incr=1, page_incr=10) ),
|
||||||
defaultValue=0,
|
defaultValue=0,
|
||||||
attrGet='get_value',
|
attrGet='get_value',
|
||||||
attrSet='set_value',
|
attrSet='set_value',
|
||||||
canEdit=False,
|
canEdit=False,
|
||||||
tooltip='Port to use to connect to the host'
|
tooltip='Port to use to connect to the host'
|
||||||
),
|
),
|
||||||
self.FieldWidget(
|
self.FieldWidget(
|
||||||
text='User:',
|
text='User:',
|
||||||
attrDatabase='user',
|
attrDatabase='user',
|
||||||
widget=gtk.Entry(),
|
widget=gtk.Entry(),
|
||||||
defaultValue='',
|
defaultValue='',
|
||||||
attrGet='get_text',
|
attrGet='get_text',
|
||||||
attrSet='set_text',
|
attrSet='set_text',
|
||||||
canEdit=False,
|
canEdit=False,
|
||||||
tooltip='User name used to login to the host'
|
tooltip='User name used to login to the host'
|
||||||
),
|
),
|
||||||
self.FieldWidget(
|
self.FieldWidget(
|
||||||
text='Pwd:',
|
text='Pwd:',
|
||||||
attrDatabase='password',
|
attrDatabase='password',
|
||||||
widget=gtk.Entry(),
|
widget=gtk.Entry(),
|
||||||
defaultValue='',
|
defaultValue='',
|
||||||
attrGet='get_text',
|
attrGet='get_text',
|
||||||
attrSet='set_text',
|
attrSet='set_text',
|
||||||
canEdit=False,
|
canEdit=False,
|
||||||
tooltip='Password used to login to the host'
|
tooltip='Password used to login to the host'
|
||||||
),
|
),
|
||||||
|
self.FieldWidget(
|
||||||
|
text='Db:',
|
||||||
|
attrDatabase='database',
|
||||||
|
widget=gtk.Entry(),
|
||||||
|
defaultValue='',
|
||||||
|
attrGet='get_text',
|
||||||
|
attrSet='set_text',
|
||||||
|
canEdit=False,
|
||||||
|
tooltip='Name of the database'
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
# setup database type combo
|
# setup database type combo
|
||||||
self.comboType = gtk.ComboBox()
|
self.comboType = gtk.ComboBox()
|
||||||
listStore= gtk.ListStore(str, str)
|
listStore= gtk.ListStore(str, str)
|
||||||
|
@ -282,7 +424,7 @@ class WidgetDatabaseProperties(gtk.VBox):
|
||||||
self.comboType.pack_start(cell, True)
|
self.comboType.pack_start(cell, True)
|
||||||
self.comboType.add_attribute(cell, 'text', 0)
|
self.comboType.add_attribute(cell, 'text', 0)
|
||||||
self.comboType.connect('changed', self.on_combo_type_changed)
|
self.comboType.connect('changed', self.on_combo_type_changed)
|
||||||
|
|
||||||
# fill database type combo with available database klasses. we store (databaseDisplayName, databaseType) in our model for later lookup
|
# fill database type combo with available database klasses. we store (databaseDisplayName, databaseType) in our model for later lookup
|
||||||
iCurrentDatabase = 0
|
iCurrentDatabase = 0
|
||||||
databaseTypes = [(klass.display_name(), klass.Type) for klass in databaseManager.DatabaseTypes.values()]
|
databaseTypes = [(klass.display_name(), klass.Type) for klass in databaseManager.DatabaseTypes.values()]
|
||||||
|
@ -293,7 +435,7 @@ class WidgetDatabaseProperties(gtk.VBox):
|
||||||
iCurrentDatabase = i
|
iCurrentDatabase = i
|
||||||
if self.mode == self.ModeEdit or len(databaseTypes) < 2:
|
if self.mode == self.ModeEdit or len(databaseTypes) < 2:
|
||||||
self.comboType.set_button_sensitivity(gtk.SENSITIVITY_OFF)
|
self.comboType.set_button_sensitivity(gtk.SENSITIVITY_OFF)
|
||||||
|
|
||||||
# init and layout field widgets
|
# init and layout field widgets
|
||||||
self.pack_start(self.comboType, False, False, 2)
|
self.pack_start(self.comboType, False, False, 2)
|
||||||
table = gtk.Table(rows=len(self.fieldWidgets) +1, columns=2, homogeneous=False)
|
table = gtk.Table(rows=len(self.fieldWidgets) +1, columns=2, homogeneous=False)
|
||||||
|
@ -301,11 +443,11 @@ class WidgetDatabaseProperties(gtk.VBox):
|
||||||
for i,fieldWidget in enumerate(self.fieldWidgets):
|
for i,fieldWidget in enumerate(self.fieldWidgets):
|
||||||
table.attach(fieldWidget.label(), 0, 1, i, i+1, xoptions=gtk.FILL)
|
table.attach(fieldWidget.label(), 0, 1, i, i+1, xoptions=gtk.FILL)
|
||||||
table.attach(fieldWidget.widget(), 1, 2, i, i+1)
|
table.attach(fieldWidget.widget(), 1, 2, i, i+1)
|
||||||
|
|
||||||
# init widget
|
# init widget
|
||||||
self.comboType.set_active(iCurrentDatabase)
|
self.comboType.set_active(iCurrentDatabase)
|
||||||
self._adjust_widgets(self.database)
|
self._adjust_widgets(self.database)
|
||||||
|
|
||||||
def _adjust_widgets(self, database):
|
def _adjust_widgets(self, database):
|
||||||
for fieldWidget in self.fieldWidgets:
|
for fieldWidget in self.fieldWidgets:
|
||||||
isSensitive = fieldWidget.is_sensitive(database)
|
isSensitive = fieldWidget.is_sensitive(database)
|
||||||
|
@ -316,24 +458,24 @@ class WidgetDatabaseProperties(gtk.VBox):
|
||||||
if self.mode == self.ModeEdit:
|
if self.mode == self.ModeEdit:
|
||||||
isSensitive = isSensitive and fieldWidget.can_edit()
|
isSensitive = isSensitive and fieldWidget.can_edit()
|
||||||
fieldWidget.set_sensitive(isSensitive)
|
fieldWidget.set_sensitive(isSensitive)
|
||||||
|
|
||||||
|
|
||||||
def on_combo_type_changed(self, combo):
|
def on_combo_type_changed(self, combo):
|
||||||
i = self.comboType.get_active()
|
i = self.comboType.get_active()
|
||||||
if i < 0:
|
if i < 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
# check if we need to init a new database
|
# check if we need to init a new database
|
||||||
currentDatabaseType = self.comboType.get_model()[i][1]
|
currentDatabaseType = self.comboType.get_model()[i][1]
|
||||||
if currentDatabaseType == self.database.Type:
|
if currentDatabaseType == self.database.Type:
|
||||||
return
|
return
|
||||||
|
|
||||||
# create new empty database
|
# create new empty database
|
||||||
#NOTE: we dont register it in DatabaseManager
|
#NOTE: we dont register it in DatabaseManager
|
||||||
self.database = self.databaseManager.DatabaseTypes[currentDatabaseType]()
|
self.database = self.databaseManager.DatabaseTypes[currentDatabaseType]()
|
||||||
self._adjust_widgets(self.database)
|
self._adjust_widgets(self.database)
|
||||||
|
|
||||||
|
|
||||||
def get_database(self):
|
def get_database(self):
|
||||||
for fieldWidget in self.fieldWidgets:
|
for fieldWidget in self.fieldWidgets:
|
||||||
if fieldWidget.is_sensitive(self.database):
|
if fieldWidget.is_sensitive(self.database):
|
||||||
|
@ -344,7 +486,7 @@ class WidgetDatabaseProperties(gtk.VBox):
|
||||||
class DialogDatabaseProperties(gtk.Dialog):
|
class DialogDatabaseProperties(gtk.Dialog):
|
||||||
def __init__(self, databaseManager, database, parent=None, mode=WidgetDatabaseProperties.ModeEdit, title=''):
|
def __init__(self, databaseManager, database, parent=None, mode=WidgetDatabaseProperties.ModeEdit, title=''):
|
||||||
gtk.Dialog.__init__(self,
|
gtk.Dialog.__init__(self,
|
||||||
title=title,
|
title=title,
|
||||||
parent=parent,
|
parent=parent,
|
||||||
flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||||
buttons=(
|
buttons=(
|
||||||
|
@ -353,7 +495,7 @@ class DialogDatabaseProperties(gtk.Dialog):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.connect('response', self.on_dialog_response)
|
self.connect('response', self.on_dialog_response)
|
||||||
|
|
||||||
# setup widget
|
# setup widget
|
||||||
self.widgetDatabaseProperties = WidgetDatabaseProperties(databaseManager,database, mode=mode, parentWidget=self)
|
self.widgetDatabaseProperties = WidgetDatabaseProperties(databaseManager,database, mode=mode, parentWidget=self)
|
||||||
self.vbox.pack_start(self.widgetDatabaseProperties, True, True)
|
self.vbox.pack_start(self.widgetDatabaseProperties, True, True)
|
||||||
|
@ -361,34 +503,49 @@ class DialogDatabaseProperties(gtk.Dialog):
|
||||||
|
|
||||||
def get_widget_database_properties(self):
|
def get_widget_database_properties(self):
|
||||||
return self.widgetDatabaseProperties
|
return self.widgetDatabaseProperties
|
||||||
|
|
||||||
def on_dialog_response(self, dlg, responseId):
|
def on_dialog_response(self, dlg, responseId):
|
||||||
if responseId == gtk.RESPONSE_REJECT:
|
if responseId == gtk.RESPONSE_REJECT:
|
||||||
pass
|
pass
|
||||||
elif responseId == gtk.RESPONSE_ACCEPT:
|
elif responseId == gtk.RESPONSE_ACCEPT:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
#TODO: derrive from gtk.VBox?
|
|
||||||
|
#TODO: derrive from gtk.VBox?
|
||||||
# ..is there a way to derrive from gtk.Widget or similar? this would make parentWidget kw obsolete
|
# ..is there a way to derrive from gtk.Widget or similar? this would make parentWidget kw obsolete
|
||||||
class WidgetDatabaseManager(gtk.VBox):
|
class WidgetDatabaseManager(gtk.VBox):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, databaseManager, parentWidget=None):
|
def __init__(self, databaseManager, parentWidget=None):
|
||||||
gtk.VBox.__init__(self)
|
gtk.VBox.__init__(self)
|
||||||
|
|
||||||
self.databaseManager = databaseManager
|
|
||||||
self.parentWidget = parentWidget
|
self.parentWidget = parentWidget
|
||||||
|
self.databaseManager = databaseManager
|
||||||
|
self.databaseManager.connect('database-activated', self.on_database_manager_database_activated)
|
||||||
|
self.databaseManager.connect('database-deactivated', self.on_database_manager_database_deactivated)
|
||||||
|
self.databaseStatusNames = {
|
||||||
|
DatabaseTypeBase.StatusActive: 'Active',
|
||||||
|
DatabaseTypeBase.StatusInactive: 'Inactive',
|
||||||
|
DatabaseTypeBase.StatusError: 'Error',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#TODO: dono how to make word wrap work as expected
|
#TODO: dono how to make word wrap work as expected
|
||||||
self.labelInfo = gtk.Label('database management')
|
self.labelInfo = gtk.Label('database management')
|
||||||
self.labelInfo.set_line_wrap(True)
|
self.labelInfo.set_line_wrap(True)
|
||||||
self.labelInfo.set_selectable(True)
|
self.labelInfo.set_selectable(True)
|
||||||
self.labelInfo.set_single_line_mode(False)
|
self.labelInfo.set_single_line_mode(False)
|
||||||
self.labelInfo.set_alignment(0, 0)
|
self.labelInfo.set_alignment(0, 0)
|
||||||
|
|
||||||
# database management buttons
|
# database management buttons
|
||||||
|
|
||||||
#TODO: bit messy the distinction New/Add/Edit. we'd have to pass three flags to DialogDatabaseProperties
|
#TODO: bit messy the distinction New/Add/Edit. we'd have to pass three flags to DialogDatabaseProperties
|
||||||
# to handle this. maybe drop Edit (is just a Remove + Add), to keep things simple
|
# to handle this. maybe drop Edit (is just a Remove + Add), to keep things simple
|
||||||
|
self.buttonDatabaseActivate = gtk.Button("Activate")
|
||||||
|
self.buttonDatabaseActivate.set_tooltip_text('activates the database')
|
||||||
|
self.buttonDatabaseActivate.connect('clicked', self.on_button_database_activate_clicked)
|
||||||
|
self.buttonDatabaseActivate.set_sensitive(False)
|
||||||
self.buttonDatabaseNew = gtk.Button("New..")
|
self.buttonDatabaseNew = gtk.Button("New..")
|
||||||
self.buttonDatabaseNew.set_tooltip_text('creates a new database')
|
self.buttonDatabaseNew.set_tooltip_text('creates a new database')
|
||||||
self.buttonDatabaseNew.connect('clicked', self.on_button_database_new_clicked)
|
self.buttonDatabaseNew.connect('clicked', self.on_button_database_new_clicked)
|
||||||
|
@ -402,33 +559,32 @@ class WidgetDatabaseManager(gtk.VBox):
|
||||||
self.buttonDatabaseRemove = gtk.Button("Remove")
|
self.buttonDatabaseRemove = gtk.Button("Remove")
|
||||||
self.buttonDatabaseRemove.set_tooltip_text('removes the database from the list')
|
self.buttonDatabaseRemove.set_tooltip_text('removes the database from the list')
|
||||||
self.buttonDatabaseRemove.set_sensitive(False)
|
self.buttonDatabaseRemove.set_sensitive(False)
|
||||||
|
self.buttonDatabaseRemove.connect('clicked', self.on_button_database_remove_clicked)
|
||||||
|
|
||||||
#TODO: i dont think we should do any real database management here. maybe drop it
|
#TODO: i dont think we should do any real database management here. maybe drop it
|
||||||
self.buttonDatabaseDelete = gtk.Button("Delete")
|
#self.buttonDatabaseDelete = gtk.Button("Delete")
|
||||||
self.buttonDatabaseDelete.set_tooltip_text('removes the database from the list and deletes it')
|
#self.buttonDatabaseDelete.set_tooltip_text('removes the database from the list and deletes it')
|
||||||
self.buttonDatabaseDelete.set_sensitive(False)
|
#self.buttonDatabaseDelete.set_sensitive(False)
|
||||||
|
|
||||||
# init database tree
|
# init database tree
|
||||||
self.treeDatabases = gtk.TreeView()
|
self.treeDatabases = gtk.TreeView()
|
||||||
self.treeDatabaseColumns = ( #NOTE: column names starting with '_' will be hidden
|
treeDatabaseColumns = ( # name, displayName, dataType
|
||||||
'Name',
|
('name', 'Name', str),
|
||||||
'Status',
|
('status', 'Status', str),
|
||||||
'Type',
|
('type', 'Type', str),
|
||||||
'_id',
|
('_id', '', int),
|
||||||
)
|
)
|
||||||
|
self.treeDatabaseColumns = {} # name --> index
|
||||||
store = gtk.ListStore(str, str, str, int)
|
store = gtk.ListStore( *[i[2] for i in treeDatabaseColumns] )
|
||||||
self.treeDatabases.set_model(store)
|
self.treeDatabases.set_model(store)
|
||||||
columns = ('Name', 'Status', 'Type', '_id')
|
for i, (name, displayName, dataType) in enumerate(treeDatabaseColumns):
|
||||||
for i, column in enumerate(columns):
|
col = gtk.TreeViewColumn(displayName, gtk.CellRendererText(), text=i)
|
||||||
col = gtk.TreeViewColumn(column, gtk.CellRendererText(), text=i)
|
|
||||||
self.treeDatabases.append_column(col)
|
self.treeDatabases.append_column(col)
|
||||||
if column.startswith('_'):
|
if name.startswith('_'):
|
||||||
col.set_visible(False)
|
col.set_visible(False)
|
||||||
|
self.treeDatabaseColumns[name] = i
|
||||||
self.treeDatabaseColumns = dict([(name, i) for (i, name) in enumerate(self.treeDatabaseColumns)])
|
|
||||||
self.treeDatabases.get_selection().connect('changed', self.on_tree_databases_selection_changed)
|
self.treeDatabases.get_selection().connect('changed', self.on_tree_databases_selection_changed)
|
||||||
|
|
||||||
# layout widgets
|
# layout widgets
|
||||||
vbox = gtk.VBox(self)
|
vbox = gtk.VBox(self)
|
||||||
vbox.pack_start(self.labelInfo, False, False, 2)
|
vbox.pack_start(self.labelInfo, False, False, 2)
|
||||||
|
@ -438,102 +594,196 @@ class WidgetDatabaseManager(gtk.VBox):
|
||||||
hbox.set_homogeneous(False)
|
hbox.set_homogeneous(False)
|
||||||
vbox = gtk.VBox()
|
vbox = gtk.VBox()
|
||||||
hbox.pack_start(vbox, False, False, 2)
|
hbox.pack_start(vbox, False, False, 2)
|
||||||
|
vbox.pack_start(self.buttonDatabaseActivate, False, False, 2)
|
||||||
vbox.pack_start(self.buttonDatabaseNew, False, False, 2)
|
vbox.pack_start(self.buttonDatabaseNew, False, False, 2)
|
||||||
vbox.pack_start(self.buttonDatabaseAdd, False, False, 2)
|
vbox.pack_start(self.buttonDatabaseAdd, False, False, 2)
|
||||||
vbox.pack_start(self.buttonDatabaseEdit, False, False, 2)
|
vbox.pack_start(self.buttonDatabaseEdit, False, False, 2)
|
||||||
vbox.pack_start(self.buttonDatabaseRemove, False, False, 2)
|
vbox.pack_start(self.buttonDatabaseRemove, False, False, 2)
|
||||||
vbox.pack_start(self.buttonDatabaseDelete, False, False, 2)
|
#vbox.pack_start(self.buttonDatabaseDelete, False, False, 2)
|
||||||
box = gtk.VBox()
|
box = gtk.VBox()
|
||||||
vbox.pack_start(box, True, True, 0)
|
vbox.pack_start(box, True, True, 0)
|
||||||
|
|
||||||
hbox.pack_start(gtk.VSeparator(), False, False, 2)
|
hbox.pack_start(gtk.VSeparator(), False, False, 2)
|
||||||
hbox.pack_end(self.treeDatabases, True, True, 2)
|
hbox.pack_end(self.treeDatabases, True, True, 2)
|
||||||
|
|
||||||
self.show_all()
|
self.show_all()
|
||||||
|
|
||||||
# init widget
|
# init widget
|
||||||
|
model = self.treeDatabases.get_model()
|
||||||
for database in self.databaseManager:
|
for database in self.databaseManager:
|
||||||
self.treeDatabases.get_model().append( (database.name, 'foo', database.Type, self.databaseManager.database_id(database)) )
|
it = model.append()
|
||||||
|
model.set_value(it, self.treeDatabaseColumns['name'], database.name)
|
||||||
#TODO: for some reason i have to click OK/Cancel twice to close the dialog
|
model.set_value(it, self.treeDatabaseColumns['status'], self.databaseStatusNames[database.status] )
|
||||||
|
model.set_value(it, self.treeDatabaseColumns['type'], database.display_name() )
|
||||||
|
model.set_value(it, self.treeDatabaseColumns['_id'], self.databaseManager.database_id(database))
|
||||||
|
|
||||||
|
|
||||||
|
def on_database_manager_database_activated(self, databaseManager, idDatabase):
|
||||||
|
database = self.databaseManager.database_from_id(idDatabase)
|
||||||
|
model = self.treeDatabases.get_model()
|
||||||
|
for row in iter(model):
|
||||||
|
if row[self.treeDatabaseColumns['_id']] == idDatabase:
|
||||||
|
row[self.treeDatabaseColumns['status']] = self.databaseStatusNames[database.StatusActive]
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise ValueError('database not found')
|
||||||
|
|
||||||
|
|
||||||
|
def on_database_manager_database_deactivated(self, databaseManager, idDatabase):
|
||||||
|
database = self.databaseManager.database_from_id(idDatabase)
|
||||||
|
model = self.treeDatabases.get_model()
|
||||||
|
for row in iter(model):
|
||||||
|
if row[self.treeDatabaseColumns['_id']] == idDatabase:
|
||||||
|
row[self.treeDatabaseColumns['status']] = self.databaseStatusNames[database.StatusInactive]
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise ValueError('database not found')
|
||||||
|
|
||||||
|
|
||||||
|
def on_button_database_activate_clicked(self, button):
|
||||||
|
selection = self.treeDatabases.get_selection()
|
||||||
|
if selection is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
model, it = selection.get_selected()
|
||||||
|
idDatabase = model.get_value(it, self.treeDatabaseColumns['_id'])
|
||||||
|
database = self.databaseManager.database_from_id(idDatabase)
|
||||||
|
self.databaseManager.activate_database(database)
|
||||||
|
|
||||||
|
|
||||||
|
#TODO: for some reason i have to click OK/Cancel twice to close the dialog
|
||||||
def on_button_database_new_clicked(self, button):
|
def on_button_database_new_clicked(self, button):
|
||||||
databaseType = self.databaseManager.get_default_database_type()
|
databaseKlass = self.databaseManager.get_default_database_type()
|
||||||
if databaseType is None:
|
if databaseKlass is None:
|
||||||
raise ValueError('no defult database type set')
|
raise ValueError('no default database type set')
|
||||||
dlg = DialogDatabaseProperties(
|
database = databaseKlass()
|
||||||
self.databaseManager,
|
|
||||||
databaseType(),
|
while True:
|
||||||
parent=self.parentWidget,
|
dlg = DialogDatabaseProperties(
|
||||||
mode=WidgetDatabaseProperties.ModeNew,
|
self.databaseManager,
|
||||||
title='[New database] - database properties'
|
database,
|
||||||
)
|
parent=self.parentWidget,
|
||||||
if dlg.run() == gtk.RESPONSE_REJECT:
|
mode=WidgetDatabaseProperties.ModeNew,
|
||||||
pass
|
title='New database'
|
||||||
if dlg.run() == gtk.RESPONSE_ACCEPT:
|
)
|
||||||
database = dlg.get_widget_database_properties().get_database()
|
response = dlg.run()
|
||||||
#TODO: sanity checks + init databse if necessary
|
if response == gtk.RESPONSE_ACCEPT:
|
||||||
|
database = dlg.get_widget_database_properties().get_database()
|
||||||
|
#TODO: initing may or may not take a while. how to handle?
|
||||||
|
error = database.init_new_database()
|
||||||
|
if error:
|
||||||
|
DialogError(parent=dlg, msg=error)
|
||||||
|
dlg.destroy()
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
database = None
|
||||||
|
dlg.destroy()
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
if database is None:
|
||||||
|
return
|
||||||
|
|
||||||
self.databaseManager.add_database(database)
|
self.databaseManager.add_database(database)
|
||||||
self.treeDatabases.get_model().append( (database.name, 'foo', database.Type, self.databaseManager.database_id(database)) )
|
model = self.treeDatabases.get_model()
|
||||||
dlg.destroy()
|
it = model.append()
|
||||||
|
model.set_value(it, self.treeDatabaseColumns['name'], database.name)
|
||||||
|
model.set_value(it, self.treeDatabaseColumns['status'], self.databaseStatusNames[database.status] )
|
||||||
|
model.set_value(it, self.treeDatabaseColumns['type'], database.display_name() )
|
||||||
|
model.set_value(it, self.treeDatabaseColumns['_id'], self.databaseManager.database_id(database))
|
||||||
|
|
||||||
|
|
||||||
def on_button_database_add_clicked(self, button):
|
def on_button_database_add_clicked(self, button):
|
||||||
databaseType = self.databaseManager.get_default_database_type()
|
databaseKlass = self.databaseManager.get_default_database_type()
|
||||||
if databaseType is None:
|
if databaseKlass is None:
|
||||||
raise ValueError('no defult database type set')
|
raise ValueError('no defult database type set')
|
||||||
dlg = DialogDatabaseProperties(
|
database = databaseKlass()
|
||||||
self.databaseManager,
|
|
||||||
databaseType(),
|
while True:
|
||||||
parent=self.parentWidget,
|
dlg = DialogDatabaseProperties(
|
||||||
mode=WidgetDatabaseProperties.ModeAdd,
|
self.databaseManager,
|
||||||
title='[Add database] - database properties'
|
database,
|
||||||
)
|
parent=self.parentWidget,
|
||||||
if dlg.run() == gtk.RESPONSE_REJECT:
|
mode=WidgetDatabaseProperties.ModeAdd,
|
||||||
pass
|
title='Add database'
|
||||||
if dlg.run() == gtk.RESPONSE_ACCEPT:
|
)
|
||||||
database = dlg.get_widget_database_properties().get_database()
|
response = dlg.run()
|
||||||
#TODO: sanity checks
|
if response == gtk.RESPONSE_ACCEPT:
|
||||||
|
database = dlg.get_widget_database_properties().get_database()
|
||||||
|
#TODO: validating may or may not take a while. how to handle?
|
||||||
|
error = database.validate_database()
|
||||||
|
if error:
|
||||||
|
DialogError(parent=self.parentWidget, msg=error)
|
||||||
|
dlg.destroy()
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
database = None
|
||||||
|
dlg.destroy()
|
||||||
|
break
|
||||||
|
|
||||||
|
if database is None:
|
||||||
|
return
|
||||||
|
|
||||||
self.databaseManager.add_database(database)
|
self.databaseManager.add_database(database)
|
||||||
self.treeDatabases.get_model().append( (database.name, 'foo', database.Type, self.databaseManager.database_id(database)) )
|
model = self.treeDatabases.get_model()
|
||||||
|
it = model.append()
|
||||||
|
model.set_value(it, self.treeDatabaseColumns['name'], database.name)
|
||||||
|
model.set_value(it, self.treeDatabaseColumns['status'], self.databaseStatusNames[database.status] )
|
||||||
|
model.set_value(it, self.treeDatabaseColumns['type'], database.display_name() )
|
||||||
|
model.set_value(it, self.treeDatabaseColumns['_id'], self.databaseManager.database_id(database))
|
||||||
dlg.destroy()
|
dlg.destroy()
|
||||||
|
|
||||||
def on_button_database_edit_clicked(self, button):
|
def on_button_database_edit_clicked(self, button):
|
||||||
selection = self.treeDatabases.get_selection()
|
selection = self.treeDatabases.get_selection()
|
||||||
if selection is None:
|
if selection is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
model, iter = selection.get_selected()
|
model, it = selection.get_selected()
|
||||||
idDatabase = model.get_value(iter, self.treeDatabaseColumns['_id'])
|
idDatabase = model.get_value(it, self.treeDatabaseColumns['_id'])
|
||||||
database = self.databaseManager.database_from_id(idDatabase)
|
database = self.databaseManager.database_from_id(idDatabase)
|
||||||
dlg = DialogDatabaseProperties(
|
dlg = DialogDatabaseProperties(
|
||||||
self.databaseManager,
|
self.databaseManager,
|
||||||
database=database,
|
database,
|
||||||
parent=self.parentWidget,
|
parent=self.parentWidget,
|
||||||
mode=WidgetDatabaseProperties.ModeEdit,
|
mode=WidgetDatabaseProperties.ModeEdit,
|
||||||
title='[Edit database] - database properties'
|
title='Edit database'
|
||||||
)
|
)
|
||||||
if dlg.run() == gtk.RESPONSE_REJECT:
|
response = dlg.run()
|
||||||
|
if response == gtk.RESPONSE_REJECT:
|
||||||
pass
|
pass
|
||||||
if dlg.run() == gtk.RESPONSE_ACCEPT:
|
elif response == gtk.RESPONSE_ACCEPT:
|
||||||
database = dlg.get_database()
|
database = dlg.get_database()
|
||||||
selection = self.treeDatabases.get_selection()
|
selection = self.treeDatabases.get_selection()
|
||||||
if selection is not None:
|
if selection is not None:
|
||||||
model, iter = selection.get_selected()
|
model, it = selection.get_selected()
|
||||||
model.set_value(iter, 0, database.name)
|
model.set_value(it, self.treeDatabaseColumns['name'], database.name)
|
||||||
dlg.destroy()
|
dlg.destroy()
|
||||||
|
|
||||||
|
|
||||||
|
def on_button_database_remove_clicked(self, button):
|
||||||
|
selection = self.treeDatabases.get_selection()
|
||||||
|
if selection is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
model, it = selection.get_selected()
|
||||||
|
#TODO: finalize database
|
||||||
|
model.remove(it)
|
||||||
|
|
||||||
|
|
||||||
def on_tree_databases_selection_changed(self, treeSelection):
|
def on_tree_databases_selection_changed(self, treeSelection):
|
||||||
hasSelection = bool(treeSelection.count_selected_rows())
|
hasSelection = bool(treeSelection.count_selected_rows())
|
||||||
|
|
||||||
# enable/disable selection dependend widgets
|
# enable/disable selection dependend widgets
|
||||||
|
self.buttonDatabaseActivate.set_sensitive(hasSelection)
|
||||||
self.buttonDatabaseEdit.set_sensitive(hasSelection)
|
self.buttonDatabaseEdit.set_sensitive(hasSelection)
|
||||||
self.buttonDatabaseRemove.set_sensitive(hasSelection)
|
self.buttonDatabaseRemove.set_sensitive(hasSelection)
|
||||||
self.buttonDatabaseDelete.set_sensitive(hasSelection)
|
#self.buttonDatabaseDelete.set_sensitive(hasSelection)
|
||||||
|
|
||||||
|
|
||||||
class DialogDatabaseManager(gtk.Dialog):
|
class DialogDatabaseManager(gtk.Dialog):
|
||||||
def __init__(self, databaseManager, parent=None):
|
def __init__(self, databaseManager, parent=None):
|
||||||
gtk.Dialog.__init__(self,
|
gtk.Dialog.__init__(self,
|
||||||
title="My dialog",
|
title="Databases",
|
||||||
parent=parent,
|
parent=parent,
|
||||||
flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||||
buttons=(
|
buttons=(
|
||||||
|
@ -544,11 +794,11 @@ class DialogDatabaseManager(gtk.Dialog):
|
||||||
self.widgetDatabaseManager = WidgetDatabaseManager(databaseManager, parentWidget=self)
|
self.widgetDatabaseManager = WidgetDatabaseManager(databaseManager, parentWidget=self)
|
||||||
self.vbox.pack_start(self.widgetDatabaseManager, True, True)
|
self.vbox.pack_start(self.widgetDatabaseManager, True, True)
|
||||||
self.show_all()
|
self.show_all()
|
||||||
|
|
||||||
#**************************************************************************************************
|
#**************************************************************************************************
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
databaseManager = DatabaseManager.from_fpdb('', defaultDatabaseType=DatabaseTypeSqLite)
|
databaseManager = DatabaseManager.from_fpdb('', defaultDatabaseType=DatabaseTypeSqLite)
|
||||||
|
|
||||||
#d = DialogDatabaseProperties(
|
#d = DialogDatabaseProperties(
|
||||||
# DatabaseManager(defaultDatabaseType=DatabaseTypeSqLite),
|
# DatabaseManager(defaultDatabaseType=DatabaseTypeSqLite),
|
||||||
#database=DatabaseTypePostgres(),
|
#database=DatabaseTypePostgres(),
|
||||||
|
@ -558,5 +808,3 @@ if __name__ == '__main__':
|
||||||
d.connect("destroy", gtk.main_quit)
|
d.connect("destroy", gtk.main_quit)
|
||||||
d.run()
|
d.run()
|
||||||
#gtk.main()
|
#gtk.main()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,13 @@
|
||||||
#fpdb modules
|
#fpdb modules
|
||||||
import Card
|
import Card
|
||||||
|
|
||||||
|
DEBUG = False
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
import pprint
|
||||||
|
pp = pprint.PrettyPrinter(indent=4)
|
||||||
|
|
||||||
|
|
||||||
class DerivedStats():
|
class DerivedStats():
|
||||||
def __init__(self, hand):
|
def __init__(self, hand):
|
||||||
self.hand = hand
|
self.hand = hand
|
||||||
|
@ -30,13 +37,31 @@ class DerivedStats():
|
||||||
for player in hand.players:
|
for player in hand.players:
|
||||||
self.handsplayers[player[1]] = {}
|
self.handsplayers[player[1]] = {}
|
||||||
#Init vars that may not be used, but still need to be inserted.
|
#Init vars that may not be used, but still need to be inserted.
|
||||||
|
# All stud street4 need this when importing holdem
|
||||||
|
self.handsplayers[player[1]]['winnings'] = 0
|
||||||
|
self.handsplayers[player[1]]['rake'] = 0
|
||||||
|
self.handsplayers[player[1]]['totalProfit'] = 0
|
||||||
|
self.handsplayers[player[1]]['street4Seen'] = False
|
||||||
self.handsplayers[player[1]]['street4Aggr'] = False
|
self.handsplayers[player[1]]['street4Aggr'] = False
|
||||||
|
self.handsplayers[player[1]]['wonWhenSeenStreet1'] = False
|
||||||
|
self.handsplayers[player[1]]['sawShowdown'] = False
|
||||||
|
self.handsplayers[player[1]]['wonAtSD'] = False
|
||||||
|
for i in range(5):
|
||||||
|
self.handsplayers[player[1]]['street%dCalls' % i] = 0
|
||||||
|
self.handsplayers[player[1]]['street%dBets' % i] = 0
|
||||||
|
for i in range(1,5):
|
||||||
|
self.handsplayers[player[1]]['street%dCBChance' %i] = False
|
||||||
|
self.handsplayers[player[1]]['street%dCBDone' %i] = False
|
||||||
|
|
||||||
self.assembleHands(self.hand)
|
self.assembleHands(self.hand)
|
||||||
self.assembleHandsPlayers(self.hand)
|
self.assembleHandsPlayers(self.hand)
|
||||||
|
|
||||||
print "hands =", self.hands
|
|
||||||
print "handsplayers =", self.handsplayers
|
if DEBUG:
|
||||||
|
print "Hands:"
|
||||||
|
pp.pprint(self.hands)
|
||||||
|
print "HandsPlayers:"
|
||||||
|
pp.pprint(self.handsplayers)
|
||||||
|
|
||||||
def getHands(self):
|
def getHands(self):
|
||||||
return self.hands
|
return self.hands
|
||||||
|
@ -68,12 +93,13 @@ class DerivedStats():
|
||||||
self.hands['boardcard5'] = cards[4]
|
self.hands['boardcard5'] = cards[4]
|
||||||
|
|
||||||
#print "DEBUG: self.getStreetTotals = (%s, %s, %s, %s, %s)" % hand.getStreetTotals()
|
#print "DEBUG: self.getStreetTotals = (%s, %s, %s, %s, %s)" % hand.getStreetTotals()
|
||||||
#FIXME: Pot size still in decimal, needs to be converted to cents
|
totals = hand.getStreetTotals()
|
||||||
(self.hands['street1Pot'],
|
totals = [int(100*i) for i in totals]
|
||||||
self.hands['street2Pot'],
|
self.hands['street1Pot'] = totals[0]
|
||||||
self.hands['street3Pot'],
|
self.hands['street2Pot'] = totals[1]
|
||||||
self.hands['street4Pot'],
|
self.hands['street3Pot'] = totals[2]
|
||||||
self.hands['showdownPot']) = hand.getStreetTotals()
|
self.hands['street4Pot'] = totals[3]
|
||||||
|
self.hands['showdownPot'] = totals[4]
|
||||||
|
|
||||||
self.vpip(hand) # Gives playersVpi (num of players vpip)
|
self.vpip(hand) # Gives playersVpi (num of players vpip)
|
||||||
#print "DEBUG: vpip: %s" %(self.hands['playersVpi'])
|
#print "DEBUG: vpip: %s" %(self.hands['playersVpi'])
|
||||||
|
@ -81,707 +107,49 @@ class DerivedStats():
|
||||||
#print "DEBUG: playersAtStreet 1:'%s' 2:'%s' 3:'%s' 4:'%s'" %(self.hands['playersAtStreet1'],self.hands['playersAtStreet2'],self.hands['playersAtStreet3'],self.hands['playersAtStreet4'])
|
#print "DEBUG: playersAtStreet 1:'%s' 2:'%s' 3:'%s' 4:'%s'" %(self.hands['playersAtStreet1'],self.hands['playersAtStreet2'],self.hands['playersAtStreet3'],self.hands['playersAtStreet4'])
|
||||||
self.streetXRaises(hand) # Empty function currently
|
self.streetXRaises(hand) # Empty function currently
|
||||||
|
|
||||||
# comment TEXT,
|
|
||||||
# commentTs DATETIME
|
|
||||||
|
|
||||||
def assembleHandsPlayers(self, hand):
|
def assembleHandsPlayers(self, hand):
|
||||||
|
#street0VPI/vpip already called in Hand
|
||||||
|
# sawShowdown is calculated in playersAtStreetX, as that calculation gives us a convenient list of names
|
||||||
|
|
||||||
#hand.players = [[seat, name, chips],[seat, name, chips]]
|
#hand.players = [[seat, name, chips],[seat, name, chips]]
|
||||||
for player in hand.players:
|
for player in hand.players:
|
||||||
self.handsplayers[player[1]]['seatNo'] = player[0]
|
self.handsplayers[player[1]]['seatNo'] = player[0]
|
||||||
self.handsplayers[player[1]]['startCash'] = player[2]
|
self.handsplayers[player[1]]['startCash'] = player[2]
|
||||||
|
|
||||||
|
for i, street in enumerate(hand.actionStreets[2:]):
|
||||||
|
self.seen(self.hand, i+1)
|
||||||
|
|
||||||
for i, street in enumerate(hand.actionStreets[1:]):
|
for i, street in enumerate(hand.actionStreets[1:]):
|
||||||
self.aggr(self.hand, i)
|
self.aggr(self.hand, i)
|
||||||
|
self.calls(self.hand, i)
|
||||||
|
self.bets(self.hand, i)
|
||||||
|
|
||||||
|
# Winnings is a non-negative value of money collected from the pot, which already includes the
|
||||||
|
# rake taken out. hand.collectees is Decimal, database requires cents
|
||||||
|
for player in hand.collectees:
|
||||||
|
self.handsplayers[player]['winnings'] = int(100 * hand.collectees[player])
|
||||||
|
#FIXME: This is pretty dodgy, rake = hand.rake/#collectees
|
||||||
|
# You can really only pay rake when you collect money, but
|
||||||
|
# different sites calculate rake differently.
|
||||||
|
# Should be fine for split-pots, but won't be accurate for multi-way pots
|
||||||
|
self.handsplayers[player]['rake'] = int(100* hand.rake)/len(hand.collectees)
|
||||||
|
if self.handsplayers[player]['street1Seen'] == True:
|
||||||
|
self.handsplayers[player]['wonWhenSeenStreet1'] = True
|
||||||
|
if self.handsplayers[player]['sawShowdown'] == True:
|
||||||
|
self.handsplayers[player]['wonAtSD'] = True
|
||||||
|
|
||||||
|
for player in hand.pot.committed:
|
||||||
|
self.handsplayers[player]['totalProfit'] = int(self.handsplayers[player]['winnings'] - (100*hand.pot.committed[player]))
|
||||||
|
|
||||||
|
self.calcCBets(hand)
|
||||||
|
|
||||||
|
for player in hand.players:
|
||||||
|
hcs = hand.join_holecards(player[1], asList=True)
|
||||||
|
hcs = hcs + [u'0x', u'0x', u'0x', u'0x', u'0x']
|
||||||
|
for i, card in enumerate(hcs[:7], 1):
|
||||||
|
self.handsplayers[player[1]]['card%s' % i] = Card.encodeCard(card)
|
||||||
|
|
||||||
def assembleHudCache(self, hand):
|
def assembleHudCache(self, hand):
|
||||||
# # def generateHudCacheData(player_ids, base, category, action_types, allIns, actionTypeByNo
|
|
||||||
# # ,winnings, totalWinnings, positions, actionTypes, actionAmounts, antes):
|
|
||||||
# #"""calculates data for the HUD during import. IMPORTANT: if you change this method make
|
|
||||||
# # sure to also change the following storage method and table_viewer.prepare_data if necessary
|
|
||||||
# #"""
|
|
||||||
# #print "generateHudCacheData, len(player_ids)=", len(player_ids)
|
|
||||||
# #setup subarrays of the result dictionary.
|
|
||||||
# street0VPI=[]
|
|
||||||
# street0Aggr=[]
|
|
||||||
# street0_3BChance=[]
|
|
||||||
# street0_3BDone=[]
|
|
||||||
# street1Seen=[]
|
|
||||||
# street2Seen=[]
|
|
||||||
# street3Seen=[]
|
|
||||||
# street4Seen=[]
|
|
||||||
# sawShowdown=[]
|
|
||||||
# street1Aggr=[]
|
|
||||||
# street2Aggr=[]
|
|
||||||
# street3Aggr=[]
|
|
||||||
# street4Aggr=[]
|
|
||||||
# otherRaisedStreet1=[]
|
|
||||||
# otherRaisedStreet2=[]
|
|
||||||
# otherRaisedStreet3=[]
|
|
||||||
# otherRaisedStreet4=[]
|
|
||||||
# foldToOtherRaisedStreet1=[]
|
|
||||||
# foldToOtherRaisedStreet2=[]
|
|
||||||
# foldToOtherRaisedStreet3=[]
|
|
||||||
# foldToOtherRaisedStreet4=[]
|
|
||||||
# wonWhenSeenStreet1=[]
|
|
||||||
#
|
|
||||||
# wonAtSD=[]
|
|
||||||
# stealAttemptChance=[]
|
|
||||||
# stealAttempted=[]
|
|
||||||
# hudDataPositions=[]
|
|
||||||
#
|
|
||||||
# street0Calls=[]
|
|
||||||
# street1Calls=[]
|
|
||||||
# street2Calls=[]
|
|
||||||
# street3Calls=[]
|
|
||||||
# street4Calls=[]
|
|
||||||
# street0Bets=[]
|
|
||||||
# street1Bets=[]
|
|
||||||
# street2Bets=[]
|
|
||||||
# street3Bets=[]
|
|
||||||
# street4Bets=[]
|
|
||||||
# #street0Raises=[]
|
|
||||||
# #street1Raises=[]
|
|
||||||
# #street2Raises=[]
|
|
||||||
# #street3Raises=[]
|
|
||||||
# #street4Raises=[]
|
|
||||||
#
|
|
||||||
# # Summary figures for hand table:
|
|
||||||
# result={}
|
|
||||||
# result['playersVpi']=0
|
|
||||||
# result['playersAtStreet1']=0
|
|
||||||
# result['playersAtStreet2']=0
|
|
||||||
# result['playersAtStreet3']=0
|
|
||||||
# result['playersAtStreet4']=0
|
|
||||||
# result['playersAtShowdown']=0
|
|
||||||
# result['street0Raises']=0
|
|
||||||
# result['street1Raises']=0
|
|
||||||
# result['street2Raises']=0
|
|
||||||
# result['street3Raises']=0
|
|
||||||
# result['street4Raises']=0
|
|
||||||
# result['street1Pot']=0
|
|
||||||
# result['street2Pot']=0
|
|
||||||
# result['street3Pot']=0
|
|
||||||
# result['street4Pot']=0
|
|
||||||
# result['showdownPot']=0
|
|
||||||
#
|
|
||||||
# firstPfRaiseByNo=-1
|
|
||||||
# firstPfRaiserId=-1
|
|
||||||
# firstPfRaiserNo=-1
|
|
||||||
# firstPfCallByNo=-1
|
|
||||||
# firstPfCallerId=-1
|
|
||||||
#
|
|
||||||
# for i, action in enumerate(actionTypeByNo[0]):
|
|
||||||
# if action[1] == "bet":
|
|
||||||
# firstPfRaiseByNo = i
|
|
||||||
# firstPfRaiserId = action[0]
|
|
||||||
# for j, pid in enumerate(player_ids):
|
|
||||||
# if pid == firstPfRaiserId:
|
|
||||||
# firstPfRaiserNo = j
|
|
||||||
# break
|
|
||||||
# break
|
|
||||||
# for i, action in enumerate(actionTypeByNo[0]):
|
|
||||||
# if action[1] == "call":
|
|
||||||
# firstPfCallByNo = i
|
|
||||||
# firstPfCallerId = action[0]
|
|
||||||
# break
|
|
||||||
# firstPlayId = firstPfCallerId
|
|
||||||
# if firstPfRaiseByNo <> -1:
|
|
||||||
# if firstPfRaiseByNo < firstPfCallByNo or firstPfCallByNo == -1:
|
|
||||||
# firstPlayId = firstPfRaiserId
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# cutoffId=-1
|
|
||||||
# buttonId=-1
|
|
||||||
# sbId=-1
|
|
||||||
# bbId=-1
|
|
||||||
# if base=="hold":
|
|
||||||
# for player, pos in enumerate(positions):
|
|
||||||
# if pos == 1:
|
|
||||||
# cutoffId = player_ids[player]
|
|
||||||
# if pos == 0:
|
|
||||||
# buttonId = player_ids[player]
|
|
||||||
# if pos == 'S':
|
|
||||||
# sbId = player_ids[player]
|
|
||||||
# if pos == 'B':
|
|
||||||
# bbId = player_ids[player]
|
|
||||||
#
|
|
||||||
# someoneStole=False
|
|
||||||
#
|
|
||||||
# #run a loop for each player preparing the actual values that will be commited to SQL
|
|
||||||
# for player in xrange(len(player_ids)):
|
|
||||||
# #set default values
|
|
||||||
# myStreet0VPI=False
|
|
||||||
# myStreet0Aggr=False
|
|
||||||
# myStreet0_3BChance=False
|
|
||||||
# myStreet0_3BDone=False
|
|
||||||
# myStreet1Seen=False
|
|
||||||
# myStreet2Seen=False
|
|
||||||
# myStreet3Seen=False
|
|
||||||
# myStreet4Seen=False
|
|
||||||
# mySawShowdown=False
|
|
||||||
# myStreet1Aggr=False
|
|
||||||
# myStreet2Aggr=False
|
|
||||||
# myStreet3Aggr=False
|
|
||||||
# myStreet4Aggr=False
|
|
||||||
# myOtherRaisedStreet1=False
|
|
||||||
# myOtherRaisedStreet2=False
|
|
||||||
# myOtherRaisedStreet3=False
|
|
||||||
# myOtherRaisedStreet4=False
|
|
||||||
# myFoldToOtherRaisedStreet1=False
|
|
||||||
# myFoldToOtherRaisedStreet2=False
|
|
||||||
# myFoldToOtherRaisedStreet3=False
|
|
||||||
# myFoldToOtherRaisedStreet4=False
|
|
||||||
# myWonWhenSeenStreet1=0.0
|
|
||||||
# myWonAtSD=0.0
|
|
||||||
# myStealAttemptChance=False
|
|
||||||
# myStealAttempted=False
|
|
||||||
# myStreet0Calls=0
|
|
||||||
# myStreet1Calls=0
|
|
||||||
# myStreet2Calls=0
|
|
||||||
# myStreet3Calls=0
|
|
||||||
# myStreet4Calls=0
|
|
||||||
# myStreet0Bets=0
|
|
||||||
# myStreet1Bets=0
|
|
||||||
# myStreet2Bets=0
|
|
||||||
# myStreet3Bets=0
|
|
||||||
# myStreet4Bets=0
|
|
||||||
# #myStreet0Raises=0
|
|
||||||
# #myStreet1Raises=0
|
|
||||||
# #myStreet2Raises=0
|
|
||||||
# #myStreet3Raises=0
|
|
||||||
# #myStreet4Raises=0
|
|
||||||
#
|
|
||||||
# #calculate VPIP and PFR
|
|
||||||
# street=0
|
|
||||||
# heroPfRaiseCount=0
|
|
||||||
# for currentAction in action_types[street][player]: # finally individual actions
|
|
||||||
# if currentAction == "bet":
|
|
||||||
# myStreet0Aggr = True
|
|
||||||
# if currentAction == "bet" or currentAction == "call":
|
|
||||||
# myStreet0VPI = True
|
|
||||||
#
|
|
||||||
# if myStreet0VPI:
|
|
||||||
# result['playersVpi'] += 1
|
|
||||||
# myStreet0Calls = action_types[street][player].count('call')
|
|
||||||
# myStreet0Bets = action_types[street][player].count('bet')
|
|
||||||
# # street0Raises = action_types[street][player].count('raise') bet count includes raises for now
|
|
||||||
# result['street0Raises'] += myStreet0Bets
|
|
||||||
#
|
|
||||||
# #PF3BChance and PF3B
|
|
||||||
# pfFold=-1
|
|
||||||
# pfRaise=-1
|
|
||||||
# if firstPfRaiseByNo != -1:
|
|
||||||
# for i, actionType in enumerate(actionTypeByNo[0]):
|
|
||||||
# if actionType[0] == player_ids[player]:
|
|
||||||
# if actionType[1] == "bet" and pfRaise == -1 and i > firstPfRaiseByNo:
|
|
||||||
# pfRaise = i
|
|
||||||
# if actionType[1] == "fold" and pfFold == -1:
|
|
||||||
# pfFold = i
|
|
||||||
# if pfFold == -1 or pfFold > firstPfRaiseByNo:
|
|
||||||
# myStreet0_3BChance = True
|
|
||||||
# if pfRaise > firstPfRaiseByNo:
|
|
||||||
# myStreet0_3BDone = True
|
|
||||||
#
|
|
||||||
# #steal calculations
|
|
||||||
# if base=="hold":
|
|
||||||
# if len(player_ids)>=3: # no point otherwise # was 5, use 3 to match pokertracker definition
|
|
||||||
# if positions[player]==1:
|
|
||||||
# if firstPfRaiserId==player_ids[player] \
|
|
||||||
# and (firstPfCallByNo==-1 or firstPfCallByNo>firstPfRaiseByNo):
|
|
||||||
# myStealAttempted=True
|
|
||||||
# myStealAttemptChance=True
|
|
||||||
# if firstPlayId==cutoffId or firstPlayId==buttonId or firstPlayId==sbId or firstPlayId==bbId or firstPlayId==-1:
|
|
||||||
# myStealAttemptChance=True
|
|
||||||
# if positions[player]==0:
|
|
||||||
# if firstPfRaiserId==player_ids[player] \
|
|
||||||
# and (firstPfCallByNo==-1 or firstPfCallByNo>firstPfRaiseByNo):
|
|
||||||
# myStealAttempted=True
|
|
||||||
# myStealAttemptChance=True
|
|
||||||
# if firstPlayId==buttonId or firstPlayId==sbId or firstPlayId==bbId or firstPlayId==-1:
|
|
||||||
# myStealAttemptChance=True
|
|
||||||
# if positions[player]=='S':
|
|
||||||
# if firstPfRaiserId==player_ids[player] \
|
|
||||||
# and (firstPfCallByNo==-1 or firstPfCallByNo>firstPfRaiseByNo):
|
|
||||||
# myStealAttempted=True
|
|
||||||
# myStealAttemptChance=True
|
|
||||||
# if firstPlayId==sbId or firstPlayId==bbId or firstPlayId==-1:
|
|
||||||
# myStealAttemptChance=True
|
|
||||||
# if positions[player]=='B':
|
|
||||||
# pass
|
|
||||||
#
|
|
||||||
# if myStealAttempted:
|
|
||||||
# someoneStole=True
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# #calculate saw* values
|
|
||||||
# isAllIn = False
|
|
||||||
# if any(i for i in allIns[0][player]):
|
|
||||||
# isAllIn = True
|
|
||||||
# if (len(action_types[1][player])>0 or isAllIn):
|
|
||||||
# myStreet1Seen = True
|
|
||||||
#
|
|
||||||
# if any(i for i in allIns[1][player]):
|
|
||||||
# isAllIn = True
|
|
||||||
# if (len(action_types[2][player])>0 or isAllIn):
|
|
||||||
# myStreet2Seen = True
|
|
||||||
#
|
|
||||||
# if any(i for i in allIns[2][player]):
|
|
||||||
# isAllIn = True
|
|
||||||
# if (len(action_types[3][player])>0 or isAllIn):
|
|
||||||
# myStreet3Seen = True
|
|
||||||
#
|
|
||||||
# #print "base:", base
|
|
||||||
# if base=="hold":
|
|
||||||
# mySawShowdown = True
|
|
||||||
# if any(actiontype == "fold" for actiontype in action_types[3][player]):
|
|
||||||
# mySawShowdown = False
|
|
||||||
# else:
|
|
||||||
# #print "in else"
|
|
||||||
# if any(i for i in allIns[3][player]):
|
|
||||||
# isAllIn = True
|
|
||||||
# if (len(action_types[4][player])>0 or isAllIn):
|
|
||||||
# #print "in if"
|
|
||||||
# myStreet4Seen = True
|
|
||||||
#
|
|
||||||
# mySawShowdown = True
|
|
||||||
# if any(actiontype == "fold" for actiontype in action_types[4][player]):
|
|
||||||
# mySawShowdown = False
|
|
||||||
#
|
|
||||||
# if myStreet1Seen:
|
|
||||||
# result['playersAtStreet1'] += 1
|
|
||||||
# if myStreet2Seen:
|
|
||||||
# result['playersAtStreet2'] += 1
|
|
||||||
# if myStreet3Seen:
|
|
||||||
# result['playersAtStreet3'] += 1
|
|
||||||
# if myStreet4Seen:
|
|
||||||
# result['playersAtStreet4'] += 1
|
|
||||||
# if mySawShowdown:
|
|
||||||
# result['playersAtShowdown'] += 1
|
|
||||||
#
|
|
||||||
# #flop stuff
|
|
||||||
# street=1
|
|
||||||
# if myStreet1Seen:
|
|
||||||
# if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
|
||||||
# myStreet1Aggr = True
|
|
||||||
#
|
|
||||||
# myStreet1Calls = action_types[street][player].count('call')
|
|
||||||
# myStreet1Bets = action_types[street][player].count('bet')
|
|
||||||
# # street1Raises = action_types[street][player].count('raise') bet count includes raises for now
|
|
||||||
# result['street1Raises'] += myStreet1Bets
|
|
||||||
#
|
|
||||||
# for otherPlayer in xrange(len(player_ids)):
|
|
||||||
# if player==otherPlayer:
|
|
||||||
# pass
|
|
||||||
# else:
|
|
||||||
# for countOther in xrange(len(action_types[street][otherPlayer])):
|
|
||||||
# if action_types[street][otherPlayer][countOther]=="bet":
|
|
||||||
# myOtherRaisedStreet1=True
|
|
||||||
# for countOtherFold in xrange(len(action_types[street][player])):
|
|
||||||
# if action_types[street][player][countOtherFold]=="fold":
|
|
||||||
# myFoldToOtherRaisedStreet1=True
|
|
||||||
#
|
|
||||||
# #turn stuff - copy of flop with different vars
|
|
||||||
# street=2
|
|
||||||
# if myStreet2Seen:
|
|
||||||
# if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
|
||||||
# myStreet2Aggr = True
|
|
||||||
#
|
|
||||||
# myStreet2Calls = action_types[street][player].count('call')
|
|
||||||
# myStreet2Bets = action_types[street][player].count('bet')
|
|
||||||
# # street2Raises = action_types[street][player].count('raise') bet count includes raises for now
|
|
||||||
# result['street2Raises'] += myStreet2Bets
|
|
||||||
#
|
|
||||||
# for otherPlayer in xrange(len(player_ids)):
|
|
||||||
# if player==otherPlayer:
|
|
||||||
# pass
|
|
||||||
# else:
|
|
||||||
# for countOther in xrange(len(action_types[street][otherPlayer])):
|
|
||||||
# if action_types[street][otherPlayer][countOther]=="bet":
|
|
||||||
# myOtherRaisedStreet2=True
|
|
||||||
# for countOtherFold in xrange(len(action_types[street][player])):
|
|
||||||
# if action_types[street][player][countOtherFold]=="fold":
|
|
||||||
# myFoldToOtherRaisedStreet2=True
|
|
||||||
#
|
|
||||||
# #river stuff - copy of flop with different vars
|
|
||||||
# street=3
|
|
||||||
# if myStreet3Seen:
|
|
||||||
# if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
|
||||||
# myStreet3Aggr = True
|
|
||||||
#
|
|
||||||
# myStreet3Calls = action_types[street][player].count('call')
|
|
||||||
# myStreet3Bets = action_types[street][player].count('bet')
|
|
||||||
# # street3Raises = action_types[street][player].count('raise') bet count includes raises for now
|
|
||||||
# result['street3Raises'] += myStreet3Bets
|
|
||||||
#
|
|
||||||
# for otherPlayer in xrange(len(player_ids)):
|
|
||||||
# if player==otherPlayer:
|
|
||||||
# pass
|
|
||||||
# else:
|
|
||||||
# for countOther in xrange(len(action_types[street][otherPlayer])):
|
|
||||||
# if action_types[street][otherPlayer][countOther]=="bet":
|
|
||||||
# myOtherRaisedStreet3=True
|
|
||||||
# for countOtherFold in xrange(len(action_types[street][player])):
|
|
||||||
# if action_types[street][player][countOtherFold]=="fold":
|
|
||||||
# myFoldToOtherRaisedStreet3=True
|
|
||||||
#
|
|
||||||
# #stud river stuff - copy of flop with different vars
|
|
||||||
# street=4
|
|
||||||
# if myStreet4Seen:
|
|
||||||
# if any(actiontype == "bet" for actiontype in action_types[street][player]):
|
|
||||||
# myStreet4Aggr=True
|
|
||||||
#
|
|
||||||
# myStreet4Calls = action_types[street][player].count('call')
|
|
||||||
# myStreet4Bets = action_types[street][player].count('bet')
|
|
||||||
# # street4Raises = action_types[street][player].count('raise') bet count includes raises for now
|
|
||||||
# result['street4Raises'] += myStreet4Bets
|
|
||||||
#
|
|
||||||
# for otherPlayer in xrange(len(player_ids)):
|
|
||||||
# if player==otherPlayer:
|
|
||||||
# pass
|
|
||||||
# else:
|
|
||||||
# for countOther in xrange(len(action_types[street][otherPlayer])):
|
|
||||||
# if action_types[street][otherPlayer][countOther]=="bet":
|
|
||||||
# myOtherRaisedStreet4=True
|
|
||||||
# for countOtherFold in xrange(len(action_types[street][player])):
|
|
||||||
# if action_types[street][player][countOtherFold]=="fold":
|
|
||||||
# myFoldToOtherRaisedStreet4=True
|
|
||||||
#
|
|
||||||
# if winnings[player] != 0:
|
|
||||||
# if myStreet1Seen:
|
|
||||||
# myWonWhenSeenStreet1 = winnings[player] / float(totalWinnings)
|
|
||||||
# if mySawShowdown:
|
|
||||||
# myWonAtSD=myWonWhenSeenStreet1
|
|
||||||
#
|
|
||||||
# #add each value to the appropriate array
|
|
||||||
# street0VPI.append(myStreet0VPI)
|
|
||||||
# street0Aggr.append(myStreet0Aggr)
|
|
||||||
# street0_3BChance.append(myStreet0_3BChance)
|
|
||||||
# street0_3BDone.append(myStreet0_3BDone)
|
|
||||||
# street1Seen.append(myStreet1Seen)
|
|
||||||
# street2Seen.append(myStreet2Seen)
|
|
||||||
# street3Seen.append(myStreet3Seen)
|
|
||||||
# street4Seen.append(myStreet4Seen)
|
|
||||||
# sawShowdown.append(mySawShowdown)
|
|
||||||
# street1Aggr.append(myStreet1Aggr)
|
|
||||||
# street2Aggr.append(myStreet2Aggr)
|
|
||||||
# street3Aggr.append(myStreet3Aggr)
|
|
||||||
# street4Aggr.append(myStreet4Aggr)
|
|
||||||
# otherRaisedStreet1.append(myOtherRaisedStreet1)
|
|
||||||
# otherRaisedStreet2.append(myOtherRaisedStreet2)
|
|
||||||
# otherRaisedStreet3.append(myOtherRaisedStreet3)
|
|
||||||
# otherRaisedStreet4.append(myOtherRaisedStreet4)
|
|
||||||
# foldToOtherRaisedStreet1.append(myFoldToOtherRaisedStreet1)
|
|
||||||
# foldToOtherRaisedStreet2.append(myFoldToOtherRaisedStreet2)
|
|
||||||
# foldToOtherRaisedStreet3.append(myFoldToOtherRaisedStreet3)
|
|
||||||
# foldToOtherRaisedStreet4.append(myFoldToOtherRaisedStreet4)
|
|
||||||
# wonWhenSeenStreet1.append(myWonWhenSeenStreet1)
|
|
||||||
# wonAtSD.append(myWonAtSD)
|
|
||||||
# stealAttemptChance.append(myStealAttemptChance)
|
|
||||||
# stealAttempted.append(myStealAttempted)
|
|
||||||
# if base=="hold":
|
|
||||||
# pos=positions[player]
|
|
||||||
# if pos=='B':
|
|
||||||
# hudDataPositions.append('B')
|
|
||||||
# elif pos=='S':
|
|
||||||
# hudDataPositions.append('S')
|
|
||||||
# elif pos==0:
|
|
||||||
# hudDataPositions.append('D')
|
|
||||||
# elif pos==1:
|
|
||||||
# hudDataPositions.append('C')
|
|
||||||
# elif pos>=2 and pos<=4:
|
|
||||||
# hudDataPositions.append('M')
|
|
||||||
# elif pos>=5 and pos<=8:
|
|
||||||
# hudDataPositions.append('E')
|
|
||||||
# ### RHH Added this elif to handle being a dead hand before the BB (pos==9)
|
|
||||||
# elif pos==9:
|
|
||||||
# hudDataPositions.append('X')
|
|
||||||
# else:
|
|
||||||
# raise FpdbError("invalid position")
|
|
||||||
# elif base=="stud":
|
|
||||||
# #todo: stud positions and steals
|
|
||||||
# pass
|
|
||||||
#
|
|
||||||
# street0Calls.append(myStreet0Calls)
|
|
||||||
# street1Calls.append(myStreet1Calls)
|
|
||||||
# street2Calls.append(myStreet2Calls)
|
|
||||||
# street3Calls.append(myStreet3Calls)
|
|
||||||
# street4Calls.append(myStreet4Calls)
|
|
||||||
# street0Bets.append(myStreet0Bets)
|
|
||||||
# street1Bets.append(myStreet1Bets)
|
|
||||||
# street2Bets.append(myStreet2Bets)
|
|
||||||
# street3Bets.append(myStreet3Bets)
|
|
||||||
# street4Bets.append(myStreet4Bets)
|
|
||||||
# #street0Raises.append(myStreet0Raises)
|
|
||||||
# #street1Raises.append(myStreet1Raises)
|
|
||||||
# #street2Raises.append(myStreet2Raises)
|
|
||||||
# #street3Raises.append(myStreet3Raises)
|
|
||||||
# #street4Raises.append(myStreet4Raises)
|
|
||||||
#
|
|
||||||
# #add each array to the to-be-returned dictionary
|
|
||||||
# result['street0VPI']=street0VPI
|
|
||||||
# result['street0Aggr']=street0Aggr
|
|
||||||
# result['street0_3BChance']=street0_3BChance
|
|
||||||
# result['street0_3BDone']=street0_3BDone
|
|
||||||
# result['street1Seen']=street1Seen
|
|
||||||
# result['street2Seen']=street2Seen
|
|
||||||
# result['street3Seen']=street3Seen
|
|
||||||
# result['street4Seen']=street4Seen
|
|
||||||
# result['sawShowdown']=sawShowdown
|
|
||||||
#
|
|
||||||
# result['street1Aggr']=street1Aggr
|
|
||||||
# result['otherRaisedStreet1']=otherRaisedStreet1
|
|
||||||
# result['foldToOtherRaisedStreet1']=foldToOtherRaisedStreet1
|
|
||||||
# result['street2Aggr']=street2Aggr
|
|
||||||
# result['otherRaisedStreet2']=otherRaisedStreet2
|
|
||||||
# result['foldToOtherRaisedStreet2']=foldToOtherRaisedStreet2
|
|
||||||
# result['street3Aggr']=street3Aggr
|
|
||||||
# result['otherRaisedStreet3']=otherRaisedStreet3
|
|
||||||
# result['foldToOtherRaisedStreet3']=foldToOtherRaisedStreet3
|
|
||||||
# result['street4Aggr']=street4Aggr
|
|
||||||
# result['otherRaisedStreet4']=otherRaisedStreet4
|
|
||||||
# result['foldToOtherRaisedStreet4']=foldToOtherRaisedStreet4
|
|
||||||
# result['wonWhenSeenStreet1']=wonWhenSeenStreet1
|
|
||||||
# result['wonAtSD']=wonAtSD
|
|
||||||
# result['stealAttemptChance']=stealAttemptChance
|
|
||||||
# result['stealAttempted']=stealAttempted
|
|
||||||
# result['street0Calls']=street0Calls
|
|
||||||
# result['street1Calls']=street1Calls
|
|
||||||
# result['street2Calls']=street2Calls
|
|
||||||
# result['street3Calls']=street3Calls
|
|
||||||
# result['street4Calls']=street4Calls
|
|
||||||
# result['street0Bets']=street0Bets
|
|
||||||
# result['street1Bets']=street1Bets
|
|
||||||
# result['street2Bets']=street2Bets
|
|
||||||
# result['street3Bets']=street3Bets
|
|
||||||
# result['street4Bets']=street4Bets
|
|
||||||
# #result['street0Raises']=street0Raises
|
|
||||||
# #result['street1Raises']=street1Raises
|
|
||||||
# #result['street2Raises']=street2Raises
|
|
||||||
# #result['street3Raises']=street3Raises
|
|
||||||
# #result['street4Raises']=street4Raises
|
|
||||||
#
|
|
||||||
# #now the various steal values
|
|
||||||
# foldBbToStealChance=[]
|
|
||||||
# foldedBbToSteal=[]
|
|
||||||
# foldSbToStealChance=[]
|
|
||||||
# foldedSbToSteal=[]
|
|
||||||
# for player in xrange(len(player_ids)):
|
|
||||||
# myFoldBbToStealChance=False
|
|
||||||
# myFoldedBbToSteal=False
|
|
||||||
# myFoldSbToStealChance=False
|
|
||||||
# myFoldedSbToSteal=False
|
|
||||||
#
|
|
||||||
# if base=="hold":
|
|
||||||
# if someoneStole and (positions[player]=='B' or positions[player]=='S') and firstPfRaiserId!=player_ids[player]:
|
|
||||||
# street=0
|
|
||||||
# for count in xrange(len(action_types[street][player])):#individual actions
|
|
||||||
# if positions[player]=='B':
|
|
||||||
# myFoldBbToStealChance=True
|
|
||||||
# if action_types[street][player][count]=="fold":
|
|
||||||
# myFoldedBbToSteal=True
|
|
||||||
# if positions[player]=='S':
|
|
||||||
# myFoldSbToStealChance=True
|
|
||||||
# if action_types[street][player][count]=="fold":
|
|
||||||
# myFoldedSbToSteal=True
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# foldBbToStealChance.append(myFoldBbToStealChance)
|
|
||||||
# foldedBbToSteal.append(myFoldedBbToSteal)
|
|
||||||
# foldSbToStealChance.append(myFoldSbToStealChance)
|
|
||||||
# foldedSbToSteal.append(myFoldedSbToSteal)
|
|
||||||
# result['foldBbToStealChance']=foldBbToStealChance
|
|
||||||
# result['foldedBbToSteal']=foldedBbToSteal
|
|
||||||
# result['foldSbToStealChance']=foldSbToStealChance
|
|
||||||
# result['foldedSbToSteal']=foldedSbToSteal
|
|
||||||
#
|
|
||||||
# #now CB
|
|
||||||
# street1CBChance=[]
|
|
||||||
# street1CBDone=[]
|
|
||||||
# didStreet1CB=[]
|
|
||||||
# for player in xrange(len(player_ids)):
|
|
||||||
# myStreet1CBChance=False
|
|
||||||
# myStreet1CBDone=False
|
|
||||||
#
|
|
||||||
# if street0VPI[player]:
|
|
||||||
# myStreet1CBChance=True
|
|
||||||
# if street1Aggr[player]:
|
|
||||||
# myStreet1CBDone=True
|
|
||||||
# didStreet1CB.append(player_ids[player])
|
|
||||||
#
|
|
||||||
# street1CBChance.append(myStreet1CBChance)
|
|
||||||
# street1CBDone.append(myStreet1CBDone)
|
|
||||||
# result['street1CBChance']=street1CBChance
|
|
||||||
# result['street1CBDone']=street1CBDone
|
|
||||||
#
|
|
||||||
# #now 2B
|
|
||||||
# street2CBChance=[]
|
|
||||||
# street2CBDone=[]
|
|
||||||
# didStreet2CB=[]
|
|
||||||
# for player in xrange(len(player_ids)):
|
|
||||||
# myStreet2CBChance=False
|
|
||||||
# myStreet2CBDone=False
|
|
||||||
#
|
|
||||||
# if street1CBDone[player]:
|
|
||||||
# myStreet2CBChance=True
|
|
||||||
# if street2Aggr[player]:
|
|
||||||
# myStreet2CBDone=True
|
|
||||||
# didStreet2CB.append(player_ids[player])
|
|
||||||
#
|
|
||||||
# street2CBChance.append(myStreet2CBChance)
|
|
||||||
# street2CBDone.append(myStreet2CBDone)
|
|
||||||
# result['street2CBChance']=street2CBChance
|
|
||||||
# result['street2CBDone']=street2CBDone
|
|
||||||
#
|
|
||||||
# #now 3B
|
|
||||||
# street3CBChance=[]
|
|
||||||
# street3CBDone=[]
|
|
||||||
# didStreet3CB=[]
|
|
||||||
# for player in xrange(len(player_ids)):
|
|
||||||
# myStreet3CBChance=False
|
|
||||||
# myStreet3CBDone=False
|
|
||||||
#
|
|
||||||
# if street2CBDone[player]:
|
|
||||||
# myStreet3CBChance=True
|
|
||||||
# if street3Aggr[player]:
|
|
||||||
# myStreet3CBDone=True
|
|
||||||
# didStreet3CB.append(player_ids[player])
|
|
||||||
#
|
|
||||||
# street3CBChance.append(myStreet3CBChance)
|
|
||||||
# street3CBDone.append(myStreet3CBDone)
|
|
||||||
# result['street3CBChance']=street3CBChance
|
|
||||||
# result['street3CBDone']=street3CBDone
|
|
||||||
#
|
|
||||||
# #and 4B
|
|
||||||
# street4CBChance=[]
|
|
||||||
# street4CBDone=[]
|
|
||||||
# didStreet4CB=[]
|
|
||||||
# for player in xrange(len(player_ids)):
|
|
||||||
# myStreet4CBChance=False
|
|
||||||
# myStreet4CBDone=False
|
|
||||||
#
|
|
||||||
# if street3CBDone[player]:
|
|
||||||
# myStreet4CBChance=True
|
|
||||||
# if street4Aggr[player]:
|
|
||||||
# myStreet4CBDone=True
|
|
||||||
# didStreet4CB.append(player_ids[player])
|
|
||||||
#
|
|
||||||
# street4CBChance.append(myStreet4CBChance)
|
|
||||||
# street4CBDone.append(myStreet4CBDone)
|
|
||||||
# result['street4CBChance']=street4CBChance
|
|
||||||
# result['street4CBDone']=street4CBDone
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# result['position']=hudDataPositions
|
|
||||||
#
|
|
||||||
# foldToStreet1CBChance=[]
|
|
||||||
# foldToStreet1CBDone=[]
|
|
||||||
# foldToStreet2CBChance=[]
|
|
||||||
# foldToStreet2CBDone=[]
|
|
||||||
# foldToStreet3CBChance=[]
|
|
||||||
# foldToStreet3CBDone=[]
|
|
||||||
# foldToStreet4CBChance=[]
|
|
||||||
# foldToStreet4CBDone=[]
|
|
||||||
#
|
|
||||||
# for player in xrange(len(player_ids)):
|
|
||||||
# myFoldToStreet1CBChance=False
|
|
||||||
# myFoldToStreet1CBDone=False
|
|
||||||
# foldToStreet1CBChance.append(myFoldToStreet1CBChance)
|
|
||||||
# foldToStreet1CBDone.append(myFoldToStreet1CBDone)
|
|
||||||
#
|
|
||||||
# myFoldToStreet2CBChance=False
|
|
||||||
# myFoldToStreet2CBDone=False
|
|
||||||
# foldToStreet2CBChance.append(myFoldToStreet2CBChance)
|
|
||||||
# foldToStreet2CBDone.append(myFoldToStreet2CBDone)
|
|
||||||
#
|
|
||||||
# myFoldToStreet3CBChance=False
|
|
||||||
# myFoldToStreet3CBDone=False
|
|
||||||
# foldToStreet3CBChance.append(myFoldToStreet3CBChance)
|
|
||||||
# foldToStreet3CBDone.append(myFoldToStreet3CBDone)
|
|
||||||
#
|
|
||||||
# myFoldToStreet4CBChance=False
|
|
||||||
# myFoldToStreet4CBDone=False
|
|
||||||
# foldToStreet4CBChance.append(myFoldToStreet4CBChance)
|
|
||||||
# foldToStreet4CBDone.append(myFoldToStreet4CBDone)
|
|
||||||
#
|
|
||||||
# if len(didStreet1CB)>=1:
|
|
||||||
# generateFoldToCB(1, player_ids, didStreet1CB, street1CBDone, foldToStreet1CBChance, foldToStreet1CBDone, actionTypeByNo)
|
|
||||||
#
|
|
||||||
# if len(didStreet2CB)>=1:
|
|
||||||
# generateFoldToCB(2, player_ids, didStreet2CB, street2CBDone, foldToStreet2CBChance, foldToStreet2CBDone, actionTypeByNo)
|
|
||||||
#
|
|
||||||
# if len(didStreet3CB)>=1:
|
|
||||||
# generateFoldToCB(3, player_ids, didStreet3CB, street3CBDone, foldToStreet3CBChance, foldToStreet3CBDone, actionTypeByNo)
|
|
||||||
#
|
|
||||||
# if len(didStreet4CB)>=1:
|
|
||||||
# generateFoldToCB(4, player_ids, didStreet4CB, street4CBDone, foldToStreet4CBChance, foldToStreet4CBDone, actionTypeByNo)
|
|
||||||
#
|
|
||||||
# result['foldToStreet1CBChance']=foldToStreet1CBChance
|
|
||||||
# result['foldToStreet1CBDone']=foldToStreet1CBDone
|
|
||||||
# result['foldToStreet2CBChance']=foldToStreet2CBChance
|
|
||||||
# result['foldToStreet2CBDone']=foldToStreet2CBDone
|
|
||||||
# result['foldToStreet3CBChance']=foldToStreet3CBChance
|
|
||||||
# result['foldToStreet3CBDone']=foldToStreet3CBDone
|
|
||||||
# result['foldToStreet4CBChance']=foldToStreet4CBChance
|
|
||||||
# result['foldToStreet4CBDone']=foldToStreet4CBDone
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# totalProfit=[]
|
|
||||||
#
|
|
||||||
# street1CheckCallRaiseChance=[]
|
|
||||||
# street1CheckCallRaiseDone=[]
|
|
||||||
# street2CheckCallRaiseChance=[]
|
|
||||||
# street2CheckCallRaiseDone=[]
|
|
||||||
# street3CheckCallRaiseChance=[]
|
|
||||||
# street3CheckCallRaiseDone=[]
|
|
||||||
# street4CheckCallRaiseChance=[]
|
|
||||||
# street4CheckCallRaiseDone=[]
|
|
||||||
# #print "b4 totprof calc, len(playerIds)=", len(player_ids)
|
|
||||||
# for pl in xrange(len(player_ids)):
|
|
||||||
# #print "pl=", pl
|
|
||||||
# myTotalProfit=winnings[pl] # still need to deduct other costs
|
|
||||||
# if antes:
|
|
||||||
# myTotalProfit=winnings[pl] - antes[pl]
|
|
||||||
# for i in xrange(len(actionTypes)): #iterate through streets
|
|
||||||
# #for j in xrange(len(actionTypes[i])): #iterate through names (using pl loop above)
|
|
||||||
# for k in xrange(len(actionTypes[i][pl])): #iterate through individual actions of that player on that street
|
|
||||||
# myTotalProfit -= actionAmounts[i][pl][k]
|
|
||||||
#
|
|
||||||
# myStreet1CheckCallRaiseChance=False
|
|
||||||
# myStreet1CheckCallRaiseDone=False
|
|
||||||
# myStreet2CheckCallRaiseChance=False
|
|
||||||
# myStreet2CheckCallRaiseDone=False
|
|
||||||
# myStreet3CheckCallRaiseChance=False
|
|
||||||
# myStreet3CheckCallRaiseDone=False
|
|
||||||
# myStreet4CheckCallRaiseChance=False
|
|
||||||
# myStreet4CheckCallRaiseDone=False
|
|
||||||
#
|
|
||||||
# #print "myTotalProfit=", myTotalProfit
|
|
||||||
# totalProfit.append(myTotalProfit)
|
|
||||||
# #print "totalProfit[]=", totalProfit
|
|
||||||
#
|
|
||||||
# street1CheckCallRaiseChance.append(myStreet1CheckCallRaiseChance)
|
|
||||||
# street1CheckCallRaiseDone.append(myStreet1CheckCallRaiseDone)
|
|
||||||
# street2CheckCallRaiseChance.append(myStreet2CheckCallRaiseChance)
|
|
||||||
# street2CheckCallRaiseDone.append(myStreet2CheckCallRaiseDone)
|
|
||||||
# street3CheckCallRaiseChance.append(myStreet3CheckCallRaiseChance)
|
|
||||||
# street3CheckCallRaiseDone.append(myStreet3CheckCallRaiseDone)
|
|
||||||
# street4CheckCallRaiseChance.append(myStreet4CheckCallRaiseChance)
|
|
||||||
# street4CheckCallRaiseDone.append(myStreet4CheckCallRaiseDone)
|
|
||||||
#
|
|
||||||
# result['totalProfit']=totalProfit
|
|
||||||
# #print "res[totalProfit]=", result['totalProfit']
|
|
||||||
#
|
|
||||||
# result['street1CheckCallRaiseChance']=street1CheckCallRaiseChance
|
|
||||||
# result['street1CheckCallRaiseDone']=street1CheckCallRaiseDone
|
|
||||||
# result['street2CheckCallRaiseChance']=street2CheckCallRaiseChance
|
|
||||||
# result['street2CheckCallRaiseDone']=street2CheckCallRaiseDone
|
|
||||||
# result['street3CheckCallRaiseChance']=street3CheckCallRaiseChance
|
|
||||||
# result['street3CheckCallRaiseDone']=street3CheckCallRaiseDone
|
|
||||||
# result['street4CheckCallRaiseChance']=street4CheckCallRaiseChance
|
|
||||||
# result['street4CheckCallRaiseDone']=street4CheckCallRaiseDone
|
|
||||||
# return result
|
|
||||||
# #end def generateHudCacheData
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def vpip(self, hand):
|
def vpip(self, hand):
|
||||||
|
@ -794,9 +162,9 @@ class DerivedStats():
|
||||||
|
|
||||||
for player in hand.players:
|
for player in hand.players:
|
||||||
if player[1] in vpipers:
|
if player[1] in vpipers:
|
||||||
self.handsplayers[player[1]]['vpip'] = True
|
self.handsplayers[player[1]]['street0VPI'] = True
|
||||||
else:
|
else:
|
||||||
self.handsplayers[player[1]]['vpip'] = False
|
self.handsplayers[player[1]]['street0VPI'] = False
|
||||||
|
|
||||||
def playersAtStreetX(self, hand):
|
def playersAtStreetX(self, hand):
|
||||||
""" playersAtStreet1 SMALLINT NOT NULL, /* num of players seeing flop/street4/draw1 */"""
|
""" playersAtStreet1 SMALLINT NOT NULL, /* num of players seeing flop/street4/draw1 */"""
|
||||||
|
@ -812,14 +180,23 @@ class DerivedStats():
|
||||||
self.hands['playersAtStreet4'] = 0
|
self.hands['playersAtStreet4'] = 0
|
||||||
self.hands['playersAtShowdown'] = 0
|
self.hands['playersAtShowdown'] = 0
|
||||||
|
|
||||||
|
alliners = set()
|
||||||
for (i, street) in enumerate(hand.actionStreets[2:]):
|
for (i, street) in enumerate(hand.actionStreets[2:]):
|
||||||
actors = {}
|
actors = set()
|
||||||
for act in hand.actions[street]:
|
for action in hand.actions[street]:
|
||||||
actors[act[0]] = 1
|
if len(action) > 2 and action[-1]: # allin
|
||||||
self.hands['playersAtStreet%s' % str(i+1)] = len(actors.keys())
|
alliners.add(action[0])
|
||||||
|
actors.add(action[0])
|
||||||
|
if len(actors)==0 and len(alliners)<2:
|
||||||
|
alliners = set()
|
||||||
|
self.hands['playersAtStreet%d' % (i+1)] = len(set.union(alliners, actors))
|
||||||
|
|
||||||
#Need playersAtShowdown
|
actions = hand.actions[hand.actionStreets[-1]]
|
||||||
|
pas = set.union(self.pfba(actions) - self.pfba(actions, l=('folds',)), alliners)
|
||||||
|
self.hands['playersAtShowdown'] = len(pas)
|
||||||
|
|
||||||
|
for player in pas:
|
||||||
|
self.handsplayers[player]['sawShowdown'] = True
|
||||||
|
|
||||||
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
|
||||||
|
@ -827,11 +204,36 @@ class DerivedStats():
|
||||||
# No idea what this value is actually supposed to be
|
# No idea what this value is actually supposed to be
|
||||||
# In theory its "num small bets paid to see flop/street4, including blind" which makes sense for limit. Not so useful for nl
|
# In theory its "num small bets paid to see flop/street4, including blind" which makes sense for limit. Not so useful for nl
|
||||||
# Leaving empty for the moment,
|
# Leaving empty for the moment,
|
||||||
self.hands['street0Raises'] = 0 # /* num small bets paid to see flop/street4, including blind */
|
|
||||||
self.hands['street1Raises'] = 0 # /* num small bets paid to see turn/street5 */
|
for i in range(5): self.hands['street%dRaises' % i] = 0
|
||||||
self.hands['street2Raises'] = 0 # /* num big bets paid to see river/street6 */
|
|
||||||
self.hands['street3Raises'] = 0 # /* num big bets paid to see sd/street7 */
|
for (i, street) in enumerate(hand.actionStreets[1:]):
|
||||||
self.hands['street4Raises'] = 0 # /* num big bets paid to see showdown */
|
self.hands['street%dRaises' % i] = len(filter( lambda action: action[1] in ('raises','bets'), hand.actions[street]))
|
||||||
|
|
||||||
|
def calcCBets(self, hand):
|
||||||
|
# Continuation Bet chance, action:
|
||||||
|
# Had the last bet (initiative) on previous street, got called, close street action
|
||||||
|
# Then no bets before the player with initiatives first action on current street
|
||||||
|
# ie. if player on street-1 had initiative
|
||||||
|
# and no donkbets occurred
|
||||||
|
for i, street in enumerate(hand.actionStreets[2:], start=1):
|
||||||
|
name = self.lastBetOrRaiser(hand.actionStreets[i])
|
||||||
|
if name:
|
||||||
|
chance = self.noBetsBefore(hand.actionStreets[i+1], name)
|
||||||
|
self.handsplayers[name]['street%dCBChance' %i] = True
|
||||||
|
if chance == True:
|
||||||
|
self.handsplayers[name]['street%dCBDone' %i] = self.betStreet(hand.actionStreets[i+1], name)
|
||||||
|
|
||||||
|
def seen(self, hand, i):
|
||||||
|
pas = set()
|
||||||
|
for act in hand.actions[hand.actionStreets[i+1]]:
|
||||||
|
pas.add(act[0])
|
||||||
|
|
||||||
|
for player in hand.players:
|
||||||
|
if player[1] in pas:
|
||||||
|
self.handsplayers[player[1]]['street%sSeen' % i] = True
|
||||||
|
else:
|
||||||
|
self.handsplayers[player[1]]['street%sSeen' % i] = False
|
||||||
|
|
||||||
def aggr(self, hand, i):
|
def aggr(self, hand, i):
|
||||||
aggrers = set()
|
aggrers = set()
|
||||||
|
@ -845,5 +247,64 @@ class DerivedStats():
|
||||||
else:
|
else:
|
||||||
self.handsplayers[player[1]]['street%sAggr' % i] = False
|
self.handsplayers[player[1]]['street%sAggr' % i] = False
|
||||||
|
|
||||||
|
def calls(self, hand, i):
|
||||||
|
callers = []
|
||||||
|
for act in hand.actions[hand.actionStreets[i+1]]:
|
||||||
|
if act[1] in ('calls'):
|
||||||
|
self.handsplayers[act[0]]['street%sCalls' % i] = 1 + self.handsplayers[act[0]]['street%sCalls' % i]
|
||||||
|
|
||||||
|
# CG - I'm sure this stat is wrong
|
||||||
|
# Best guess is that raise = 2 bets
|
||||||
|
def bets(self, hand, i):
|
||||||
|
betters = []
|
||||||
|
for act in hand.actions[hand.actionStreets[i+1]]:
|
||||||
|
if act[1] in ('bets'):
|
||||||
|
self.handsplayers[act[0]]['street%sBets' % i] = 1 + self.handsplayers[act[0]]['street%sBets' % i]
|
||||||
|
|
||||||
def countPlayers(self, hand):
|
def countPlayers(self, hand):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def pfba(self, actions, f=None, l=None):
|
||||||
|
"""Helper method. Returns set of PlayersFilteredByActions
|
||||||
|
|
||||||
|
f - forbidden actions
|
||||||
|
l - limited to actions
|
||||||
|
"""
|
||||||
|
players = set()
|
||||||
|
for action in actions:
|
||||||
|
if l is not None and action[1] not in l: continue
|
||||||
|
if f is not None and action[1] in f: continue
|
||||||
|
players.add(action[0])
|
||||||
|
return players
|
||||||
|
|
||||||
|
def noBetsBefore(self, street, player):
|
||||||
|
"""Returns true if there were no bets before the specified players turn, false otherwise"""
|
||||||
|
betOrRaise = False
|
||||||
|
for act in self.hand.actions[street]:
|
||||||
|
#Must test for player first in case UTG
|
||||||
|
if act[0] == player:
|
||||||
|
betOrRaise = True
|
||||||
|
break
|
||||||
|
if act[1] in ('bets', 'raises'):
|
||||||
|
break
|
||||||
|
return betOrRaise
|
||||||
|
|
||||||
|
def betStreet(self, street, player):
|
||||||
|
"""Returns true if player bet/raised the street as their first action"""
|
||||||
|
betOrRaise = False
|
||||||
|
for act in self.hand.actions[street]:
|
||||||
|
if act[0] == player and act[1] in ('bets', 'raises'):
|
||||||
|
betOrRaise = True
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
return betOrRaise
|
||||||
|
|
||||||
|
|
||||||
|
def lastBetOrRaiser(self, street):
|
||||||
|
"""Returns player name that placed the last bet or raise for that street.
|
||||||
|
None if there were no bets or raises on that street"""
|
||||||
|
lastbet = None
|
||||||
|
for act in self.hand.actions[street]:
|
||||||
|
if act[1] in ('bets', 'raises'):
|
||||||
|
lastbet = act[0]
|
||||||
|
return lastbet
|
||||||
|
|
|
@ -4,7 +4,7 @@ class FpdbError(Exception):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return repr(self.value)
|
return repr(self.value)
|
||||||
|
|
||||||
class FpdbParseError(FpdbError):
|
class FpdbParseError(FpdbError):
|
||||||
def __init__(self,value='',hid=''):
|
def __init__(self,value='',hid=''):
|
||||||
self.value = value
|
self.value = value
|
||||||
self.hid = hid
|
self.hid = hid
|
||||||
|
@ -17,8 +17,22 @@ class FpdbParseError(FpdbError):
|
||||||
class FpdbDatabaseError(FpdbError):
|
class FpdbDatabaseError(FpdbError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class FpdbMySQLFailedError(FpdbDatabaseError):
|
class FpdbMySQLError(FpdbDatabaseError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class FpdbMySQLAccessDenied(FpdbDatabaseError):
|
||||||
|
def __init__(self, value='', errmsg=''):
|
||||||
|
self.value = value
|
||||||
|
self.errmsg = errmsg
|
||||||
|
def __str__(self):
|
||||||
|
return repr(self.value +" " + self.errmsg)
|
||||||
|
|
||||||
|
class FpdbMySQLNoDatabase(FpdbDatabaseError):
|
||||||
|
def __init__(self, value='', errmsg=''):
|
||||||
|
self.value = value
|
||||||
|
self.errmsg = errmsg
|
||||||
|
def __str__(self):
|
||||||
|
return repr(self.value +" " + self.errmsg)
|
||||||
|
|
||||||
class DuplicateError(FpdbError):
|
class DuplicateError(FpdbError):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -69,7 +69,7 @@ class Filters(threading.Thread):
|
||||||
self.sbGroups = {}
|
self.sbGroups = {}
|
||||||
self.numHands = 0
|
self.numHands = 0
|
||||||
|
|
||||||
# Outer Packing box
|
# Outer Packing box
|
||||||
self.mainVBox = gtk.VBox(False, 0)
|
self.mainVBox = gtk.VBox(False, 0)
|
||||||
|
|
||||||
playerFrame = gtk.Frame("Hero:")
|
playerFrame = gtk.Frame("Hero:")
|
||||||
|
@ -312,9 +312,11 @@ class Filters(threading.Thread):
|
||||||
self.cbAllLimits.set_active(False)
|
self.cbAllLimits.set_active(False)
|
||||||
if not self.limits[limit]:
|
if not self.limits[limit]:
|
||||||
if limit.isdigit():
|
if limit.isdigit():
|
||||||
self.cbFL.set_active(False)
|
if self.cbFL is not None:
|
||||||
|
self.cbFL.set_active(False)
|
||||||
else:
|
else:
|
||||||
self.cbNL.set_active(False)
|
if self.cbNL is not None:
|
||||||
|
self.cbNL.set_active(False)
|
||||||
elif limit == "all":
|
elif limit == "all":
|
||||||
if self.limits[limit]:
|
if self.limits[limit]:
|
||||||
#for cb in self.cbLimits.values():
|
#for cb in self.cbLimits.values():
|
||||||
|
@ -327,12 +329,14 @@ class Filters(threading.Thread):
|
||||||
if self.limits[limit]:
|
if self.limits[limit]:
|
||||||
for cb in self.cbLimits.values():
|
for cb in self.cbLimits.values():
|
||||||
cb.set_active(False)
|
cb.set_active(False)
|
||||||
self.cbNL.set_active(False)
|
if self.cbNL is not None:
|
||||||
self.cbFL.set_active(False)
|
self.cbNL.set_active(False)
|
||||||
|
if self.cbFL is not None:
|
||||||
|
self.cbFL.set_active(False)
|
||||||
elif limit == "fl":
|
elif limit == "fl":
|
||||||
if not self.limits[limit]:
|
if not self.limits[limit]:
|
||||||
# only toggle all fl limits off if they are all currently on
|
# only toggle all fl limits off if they are all currently on
|
||||||
# this stops turning one off from cascading into 'fl' box off
|
# this stops turning one off from cascading into 'fl' box off
|
||||||
# and then all fl limits being turned off
|
# and then all fl limits being turned off
|
||||||
all_fl_on = True
|
all_fl_on = True
|
||||||
for cb in self.cbLimits.values():
|
for cb in self.cbLimits.values():
|
||||||
|
@ -359,7 +363,7 @@ class Filters(threading.Thread):
|
||||||
elif limit == "nl":
|
elif limit == "nl":
|
||||||
if not self.limits[limit]:
|
if not self.limits[limit]:
|
||||||
# only toggle all nl limits off if they are all currently on
|
# only toggle all nl limits off if they are all currently on
|
||||||
# this stops turning one off from cascading into 'nl' box off
|
# this stops turning one off from cascading into 'nl' box off
|
||||||
# and then all nl limits being turned off
|
# and then all nl limits being turned off
|
||||||
all_nl_on = True
|
all_nl_on = True
|
||||||
for cb in self.cbLimits.values():
|
for cb in self.cbLimits.values():
|
||||||
|
@ -731,11 +735,11 @@ def main(argv=None):
|
||||||
gtk.main_quit()
|
gtk.main_quit()
|
||||||
|
|
||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
(options, sys.argv) = parser.parse_args(args = argv)
|
(options, argv) = parser.parse_args(args = argv)
|
||||||
|
|
||||||
config = Configuration.Config()
|
config = Configuration.Config()
|
||||||
db = None
|
db = None
|
||||||
|
|
||||||
db = fpdb_db.fpdb_db()
|
db = fpdb_db.fpdb_db()
|
||||||
db.do_connect(config)
|
db.do_connect(config)
|
||||||
|
|
||||||
|
@ -750,5 +754,3 @@ def main(argv=None):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ class GuiAutoImport (threading.Thread):
|
||||||
self.importer.setFailOnError(False)
|
self.importer.setFailOnError(False)
|
||||||
self.importer.setHandCount(0)
|
self.importer.setHandCount(0)
|
||||||
# self.importer.setWatchTime()
|
# self.importer.setWatchTime()
|
||||||
|
|
||||||
self.server = settings['db-host']
|
self.server = settings['db-host']
|
||||||
self.user = settings['db-user']
|
self.user = settings['db-user']
|
||||||
self.password = settings['db-password']
|
self.password = settings['db-password']
|
||||||
|
@ -63,7 +63,7 @@ class GuiAutoImport (threading.Thread):
|
||||||
|
|
||||||
hbox = gtk.HBox(True, 0) # contains 2 equal vboxes
|
hbox = gtk.HBox(True, 0) # contains 2 equal vboxes
|
||||||
self.mainVBox.pack_start(hbox, False, False, 0)
|
self.mainVBox.pack_start(hbox, False, False, 0)
|
||||||
|
|
||||||
vbox1 = gtk.VBox(True, 0)
|
vbox1 = gtk.VBox(True, 0)
|
||||||
hbox.pack_start(vbox1, True, True, 0)
|
hbox.pack_start(vbox1, True, True, 0)
|
||||||
vbox2 = gtk.VBox(True, 0)
|
vbox2 = gtk.VBox(True, 0)
|
||||||
|
@ -71,22 +71,24 @@ class GuiAutoImport (threading.Thread):
|
||||||
|
|
||||||
self.intervalLabel = gtk.Label("Time between imports in seconds:")
|
self.intervalLabel = gtk.Label("Time between imports in seconds:")
|
||||||
self.intervalLabel.set_alignment(xalign=1.0, yalign=0.5)
|
self.intervalLabel.set_alignment(xalign=1.0, yalign=0.5)
|
||||||
vbox1.pack_start(self.intervalLabel, True, True, 0)
|
vbox1.pack_start(self.intervalLabel, False, True, 0)
|
||||||
|
|
||||||
hbox = gtk.HBox(False, 0)
|
hbox = gtk.HBox(False, 0)
|
||||||
vbox2.pack_start(hbox, True, True, 0)
|
vbox2.pack_start(hbox, False, True, 0)
|
||||||
self.intervalEntry = gtk.Entry()
|
self.intervalEntry = gtk.Entry()
|
||||||
self.intervalEntry.set_text(str(self.config.get_import_parameters().get("interval")))
|
self.intervalEntry.set_text(str(self.config.get_import_parameters().get("interval")))
|
||||||
hbox.pack_start(self.intervalEntry, False, False, 0)
|
hbox.pack_start(self.intervalEntry, False, False, 0)
|
||||||
lbl1 = gtk.Label()
|
lbl1 = gtk.Label()
|
||||||
hbox.pack_start(lbl1, expand=True, fill=True)
|
hbox.pack_start(lbl1, expand=False, fill=True)
|
||||||
|
|
||||||
lbl = gtk.Label('')
|
lbl = gtk.Label('')
|
||||||
vbox1.pack_start(lbl, expand=True, fill=True)
|
vbox1.pack_start(lbl, expand=False, fill=True)
|
||||||
lbl = gtk.Label('')
|
lbl = gtk.Label('')
|
||||||
vbox2.pack_start(lbl, expand=True, fill=True)
|
vbox2.pack_start(lbl, expand=False, fill=True)
|
||||||
|
|
||||||
self.addSites(vbox1, vbox2)
|
self.addSites(vbox1, vbox2)
|
||||||
|
self.textbuffer = gtk.TextBuffer()
|
||||||
|
self.textview = gtk.TextView(self.textbuffer)
|
||||||
|
|
||||||
hbox = gtk.HBox(False, 0)
|
hbox = gtk.HBox(False, 0)
|
||||||
self.mainVBox.pack_start(hbox, expand=True, padding=3)
|
self.mainVBox.pack_start(hbox, expand=True, padding=3)
|
||||||
|
@ -102,13 +104,27 @@ class GuiAutoImport (threading.Thread):
|
||||||
self.startButton.connect("clicked", self.startClicked, "start clicked")
|
self.startButton.connect("clicked", self.startClicked, "start clicked")
|
||||||
hbox.pack_start(self.startButton, expand=False, fill=False)
|
hbox.pack_start(self.startButton, expand=False, fill=False)
|
||||||
|
|
||||||
|
|
||||||
lbl2 = gtk.Label()
|
lbl2 = gtk.Label()
|
||||||
hbox.pack_start(lbl2, expand=True, fill=False)
|
hbox.pack_start(lbl2, expand=True, fill=False)
|
||||||
|
|
||||||
hbox = gtk.HBox(False, 0)
|
hbox = gtk.HBox(False, 0)
|
||||||
hbox.show()
|
hbox.show()
|
||||||
|
|
||||||
self.mainVBox.pack_start(hbox, expand=True, padding=3)
|
self.mainVBox.pack_start(hbox, expand=True, padding=3)
|
||||||
|
|
||||||
|
scrolledwindow = gtk.ScrolledWindow()
|
||||||
|
scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||||
|
self.mainVBox.pack_end(scrolledwindow, expand=True)
|
||||||
|
scrolledwindow.add(self.textview)
|
||||||
|
|
||||||
self.mainVBox.show_all()
|
self.mainVBox.show_all()
|
||||||
|
self.addText("AutoImport Ready.")
|
||||||
|
|
||||||
|
def addText(self, text):
|
||||||
|
end_iter = self.textbuffer.get_end_iter()
|
||||||
|
self.textbuffer.insert(end_iter, text)
|
||||||
|
self.textview.scroll_to_mark(self.textbuffer.get_insert(), 0)
|
||||||
|
|
||||||
|
|
||||||
#end of GuiAutoImport.__init__
|
#end of GuiAutoImport.__init__
|
||||||
|
@ -139,18 +155,19 @@ class GuiAutoImport (threading.Thread):
|
||||||
if self.doAutoImportBool:
|
if self.doAutoImportBool:
|
||||||
self.startButton.set_label(u' I M P O R T I N G ')
|
self.startButton.set_label(u' I M P O R T I N G ')
|
||||||
self.importer.runUpdated()
|
self.importer.runUpdated()
|
||||||
sys.stdout.write(".")
|
self.addText(".")
|
||||||
sys.stdout.flush()
|
#sys.stdout.write(".")
|
||||||
|
#sys.stdout.flush()
|
||||||
gobject.timeout_add(1000, self.reset_startbutton)
|
gobject.timeout_add(1000, self.reset_startbutton)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def reset_startbutton(self):
|
def reset_startbutton(self):
|
||||||
if self.pipe_to_hud is not None:
|
if self.pipe_to_hud is not None:
|
||||||
self.startButton.set_label(u' _Stop Autoimport ')
|
self.startButton.set_label(u' _Stop Autoimport ')
|
||||||
else:
|
else:
|
||||||
self.startButton.set_label(u' _Start Autoimport ')
|
self.startButton.set_label(u' _Start Autoimport ')
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@ -169,10 +186,10 @@ class GuiAutoImport (threading.Thread):
|
||||||
if widget.get_active(): # toggled on
|
if widget.get_active(): # toggled on
|
||||||
# - Does the lock acquisition need to be more sophisticated for multiple dirs?
|
# - Does the lock acquisition need to be more sophisticated for multiple dirs?
|
||||||
# (see comment above about what to do if pipe already open)
|
# (see comment above about what to do if pipe already open)
|
||||||
# - Ideally we want to release the lock if the auto-import is killed by some
|
# - Ideally we want to release the lock if the auto-import is killed by some
|
||||||
# kind of exception - is this possible?
|
# kind of exception - is this possible?
|
||||||
if self.settings['global_lock'].acquire(False): # returns false immediately if lock not acquired
|
if self.settings['global_lock'].acquire(False): # returns false immediately if lock not acquired
|
||||||
print "\nGlobal lock taken ..."
|
self.addText("\nGlobal lock taken ... Auto Import Started.\n")
|
||||||
self.doAutoImportBool = True
|
self.doAutoImportBool = True
|
||||||
widget.set_label(u' _Stop Autoimport ')
|
widget.set_label(u' _Stop Autoimport ')
|
||||||
if self.pipe_to_hud is None:
|
if self.pipe_to_hud is None:
|
||||||
|
@ -183,34 +200,33 @@ class GuiAutoImport (threading.Thread):
|
||||||
command = os.path.join(sys.path[0], 'HUD_main.py')
|
command = os.path.join(sys.path[0], 'HUD_main.py')
|
||||||
command = [command, ] + string.split(self.settings['cl_options'])
|
command = [command, ] + string.split(self.settings['cl_options'])
|
||||||
bs = 1
|
bs = 1
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.pipe_to_hud = subprocess.Popen(command, bufsize=bs,
|
self.pipe_to_hud = subprocess.Popen(command, bufsize=bs,
|
||||||
stdin=subprocess.PIPE,
|
stdin=subprocess.PIPE,
|
||||||
universal_newlines=True)
|
universal_newlines=True)
|
||||||
except:
|
except:
|
||||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||||
print "*** GuiAutoImport Error opening pipe: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
|
self.addText( "\n*** GuiAutoImport Error opening pipe: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1]))
|
||||||
else:
|
else:
|
||||||
for site in self.input_settings:
|
for site in self.input_settings:
|
||||||
self.importer.addImportDirectory(self.input_settings[site][0], True, site, self.input_settings[site][1])
|
self.importer.addImportDirectory(self.input_settings[site][0], True, site, self.input_settings[site][1])
|
||||||
print " * Add", site, " import directory", str(self.input_settings[site][0])
|
self.addText("\n * Add "+ site+ " import directory "+ str(self.input_settings[site][0]))
|
||||||
print "+Import directory - Site: " + site + " dir: " + str(self.input_settings[site][0])
|
self.do_import()
|
||||||
self.do_import()
|
|
||||||
interval = int(self.intervalEntry.get_text())
|
interval = int(self.intervalEntry.get_text())
|
||||||
if self.importtimer != 0:
|
if self.importtimer != 0:
|
||||||
gobject.source_remove(self.importtimer)
|
gobject.source_remove(self.importtimer)
|
||||||
self.importtimer = gobject.timeout_add(interval * 1000, self.do_import)
|
self.importtimer = gobject.timeout_add(interval * 1000, self.do_import)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print "auto-import aborted - global lock not available"
|
self.addText("\nauto-import aborted - global lock not available")
|
||||||
else: # toggled off
|
else: # toggled off
|
||||||
gobject.source_remove(self.importtimer)
|
gobject.source_remove(self.importtimer)
|
||||||
self.settings['global_lock'].release()
|
self.settings['global_lock'].release()
|
||||||
self.doAutoImportBool = False # do_import will return this and stop the gobject callback timer
|
self.doAutoImportBool = False # do_import will return this and stop the gobject callback timer
|
||||||
print "Stopping autoimport - global lock released."
|
self.addText("\nStopping autoimport - global lock released.")
|
||||||
if self.pipe_to_hud.poll() is not None:
|
if self.pipe_to_hud.poll() is not None:
|
||||||
print " * Stop Autoimport: HUD already terminated"
|
self.addText("\n * Stop Autoimport: HUD already terminated")
|
||||||
else:
|
else:
|
||||||
#print >>self.pipe_to_hud.stdin, "\n"
|
#print >>self.pipe_to_hud.stdin, "\n"
|
||||||
self.pipe_to_hud.communicate('\n') # waits for process to terminate
|
self.pipe_to_hud.communicate('\n') # waits for process to terminate
|
||||||
|
@ -258,7 +274,7 @@ class GuiAutoImport (threading.Thread):
|
||||||
vbox1.pack_start(pathHBox1, False, True, 0)
|
vbox1.pack_start(pathHBox1, False, True, 0)
|
||||||
pathHBox2 = gtk.HBox(False, 0)
|
pathHBox2 = gtk.HBox(False, 0)
|
||||||
vbox2.pack_start(pathHBox2, False, True, 0)
|
vbox2.pack_start(pathHBox2, False, True, 0)
|
||||||
|
|
||||||
params = self.config.get_site_parameters(site)
|
params = self.config.get_site_parameters(site)
|
||||||
paths = self.config.get_default_paths(site)
|
paths = self.config.get_default_paths(site)
|
||||||
self.createSiteLine(pathHBox1, pathHBox2, site, False, paths['hud-defaultPath'], params['converter'], params['enabled'])
|
self.createSiteLine(pathHBox1, pathHBox2, site, False, paths['hud-defaultPath'], params['converter'], params['enabled'])
|
||||||
|
@ -281,7 +297,7 @@ if __name__== "__main__":
|
||||||
parser.add_option("-q", "--quiet", action="store_false", dest="gui", default=True, help="don't start gui")
|
parser.add_option("-q", "--quiet", action="store_false", dest="gui", default=True, help="don't start gui")
|
||||||
parser.add_option("-m", "--minPrint", "--status", dest="minPrint", default="0", type="int",
|
parser.add_option("-m", "--minPrint", "--status", dest="minPrint", default="0", type="int",
|
||||||
help="How often to print a one-line status report (0 (default) means never)")
|
help="How often to print a one-line status report (0 (default) means never)")
|
||||||
(options, sys.argv) = parser.parse_args()
|
(options, argv) = parser.parse_args()
|
||||||
|
|
||||||
config = Configuration.Config()
|
config = Configuration.Config()
|
||||||
# db = fpdb_db.fpdb_db()
|
# db = fpdb_db.fpdb_db()
|
||||||
|
@ -305,4 +321,3 @@ if __name__== "__main__":
|
||||||
gtk.main()
|
gtk.main()
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ class GuiBulkImport():
|
||||||
def dopulse(self):
|
def dopulse(self):
|
||||||
self.progressbar.pulse()
|
self.progressbar.pulse()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def load_clicked(self, widget, data=None):
|
def load_clicked(self, widget, data=None):
|
||||||
stored = None
|
stored = None
|
||||||
dups = None
|
dups = None
|
||||||
|
@ -53,14 +53,14 @@ class GuiBulkImport():
|
||||||
# Does the lock acquisition need to be more sophisticated for multiple dirs?
|
# Does the lock acquisition need to be more sophisticated for multiple dirs?
|
||||||
# (see comment above about what to do if pipe already open)
|
# (see comment above about what to do if pipe already open)
|
||||||
if self.settings['global_lock'].acquire(False): # returns false immediately if lock not acquired
|
if self.settings['global_lock'].acquire(False): # returns false immediately if lock not acquired
|
||||||
try:
|
#try:
|
||||||
print "\nGlobal lock taken ..."
|
print "\nGlobal lock taken ..."
|
||||||
self.progressbar.set_text("Importing...")
|
self.progressbar.set_text("Importing...")
|
||||||
self.progressbar.pulse()
|
self.progressbar.pulse()
|
||||||
while gtk.events_pending(): # see http://faq.pygtk.org/index.py?req=index for more hints (3.7)
|
while gtk.events_pending(): # see http://faq.pygtk.org/index.py?req=index for more hints (3.7)
|
||||||
gtk.main_iteration(False)
|
gtk.main_iteration(False)
|
||||||
self.timer = gobject.timeout_add(100, self.dopulse)
|
self.timer = gobject.timeout_add(100, self.dopulse)
|
||||||
|
|
||||||
# get the dir to import from the chooser
|
# get the dir to import from the chooser
|
||||||
selected = self.chooser.get_filenames()
|
selected = self.chooser.get_filenames()
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ class GuiBulkImport():
|
||||||
else:
|
else:
|
||||||
self.importer.setDropHudCache("auto")
|
self.importer.setDropHudCache("auto")
|
||||||
sitename = self.cbfilter.get_model()[self.cbfilter.get_active()][0]
|
sitename = self.cbfilter.get_model()[self.cbfilter.get_active()][0]
|
||||||
|
|
||||||
for selection in selected:
|
for selection in selected:
|
||||||
self.importer.addBulkImportImportFileOrDir(selection, site = sitename)
|
self.importer.addBulkImportImportFileOrDir(selection, site = sitename)
|
||||||
self.importer.setCallHud(False)
|
self.importer.setCallHud(False)
|
||||||
|
@ -99,7 +99,7 @@ class GuiBulkImport():
|
||||||
# raise Exceptions.FpdbError
|
# raise Exceptions.FpdbError
|
||||||
# finally:
|
# finally:
|
||||||
gobject.source_remove(self.timer)
|
gobject.source_remove(self.timer)
|
||||||
|
|
||||||
ttime = time() - starttime
|
ttime = time() - starttime
|
||||||
if ttime == 0:
|
if ttime == 0:
|
||||||
ttime = 1
|
ttime = 1
|
||||||
|
@ -116,10 +116,11 @@ class GuiBulkImport():
|
||||||
|
|
||||||
self.progressbar.set_text("Import Complete")
|
self.progressbar.set_text("Import Complete")
|
||||||
self.progressbar.set_fraction(0)
|
self.progressbar.set_fraction(0)
|
||||||
except:
|
#except:
|
||||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
#err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||||
print "*** BulkImport Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
#print "*** BulkImport Error: "+err[2]+"("+str(err[1])+"): "+str(sys.exc_info()[1])
|
||||||
self.settings['global_lock'].release()
|
#self.settings['global_lock'].release()
|
||||||
|
self.settings['global_lock'].release()
|
||||||
else:
|
else:
|
||||||
print "bulk-import aborted - global lock not available"
|
print "bulk-import aborted - global lock not available"
|
||||||
|
|
||||||
|
@ -323,9 +324,9 @@ def main(argv=None):
|
||||||
help="If this option is passed it quits when it encounters any error")
|
help="If this option is passed it quits when it encounters any error")
|
||||||
parser.add_option("-m", "--minPrint", "--status", dest="minPrint", default="0", type="int",
|
parser.add_option("-m", "--minPrint", "--status", dest="minPrint", default="0", type="int",
|
||||||
help="How often to print a one-line status report (0 (default) means never)")
|
help="How often to print a one-line status report (0 (default) means never)")
|
||||||
parser.add_option("-u", "--usage", action="store_true", dest="usage", default=False,
|
parser.add_option("-u", "--usage", action="store_true", dest="usage", default=False,
|
||||||
help="Print some useful one liners")
|
help="Print some useful one liners")
|
||||||
(options, sys.argv) = parser.parse_args(args = argv)
|
(options, argv) = parser.parse_args(args = argv)
|
||||||
|
|
||||||
if options.usage == True:
|
if options.usage == True:
|
||||||
#Print usage examples and exit
|
#Print usage examples and exit
|
||||||
|
@ -338,7 +339,7 @@ def main(argv=None):
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
config = Configuration.Config()
|
config = Configuration.Config()
|
||||||
|
|
||||||
settings = {}
|
settings = {}
|
||||||
settings['minPrint'] = options.minPrint
|
settings['minPrint'] = options.minPrint
|
||||||
if os.name == 'nt': settings['os'] = 'windows'
|
if os.name == 'nt': settings['os'] = 'windows'
|
||||||
|
@ -361,7 +362,7 @@ def main(argv=None):
|
||||||
gtk.main()
|
gtk.main()
|
||||||
else:
|
else:
|
||||||
#Do something useful
|
#Do something useful
|
||||||
importer = fpdb_import.Importer(False,settings, config)
|
importer = fpdb_import.Importer(False,settings, config)
|
||||||
# importer.setDropIndexes("auto")
|
# importer.setDropIndexes("auto")
|
||||||
importer.setDropIndexes("don't drop")
|
importer.setDropIndexes("don't drop")
|
||||||
importer.setFailOnError(options.failOnError)
|
importer.setFailOnError(options.failOnError)
|
||||||
|
@ -376,4 +377,3 @@ def main(argv=None):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
|
||||||
|
|
|
@ -152,14 +152,17 @@ class GuiGraphViewer (threading.Thread):
|
||||||
if not sitenos:
|
if not sitenos:
|
||||||
#Should probably pop up here.
|
#Should probably pop up here.
|
||||||
print "No sites selected - defaulting to PokerStars"
|
print "No sites selected - defaulting to PokerStars"
|
||||||
|
self.db.rollback()
|
||||||
return
|
return
|
||||||
|
|
||||||
if not playerids:
|
if not playerids:
|
||||||
print "No player ids found"
|
print "No player ids found"
|
||||||
|
self.db.rollback()
|
||||||
return
|
return
|
||||||
|
|
||||||
if not limits:
|
if not limits:
|
||||||
print "No limits found"
|
print "No limits found"
|
||||||
|
self.db.rollback()
|
||||||
return
|
return
|
||||||
|
|
||||||
#Set graph properties
|
#Set graph properties
|
||||||
|
@ -216,6 +219,7 @@ class GuiGraphViewer (threading.Thread):
|
||||||
#nametest = nametest.replace("L", "")
|
#nametest = nametest.replace("L", "")
|
||||||
|
|
||||||
lims = [int(x) for x in limits if x.isdigit()]
|
lims = [int(x) for x in limits if x.isdigit()]
|
||||||
|
potlims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'pl']
|
||||||
nolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'nl']
|
nolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'nl']
|
||||||
limittest = "and ( (gt.limitType = 'fl' and gt.bigBlind in "
|
limittest = "and ( (gt.limitType = 'fl' and gt.bigBlind in "
|
||||||
# and ( (limit and bb in()) or (nolimit and bb in ()) )
|
# and ( (limit and bb in()) or (nolimit and bb in ()) )
|
||||||
|
@ -226,6 +230,14 @@ class GuiGraphViewer (threading.Thread):
|
||||||
limittest = limittest + blindtest + ' ) '
|
limittest = limittest + blindtest + ' ) '
|
||||||
else:
|
else:
|
||||||
limittest = limittest + '(-1) ) '
|
limittest = limittest + '(-1) ) '
|
||||||
|
limittest = limittest + " or (gt.limitType = 'pl' and gt.bigBlind in "
|
||||||
|
if potlims:
|
||||||
|
blindtest = str(tuple(potlims))
|
||||||
|
blindtest = blindtest.replace("L", "")
|
||||||
|
blindtest = blindtest.replace(",)",")")
|
||||||
|
limittest = limittest + blindtest + ' ) '
|
||||||
|
else:
|
||||||
|
limittest = limittest + '(-1) ) '
|
||||||
limittest = limittest + " or (gt.limitType = 'nl' and gt.bigBlind in "
|
limittest = limittest + " or (gt.limitType = 'nl' and gt.bigBlind in "
|
||||||
if nolims:
|
if nolims:
|
||||||
blindtest = str(tuple(nolims))
|
blindtest = str(tuple(nolims))
|
||||||
|
@ -234,6 +246,7 @@ class GuiGraphViewer (threading.Thread):
|
||||||
limittest = limittest + blindtest + ' ) )'
|
limittest = limittest + blindtest + ' ) )'
|
||||||
else:
|
else:
|
||||||
limittest = limittest + '(-1) ) )'
|
limittest = limittest + '(-1) ) )'
|
||||||
|
|
||||||
if type == 'ring':
|
if type == 'ring':
|
||||||
limittest = limittest + " and gt.type = 'ring' "
|
limittest = limittest + " and gt.type = 'ring' "
|
||||||
elif type == 'tour':
|
elif type == 'tour':
|
||||||
|
|
|
@ -480,6 +480,7 @@ class GuiPlayerStats (threading.Thread):
|
||||||
query = query.replace('<orderbyseats>', '')
|
query = query.replace('<orderbyseats>', '')
|
||||||
|
|
||||||
lims = [int(x) for x in limits if x.isdigit()]
|
lims = [int(x) for x in limits if x.isdigit()]
|
||||||
|
potlims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'pl']
|
||||||
nolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'nl']
|
nolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'nl']
|
||||||
bbtest = "and ( (gt.limitType = 'fl' and gt.bigBlind in "
|
bbtest = "and ( (gt.limitType = 'fl' and gt.bigBlind in "
|
||||||
# and ( (limit and bb in()) or (nolimit and bb in ()) )
|
# and ( (limit and bb in()) or (nolimit and bb in ()) )
|
||||||
|
@ -490,6 +491,14 @@ class GuiPlayerStats (threading.Thread):
|
||||||
bbtest = bbtest + blindtest + ' ) '
|
bbtest = bbtest + blindtest + ' ) '
|
||||||
else:
|
else:
|
||||||
bbtest = bbtest + '(-1) ) '
|
bbtest = bbtest + '(-1) ) '
|
||||||
|
bbtest = bbtest + " or (gt.limitType = 'pl' and gt.bigBlind in "
|
||||||
|
if potlims:
|
||||||
|
blindtest = str(tuple(potlims))
|
||||||
|
blindtest = blindtest.replace("L", "")
|
||||||
|
blindtest = blindtest.replace(",)",")")
|
||||||
|
bbtest = bbtest + blindtest + ' ) '
|
||||||
|
else:
|
||||||
|
bbtest = bbtest + '(-1) ) '
|
||||||
bbtest = bbtest + " or (gt.limitType = 'nl' and gt.bigBlind in "
|
bbtest = bbtest + " or (gt.limitType = 'nl' and gt.bigBlind in "
|
||||||
if nolims:
|
if nolims:
|
||||||
blindtest = str(tuple(nolims))
|
blindtest = str(tuple(nolims))
|
||||||
|
@ -544,7 +553,7 @@ class GuiPlayerStats (threading.Thread):
|
||||||
# set flag in self.columns to show posn column
|
# set flag in self.columns to show posn column
|
||||||
[x for x in self.columns if x[0] == 'plposition'][0][1] = True
|
[x for x in self.columns if x[0] == 'plposition'][0][1] = True
|
||||||
else:
|
else:
|
||||||
query = query.replace("<position>", "'1'")
|
query = query.replace("<position>", "gt.base")
|
||||||
# unset flag in self.columns to hide posn column
|
# unset flag in self.columns to hide posn column
|
||||||
[x for x in self.columns if x[0] == 'plposition'][0][1] = False
|
[x for x in self.columns if x[0] == 'plposition'][0][1] = False
|
||||||
|
|
||||||
|
|
169
pyfpdb/GuiPrefs.py
Executable file
169
pyfpdb/GuiPrefs.py
Executable file
|
@ -0,0 +1,169 @@
|
||||||
|
#!/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 xml.dom.minidom
|
||||||
|
from xml.dom.minidom import Node
|
||||||
|
|
||||||
|
import pygtk
|
||||||
|
pygtk.require('2.0')
|
||||||
|
import gtk
|
||||||
|
import gobject
|
||||||
|
|
||||||
|
import Configuration
|
||||||
|
|
||||||
|
|
||||||
|
class GuiPrefs:
|
||||||
|
|
||||||
|
def __init__(self, config, mainwin, dia):
|
||||||
|
self.config = config
|
||||||
|
self.main_window = mainwin
|
||||||
|
self.dialog = dia
|
||||||
|
|
||||||
|
self.tree_box = gtk.ScrolledWindow()
|
||||||
|
self.tree_box.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||||
|
|
||||||
|
self.dialog.add(self.tree_box)
|
||||||
|
self.dialog.show()
|
||||||
|
|
||||||
|
self.doc = None
|
||||||
|
self.configStore = None
|
||||||
|
self.configView = None
|
||||||
|
|
||||||
|
self.fillFrames()
|
||||||
|
|
||||||
|
def fillFrames(self):
|
||||||
|
self.doc = self.config.get_doc()
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
configColumn = gtk.TreeViewColumn("Setting")
|
||||||
|
self.configView.append_column(configColumn)
|
||||||
|
cRender = gtk.CellRendererText()
|
||||||
|
configColumn.pack_start(cRender, True)
|
||||||
|
configColumn.add_attribute(cRender, 'text', 1)
|
||||||
|
|
||||||
|
configColumn = gtk.TreeViewColumn("Value")
|
||||||
|
self.configView.append_column(configColumn)
|
||||||
|
cRender = gtk.CellRendererText()
|
||||||
|
configColumn.pack_start(cRender, True)
|
||||||
|
configColumn.add_attribute(cRender, 'text', 2)
|
||||||
|
|
||||||
|
if self.doc.documentElement.tagName == 'FreePokerToolsConfig':
|
||||||
|
self.configStore.clear()
|
||||||
|
self.root = self.configStore.append( None, [self.doc.documentElement, "fpdb", None] )
|
||||||
|
for elem in self.doc.documentElement.childNodes:
|
||||||
|
iter = self.addTreeRows(self.root, elem)
|
||||||
|
if self.root != None:
|
||||||
|
self.configView.expand_row(self.configStore.get_path(self.root), False)
|
||||||
|
self.configView.connect("row-activated", self.rowChosen)
|
||||||
|
self.configView.show()
|
||||||
|
self.tree_box.add(self.configView)
|
||||||
|
self.tree_box.show()
|
||||||
|
self.dialog.show()
|
||||||
|
|
||||||
|
def addTreeRows(self, parent, node):
|
||||||
|
if (node.nodeType == node.ELEMENT_NODE):
|
||||||
|
(setting, value) = (node.nodeName, None)
|
||||||
|
elif (node.nodeType == node.TEXT_NODE):
|
||||||
|
# text nodes hold the whitespace (or whatever) between the xml elements, not used here
|
||||||
|
(setting, value) = ("TEXT: ["+node.nodeValue+"|"+node.nodeValue+"]", node.data)
|
||||||
|
else:
|
||||||
|
(setting, value) = ("?? "+node.nodeValue, "type="+str(node.nodeType))
|
||||||
|
|
||||||
|
#iter = self.configStore.append( parent, [node.nodeValue, None] )
|
||||||
|
iter = None
|
||||||
|
if node.nodeType != node.TEXT_NODE and node.nodeType != node.COMMENT_NODE:
|
||||||
|
iter = self.configStore.append( parent, [node, setting, value] )
|
||||||
|
if node.hasAttributes():
|
||||||
|
for i in xrange(node.attributes.length):
|
||||||
|
self.configStore.append( iter, [node, node.attributes.item(i).localName, node.attributes.item(i).value] )
|
||||||
|
if node.hasChildNodes():
|
||||||
|
for elem in node.childNodes:
|
||||||
|
self.addTreeRows(iter, elem)
|
||||||
|
return iter
|
||||||
|
|
||||||
|
def rowChosen(self, tview, path, something2, data=None):
|
||||||
|
# tview should= self.configStore
|
||||||
|
tmodel = tview.get_model()
|
||||||
|
iter = tmodel.get_iter(path)
|
||||||
|
if tmodel.iter_has_child(iter):
|
||||||
|
# toggle children display
|
||||||
|
if tview.row_expanded(path):
|
||||||
|
tview.collapse_row(tmodel.get_path(iter))
|
||||||
|
else:
|
||||||
|
tview.expand_row(tmodel.get_path(iter), False)
|
||||||
|
else:
|
||||||
|
# display value and allow edit
|
||||||
|
name = tmodel.get_value( iter, 1 )
|
||||||
|
val = tmodel.get_value( iter, 2 )
|
||||||
|
dia_edit = gtk.Dialog(name,
|
||||||
|
self.main_window,
|
||||||
|
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
|
||||||
|
gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
|
||||||
|
#dia_edit.set_default_size(350, 100)
|
||||||
|
entry = gtk.Entry()
|
||||||
|
if val:
|
||||||
|
entry.set_text(val)
|
||||||
|
entry.set_width_chars(40)
|
||||||
|
dia_edit.vbox.pack_start(entry, False, False, 0)
|
||||||
|
entry.show()
|
||||||
|
entry.connect("activate", self.__set_entry, dia_edit)
|
||||||
|
response = dia_edit.run()
|
||||||
|
if response == gtk.RESPONSE_ACCEPT:
|
||||||
|
# update configStore
|
||||||
|
new_val = entry.get_text()
|
||||||
|
tmodel.set_value(iter, 2, new_val)
|
||||||
|
tmodel.get_value(iter, 0).setAttribute(name, new_val)
|
||||||
|
dia_edit.destroy()
|
||||||
|
|
||||||
|
def __set_entry(self, w, dia=None):
|
||||||
|
if dia is not None:
|
||||||
|
dia.response(gtk.RESPONSE_ACCEPT)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__=="__main__":
|
||||||
|
|
||||||
|
config = Configuration.Config()
|
||||||
|
|
||||||
|
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
|
||||||
|
win.set_title("Test Preferences Dialog")
|
||||||
|
win.set_border_width(1)
|
||||||
|
win.set_default_size(600, 500)
|
||||||
|
win.set_resizable(True)
|
||||||
|
|
||||||
|
dia = gtk.Dialog("Preferences",
|
||||||
|
win,
|
||||||
|
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
|
||||||
|
gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT))
|
||||||
|
dia.set_default_size(500, 500)
|
||||||
|
prefs = GuiPrefs(config, win, dia.vbox)
|
||||||
|
response = dia.run()
|
||||||
|
if response == gtk.RESPONSE_ACCEPT:
|
||||||
|
# save updated config
|
||||||
|
config.save()
|
||||||
|
dia.destroy()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
581
pyfpdb/HUD_config.test.xml
Normal file
581
pyfpdb/HUD_config.test.xml
Normal file
|
@ -0,0 +1,581 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
|
||||||
|
<FreePokerToolsConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FreePokerToolsConfig.xsd">
|
||||||
|
|
||||||
|
<import callFpdbHud = "True" interval = "10" fastStoreHudCache="False" hhArchiveBase="~/.fpdb/HandHistories/" saveActions="True"></import>
|
||||||
|
|
||||||
|
<!-- These values determine what stats are displayed in the HUD
|
||||||
|
|
||||||
|
The following values define how opponents' stats are done, the first 2 determine
|
||||||
|
the time period stats are displayed for, the next 3 determine what blind levels
|
||||||
|
are included (i.e. aggregated):
|
||||||
|
|
||||||
|
stat_range :
|
||||||
|
- A/S/T
|
||||||
|
- if set to A, includes stats from all time
|
||||||
|
- if set to S, includes stats from current session
|
||||||
|
- if set to T, includes stats from last N days; set value in stat_days
|
||||||
|
- defaults to A
|
||||||
|
|
||||||
|
stat_days :
|
||||||
|
- a numeric value
|
||||||
|
- only used if stat_range is set to 'T', this value tells how many days are
|
||||||
|
included in the stat calculation
|
||||||
|
- defaults to 90
|
||||||
|
- value not used by default as it depends on stat_range setting
|
||||||
|
|
||||||
|
aggregate_ring_game_stats :
|
||||||
|
- True/False
|
||||||
|
- if set to True, opponents stats include other blind levels during ring games
|
||||||
|
- defaults to False
|
||||||
|
|
||||||
|
aggregate_tourney_stats :
|
||||||
|
- True/False
|
||||||
|
- if set to True, opponents stats include other blind levels during tourneys
|
||||||
|
- defaults to True
|
||||||
|
|
||||||
|
aggregation_level_multiplier :
|
||||||
|
- float value
|
||||||
|
- defines how many blind levels are included in stats displayed in HUD
|
||||||
|
- if value is M, stats for blind levels are combined if the higher level
|
||||||
|
is less than or equal to M times the lower blind level
|
||||||
|
- defaults to 3, meaning blind levels from 1/3 of the current level to 3
|
||||||
|
times the current level are included in the stats displayed in the HUD
|
||||||
|
- e.g. if current big blind is 50, stats for blind levels from big blind
|
||||||
|
of 16.7 (50 divided by 3) to big blind of 150 (50 times 3) are included
|
||||||
|
|
||||||
|
|
||||||
|
The following values define how hero's stats are done, the first 2 determine
|
||||||
|
the time period stats are displayed for, the next 3 determine what blind levels
|
||||||
|
are included (i.e. aggregated):
|
||||||
|
|
||||||
|
hero_stat_range :
|
||||||
|
- A/S/T
|
||||||
|
- if set to A, includes stats from all time
|
||||||
|
- if set to S, includes stats from current session
|
||||||
|
- if set to T, includes stats from last N days; set value in hero_stat_days
|
||||||
|
- defaults to S
|
||||||
|
|
||||||
|
hero_stat_days :
|
||||||
|
- a numeric value
|
||||||
|
- if hero_stat_range is set to 'T', this value tells how many days are
|
||||||
|
included in the stat calculation
|
||||||
|
- defaults to 30
|
||||||
|
- value not used by default as it depends on hero_stat_range setting
|
||||||
|
|
||||||
|
aggregate_hero_ring_game_stats :
|
||||||
|
- True/False
|
||||||
|
- if set to True, hero's stats are calculated over multiple blind levels
|
||||||
|
- defaults to False
|
||||||
|
|
||||||
|
aggregate_hero_tourney_stats :
|
||||||
|
- True/False
|
||||||
|
- if set to True, hero's stats are calculated over multiple blind levels
|
||||||
|
- defaults to False
|
||||||
|
|
||||||
|
hero_aggregation_level_multiplier :
|
||||||
|
- float value
|
||||||
|
- defines how many blind levels are included in stats displayed in HUD
|
||||||
|
- if value is M, stats for blind levels are combined if the higher level
|
||||||
|
is less than or equal to M times the lower blind level
|
||||||
|
- defaults to 1, meaning only stats from current blind level are included
|
||||||
|
- e.g. if set to 3 and current big blind is 50, stats for blind levels from
|
||||||
|
16.7 (50 divided by 3) to big blind of 150 (50 times 3) are included
|
||||||
|
-->
|
||||||
|
<hud_ui
|
||||||
|
stat_range="A"
|
||||||
|
stat_days="90"
|
||||||
|
aggregate_ring_game_stats="False"
|
||||||
|
aggregate_tourney_stats="True"
|
||||||
|
aggregation_level_multiplier="3"
|
||||||
|
|
||||||
|
hero_stat_range="S"
|
||||||
|
hero_stat_days="30"
|
||||||
|
aggregate_hero_ring_game_stats="False"
|
||||||
|
aggregate_hero_tourney_stats="False"
|
||||||
|
hero_aggregation_level_multiplier="1"
|
||||||
|
|
||||||
|
label="FPDB Menu - Right-click
|
||||||
|
Left-Drag to Move"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<supported_sites>
|
||||||
|
|
||||||
|
<site enabled="True"
|
||||||
|
site_name="PokerStars"
|
||||||
|
table_finder="PokerStars.exe"
|
||||||
|
screen_name="YOUR SCREEN NAME HERE"
|
||||||
|
site_path="C:/Program Files/PokerStars/"
|
||||||
|
HH_path="C:/Program Files/PokerStars/HandHistory/YOUR SCREEN NAME HERE/"
|
||||||
|
decoder="pokerstars_decode_table"
|
||||||
|
converter="PokerStarsToFpdb"
|
||||||
|
bgcolor="#000000"
|
||||||
|
fgcolor="#FFFFFF"
|
||||||
|
hudopacity="1.0"
|
||||||
|
font="Sans"
|
||||||
|
font_size="8"
|
||||||
|
supported_games="holdem,razz,omahahi,omahahilo,studhi,studhilo">
|
||||||
|
<layout max="8" width="792" height="546" fav_seat="0">
|
||||||
|
<location seat="1" x="684" y="61"> </location>
|
||||||
|
<location seat="2" x="689" y="239"> </location>
|
||||||
|
<location seat="3" x="692" y="346"> </location>
|
||||||
|
<location seat="4" x="525" y="402"> </location>
|
||||||
|
<location seat="5" x="259" y="402"> </location>
|
||||||
|
<location seat="6" x="0" y="348"> </location>
|
||||||
|
<location seat="7" x="0" y="240"> </location>
|
||||||
|
<location seat="8" x="0" y="35"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout max="6" width="792" height="546" fav_seat="0">
|
||||||
|
<location seat="1" x="681" y="119"> </location>
|
||||||
|
<location seat="2" x="681" y="301"> </location>
|
||||||
|
<location seat="3" x="487" y="369"> </location>
|
||||||
|
<location seat="4" x="226" y="369"> </location>
|
||||||
|
<location seat="5" x="0" y="301"> </location>
|
||||||
|
<location seat="6" x="0" y="119"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout max="10" width="792" height="546" fav_seat="0">
|
||||||
|
<location seat="1" x="684" y="61"> </location>
|
||||||
|
<location seat="2" x="689" y="239"> </location>
|
||||||
|
<location seat="3" x="692" y="346"> </location>
|
||||||
|
<location seat="4" x="586" y="393"> </location>
|
||||||
|
<location seat="5" x="421" y="440"> </location>
|
||||||
|
<location seat="6" x="267" y="440"> </location>
|
||||||
|
<location seat="7" x="0" y="361"> </location>
|
||||||
|
<location seat="8" x="0" y="280"> </location>
|
||||||
|
<location seat="9" x="121" y="280"> </location>
|
||||||
|
<location seat="10" x="46" y="30"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout max="9" width="792" height="546" fav_seat="0">
|
||||||
|
<location seat="1" x="560" y="0"> </location>
|
||||||
|
<location seat="2" x="679" y="123"> </location>
|
||||||
|
<location seat="3" x="688" y="309"> </location>
|
||||||
|
<location seat="4" x="483" y="370"> </location>
|
||||||
|
<location seat="5" x="444" y="413"> </location>
|
||||||
|
<location seat="6" x="224" y="372"> </location>
|
||||||
|
<location seat="7" x="0" y="307"> </location>
|
||||||
|
<location seat="8" x="0" y="121"> </location>
|
||||||
|
<location seat="9" x="140" y="0"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="546" max="2" width="792">
|
||||||
|
<location seat="1" x="651" y="288"> </location>
|
||||||
|
<location seat="2" x="10" y="288"> </location>
|
||||||
|
</layout>
|
||||||
|
</site>
|
||||||
|
|
||||||
|
<site enabled="True"
|
||||||
|
site_name="Full Tilt Poker"
|
||||||
|
table_finder="FullTiltPoker"
|
||||||
|
screen_name="YOUR SCREEN NAME HERE"
|
||||||
|
site_path="C:/Program Files/Full Tilt Poker/"
|
||||||
|
HH_path="C:/Program Files/Full Tilt Poker/HandHistory/YOUR SCREEN NAME HERE/"
|
||||||
|
decoder="fulltilt_decode_table"
|
||||||
|
converter="FulltiltToFpdb"
|
||||||
|
bgcolor="#000000"
|
||||||
|
fgcolor="#FFFFFF"
|
||||||
|
hudopacity="1.0"
|
||||||
|
font="Sans"
|
||||||
|
font_size="8"
|
||||||
|
supported_games="holdem,razz,omahahi,omahahilo,studhi,studhilo">
|
||||||
|
<layout fav_seat="0" height="547" max="8" width="794">
|
||||||
|
<location seat="1" x="640" y="64"> </location>
|
||||||
|
<location seat="2" x="650" y="230"> </location>
|
||||||
|
<location seat="3" x="650" y="385"> </location>
|
||||||
|
<location seat="4" x="588" y="425"> </location>
|
||||||
|
<location seat="5" x="92" y="425"> </location>
|
||||||
|
<location seat="6" x="0" y="373"> </location>
|
||||||
|
<location seat="7" x="0" y="223"> </location>
|
||||||
|
<location seat="8" x="25" y="50"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="6" width="794">
|
||||||
|
<location seat="1" x="640" y="58"> </location>
|
||||||
|
<location seat="2" x="654" y="288"> </location>
|
||||||
|
<location seat="3" x="615" y="424"> </location>
|
||||||
|
<location seat="4" x="70" y="421"> </location>
|
||||||
|
<location seat="5" x="0" y="280"> </location>
|
||||||
|
<location seat="6" x="70" y="58"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="2" width="794">
|
||||||
|
<location seat="1" x="651" y="288"> </location>
|
||||||
|
<location seat="2" x="10" y="288"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="9" width="794">
|
||||||
|
<location seat="1" x="634" y="38"> </location>
|
||||||
|
<location seat="2" x="667" y="184"> </location>
|
||||||
|
<location seat="3" x="667" y="321"> </location>
|
||||||
|
<location seat="4" x="667" y="445"> </location>
|
||||||
|
<location seat="5" x="337" y="459"> </location>
|
||||||
|
<location seat="6" x="0" y="400"> </location>
|
||||||
|
<location seat="7" x="0" y="322"> </location>
|
||||||
|
<location seat="8" x="0" y="181"> </location>
|
||||||
|
<location seat="9" x="70" y="53"> </location>
|
||||||
|
</layout>
|
||||||
|
</site>
|
||||||
|
|
||||||
|
<site enabled="False"
|
||||||
|
site_name="Everleaf"
|
||||||
|
table_finder="Everleaf.exe"
|
||||||
|
screen_name="YOUR SCREEN NAME HERE"
|
||||||
|
site_path=""
|
||||||
|
HH_path=""
|
||||||
|
decoder="everleaf_decode_table"
|
||||||
|
converter="EverleafToFpdb"
|
||||||
|
supported_games="holdem">
|
||||||
|
<layout fav_seat="0" height="547" max="8" width="794">
|
||||||
|
<location seat="1" x="640" y="64"> </location>
|
||||||
|
<location seat="2" x="650" y="230"> </location>
|
||||||
|
<location seat="3" x="650" y="385"> </location>
|
||||||
|
<location seat="4" x="588" y="425"> </location>
|
||||||
|
<location seat="5" x="92" y="425"> </location>
|
||||||
|
<location seat="6" x="0" y="373"> </location>
|
||||||
|
<location seat="7" x="0" y="223"> </location>
|
||||||
|
<location seat="8" x="25" y="50"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="6" width="794">
|
||||||
|
<location seat="1" x="640" y="58"> </location>
|
||||||
|
<location seat="2" x="654" y="288"> </location>
|
||||||
|
<location seat="3" x="615" y="424"> </location>
|
||||||
|
<location seat="4" x="70" y="421"> </location>
|
||||||
|
<location seat="5" x="0" y="280"> </location>
|
||||||
|
<location seat="6" x="70" y="58"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="2" width="794">
|
||||||
|
<location seat="1" x="651" y="288"> </location>
|
||||||
|
<location seat="2" x="10" y="288"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="9" width="794">
|
||||||
|
<location seat="1" x="634" y="38"> </location>
|
||||||
|
<location seat="2" x="667" y="184"> </location>
|
||||||
|
<location seat="3" x="667" y="321"> </location>
|
||||||
|
<location seat="4" x="667" y="445"> </location>
|
||||||
|
<location seat="5" x="337" y="459"> </location>
|
||||||
|
<location seat="6" x="0" y="400"> </location>
|
||||||
|
<location seat="7" x="0" y="322"> </location>
|
||||||
|
<location seat="8" x="0" y="181"> </location>
|
||||||
|
<location seat="9" x="70" y="53"> </location>
|
||||||
|
</layout>
|
||||||
|
</site>
|
||||||
|
|
||||||
|
<site enabled="False"
|
||||||
|
site_name="Win2day"
|
||||||
|
table_finder="Win2day.exe"
|
||||||
|
screen_name="YOUR SCREEN NAME HERE"
|
||||||
|
site_path=""
|
||||||
|
HH_path=""
|
||||||
|
decoder="everleaf_decode_table"
|
||||||
|
converter="Win2dayToFpdb"
|
||||||
|
supported_games="holdem">
|
||||||
|
<layout fav_seat="0" height="547" max="8" width="794">
|
||||||
|
<location seat="1" x="640" y="64"> </location>
|
||||||
|
<location seat="2" x="650" y="230"> </location>
|
||||||
|
<location seat="3" x="650" y="385"> </location>
|
||||||
|
<location seat="4" x="588" y="425"> </location>
|
||||||
|
<location seat="5" x="92" y="425"> </location>
|
||||||
|
<location seat="6" x="0" y="373"> </location>
|
||||||
|
<location seat="7" x="0" y="223"> </location>
|
||||||
|
<location seat="8" x="25" y="50"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="6" width="794">
|
||||||
|
<location seat="1" x="640" y="58"> </location>
|
||||||
|
<location seat="2" x="654" y="288"> </location>
|
||||||
|
<location seat="3" x="615" y="424"> </location>
|
||||||
|
<location seat="4" x="70" y="421"> </location>
|
||||||
|
<location seat="5" x="0" y="280"> </location>
|
||||||
|
<location seat="6" x="70" y="58"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="2" width="794">
|
||||||
|
<location seat="1" x="651" y="288"> </location>
|
||||||
|
<location seat="2" x="10" y="288"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="9" width="794">
|
||||||
|
<location seat="1" x="634" y="38"> </location>
|
||||||
|
<location seat="2" x="667" y="184"> </location>
|
||||||
|
<location seat="3" x="667" y="321"> </location>
|
||||||
|
<location seat="4" x="667" y="445"> </location>
|
||||||
|
<location seat="5" x="337" y="459"> </location>
|
||||||
|
<location seat="6" x="0" y="400"> </location>
|
||||||
|
<location seat="7" x="0" y="322"> </location>
|
||||||
|
<location seat="8" x="0" y="181"> </location>
|
||||||
|
<location seat="9" x="70" y="53"> </location>
|
||||||
|
</layout>
|
||||||
|
</site>
|
||||||
|
|
||||||
|
|
||||||
|
<site enabled="False"
|
||||||
|
site_name="Absolute"
|
||||||
|
table_finder="AbsolutePoker.exe"
|
||||||
|
screen_name="YOUR SCREEN NAME HERE"
|
||||||
|
site_path=""
|
||||||
|
HH_path=""
|
||||||
|
decoder="everleaf_decode_table"
|
||||||
|
converter="AbsoluteToFpdb"
|
||||||
|
supported_games="holdem">
|
||||||
|
<layout fav_seat="0" height="547" max="8" width="794">
|
||||||
|
<location seat="1" x="640" y="64"> </location>
|
||||||
|
<location seat="2" x="650" y="230"> </location>
|
||||||
|
<location seat="3" x="650" y="385"> </location>
|
||||||
|
<location seat="4" x="588" y="425"> </location>
|
||||||
|
<location seat="5" x="92" y="425"> </location>
|
||||||
|
<location seat="6" x="0" y="373"> </location>
|
||||||
|
<location seat="7" x="0" y="223"> </location>
|
||||||
|
<location seat="8" x="25" y="50"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="6" width="794">
|
||||||
|
<location seat="1" x="640" y="58"> </location>
|
||||||
|
<location seat="2" x="654" y="288"> </location>
|
||||||
|
<location seat="3" x="615" y="424"> </location>
|
||||||
|
<location seat="4" x="70" y="421"> </location>
|
||||||
|
<location seat="5" x="0" y="280"> </location>
|
||||||
|
<location seat="6" x="70" y="58"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="2" width="794">
|
||||||
|
<location seat="1" x="651" y="288"> </location>
|
||||||
|
<location seat="2" x="10" y="288"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="9" width="794">
|
||||||
|
<location seat="1" x="634" y="38"> </location>
|
||||||
|
<location seat="2" x="667" y="184"> </location>
|
||||||
|
<location seat="3" x="667" y="321"> </location>
|
||||||
|
<location seat="4" x="667" y="445"> </location>
|
||||||
|
<location seat="5" x="337" y="459"> </location>
|
||||||
|
<location seat="6" x="0" y="400"> </location>
|
||||||
|
<location seat="7" x="0" y="322"> </location>
|
||||||
|
<location seat="8" x="0" y="181"> </location>
|
||||||
|
<location seat="9" x="70" y="53"> </location>
|
||||||
|
</layout>
|
||||||
|
</site>
|
||||||
|
|
||||||
|
|
||||||
|
<site enabled="False"
|
||||||
|
site_name="PartyPoker"
|
||||||
|
table_finder="PartyGaming.exe"
|
||||||
|
screen_name="YOUR SCREEN NAME HERE"
|
||||||
|
site_path="C:/Program Files/PartyGaming/PartyPoker"
|
||||||
|
HH_path="C:/Program Files/PartyGaming/PartyPoker/HandHistory/YOUR SCREEN NAME HERE/"
|
||||||
|
decoder="everleaf_decode_table"
|
||||||
|
converter="PartyPokerToFpdb"
|
||||||
|
supported_games="holdem">
|
||||||
|
<layout fav_seat="0" height="547" max="8" width="794">
|
||||||
|
<location seat="1" x="640" y="64"> </location>
|
||||||
|
<location seat="2" x="650" y="230"> </location>
|
||||||
|
<location seat="3" x="650" y="385"> </location>
|
||||||
|
<location seat="4" x="588" y="425"> </location>
|
||||||
|
<location seat="5" x="92" y="425"> </location>
|
||||||
|
<location seat="6" x="0" y="373"> </location>
|
||||||
|
<location seat="7" x="0" y="223"> </location>
|
||||||
|
<location seat="8" x="25" y="50"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="6" width="794">
|
||||||
|
<location seat="1" x="640" y="58"> </location>
|
||||||
|
<location seat="2" x="654" y="288"> </location>
|
||||||
|
<location seat="3" x="615" y="424"> </location>
|
||||||
|
<location seat="4" x="70" y="421"> </location>
|
||||||
|
<location seat="5" x="0" y="280"> </location>
|
||||||
|
<location seat="6" x="70" y="58"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="2" width="794">
|
||||||
|
<location seat="1" x="651" y="288"> </location>
|
||||||
|
<location seat="2" x="10" y="288"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="9" width="794">
|
||||||
|
<location seat="1" x="634" y="38"> </location>
|
||||||
|
<location seat="2" x="667" y="184"> </location>
|
||||||
|
<location seat="3" x="667" y="321"> </location>
|
||||||
|
<location seat="4" x="667" y="445"> </location>
|
||||||
|
<location seat="5" x="337" y="459"> </location>
|
||||||
|
<location seat="6" x="0" y="400"> </location>
|
||||||
|
<location seat="7" x="0" y="322"> </location>
|
||||||
|
<location seat="8" x="0" y="181"> </location>
|
||||||
|
<location seat="9" x="70" y="53"> </location>
|
||||||
|
</layout>
|
||||||
|
</site>
|
||||||
|
|
||||||
|
|
||||||
|
<site enabled="False"
|
||||||
|
site_name="Betfair"
|
||||||
|
table_finder="Betfair Poker.exe"
|
||||||
|
screen_name="YOUR SCREEN NAME HERE"
|
||||||
|
site_path="C:/Program Files/Betfair/Betfair Poker/"
|
||||||
|
HH_path="C:/Program Files/Betfair/Betfair Poker/HandHistory/YOUR SCREEN NAME HERE/"
|
||||||
|
decoder="everleaf_decode_table"
|
||||||
|
converter="BetfairToFpdb"
|
||||||
|
supported_games="holdem">
|
||||||
|
<layout fav_seat="0" height="547" max="8" width="794">
|
||||||
|
<location seat="1" x="640" y="64"> </location>
|
||||||
|
<location seat="2" x="650" y="230"> </location>
|
||||||
|
<location seat="3" x="650" y="385"> </location>
|
||||||
|
<location seat="4" x="588" y="425"> </location>
|
||||||
|
<location seat="5" x="92" y="425"> </location>
|
||||||
|
<location seat="6" x="0" y="373"> </location>
|
||||||
|
<location seat="7" x="0" y="223"> </location>
|
||||||
|
<location seat="8" x="25" y="50"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="6" width="794">
|
||||||
|
<location seat="1" x="640" y="58"> </location>
|
||||||
|
<location seat="2" x="654" y="288"> </location>
|
||||||
|
<location seat="3" x="615" y="424"> </location>
|
||||||
|
<location seat="4" x="70" y="421"> </location>
|
||||||
|
<location seat="5" x="0" y="280"> </location>
|
||||||
|
<location seat="6" x="70" y="58"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="2" width="794">
|
||||||
|
<location seat="1" x="651" y="288"> </location>
|
||||||
|
<location seat="2" x="10" y="288"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout fav_seat="0" height="547" max="9" width="794">
|
||||||
|
<location seat="1" x="634" y="38"> </location>
|
||||||
|
<location seat="2" x="667" y="184"> </location>
|
||||||
|
<location seat="3" x="667" y="321"> </location>
|
||||||
|
<location seat="4" x="667" y="445"> </location>
|
||||||
|
<location seat="5" x="337" y="459"> </location>
|
||||||
|
<location seat="6" x="0" y="400"> </location>
|
||||||
|
<location seat="7" x="0" y="322"> </location>
|
||||||
|
<location seat="8" x="0" y="181"> </location>
|
||||||
|
<location seat="9" x="70" y="53"> </location>
|
||||||
|
</layout>
|
||||||
|
</site>
|
||||||
|
</supported_sites>
|
||||||
|
|
||||||
|
<supported_games>
|
||||||
|
|
||||||
|
<game cols="3" db="fpdb" game_name="holdem" rows="2" aux="mucked">
|
||||||
|
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
||||||
|
</game>
|
||||||
|
|
||||||
|
<game cols="3" db="fpdb" game_name="razz" rows="2" aux="stud_mucked">
|
||||||
|
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
||||||
|
</game>
|
||||||
|
|
||||||
|
<game cols="3" db="fpdb" game_name="omahahi" rows="2" aux="mucked">
|
||||||
|
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
||||||
|
</game>
|
||||||
|
|
||||||
|
<game cols="3" db="fpdb" game_name="omahahilo" rows="2" aux="mucked">
|
||||||
|
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
||||||
|
</game>
|
||||||
|
|
||||||
|
<game cols="3" db="fpdb" game_name="studhi" rows="2" aux="stud_mucked">
|
||||||
|
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
||||||
|
</game>
|
||||||
|
|
||||||
|
<game cols="3" db="fpdb" game_name="studhilo" rows="2" aux="stud_mucked">
|
||||||
|
<stat click="tog_decorate" col="0" popup="default" row="0" stat_name="vpip" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="1" popup="default" row="0" stat_name="pfr" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="2" popup="default" row="0" stat_name="ffreq1" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="0" popup="default" row="1" stat_name="n" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="1" popup="default" row="1" stat_name="wtsd" tip="tip1"> </stat>
|
||||||
|
<stat click="tog_decorate" col="2" popup="default" row="1" stat_name="wmsd" tip="tip1"> </stat>
|
||||||
|
</game>
|
||||||
|
</supported_games>
|
||||||
|
|
||||||
|
<popup_windows>
|
||||||
|
<pu pu_name="default">
|
||||||
|
<pu_stat pu_stat_name="n"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="vpip"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="pfr"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="three_B_0"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="steal"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="f_BB_steal"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="f_SB_steal"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="wmsd"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="wtsd"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="WMsF"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="a_freq1"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="a_freq2"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="a_freq3"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="a_freq4"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="cb1"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="cb2"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="cb3"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="cb4"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="ffreq1"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="ffreq2"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="ffreq3"> </pu_stat>
|
||||||
|
<pu_stat pu_stat_name="ffreq4"> </pu_stat>
|
||||||
|
</pu>
|
||||||
|
</popup_windows>
|
||||||
|
|
||||||
|
<aux_windows>
|
||||||
|
<aw card_ht="42" card_wd="30" class="Stud_mucked" cols="11" deck="Cards01.png" module="Mucked" name="stud_mucked" rows="8"> </aw>
|
||||||
|
<aw class="Hello" module="Hello" name="Hello"> </aw>
|
||||||
|
<aw class="Hello_Menu" module="Hello" name="Hello_menu"> </aw>
|
||||||
|
<aw class="Hello_plus" module="Hello" name="Hello_plus"> </aw>
|
||||||
|
<aw card_ht="42" card_wd="30" class="Flop_Mucked" deck="Cards01.png" module="Mucked" name="mucked" opacity="0.7" timeout="5">
|
||||||
|
<layout height="546" max="6" width="792">
|
||||||
|
<location seat="1" x="555" y="169"> </location>
|
||||||
|
<location seat="2" x="572" y="276"> </location>
|
||||||
|
<location seat="3" x="363" y="348"> </location>
|
||||||
|
<location seat="4" x="150" y="273"> </location>
|
||||||
|
<location seat="5" x="150" y="169"> </location>
|
||||||
|
<location seat="6" x="363" y="113"> </location>
|
||||||
|
<location common="1" x="323" y="232"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout height="546" max="9" width="792">
|
||||||
|
<location seat="1" x="486" y="113"> </location>
|
||||||
|
<location seat="2" x="555" y="169"> </location>
|
||||||
|
<location seat="3" x="572" y="276"> </location>
|
||||||
|
<location seat="4" x="522" y="345"> </location>
|
||||||
|
<location seat="5" x="363" y="348"> </location>
|
||||||
|
<location seat="6" x="217" y="341"> </location>
|
||||||
|
<location seat="7" x="150" y="273"> </location>
|
||||||
|
<location seat="8" x="150" y="169"> </location>
|
||||||
|
<location seat="9" x="230" y="115"> </location>
|
||||||
|
<location common="1" x="323" y="232"> </location>
|
||||||
|
</layout>
|
||||||
|
<layout height="546" max="10" width="792">
|
||||||
|
<location seat="1" x="486" y="113"> </location>
|
||||||
|
<location seat="2" x="499" y="138"> </location>
|
||||||
|
<location seat="3" x="522" y="212"> </location>
|
||||||
|
<location seat="4" x="501" y="281"> </location>
|
||||||
|
<location seat="5" x="402" y="323"> </location>
|
||||||
|
<location seat="6" x="243" y="311"> </location>
|
||||||
|
<location seat="7" x="203" y="262"> </location>
|
||||||
|
<location seat="8" x="170" y="185"> </location>
|
||||||
|
<location seat="9" x="183" y="128"> </location>
|
||||||
|
<location seat="10" x="213" y="86"> </location>
|
||||||
|
<location common="1" x="317" y="237"> </location>
|
||||||
|
</layout>
|
||||||
|
</aw>
|
||||||
|
</aux_windows>
|
||||||
|
|
||||||
|
<hhcs>
|
||||||
|
<hhc site="PokerStars" converter="PokerStarsToFpdb"/>
|
||||||
|
<hhc site="Full Tilt Poker" converter="FulltiltToFpdb"/>
|
||||||
|
<hhc site="Everleaf" converter="EverleafToFpdb"/>
|
||||||
|
<hhc site="Win2day" converter="Win2dayToFpdb"/>
|
||||||
|
<hhc site="Absolute" converter="AbsoluteToFpdb"/>
|
||||||
|
<hhc site="PartyPoker" converter="PartyPokerToFpdb"/>
|
||||||
|
<hhc site="Betfair" converter="BetfairToFpdb"/>
|
||||||
|
<hhc site="Partouche" converter="PartoucheToFpdb"/>
|
||||||
|
</hhcs>
|
||||||
|
|
||||||
|
<supported_databases>
|
||||||
|
<database db_ip="localhost" db_name=":memory:" db_pass="fpdb" db_server="sqlite" db_user="fpdb"/>
|
||||||
|
</supported_databases>
|
||||||
|
|
||||||
|
</FreePokerToolsConfig>
|
||||||
|
|
|
@ -4,91 +4,95 @@
|
||||||
|
|
||||||
<import callFpdbHud = "True" interval = "10" fastStoreHudCache="False" hhArchiveBase="~/.fpdb/HandHistories/" saveActions="True"></import>
|
<import callFpdbHud = "True" interval = "10" fastStoreHudCache="False" hhArchiveBase="~/.fpdb/HandHistories/" saveActions="True"></import>
|
||||||
|
|
||||||
<!-- These values need some explaining
|
<!-- These values determine what stats are displayed in the HUD
|
||||||
|
|
||||||
aggregate_ring_game_stats :
|
The following values define how opponents' stats are done, the first 2 determine
|
||||||
|
the time period stats are displayed for, the next 3 determine what blind levels
|
||||||
|
are included (i.e. aggregated):
|
||||||
|
|
||||||
|
stat_range :
|
||||||
|
- A/S/T
|
||||||
|
- if set to A, includes stats from all time
|
||||||
|
- if set to S, includes stats from current session
|
||||||
|
- if set to T, includes stats from last N days; set value in stat_days
|
||||||
|
- defaults to A
|
||||||
|
|
||||||
|
stat_days :
|
||||||
|
- a numeric value
|
||||||
|
- only used if stat_range is set to 'T', this value tells how many days are
|
||||||
|
included in the stat calculation
|
||||||
|
- defaults to 90
|
||||||
|
- value not used by default as it depends on stat_range setting
|
||||||
|
|
||||||
|
aggregate_ring_game_stats :
|
||||||
- True/False
|
- True/False
|
||||||
- if set to True, includes data from other blind levels
|
- if set to True, opponents stats include other blind levels during ring games
|
||||||
- defaults to False
|
- defaults to False
|
||||||
|
|
||||||
aggregate_tourney_stats :
|
aggregate_tourney_stats :
|
||||||
- True/False
|
- True/False
|
||||||
- if set to True, includes data from other blind levels
|
- if set to True, opponents stats include other blind levels during tourneys
|
||||||
- defaults to True
|
- defaults to True
|
||||||
|
|
||||||
stat_aggregation_range :
|
|
||||||
- A/S/T
|
|
||||||
- if set to A, includes stats from all time
|
|
||||||
- if set to S, includes stats from current sessions
|
|
||||||
- if set to T, includes stats from last N days; set value in hud_days
|
|
||||||
- defaults to A
|
|
||||||
|
|
||||||
aggregation_days :
|
|
||||||
- a numeric value
|
|
||||||
- if hud_style is set to 'T', this value tells how many days are
|
|
||||||
included in the stat calculation
|
|
||||||
- defaults to 90
|
|
||||||
- value not used by default, as depends on hud_style setting
|
|
||||||
|
|
||||||
aggregation_level_multiplier :
|
aggregation_level_multiplier :
|
||||||
- float value
|
- float value
|
||||||
- defines how many blind levels are used for aggregation
|
- defines how many blind levels are included in stats displayed in HUD
|
||||||
- the logic is weird, at best
|
- if value is M, stats for blind levels are combined if the higher level
|
||||||
- if value is 100, almost all levels are included
|
is less than or equal to M times the lower blind level
|
||||||
- if value is 2.1, levels from half to double the current blind
|
- defaults to 3, meaning blind levels from 1/3 of the current level to 3
|
||||||
level are included
|
times the current level are included in the stats displayed in the HUD
|
||||||
- if value it 1, no aggregation is performed
|
- e.g. if current big blind is 50, stats for blind levels from big blind
|
||||||
- defaults to 1
|
of 16.7 (50 divided by 3) to big blind of 150 (50 times 3) are included
|
||||||
|
|
||||||
|
|
||||||
The following values define how hero's stats are done
|
The following values define how hero's stats are done, the first 2 determine
|
||||||
|
the time period stats are displayed for, the next 3 determine what blind levels
|
||||||
|
are included (i.e. aggregated):
|
||||||
|
|
||||||
|
hero_stat_range :
|
||||||
|
- A/S/T
|
||||||
|
- if set to A, includes stats from all time
|
||||||
|
- if set to S, includes stats from current session
|
||||||
|
- if set to T, includes stats from last N days; set value in hero_stat_days
|
||||||
|
- defaults to S
|
||||||
|
|
||||||
|
hero_stat_days :
|
||||||
|
- a numeric value
|
||||||
|
- if hero_stat_range is set to 'T', this value tells how many days are
|
||||||
|
included in the stat calculation
|
||||||
|
- defaults to 30
|
||||||
|
- value not used by default as it depends on hero_stat_range setting
|
||||||
|
|
||||||
aggregate_hero_ring_game_stats :
|
aggregate_hero_ring_game_stats :
|
||||||
- True/False
|
- True/False
|
||||||
- if set to True, hero's data is calculated over multiple blind levels
|
- if set to True, hero's stats are calculated over multiple blind levels
|
||||||
- defaults to False
|
- defaults to False
|
||||||
|
|
||||||
aggregate_hero_tourney_stats :
|
aggregate_hero_tourney_stats :
|
||||||
- True/False
|
- True/False
|
||||||
- if set to True, hero's data is calculated over multiple blind levels
|
- if set to True, hero's stats are calculated over multiple blind levels
|
||||||
- defaults to False
|
- defaults to False
|
||||||
|
|
||||||
hero_stat_aggregation_range :
|
|
||||||
- A/S/T
|
|
||||||
- if set to A, includes stats from all time
|
|
||||||
- if set to S, includes stats from current sessions
|
|
||||||
- if set to T, includes stats from last N days; set value in hud_days
|
|
||||||
- defaults to S
|
|
||||||
|
|
||||||
hero_aggregation_days :
|
|
||||||
- a numeric value
|
|
||||||
- if hero_stat_aggregation_range is set to 'T', this value tells
|
|
||||||
how many days are included in the stat calculation
|
|
||||||
- defaults to 30
|
|
||||||
- value not used by default, as depends on hud_style setting
|
|
||||||
|
|
||||||
hero_aggregation_level_multiplier :
|
hero_aggregation_level_multiplier :
|
||||||
- float value
|
- float value
|
||||||
- defines how many blind levels are used for aggregation
|
- defines how many blind levels are included in stats displayed in HUD
|
||||||
- the logic is weird, at best
|
- if value is M, stats for blind levels are combined if the higher level
|
||||||
- if value is 100, almost all levels are included
|
is less than or equal to M times the lower blind level
|
||||||
- if value is 2.1, levels from half to double the current blind
|
- defaults to 1, meaning only stats from current blind level are included
|
||||||
level are included
|
- e.g. if set to 3 and current big blind is 50, stats for blind levels from
|
||||||
- if value it 1, no aggregation is performed
|
16.7 (50 divided by 3) to big blind of 150 (50 times 3) are included
|
||||||
- defaults to 1
|
|
||||||
-->
|
-->
|
||||||
<hud_ui
|
<hud_ui
|
||||||
|
stat_range="A"
|
||||||
|
stat_days="90"
|
||||||
aggregate_ring_game_stats="False"
|
aggregate_ring_game_stats="False"
|
||||||
aggregate_tourney_stats="False"
|
aggregate_tourney_stats="True"
|
||||||
stat_aggregation_range="A"
|
aggregation_level_multiplier="3"
|
||||||
aggregation_days="90"
|
|
||||||
aggregation_level_multiplier="1"
|
|
||||||
|
|
||||||
|
hero_stat_range="S"
|
||||||
|
hero_stat_days="30"
|
||||||
aggregate_hero_ring_game_stats="False"
|
aggregate_hero_ring_game_stats="False"
|
||||||
aggregate_hero_tourney_stats="True"
|
aggregate_hero_tourney_stats="False"
|
||||||
hero_stat_aggregation_range="S"
|
|
||||||
hero_aggregation_days="30"
|
|
||||||
hero_aggregation_level_multiplier="1"
|
hero_aggregation_level_multiplier="1"
|
||||||
|
|
||||||
label="FPDB Menu - Right-click
|
label="FPDB Menu - Right-click
|
||||||
|
@ -570,8 +574,8 @@ Left-Drag to Move"
|
||||||
</hhcs>
|
</hhcs>
|
||||||
|
|
||||||
<supported_databases>
|
<supported_databases>
|
||||||
<database db_name="fpdb" db_server="mysql" db_ip="localhost" db_user="fpdb" db_pass="YOUR MYSQL PASSWORD" db_type="fpdb"></database>
|
<database db_name="fpdb" db_server="mysql" db_ip="localhost" db_user="fpdb" db_pass="YOUR MYSQL PASSWORD"></database>
|
||||||
<!-- <database db_ip="localhost" db_name="fpdb" db_pass="fpdb" db_server="sqlite" db_type="fpdb" 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>
|
||||||
|
|
|
@ -5,17 +5,17 @@
|
||||||
Main for FreePokerTools HUD.
|
Main for FreePokerTools HUD.
|
||||||
"""
|
"""
|
||||||
# Copyright 2008, 2009, Ray E. Barker
|
# Copyright 2008, 2009, Ray E. Barker
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
@ -33,7 +33,7 @@ import os
|
||||||
import Options
|
import Options
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
(options, sys.argv) = Options.fpdb_options()
|
(options, argv) = Options.fpdb_options()
|
||||||
|
|
||||||
if not options.errorsToConsole:
|
if not options.errorsToConsole:
|
||||||
print "Note: error output is being diverted to fpdb-error-log.txt and HUD-error.txt. Any major error will be reported there _only_."
|
print "Note: error output is being diverted to fpdb-error-log.txt and HUD-error.txt. Any major error will be reported there _only_."
|
||||||
|
@ -63,34 +63,6 @@ elif os.name == 'nt':
|
||||||
import Hud
|
import Hud
|
||||||
|
|
||||||
|
|
||||||
# HUD params:
|
|
||||||
# - Set aggregate_ring and/or aggregate_tour to True is you want to include stats from other blind levels in the HUD display
|
|
||||||
# - If aggregation is used, the value of agg_bb_mult determines what levels are included. If
|
|
||||||
# agg_bb_mult is M and current blind level is L, blinds between L/M and L*M are included. e.g.
|
|
||||||
# if agg_bb_mult is 100, almost all levels are included in all HUD displays
|
|
||||||
# if agg_bb_mult is 2, levels from half to double the current blind level are included in the HUD
|
|
||||||
# if agg_bb_mult is 1 only the current level is included
|
|
||||||
# - Set hud_style to A to see stats for all-time
|
|
||||||
# Set hud_style to S to only see stats for current session (currently this shows stats for the last 24 hours)
|
|
||||||
# Set hud_style to T to only see stats for the last N days (uses value in hud_days)
|
|
||||||
# - Set hud_days to N to see stats for the last N days in the HUD (only applies if hud_style is T)
|
|
||||||
def_hud_params = { # Settings for all players apart from program owner ('hero')
|
|
||||||
'aggregate_ring' : False
|
|
||||||
, 'aggregate_tour' : True
|
|
||||||
, 'hud_style' : 'A'
|
|
||||||
, 'hud_days' : 90
|
|
||||||
, 'agg_bb_mult' : 10000 # 1 means no aggregation
|
|
||||||
# , 'hud_session_gap' : 30 not currently used
|
|
||||||
# Second set of variables for hero - these settings only apply to the program owner
|
|
||||||
, 'h_aggregate_ring' : False
|
|
||||||
, 'h_aggregate_tour' : True
|
|
||||||
, 'h_hud_style' : 'S' # A(ll) / S(ession) / T(ime in days)
|
|
||||||
, 'h_hud_days' : 60
|
|
||||||
, 'h_agg_bb_mult' : 10000 # 1 means no aggregation
|
|
||||||
# , 'h_hud_session_gap' : 30 not currently used
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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.
|
||||||
|
@ -129,20 +101,17 @@ class HUD_main(object):
|
||||||
|
|
||||||
def create_HUD(self, new_hand_id, table, table_name, max, poker_game, type, stat_dict, cards):
|
def create_HUD(self, new_hand_id, table, table_name, max, poker_game, type, stat_dict, cards):
|
||||||
"""type is "ring" or "tour" used to set hud_params"""
|
"""type is "ring" or "tour" used to set hud_params"""
|
||||||
|
|
||||||
def idle_func():
|
def idle_func():
|
||||||
|
|
||||||
gtk.gdk.threads_enter()
|
gtk.gdk.threads_enter()
|
||||||
try: # TODO: seriously need to decrease the scope of this block.. what are we expecting to error?
|
try:
|
||||||
# TODO: The purpose of this try/finally block is to make darn sure that threads_leave()
|
|
||||||
# TODO: gets called. If there is an exception and threads_leave() doesn't get called we
|
|
||||||
# TODO: lock up. REB
|
|
||||||
table.gdkhandle = gtk.gdk.window_foreign_new(table.number)
|
table.gdkhandle = gtk.gdk.window_foreign_new(table.number)
|
||||||
newlabel = gtk.Label("%s - %s" % (table.site, table_name))
|
newlabel = gtk.Label("%s - %s" % (table.site, table_name))
|
||||||
self.vb.add(newlabel)
|
self.vb.add(newlabel)
|
||||||
newlabel.show()
|
newlabel.show()
|
||||||
self.main_window.resize_children()
|
self.main_window.resize_children()
|
||||||
|
|
||||||
self.hud_dict[table_name].tablehudlabel = newlabel
|
self.hud_dict[table_name].tablehudlabel = newlabel
|
||||||
self.hud_dict[table_name].create(new_hand_id, self.config, stat_dict, cards)
|
self.hud_dict[table_name].create(new_hand_id, self.config, stat_dict, cards)
|
||||||
for m in self.hud_dict[table_name].aux_windows:
|
for m in self.hud_dict[table_name].aux_windows:
|
||||||
|
@ -150,15 +119,20 @@ class HUD_main(object):
|
||||||
m.update_gui(new_hand_id)
|
m.update_gui(new_hand_id)
|
||||||
self.hud_dict[table_name].update(new_hand_id, self.config)
|
self.hud_dict[table_name].update(new_hand_id, self.config)
|
||||||
self.hud_dict[table_name].reposition_windows()
|
self.hud_dict[table_name].reposition_windows()
|
||||||
return False
|
except:
|
||||||
|
print "*** Exception in HUD_main::idle_func() *** "
|
||||||
|
traceback.print_stack()
|
||||||
finally:
|
finally:
|
||||||
gtk.gdk.threads_leave()
|
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] = 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].table_name = table_name
|
||||||
self.hud_dict[table_name].stat_dict = stat_dict
|
self.hud_dict[table_name].stat_dict = stat_dict
|
||||||
self.hud_dict[table_name].cards = cards
|
self.hud_dict[table_name].cards = cards
|
||||||
|
|
||||||
|
# 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:
|
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_name].hud_params['agg_bb_mult'] = 1
|
||||||
elif type == "ring" and self.hud_params['aggregate_ring'] == False:
|
elif type == "ring" and self.hud_params['aggregate_ring'] == False:
|
||||||
|
@ -167,28 +141,37 @@ class HUD_main(object):
|
||||||
self.hud_dict[table_name].hud_params['h_agg_bb_mult'] = 1
|
self.hud_dict[table_name].hud_params['h_agg_bb_mult'] = 1
|
||||||
elif type == "ring" and self.hud_params['h_aggregate_ring'] == False:
|
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_name].hud_params['h_agg_bb_mult'] = 1
|
||||||
self.hud_params['aggregate_ring'] == True
|
# sqlcoder: I forget why these are set to true (aren't they ignored from now on?)
|
||||||
self.hud_params['h_aggregate_ring'] == True
|
# but I think it's needed:
|
||||||
|
self.hud_params['aggregate_ring'] = True
|
||||||
|
self.hud_params['h_aggregate_ring'] = True
|
||||||
|
# so maybe the tour ones should be set as well? does this fix the bug I see mentioned?
|
||||||
|
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_name].aux_windows]
|
||||||
gobject.idle_add(idle_func)
|
gobject.idle_add(idle_func)
|
||||||
|
|
||||||
def update_HUD(self, new_hand_id, table_name, config):
|
def update_HUD(self, new_hand_id, table_name, config):
|
||||||
"""Update a HUD gui from inside the non-gui read_stdin thread."""
|
"""Update a HUD gui from inside the non-gui read_stdin thread."""
|
||||||
# This is written so that only 1 thread can touch the gui--mainly
|
# This is written so that only 1 thread can touch the gui--mainly
|
||||||
# for compatibility with Windows. This method dispatches the
|
# for compatibility with Windows. This method dispatches the
|
||||||
# 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()
|
||||||
# try:
|
|
||||||
self.hud_dict[table_name].update(new_hand_id, config)
|
self.hud_dict[table_name].update(new_hand_id, config)
|
||||||
[aw.update_gui(new_hand_id) for aw in self.hud_dict[table_name].aux_windows]
|
# The HUD could get destroyed in the above call ^^, which leaves us with a KeyError here vv
|
||||||
# finally:
|
# if we ever get an error we need to expect ^^ then we need to handle it vv - Eric
|
||||||
gtk.gdk.threads_leave()
|
try:
|
||||||
return False
|
[aw.update_gui(new_hand_id) for aw in self.hud_dict[table_name].aux_windows]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
gtk.gdk.threads_leave()
|
||||||
|
return False
|
||||||
|
|
||||||
gobject.idle_add(idle_func)
|
gobject.idle_add(idle_func)
|
||||||
|
|
||||||
def read_stdin(self): # This is the thread function
|
def read_stdin(self): # This is the thread function
|
||||||
"""Do all the non-gui heavy lifting for the HUD program."""
|
"""Do all the non-gui heavy lifting for the HUD program."""
|
||||||
|
|
||||||
|
@ -197,7 +180,7 @@ class HUD_main(object):
|
||||||
# need their own access to the database, but should open their own
|
# need their own access to the database, but should open their own
|
||||||
# if it is required.
|
# if it is required.
|
||||||
self.db_connection = Database.Database(self.config)
|
self.db_connection = Database.Database(self.config)
|
||||||
|
|
||||||
# get hero's screen names and player ids
|
# get hero's screen names and player ids
|
||||||
self.hero, self.hero_ids = {}, {}
|
self.hero, self.hero_ids = {}, {}
|
||||||
for site in self.config.get_supported_sites():
|
for site in self.config.get_supported_sites():
|
||||||
|
@ -206,7 +189,7 @@ class HUD_main(object):
|
||||||
site_id = result[0][0]
|
site_id = result[0][0]
|
||||||
self.hero[site_id] = self.config.supported_sites[site].screen_name
|
self.hero[site_id] = self.config.supported_sites[site].screen_name
|
||||||
self.hero_ids[site_id] = self.db_connection.get_player_id(self.config, site, self.hero[site_id])
|
self.hero_ids[site_id] = self.db_connection.get_player_id(self.config, site, self.hero[site_id])
|
||||||
|
|
||||||
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()
|
||||||
new_hand_id = string.rstrip(new_hand_id)
|
new_hand_id = string.rstrip(new_hand_id)
|
||||||
|
@ -217,10 +200,10 @@ class HUD_main(object):
|
||||||
# get basic info about the new hand from the db
|
# get basic info about the new hand from the db
|
||||||
# if there is a db error, complain, skip hand, and proceed
|
# if there is a db error, complain, skip hand, and proceed
|
||||||
try:
|
try:
|
||||||
(table_name, max, poker_game, type, site_id, site_name, tour_number, tab_number) = \
|
(table_name, max, poker_game, type, site_id, site_name, num_seats, tour_number, tab_number) = \
|
||||||
self.db_connection.get_table_info(new_hand_id)
|
self.db_connection.get_table_info(new_hand_id)
|
||||||
except Exception, err:
|
except Exception, err: # TODO: we need to make this a much less generic Exception lulz
|
||||||
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
|
||||||
|
|
||||||
|
@ -231,11 +214,18 @@ 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']
|
try:
|
||||||
|
self.db_connection.init_hud_stat_vars( self.hud_dict[temp_key].hud_params['hud_days']
|
||||||
, self.hud_dict[temp_key].hud_params['h_hud_days'])
|
, self.hud_dict[temp_key].hud_params['h_hud_days'])
|
||||||
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])
|
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])
|
||||||
self.hud_dict[temp_key].stat_dict = stat_dict
|
self.hud_dict[temp_key].stat_dict = stat_dict
|
||||||
|
except KeyError: # HUD instance has been killed off, key is stale
|
||||||
|
sys.stderr.write('hud_dict[%s] was not found\n' % temp_key)
|
||||||
|
sys.stderr.write('will not send hand\n')
|
||||||
|
# Unlocks table, copied from end of function
|
||||||
|
self.db_connection.connection.rollback()
|
||||||
|
return
|
||||||
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!
|
||||||
|
@ -243,12 +233,13 @@ class HUD_main(object):
|
||||||
self.hud_dict[temp_key].cards = cards
|
self.hud_dict[temp_key].cards = cards
|
||||||
[aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[temp_key].aux_windows]
|
[aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[temp_key].aux_windows]
|
||||||
self.update_HUD(new_hand_id, temp_key, self.config)
|
self.update_HUD(new_hand_id, temp_key, self.config)
|
||||||
|
|
||||||
# Or create a new HUD
|
# Or create a new HUD
|
||||||
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'] )
|
||||||
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_params, self.hero_ids[site_id])
|
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, type, self.hud_params
|
||||||
|
,self.hero_ids[site_id], num_seats)
|
||||||
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!
|
||||||
|
@ -266,7 +257,12 @@ class HUD_main(object):
|
||||||
else:
|
else:
|
||||||
tablewindow.max = max
|
tablewindow.max = max
|
||||||
tablewindow.site = site_name
|
tablewindow.site = site_name
|
||||||
self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, type, stat_dict, cards)
|
# Test that the table window still exists
|
||||||
|
if hasattr(tablewindow, 'number'):
|
||||||
|
self.create_HUD(new_hand_id, tablewindow, temp_key, max, poker_game, type, stat_dict, cards)
|
||||||
|
else:
|
||||||
|
sys.stderr.write('Table "%s" no longer exists\n' % table_name)
|
||||||
|
|
||||||
self.db_connection.connection.rollback()
|
self.db_connection.connection.rollback()
|
||||||
|
|
||||||
if __name__== "__main__":
|
if __name__== "__main__":
|
||||||
|
|
|
@ -37,7 +37,8 @@ if __name__== "__main__":
|
||||||
HUD_main.config = Configuration.Config()
|
HUD_main.config = Configuration.Config()
|
||||||
|
|
||||||
gobject.threads_init() # this is required
|
gobject.threads_init() # this is required
|
||||||
thread.start_new_thread(HUD_main.read_stdin, ()) # starts the thread
|
hud = HUD_main.HUD_main()
|
||||||
|
thread.start_new_thread(hud.read_stdin, ()) # starts the thread
|
||||||
|
|
||||||
HUD_main.main_window = gtk.Window()
|
HUD_main.main_window = gtk.Window()
|
||||||
HUD_main.main_window.connect("destroy", destroy)
|
HUD_main.main_window.connect("destroy", destroy)
|
||||||
|
|
114
pyfpdb/Hand.py
114
pyfpdb/Hand.py
|
@ -210,24 +210,24 @@ db: a connected fpdb_db object"""
|
||||||
#####
|
#####
|
||||||
# End prep functions
|
# End prep functions
|
||||||
#####
|
#####
|
||||||
|
|
||||||
# HandsActions - all actions for all players for all streets - self.actions
|
|
||||||
# HudCache data can be generated from HandsActions (HandsPlayers?)
|
|
||||||
|
|
||||||
# Hands - Summary information of hand indexed by handId - gameinfo
|
|
||||||
hh = self.stats.getHands()
|
hh = self.stats.getHands()
|
||||||
hh['gameTypeId'] = gtid
|
|
||||||
# seats TINYINT NOT NULL,
|
|
||||||
hh['seats'] = len(sqlids)
|
|
||||||
|
|
||||||
#print hh
|
if not db.isDuplicate(gtid, hh['siteHandNo']):
|
||||||
handid = db.storeHand(hh)
|
# Hands - Summary information of hand indexed by handId - gameinfo
|
||||||
# HandsPlayers - ? ... Do we fix winnings?
|
hh['gameTypeId'] = gtid
|
||||||
db.storeHandsPlayers(handid, sqlids, self.stats.getHandsPlayers())
|
# seats TINYINT NOT NULL,
|
||||||
# Tourneys ?
|
hh['seats'] = len(sqlids)
|
||||||
# TourneysPlayers
|
|
||||||
|
|
||||||
pass
|
handid = db.storeHand(hh)
|
||||||
|
db.storeHandsPlayers(handid, sqlids, self.stats.getHandsPlayers())
|
||||||
|
# HandsActions - all actions for all players for all streets - self.actions
|
||||||
|
# HudCache data can be generated from HandsActions (HandsPlayers?)
|
||||||
|
# Tourneys ?
|
||||||
|
# TourneysPlayers
|
||||||
|
else:
|
||||||
|
log.info("Hand.insert(): hid #: %s is a duplicate" % hh['siteHandNo'])
|
||||||
|
#Raise Duplicate exception?
|
||||||
|
pass
|
||||||
|
|
||||||
def select(self, handId):
|
def select(self, handId):
|
||||||
""" Function to create Hand object from database """
|
""" Function to create Hand object from database """
|
||||||
|
@ -510,7 +510,7 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
||||||
def printHand(self):
|
def printHand(self):
|
||||||
self.writeHand(sys.stdout)
|
self.writeHand(sys.stdout)
|
||||||
|
|
||||||
def actionString(self, act):
|
def actionString(self, act, street=None):
|
||||||
if act[1] == 'folds':
|
if act[1] == 'folds':
|
||||||
return ("%s: folds " %(act[0]))
|
return ("%s: folds " %(act[0]))
|
||||||
elif act[1] == 'checks':
|
elif act[1] == 'checks':
|
||||||
|
@ -535,7 +535,7 @@ Map the tuple self.gametype onto the pokerstars string describing it
|
||||||
elif act[1] == 'bringin':
|
elif act[1] == 'bringin':
|
||||||
return ("%s: brings in for %s%s%s" %(act[0], self.sym, act[2], ' and is all-in' if act[3] else ''))
|
return ("%s: brings in for %s%s%s" %(act[0], self.sym, act[2], ' and is all-in' if act[3] else ''))
|
||||||
elif act[1] == 'discards':
|
elif act[1] == 'discards':
|
||||||
return ("%s: discards %s %s%s" %(act[0], act[2], 'card' if act[2] == 1 else 'cards' , " [" + " ".join(self.discards[act[0]]['DRAWONE']) + "]" if self.hero == act[0] else ''))
|
return ("%s: discards %s %s%s" %(act[0], act[2], 'card' if act[2] == 1 else 'cards' , " [" + " ".join(self.discards[street][act[0]]) + "]" if self.hero == act[0] else ''))
|
||||||
elif act[1] == 'stands pat':
|
elif act[1] == 'stands pat':
|
||||||
return ("%s: stands pat" %(act[0]))
|
return ("%s: stands pat" %(act[0]))
|
||||||
|
|
||||||
|
@ -668,6 +668,27 @@ class HoldemOmahaHand(Hand):
|
||||||
tmp5 = 0
|
tmp5 = 0
|
||||||
return (tmp1,tmp2,tmp3,tmp4,tmp5)
|
return (tmp1,tmp2,tmp3,tmp4,tmp5)
|
||||||
|
|
||||||
|
def join_holecards(self, player, asList=False):
|
||||||
|
"""With asList = True it returns the set cards for a player including down cards if they aren't know"""
|
||||||
|
# FIXME: This should actually return
|
||||||
|
hcs = [u'0x', u'0x', u'0x', u'0x']
|
||||||
|
|
||||||
|
for street in self.holeStreets:
|
||||||
|
if player in self.holecards[street].keys():
|
||||||
|
hcs[0] = self.holecards[street][player][1][0]
|
||||||
|
hcs[1] = self.holecards[street][player][1][1]
|
||||||
|
try:
|
||||||
|
hcs[2] = self.holecards[street][player][1][2]
|
||||||
|
hcs[3] = self.holecards[street][player][1][3]
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if asList == False:
|
||||||
|
return " ".join(hcs)
|
||||||
|
else:
|
||||||
|
return hcs
|
||||||
|
|
||||||
|
|
||||||
def writeHTMLHand(self):
|
def writeHTMLHand(self):
|
||||||
from nevow import tags as T
|
from nevow import tags as T
|
||||||
from nevow import flat
|
from nevow import flat
|
||||||
|
@ -872,7 +893,7 @@ class DrawHand(Hand):
|
||||||
self.streetList = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
self.streetList = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
||||||
self.allStreets = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
self.allStreets = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
||||||
self.holeStreets = ['DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
self.holeStreets = ['DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
||||||
self.actionStreets = ['PREDEAL', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
self.actionStreets = ['BLINDSANTES', 'DEAL', 'DRAWONE', 'DRAWTWO', 'DRAWTHREE']
|
||||||
self.communityStreets = []
|
self.communityStreets = []
|
||||||
Hand.__init__(self, sitename, gametype, handText)
|
Hand.__init__(self, sitename, gametype, handText)
|
||||||
self.sb = gametype['sb']
|
self.sb = gametype['sb']
|
||||||
|
@ -953,6 +974,13 @@ class DrawHand(Hand):
|
||||||
act = (player, 'discards', num)
|
act = (player, 'discards', num)
|
||||||
self.actions[street].append(act)
|
self.actions[street].append(act)
|
||||||
|
|
||||||
|
def holecardsAsSet(self, street, player):
|
||||||
|
"""Return holdcards: (oc, nc) as set()"""
|
||||||
|
(nc,oc) = self.holecards[street][player]
|
||||||
|
nc = set(nc)
|
||||||
|
oc = set(oc)
|
||||||
|
return (nc, oc)
|
||||||
|
|
||||||
def getStreetTotals(self):
|
def getStreetTotals(self):
|
||||||
# street1Pot INT, /* pot size at flop/street4 */
|
# street1Pot INT, /* pot size at flop/street4 */
|
||||||
# street2Pot INT, /* pot size at turn/street5 */
|
# street2Pot INT, /* pot size at turn/street5 */
|
||||||
|
@ -961,6 +989,16 @@ class DrawHand(Hand):
|
||||||
# showdownPot INT, /* pot size at sd/street7 */
|
# showdownPot INT, /* pot size at sd/street7 */
|
||||||
return (0,0,0,0,0)
|
return (0,0,0,0,0)
|
||||||
|
|
||||||
|
def join_holecards(self, player, asList=False):
|
||||||
|
"""With asList = True it returns the set cards for a player including down cards if they aren't know"""
|
||||||
|
# FIXME: This should actually return
|
||||||
|
holecards = [u'0x', u'0x', u'0x', u'0x', u'0x']
|
||||||
|
|
||||||
|
if asList == False:
|
||||||
|
return " ".join(holecards)
|
||||||
|
else:
|
||||||
|
return holecards
|
||||||
|
|
||||||
|
|
||||||
def writeHand(self, fh=sys.__stdout__):
|
def writeHand(self, fh=sys.__stdout__):
|
||||||
# PokerStars format.
|
# PokerStars format.
|
||||||
|
@ -979,18 +1017,19 @@ class DrawHand(Hand):
|
||||||
if 'DEAL' in self.actions:
|
if 'DEAL' in self.actions:
|
||||||
print >>fh, _("*** DEALING HANDS ***")
|
print >>fh, _("*** DEALING HANDS ***")
|
||||||
for player in [x[1] for x in self.players if x[1] in players_who_act_ondeal]:
|
for player in [x[1] for x in self.players if x[1] in players_who_act_ondeal]:
|
||||||
if 'DEAL' in self.holecards[player]:
|
if 'DEAL' in self.holecards:
|
||||||
(nc,oc) = self.holecards[player]['DEAL']
|
if self.holecards['DEAL'].has_key(player):
|
||||||
print >>fh, _("Dealt to %s: [%s]") % (player, " ".join(nc))
|
(nc,oc) = self.holecards['DEAL'][player]
|
||||||
|
print >>fh, _("Dealt to %s: [%s]") % (player, " ".join(nc))
|
||||||
for act in self.actions['DEAL']:
|
for act in self.actions['DEAL']:
|
||||||
print >>fh, self.actionString(act)
|
print >>fh, self.actionString(act, 'DEAL')
|
||||||
|
|
||||||
if 'DRAWONE' in self.actions:
|
if 'DRAWONE' in self.actions:
|
||||||
print >>fh, _("*** FIRST DRAW ***")
|
print >>fh, _("*** FIRST DRAW ***")
|
||||||
for act in self.actions['DRAWONE']:
|
for act in self.actions['DRAWONE']:
|
||||||
print >>fh, self.actionString(act)
|
print >>fh, self.actionString(act, 'DRAWONE')
|
||||||
if act[0] == self.hero and act[1] == 'discards':
|
if act[0] == self.hero and act[1] == 'discards':
|
||||||
(nc,oc) = self.holecards['DRAWONE'][act[0]]
|
(nc,oc) = self.holecardsAsSet('DRAWONE', act[0])
|
||||||
dc = self.discards['DRAWONE'][act[0]]
|
dc = self.discards['DRAWONE'][act[0]]
|
||||||
kc = oc - dc
|
kc = oc - dc
|
||||||
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
||||||
|
@ -998,9 +1037,9 @@ class DrawHand(Hand):
|
||||||
if 'DRAWTWO' in self.actions:
|
if 'DRAWTWO' in self.actions:
|
||||||
print >>fh, _("*** SECOND DRAW ***")
|
print >>fh, _("*** SECOND DRAW ***")
|
||||||
for act in self.actions['DRAWTWO']:
|
for act in self.actions['DRAWTWO']:
|
||||||
print >>fh, self.actionString(act)
|
print >>fh, self.actionString(act, 'DRAWTWO')
|
||||||
if act[0] == self.hero and act[1] == 'discards':
|
if act[0] == self.hero and act[1] == 'discards':
|
||||||
(nc,oc) = self.holecards['DRAWTWO'][act[0]]
|
(nc,oc) = self.holecardsAsSet('DRAWONE', act[0])
|
||||||
dc = self.discards['DRAWTWO'][act[0]]
|
dc = self.discards['DRAWTWO'][act[0]]
|
||||||
kc = oc - dc
|
kc = oc - dc
|
||||||
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
||||||
|
@ -1008,9 +1047,9 @@ class DrawHand(Hand):
|
||||||
if 'DRAWTHREE' in self.actions:
|
if 'DRAWTHREE' in self.actions:
|
||||||
print >>fh, _("*** THIRD DRAW ***")
|
print >>fh, _("*** THIRD DRAW ***")
|
||||||
for act in self.actions['DRAWTHREE']:
|
for act in self.actions['DRAWTHREE']:
|
||||||
print >>fh, self.actionString(act)
|
print >>fh, self.actionString(act, 'DRAWTHREE')
|
||||||
if act[0] == self.hero and act[1] == 'discards':
|
if act[0] == self.hero and act[1] == 'discards':
|
||||||
(nc,oc) = self.holecards['DRAWTHREE'][act[0]]
|
(nc,oc) = self.holecardsAsSet('DRAWONE', act[0])
|
||||||
dc = self.discards['DRAWTHREE'][act[0]]
|
dc = self.discards['DRAWTHREE'][act[0]]
|
||||||
kc = oc - dc
|
kc = oc - dc
|
||||||
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
print >>fh, _("Dealt to %s [%s] [%s]" % (act[0], " ".join(kc), " ".join(nc)))
|
||||||
|
@ -1286,7 +1325,9 @@ Add a complete on [street] by [player] to [amountTo]
|
||||||
if street == 'SEVENTH' and player != self.hero: return # only write 7th st line for hero, LDO
|
if street == 'SEVENTH' and player != self.hero: return # only write 7th st line for hero, LDO
|
||||||
return hc + " ".join(self.holecards[street][player][1]) + "] [" + " ".join(self.holecards[street][player][0]) + "]"
|
return hc + " ".join(self.holecards[street][player][1]) + "] [" + " ".join(self.holecards[street][player][0]) + "]"
|
||||||
|
|
||||||
def join_holecards(self, player):
|
def join_holecards(self, player, asList=False):
|
||||||
|
"""Function returns a string for the stud writeHand method by default
|
||||||
|
With asList = True it returns the set cards for a player including down cards if they aren't know"""
|
||||||
holecards = []
|
holecards = []
|
||||||
for street in self.holeStreets:
|
for street in self.holeStreets:
|
||||||
if self.holecards[street].has_key(player):
|
if self.holecards[street].has_key(player):
|
||||||
|
@ -1299,7 +1340,20 @@ Add a complete on [street] by [player] to [amountTo]
|
||||||
holecards = holecards + self.holecards[street][player][1]
|
holecards = holecards + self.holecards[street][player][1]
|
||||||
else:
|
else:
|
||||||
holecards = holecards + self.holecards[street][player][0]
|
holecards = holecards + self.holecards[street][player][0]
|
||||||
return " ".join(holecards)
|
|
||||||
|
if asList == False:
|
||||||
|
return " ".join(holecards)
|
||||||
|
else:
|
||||||
|
if player == self.hero or len(holecards) == 7:
|
||||||
|
return holecards
|
||||||
|
elif len(holecards) <= 4:
|
||||||
|
#Non hero folded before showdown, add first two downcards
|
||||||
|
holecards = [u'0x', u'0x'] + holecards
|
||||||
|
else:
|
||||||
|
log.warning("join_holecards: # of holecards should be either < 4, 4 or 7 - 5 and 6 should be impossible for anyone who is not a hero")
|
||||||
|
log.warning("join_holcards: holecards(%s): %s" %(player, holecards))
|
||||||
|
return holecards
|
||||||
|
|
||||||
|
|
||||||
class Pot(object):
|
class Pot(object):
|
||||||
|
|
||||||
|
|
|
@ -32,19 +32,12 @@ from xml.dom.minidom import Node
|
||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
from Exceptions import FpdbParseError
|
from Exceptions import FpdbParseError
|
||||||
|
import Configuration
|
||||||
|
|
||||||
import gettext
|
import gettext
|
||||||
gettext.install('fpdb')
|
gettext.install('fpdb')
|
||||||
|
|
||||||
import logging, logging.config
|
log = Configuration.get_logger("logging.conf")
|
||||||
import ConfigParser
|
|
||||||
|
|
||||||
try:
|
|
||||||
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf"))
|
|
||||||
except ConfigParser.NoSectionError: # debian package path
|
|
||||||
logging.config.fileConfig('/usr/share/python-fpdb/logging.conf')
|
|
||||||
|
|
||||||
log = logging.getLogger("parser")
|
|
||||||
|
|
||||||
import pygtk
|
import pygtk
|
||||||
import gtk
|
import gtk
|
||||||
|
@ -101,7 +94,7 @@ follow : whether to tail -f the input"""
|
||||||
else:
|
else:
|
||||||
log.info("Created directory '%s'" % out_dir)
|
log.info("Created directory '%s'" % out_dir)
|
||||||
try:
|
try:
|
||||||
self.out_fh = codecs.open(self.out_path, 'w', 'cp1252')
|
self.out_fh = codecs.open(self.out_path, 'w', 'utf8')
|
||||||
except:
|
except:
|
||||||
log.error("out_path %s couldn't be opened" % (self.out_path))
|
log.error("out_path %s couldn't be opened" % (self.out_path))
|
||||||
else:
|
else:
|
||||||
|
@ -268,8 +261,8 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
|
||||||
gametype = self.determineGameType(handText)
|
gametype = self.determineGameType(handText)
|
||||||
log.debug("gametype %s" % gametype)
|
log.debug("gametype %s" % gametype)
|
||||||
hand = None
|
hand = None
|
||||||
|
l = None
|
||||||
if gametype is None:
|
if gametype is None:
|
||||||
l = None
|
|
||||||
gametype = "unmatched"
|
gametype = "unmatched"
|
||||||
# TODO: not ideal, just trying to not error.
|
# TODO: not ideal, just trying to not error.
|
||||||
# TODO: Need to count failed hands.
|
# TODO: Need to count failed hands.
|
||||||
|
@ -291,10 +284,8 @@ which it expects to find at self.re_TailSplitHands -- see for e.g. Everleaf.py.
|
||||||
log.info("Unsupported game type: %s" % gametype)
|
log.info("Unsupported game type: %s" % gametype)
|
||||||
|
|
||||||
if hand:
|
if hand:
|
||||||
# uncomment these to calculate some stats
|
if Configuration.NEWIMPORT == False:
|
||||||
# print hand
|
hand.writeHand(self.out_fh)
|
||||||
# hand.stats.getStats(hand)
|
|
||||||
hand.writeHand(self.out_fh)
|
|
||||||
return hand
|
return hand
|
||||||
else:
|
else:
|
||||||
log.info("Unsupported game type: %s" % gametype)
|
log.info("Unsupported game type: %s" % gametype)
|
||||||
|
|
266
pyfpdb/Hud.py
266
pyfpdb/Hud.py
|
@ -6,17 +6,17 @@ Create and manage the hud overlays.
|
||||||
"""
|
"""
|
||||||
# Copyright 2008, 2009 Ray E. Barker
|
# Copyright 2008, 2009 Ray E. Barker
|
||||||
|
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
@ -57,7 +57,7 @@ def importName(module_name, name):
|
||||||
return(getattr(module, name))
|
return(getattr(module, name))
|
||||||
|
|
||||||
class Hud:
|
class Hud:
|
||||||
|
|
||||||
def __init__(self, parent, table, max, poker_game, config, db_connection):
|
def __init__(self, parent, table, max, poker_game, config, db_connection):
|
||||||
# __init__ is (now) intended to be called from the stdin thread, so it
|
# __init__ is (now) intended to be called from the stdin thread, so it
|
||||||
# cannot touch the gui
|
# cannot touch the gui
|
||||||
|
@ -74,16 +74,16 @@ class Hud:
|
||||||
self.site = table.site
|
self.site = table.site
|
||||||
self.mw_created = False
|
self.mw_created = False
|
||||||
self.hud_params = parent.hud_params
|
self.hud_params = parent.hud_params
|
||||||
|
|
||||||
|
|
||||||
self.stat_windows = {}
|
self.stat_windows = {}
|
||||||
self.popup_windows = {}
|
self.popup_windows = {}
|
||||||
self.aux_windows = []
|
self.aux_windows = []
|
||||||
|
|
||||||
(font, font_size) = config.get_default_font(self.table.site)
|
(font, font_size) = config.get_default_font(self.table.site)
|
||||||
self.colors = config.get_default_colors(self.table.site)
|
self.colors = config.get_default_colors(self.table.site)
|
||||||
self.hud_ui = config.get_hud_ui_parameters()
|
self.hud_ui = config.get_hud_ui_parameters()
|
||||||
|
|
||||||
self.backgroundcolor = gtk.gdk.color_parse(self.colors['hudbgcolor'])
|
self.backgroundcolor = gtk.gdk.color_parse(self.colors['hudbgcolor'])
|
||||||
self.foregroundcolor = gtk.gdk.color_parse(self.colors['hudfgcolor'])
|
self.foregroundcolor = gtk.gdk.color_parse(self.colors['hudfgcolor'])
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ class Hud:
|
||||||
if my_import == None:
|
if my_import == None:
|
||||||
continue
|
continue
|
||||||
self.aux_windows.append(my_import(self, config, aux_params))
|
self.aux_windows.append(my_import(self, config, aux_params))
|
||||||
|
|
||||||
self.creation_attrs = None
|
self.creation_attrs = None
|
||||||
|
|
||||||
def create_mw(self):
|
def create_mw(self):
|
||||||
|
@ -110,16 +110,16 @@ class Hud:
|
||||||
win.set_skip_taskbar_hint(True)
|
win.set_skip_taskbar_hint(True)
|
||||||
win.set_decorated(False)
|
win.set_decorated(False)
|
||||||
win.set_opacity(self.colors["hudopacity"])
|
win.set_opacity(self.colors["hudopacity"])
|
||||||
|
|
||||||
eventbox = gtk.EventBox()
|
eventbox = gtk.EventBox()
|
||||||
label = gtk.Label(self.hud_ui['label'])
|
label = gtk.Label(self.hud_ui['label'])
|
||||||
|
|
||||||
win.add(eventbox)
|
win.add(eventbox)
|
||||||
eventbox.add(label)
|
eventbox.add(label)
|
||||||
|
|
||||||
label.modify_bg(gtk.STATE_NORMAL, self.backgroundcolor)
|
label.modify_bg(gtk.STATE_NORMAL, self.backgroundcolor)
|
||||||
label.modify_fg(gtk.STATE_NORMAL, self.foregroundcolor)
|
label.modify_fg(gtk.STATE_NORMAL, self.foregroundcolor)
|
||||||
|
|
||||||
eventbox.modify_bg(gtk.STATE_NORMAL, self.backgroundcolor)
|
eventbox.modify_bg(gtk.STATE_NORMAL, self.backgroundcolor)
|
||||||
eventbox.modify_fg(gtk.STATE_NORMAL, self.foregroundcolor)
|
eventbox.modify_fg(gtk.STATE_NORMAL, self.foregroundcolor)
|
||||||
|
|
||||||
|
@ -128,20 +128,20 @@ class Hud:
|
||||||
|
|
||||||
# A popup menu for the main window
|
# A popup menu for the main window
|
||||||
menu = gtk.Menu()
|
menu = gtk.Menu()
|
||||||
|
|
||||||
killitem = gtk.MenuItem('Kill This HUD')
|
killitem = gtk.MenuItem('Kill This HUD')
|
||||||
menu.append(killitem)
|
menu.append(killitem)
|
||||||
if self.parent is not None:
|
if self.parent is not None:
|
||||||
killitem.connect("activate", self.parent.kill_hud, self.table_name)
|
killitem.connect("activate", self.parent.kill_hud, self.table_name)
|
||||||
|
|
||||||
saveitem = gtk.MenuItem('Save HUD Layout')
|
saveitem = gtk.MenuItem('Save HUD Layout')
|
||||||
menu.append(saveitem)
|
menu.append(saveitem)
|
||||||
saveitem.connect("activate", self.save_layout)
|
saveitem.connect("activate", self.save_layout)
|
||||||
|
|
||||||
repositem = gtk.MenuItem('Reposition StatWindows')
|
repositem = gtk.MenuItem('Reposition StatWindows')
|
||||||
menu.append(repositem)
|
menu.append(repositem)
|
||||||
repositem.connect("activate", self.reposition_windows)
|
repositem.connect("activate", self.reposition_windows)
|
||||||
|
|
||||||
aggitem = gtk.MenuItem('Show Player Stats')
|
aggitem = gtk.MenuItem('Show Player Stats')
|
||||||
menu.append(aggitem)
|
menu.append(aggitem)
|
||||||
self.aggMenu = gtk.Menu()
|
self.aggMenu = gtk.Menu()
|
||||||
|
@ -150,49 +150,67 @@ class Hud:
|
||||||
item = gtk.CheckMenuItem('For This Blind Level Only')
|
item = gtk.CheckMenuItem('For This Blind Level Only')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
item.connect("activate", self.set_aggregation, ('P',1))
|
item.connect("activate", self.set_aggregation, ('P',1))
|
||||||
setattr(self, 'h_aggBBmultItem1', item)
|
setattr(self, 'h_aggBBmultItem1', item)
|
||||||
#
|
#
|
||||||
item = gtk.MenuItem('For Multiple Blind Levels:')
|
item = gtk.MenuItem('For Multiple Blind Levels:')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
#
|
#
|
||||||
item = gtk.CheckMenuItem(' 0.5 to 2.0 x Current Blinds')
|
item = gtk.CheckMenuItem(' 0.5 to 2.0 x Current Blinds')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
item.connect("activate", self.set_aggregation, ('P',2))
|
item.connect("activate", self.set_aggregation, ('P',2))
|
||||||
setattr(self, 'h_aggBBmultItem2', item)
|
setattr(self, 'h_aggBBmultItem2', item)
|
||||||
#
|
#
|
||||||
item = gtk.CheckMenuItem(' 0.33 to 3.0 x Current Blinds')
|
item = gtk.CheckMenuItem(' 0.33 to 3.0 x Current Blinds')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
item.connect("activate", self.set_aggregation, ('P',3))
|
item.connect("activate", self.set_aggregation, ('P',3))
|
||||||
setattr(self, 'h_aggBBmultItem3', item)
|
setattr(self, 'h_aggBBmultItem3', item)
|
||||||
#
|
#
|
||||||
item = gtk.CheckMenuItem(' 0.1 to 10 x Current Blinds')
|
item = gtk.CheckMenuItem(' 0.1 to 10 x Current Blinds')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
item.connect("activate", self.set_aggregation, ('P',10))
|
item.connect("activate", self.set_aggregation, ('P',10))
|
||||||
setattr(self, 'h_aggBBmultItem10', item)
|
setattr(self, 'h_aggBBmultItem10', item)
|
||||||
#
|
#
|
||||||
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('Since:')
|
item = gtk.MenuItem('For #Seats:')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
#
|
#
|
||||||
|
item = gtk.CheckMenuItem(' Any Number')
|
||||||
|
self.aggMenu.append(item)
|
||||||
|
item.connect("activate", self.set_seats_style, ('P','A'))
|
||||||
|
setattr(self, 'h_seatsStyleOptionA', item)
|
||||||
|
#
|
||||||
|
item = gtk.CheckMenuItem(' Custom')
|
||||||
|
self.aggMenu.append(item)
|
||||||
|
item.connect("activate", self.set_seats_style, ('P','C'))
|
||||||
|
setattr(self, 'h_seatsStyleOptionC', item)
|
||||||
|
#
|
||||||
|
item = gtk.CheckMenuItem(' Exact')
|
||||||
|
self.aggMenu.append(item)
|
||||||
|
item.connect("activate", self.set_seats_style, ('P','E'))
|
||||||
|
setattr(self, 'h_seatsStyleOptionE', item)
|
||||||
|
#
|
||||||
|
item = gtk.MenuItem('Since:')
|
||||||
|
self.aggMenu.append(item)
|
||||||
|
#
|
||||||
item = gtk.CheckMenuItem(' All Time')
|
item = gtk.CheckMenuItem(' All Time')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
item.connect("activate", self.set_hud_style, ('P','A'))
|
item.connect("activate", self.set_hud_style, ('P','A'))
|
||||||
setattr(self, 'h_hudStyleOptionA', item)
|
setattr(self, 'h_hudStyleOptionA', item)
|
||||||
#
|
#
|
||||||
item = gtk.CheckMenuItem(' Session')
|
item = gtk.CheckMenuItem(' Session')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
item.connect("activate", self.set_hud_style, ('P','S'))
|
item.connect("activate", self.set_hud_style, ('P','S'))
|
||||||
setattr(self, 'h_hudStyleOptionS', item)
|
setattr(self, 'h_hudStyleOptionS', item)
|
||||||
#
|
#
|
||||||
item = gtk.CheckMenuItem(' %s Days' % (self.hud_params['h_hud_days']))
|
item = gtk.CheckMenuItem(' %s Days' % (self.hud_params['h_hud_days']))
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
item.connect("activate", self.set_hud_style, ('P','T'))
|
item.connect("activate", self.set_hud_style, ('P','T'))
|
||||||
setattr(self, 'h_hudStyleOptionT', item)
|
setattr(self, 'h_hudStyleOptionT', item)
|
||||||
|
|
||||||
aggitem = gtk.MenuItem('Show Opponent Stats')
|
aggitem = gtk.MenuItem('Show Opponent Stats')
|
||||||
menu.append(aggitem)
|
menu.append(aggitem)
|
||||||
self.aggMenu = gtk.Menu()
|
self.aggMenu = gtk.Menu()
|
||||||
|
@ -201,48 +219,66 @@ class Hud:
|
||||||
item = gtk.CheckMenuItem('For This Blind Level Only')
|
item = gtk.CheckMenuItem('For This Blind Level Only')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
item.connect("activate", self.set_aggregation, ('O',1))
|
item.connect("activate", self.set_aggregation, ('O',1))
|
||||||
setattr(self, 'aggBBmultItem1', item)
|
setattr(self, 'aggBBmultItem1', item)
|
||||||
#
|
#
|
||||||
item = gtk.MenuItem('For Multiple Blind Levels:')
|
item = gtk.MenuItem('For Multiple Blind Levels:')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
#
|
#
|
||||||
item = gtk.CheckMenuItem(' 0.5 to 2.0 x Current Blinds')
|
item = gtk.CheckMenuItem(' 0.5 to 2.0 x Current Blinds')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
item.connect("activate", self.set_aggregation, ('O',2))
|
item.connect("activate", self.set_aggregation, ('O',2))
|
||||||
setattr(self, 'aggBBmultItem2', item)
|
setattr(self, 'aggBBmultItem2', item)
|
||||||
#
|
#
|
||||||
item = gtk.CheckMenuItem(' 0.33 to 3.0 x Current Blinds')
|
item = gtk.CheckMenuItem(' 0.33 to 3.0 x Current Blinds')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
item.connect("activate", self.set_aggregation, ('O',3))
|
item.connect("activate", self.set_aggregation, ('O',3))
|
||||||
setattr(self, 'aggBBmultItem3', item)
|
setattr(self, 'aggBBmultItem3', item)
|
||||||
#
|
#
|
||||||
item = gtk.CheckMenuItem(' 0.1 to 10 x Current Blinds')
|
item = gtk.CheckMenuItem(' 0.1 to 10 x Current Blinds')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
item.connect("activate", self.set_aggregation, ('O',10))
|
item.connect("activate", self.set_aggregation, ('O',10))
|
||||||
setattr(self, 'aggBBmultItem10', item)
|
setattr(self, 'aggBBmultItem10', item)
|
||||||
#
|
#
|
||||||
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('Since:')
|
item = gtk.MenuItem('For #Seats:')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
#
|
#
|
||||||
|
item = gtk.CheckMenuItem(' Any Number')
|
||||||
|
self.aggMenu.append(item)
|
||||||
|
item.connect("activate", self.set_seats_style, ('O','A'))
|
||||||
|
setattr(self, 'seatsStyleOptionA', item)
|
||||||
|
#
|
||||||
|
item = gtk.CheckMenuItem(' Custom')
|
||||||
|
self.aggMenu.append(item)
|
||||||
|
item.connect("activate", self.set_seats_style, ('O','C'))
|
||||||
|
setattr(self, 'seatsStyleOptionC', item)
|
||||||
|
#
|
||||||
|
item = gtk.CheckMenuItem(' Exact')
|
||||||
|
self.aggMenu.append(item)
|
||||||
|
item.connect("activate", self.set_seats_style, ('O','E'))
|
||||||
|
setattr(self, 'seatsStyleOptionE', item)
|
||||||
|
#
|
||||||
|
item = gtk.MenuItem('Since:')
|
||||||
|
self.aggMenu.append(item)
|
||||||
|
#
|
||||||
item = gtk.CheckMenuItem(' All Time')
|
item = gtk.CheckMenuItem(' All Time')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
item.connect("activate", self.set_hud_style, ('O','A'))
|
item.connect("activate", self.set_hud_style, ('O','A'))
|
||||||
setattr(self, 'hudStyleOptionA', item)
|
setattr(self, 'hudStyleOptionA', item)
|
||||||
#
|
#
|
||||||
item = gtk.CheckMenuItem(' Session')
|
item = gtk.CheckMenuItem(' Session')
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
item.connect("activate", self.set_hud_style, ('O','S'))
|
item.connect("activate", self.set_hud_style, ('O','S'))
|
||||||
setattr(self, 'hudStyleOptionS', item)
|
setattr(self, 'hudStyleOptionS', item)
|
||||||
#
|
#
|
||||||
item = gtk.CheckMenuItem(' %s Days' % (self.hud_params['h_hud_days']))
|
item = gtk.CheckMenuItem(' %s Days' % (self.hud_params['h_hud_days']))
|
||||||
self.aggMenu.append(item)
|
self.aggMenu.append(item)
|
||||||
item.connect("activate", self.set_hud_style, ('O','T'))
|
item.connect("activate", self.set_hud_style, ('O','T'))
|
||||||
setattr(self, 'hudStyleOptionT', item)
|
setattr(self, 'hudStyleOptionT', item)
|
||||||
|
|
||||||
# set active on current options:
|
# set active on current options:
|
||||||
if self.hud_params['h_agg_bb_mult'] == 1:
|
if self.hud_params['h_agg_bb_mult'] == 1:
|
||||||
|
@ -267,6 +303,20 @@ class Hud:
|
||||||
elif self.hud_params['agg_bb_mult'] > 9000:
|
elif self.hud_params['agg_bb_mult'] > 9000:
|
||||||
getattr(self, 'aggBBmultItem10000').set_active(True)
|
getattr(self, 'aggBBmultItem10000').set_active(True)
|
||||||
#
|
#
|
||||||
|
if self.hud_params['h_seats_style'] == 'A':
|
||||||
|
getattr(self, 'h_seatsStyleOptionA').set_active(True)
|
||||||
|
elif self.hud_params['h_seats_style'] == 'C':
|
||||||
|
getattr(self, 'h_seatsStyleOptionC').set_active(True)
|
||||||
|
elif self.hud_params['h_seats_style'] == 'E':
|
||||||
|
getattr(self, 'h_seatsStyleOptionE').set_active(True)
|
||||||
|
#
|
||||||
|
if self.hud_params['seats_style'] == 'A':
|
||||||
|
getattr(self, 'seatsStyleOptionA').set_active(True)
|
||||||
|
elif self.hud_params['seats_style'] == 'C':
|
||||||
|
getattr(self, 'seatsStyleOptionC').set_active(True)
|
||||||
|
elif self.hud_params['seats_style'] == 'E':
|
||||||
|
getattr(self, 'seatsStyleOptionE').set_active(True)
|
||||||
|
#
|
||||||
if self.hud_params['h_hud_style'] == 'A':
|
if self.hud_params['h_hud_style'] == 'A':
|
||||||
getattr(self, 'h_hudStyleOptionA').set_active(True)
|
getattr(self, 'h_hudStyleOptionA').set_active(True)
|
||||||
elif self.hud_params['h_hud_style'] == 'S':
|
elif self.hud_params['h_hud_style'] == 'S':
|
||||||
|
@ -280,13 +330,13 @@ class Hud:
|
||||||
getattr(self, 'hudStyleOptionS').set_active(True)
|
getattr(self, 'hudStyleOptionS').set_active(True)
|
||||||
elif self.hud_params['hud_style'] == 'T':
|
elif self.hud_params['hud_style'] == 'T':
|
||||||
getattr(self, 'hudStyleOptionT').set_active(True)
|
getattr(self, 'hudStyleOptionT').set_active(True)
|
||||||
|
|
||||||
eventbox.connect_object("button-press-event", self.on_button_press, menu)
|
eventbox.connect_object("button-press-event", self.on_button_press, menu)
|
||||||
|
|
||||||
debugitem = gtk.MenuItem('Debug StatWindows')
|
debugitem = gtk.MenuItem('Debug StatWindows')
|
||||||
menu.append(debugitem)
|
menu.append(debugitem)
|
||||||
debugitem.connect("activate", self.debug_stat_windows)
|
debugitem.connect("activate", self.debug_stat_windows)
|
||||||
|
|
||||||
item5 = gtk.MenuItem('Set max seats')
|
item5 = gtk.MenuItem('Set max seats')
|
||||||
menu.append(item5)
|
menu.append(item5)
|
||||||
maxSeatsMenu = gtk.Menu()
|
maxSeatsMenu = gtk.Menu()
|
||||||
|
@ -296,8 +346,8 @@ class Hud:
|
||||||
item.ms = i
|
item.ms = i
|
||||||
maxSeatsMenu.append(item)
|
maxSeatsMenu.append(item)
|
||||||
item.connect("activate", self.change_max_seats)
|
item.connect("activate", self.change_max_seats)
|
||||||
setattr(self, 'maxSeatsMenuItem%d' % (i-1), item)
|
setattr(self, 'maxSeatsMenuItem%d' % (i-1), item)
|
||||||
|
|
||||||
eventbox.connect_object("button-press-event", self.on_button_press, menu)
|
eventbox.connect_object("button-press-event", self.on_button_press, menu)
|
||||||
|
|
||||||
self.mw_created = True
|
self.mw_created = True
|
||||||
|
@ -305,7 +355,7 @@ class Hud:
|
||||||
menu.show_all()
|
menu.show_all()
|
||||||
self.main_window.show_all()
|
self.main_window.show_all()
|
||||||
self.topify_window(self.main_window)
|
self.topify_window(self.main_window)
|
||||||
|
|
||||||
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
|
||||||
|
@ -344,6 +394,29 @@ class Hud:
|
||||||
if mult != str(num):
|
if mult != str(num):
|
||||||
getattr(self, 'aggBBmultItem'+mult).set_active(False)
|
getattr(self, 'aggBBmultItem'+mult).set_active(False)
|
||||||
|
|
||||||
|
def set_seats_style(self, widget, val):
|
||||||
|
(player_opp, style) = val
|
||||||
|
if player_opp == 'P':
|
||||||
|
param = 'h_seats_style'
|
||||||
|
prefix = 'h_'
|
||||||
|
else:
|
||||||
|
param = 'seats_style'
|
||||||
|
prefix = ''
|
||||||
|
|
||||||
|
if style == 'A' and getattr(self, prefix+'seatsStyleOptionA').get_active():
|
||||||
|
self.hud_params[param] = 'A'
|
||||||
|
getattr(self, prefix+'seatsStyleOptionC').set_active(False)
|
||||||
|
getattr(self, prefix+'seatsStyleOptionE').set_active(False)
|
||||||
|
elif style == 'C' and getattr(self, prefix+'seatsStyleOptionC').get_active():
|
||||||
|
self.hud_params[param] = 'C'
|
||||||
|
getattr(self, prefix+'seatsStyleOptionA').set_active(False)
|
||||||
|
getattr(self, prefix+'seatsStyleOptionE').set_active(False)
|
||||||
|
elif style == 'E' and getattr(self, prefix+'seatsStyleOptionE').get_active():
|
||||||
|
self.hud_params[param] = 'E'
|
||||||
|
getattr(self, prefix+'seatsStyleOptionA').set_active(False)
|
||||||
|
getattr(self, prefix+'seatsStyleOptionC').set_active(False)
|
||||||
|
print "setting self.hud_params[%s] = %s" % (param, style)
|
||||||
|
|
||||||
def set_hud_style(self, widget, val):
|
def set_hud_style(self, widget, val):
|
||||||
(player_opp, style) = val
|
(player_opp, style) = val
|
||||||
if player_opp == 'P':
|
if player_opp == 'P':
|
||||||
|
@ -352,7 +425,7 @@ class Hud:
|
||||||
else:
|
else:
|
||||||
param = 'hud_style'
|
param = 'hud_style'
|
||||||
prefix = ''
|
prefix = ''
|
||||||
|
|
||||||
if style == 'A' and getattr(self, prefix+'hudStyleOptionA').get_active():
|
if style == 'A' and getattr(self, prefix+'hudStyleOptionA').get_active():
|
||||||
self.hud_params[param] = 'A'
|
self.hud_params[param] = 'A'
|
||||||
getattr(self, prefix+'hudStyleOptionS').set_active(False)
|
getattr(self, prefix+'hudStyleOptionS').set_active(False)
|
||||||
|
@ -409,7 +482,7 @@ class Hud:
|
||||||
try:
|
try:
|
||||||
# throws "invalid window handle" in WinXP (sometimes?)
|
# throws "invalid window handle" in WinXP (sometimes?)
|
||||||
s.window.destroy()
|
s.window.destroy()
|
||||||
except:
|
except: # TODO: what exception?
|
||||||
pass
|
pass
|
||||||
self.stat_windows = {}
|
self.stat_windows = {}
|
||||||
# also kill any aux windows
|
# also kill any aux windows
|
||||||
|
@ -431,7 +504,7 @@ class Hud:
|
||||||
# print self.table, "\n", self.main_window.window.get_transient_for()
|
# print self.table, "\n", self.main_window.window.get_transient_for()
|
||||||
for w in self.stat_windows:
|
for w in self.stat_windows:
|
||||||
print self.stat_windows[w].window.window.get_transient_for()
|
print self.stat_windows[w].window.window.get_transient_for()
|
||||||
|
|
||||||
def save_layout(self, *args):
|
def save_layout(self, *args):
|
||||||
new_layout = [(0, 0)] * self.max
|
new_layout = [(0, 0)] * self.max
|
||||||
for sw in self.stat_windows:
|
for sw in self.stat_windows:
|
||||||
|
@ -447,7 +520,7 @@ class Hud:
|
||||||
|
|
||||||
def adj_seats(self, hand, config):
|
def adj_seats(self, hand, config):
|
||||||
|
|
||||||
# Need range here, not xrange -> need the actual list
|
# Need range here, not xrange -> need the actual list
|
||||||
adj = range(0, self.max + 1) # default seat adjustments = no adjustment
|
adj = range(0, self.max + 1) # default seat adjustments = no adjustment
|
||||||
# does the user have a fav_seat?
|
# does the user have a fav_seat?
|
||||||
if self.max not in config.supported_sites[self.table.site].layout:
|
if self.max not in config.supported_sites[self.table.site].layout:
|
||||||
|
@ -481,12 +554,12 @@ class Hud:
|
||||||
#
|
#
|
||||||
# this method also manages the creating and destruction of stat
|
# this method also manages the creating and destruction of stat
|
||||||
# windows via calls to the Stat_Window class
|
# windows via calls to the Stat_Window class
|
||||||
self.creation_attrs = hand, config, stat_dict, cards
|
self.creation_attrs = hand, config, stat_dict, cards
|
||||||
|
|
||||||
self.hand = hand
|
self.hand = hand
|
||||||
if not self.mw_created:
|
if not self.mw_created:
|
||||||
self.create_mw()
|
self.create_mw()
|
||||||
|
|
||||||
self.stat_dict = stat_dict
|
self.stat_dict = stat_dict
|
||||||
self.cards = cards
|
self.cards = cards
|
||||||
sys.stderr.write("------------------------------------------------------------\nCreating hud from hand %s\n" % hand)
|
sys.stderr.write("------------------------------------------------------------\nCreating hud from hand %s\n" % hand)
|
||||||
|
@ -498,24 +571,24 @@ class Hud:
|
||||||
loc = self.config.get_locations(self.table.site, 9)
|
loc = self.config.get_locations(self.table.site, 9)
|
||||||
|
|
||||||
# create the stat windows
|
# create the stat windows
|
||||||
for i in xrange(1, self.max + 1):
|
for i in xrange(1, self.max + 1):
|
||||||
(x, y) = loc[adj[i]]
|
(x, y) = loc[adj[i]]
|
||||||
if i in self.stat_windows:
|
if i in self.stat_windows:
|
||||||
self.stat_windows[i].relocate(x, y)
|
self.stat_windows[i].relocate(x, y)
|
||||||
else:
|
else:
|
||||||
self.stat_windows[i] = Stat_Window(game = config.supported_games[self.poker_game],
|
self.stat_windows[i] = Stat_Window(game = config.supported_games[self.poker_game],
|
||||||
parent = self,
|
parent = self,
|
||||||
table = self.table,
|
table = self.table,
|
||||||
x = x,
|
x = x,
|
||||||
y = y,
|
y = y,
|
||||||
seat = i,
|
seat = i,
|
||||||
adj = adj[i],
|
adj = adj[i],
|
||||||
player_id = 'fake',
|
player_id = 'fake',
|
||||||
font = self.font)
|
font = self.font)
|
||||||
|
|
||||||
self.stats = []
|
self.stats = []
|
||||||
game = config.supported_games[self.poker_game]
|
game = config.supported_games[self.poker_game]
|
||||||
|
|
||||||
for i in xrange(0, game.rows + 1):
|
for i in xrange(0, game.rows + 1):
|
||||||
row_list = [''] * game.cols
|
row_list = [''] * game.cols
|
||||||
self.stats.append(row_list)
|
self.stats.append(row_list)
|
||||||
|
@ -523,14 +596,15 @@ class Hud:
|
||||||
self.stats[config.supported_games[self.poker_game].stats[stat].row] \
|
self.stats[config.supported_games[self.poker_game].stats[stat].row] \
|
||||||
[config.supported_games[self.poker_game].stats[stat].col] = \
|
[config.supported_games[self.poker_game].stats[stat].col] = \
|
||||||
config.supported_games[self.poker_game].stats[stat].stat_name
|
config.supported_games[self.poker_game].stats[stat].stat_name
|
||||||
|
|
||||||
if os.name == "nt":
|
if os.name == "nt":
|
||||||
gobject.timeout_add(500, self.update_table_position)
|
gobject.timeout_add(500, self.update_table_position)
|
||||||
|
|
||||||
def update(self, hand, config):
|
def update(self, hand, config):
|
||||||
self.hand = hand # this is the last hand, so it is available later
|
self.hand = hand # this is the last hand, so it is available later
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
self.update_table_position()
|
if self.update_table_position() == False: # we got killed by finding our table was gone
|
||||||
|
return
|
||||||
|
|
||||||
for s in self.stat_dict:
|
for s in self.stat_dict:
|
||||||
try:
|
try:
|
||||||
|
@ -546,18 +620,18 @@ class Hud:
|
||||||
self.max = 10
|
self.max = 10
|
||||||
self.create(hand, config, self.stat_dict, self.cards)
|
self.create(hand, config, self.stat_dict, self.cards)
|
||||||
self.stat_windows[statd['seat']].player_id = statd['player_id']
|
self.stat_windows[statd['seat']].player_id = statd['player_id']
|
||||||
|
|
||||||
for r in xrange(0, config.supported_games[self.poker_game].rows):
|
for r in xrange(0, config.supported_games[self.poker_game].rows):
|
||||||
for c in xrange(0, config.supported_games[self.poker_game].cols):
|
for c in xrange(0, config.supported_games[self.poker_game].cols):
|
||||||
this_stat = config.supported_games[self.poker_game].stats[self.stats[r][c]]
|
this_stat = config.supported_games[self.poker_game].stats[self.stats[r][c]]
|
||||||
number = Stats.do_stat(self.stat_dict, player = statd['player_id'], stat = self.stats[r][c])
|
number = Stats.do_stat(self.stat_dict, player = statd['player_id'], stat = self.stats[r][c])
|
||||||
statstring = "%s%s%s" % (this_stat.hudprefix, str(number[1]), this_stat.hudsuffix)
|
statstring = "%s%s%s" % (this_stat.hudprefix, str(number[1]), this_stat.hudsuffix)
|
||||||
window = self.stat_windows[statd['seat']]
|
window = self.stat_windows[statd['seat']]
|
||||||
|
|
||||||
if this_stat.hudcolor != "":
|
if this_stat.hudcolor != "":
|
||||||
self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor']))
|
self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.colors['hudfgcolor']))
|
||||||
window.label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(this_stat.hudcolor))
|
window.label[r][c].modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(this_stat.hudcolor))
|
||||||
|
|
||||||
window.label[r][c].set_text(statstring)
|
window.label[r][c].set_text(statstring)
|
||||||
if statstring != "xxx": # is there a way to tell if this particular stat window is visible already, or no?
|
if statstring != "xxx": # is there a way to tell if this particular stat window is visible already, or no?
|
||||||
window.window.show_all()
|
window.window.show_all()
|
||||||
|
@ -567,7 +641,7 @@ class Hud:
|
||||||
def topify_window(self, window):
|
def topify_window(self, window):
|
||||||
window.set_focus_on_map(False)
|
window.set_focus_on_map(False)
|
||||||
window.set_accept_focus(False)
|
window.set_accept_focus(False)
|
||||||
|
|
||||||
if not self.table.gdkhandle:
|
if not self.table.gdkhandle:
|
||||||
self.table.gdkhandle = gtk.gdk.window_foreign_new(int(self.table.number)) # gtk handle to poker window
|
self.table.gdkhandle = gtk.gdk.window_foreign_new(int(self.table.number)) # gtk handle to poker window
|
||||||
window.window.set_transient_for(self.table.gdkhandle)
|
window.window.set_transient_for(self.table.gdkhandle)
|
||||||
|
@ -575,7 +649,7 @@ class Hud:
|
||||||
class Stat_Window:
|
class Stat_Window:
|
||||||
|
|
||||||
def button_press_cb(self, widget, event, *args):
|
def button_press_cb(self, widget, event, *args):
|
||||||
# This handles all callbacks from button presses on the event boxes in
|
# This handles all callbacks from button presses on the event boxes in
|
||||||
# the stat windows. There is a bit of an ugly kludge to separate single-
|
# the stat windows. There is a bit of an ugly kludge to separate single-
|
||||||
# and double-clicks.
|
# and double-clicks.
|
||||||
self.window.show_all()
|
self.window.show_all()
|
||||||
|
@ -599,15 +673,15 @@ class Stat_Window:
|
||||||
self.window.begin_move_drag(event.button, int(event.x_root), int(event.y_root), event.time)
|
self.window.begin_move_drag(event.button, int(event.x_root), int(event.y_root), event.time)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def noop(self, arga=None, argb=None): # i'm going to try to connect the focus-in and focus-out events here, to see if that fixes any of the focus problems.
|
def noop(self, arga=None, argb=None): # i'm going to try to connect the focus-in and focus-out events here, to see if that fixes any of the focus problems.
|
||||||
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()
|
||||||
|
|
||||||
def kill_popups(self):
|
def kill_popups(self):
|
||||||
map(lambda x: x.window.destroy(), self.popups)
|
map(lambda x: x.window.destroy(), self.popups)
|
||||||
self.popups = { }
|
self.popups = { }
|
||||||
|
@ -639,10 +713,10 @@ class Stat_Window:
|
||||||
self.window.set_focus_on_map(False)
|
self.window.set_focus_on_map(False)
|
||||||
|
|
||||||
grid = gtk.Table(rows = game.rows, columns = game.cols, homogeneous = False)
|
grid = gtk.Table(rows = game.rows, columns = game.cols, homogeneous = False)
|
||||||
self.grid = grid
|
self.grid = grid
|
||||||
self.window.add(grid)
|
self.window.add(grid)
|
||||||
self.window.modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
self.window.modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
||||||
|
|
||||||
self.e_box = []
|
self.e_box = []
|
||||||
self.frame = []
|
self.frame = []
|
||||||
self.label = []
|
self.label = []
|
||||||
|
@ -658,10 +732,10 @@ class Stat_Window:
|
||||||
if usegtkframes:
|
if usegtkframes:
|
||||||
self.frame[r].append( gtk.Frame() )
|
self.frame[r].append( gtk.Frame() )
|
||||||
e_box[r].append( gtk.EventBox() )
|
e_box[r].append( gtk.EventBox() )
|
||||||
|
|
||||||
e_box[r][c].modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
e_box[r][c].modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
||||||
e_box[r][c].modify_fg(gtk.STATE_NORMAL, parent.foregroundcolor)
|
e_box[r][c].modify_fg(gtk.STATE_NORMAL, parent.foregroundcolor)
|
||||||
|
|
||||||
Stats.do_tip(e_box[r][c], 'stuff')
|
Stats.do_tip(e_box[r][c], 'stuff')
|
||||||
if usegtkframes:
|
if usegtkframes:
|
||||||
grid.attach(self.frame[r][c], c, c+1, r, r+1, xpadding = game.xpad, ypadding = game.ypad)
|
grid.attach(self.frame[r][c], c, c+1, r, r+1, xpadding = game.xpad, ypadding = game.ypad)
|
||||||
|
@ -669,7 +743,7 @@ class Stat_Window:
|
||||||
else:
|
else:
|
||||||
grid.attach(e_box[r][c], c, c+1, r, r+1, xpadding = game.xpad, ypadding = game.ypad)
|
grid.attach(e_box[r][c], c, c+1, r, r+1, xpadding = game.xpad, ypadding = game.ypad)
|
||||||
label[r].append( gtk.Label('xxx') )
|
label[r].append( gtk.Label('xxx') )
|
||||||
|
|
||||||
if usegtkframes:
|
if usegtkframes:
|
||||||
self.frame[r][c].modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
self.frame[r][c].modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
||||||
label[r][c].modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
label[r][c].modify_bg(gtk.STATE_NORMAL, parent.backgroundcolor)
|
||||||
|
@ -690,17 +764,17 @@ class Stat_Window:
|
||||||
self.window.set_focus_on_map(False)
|
self.window.set_focus_on_map(False)
|
||||||
self.window.set_accept_focus(False)
|
self.window.set_accept_focus(False)
|
||||||
|
|
||||||
|
|
||||||
self.window.move(self.x, self.y)
|
self.window.move(self.x, self.y)
|
||||||
self.window.realize() # window must be realized before it has a gdkwindow so we can attach it to the table window..
|
self.window.realize() # window must be realized before it has a gdkwindow so we can attach it to the table window..
|
||||||
self.topify_window(self.window)
|
self.topify_window(self.window)
|
||||||
|
|
||||||
self.window.hide()
|
self.window.hide()
|
||||||
|
|
||||||
def topify_window(self, window):
|
def topify_window(self, window):
|
||||||
window.set_focus_on_map(False)
|
window.set_focus_on_map(False)
|
||||||
window.set_accept_focus(False)
|
window.set_accept_focus(False)
|
||||||
|
|
||||||
if not self.table.gdkhandle:
|
if not self.table.gdkhandle:
|
||||||
self.table.gdkhandle = gtk.gdk.window_foreign_new(int(self.table.number)) # gtk handle to poker window
|
self.table.gdkhandle = gtk.gdk.window_foreign_new(int(self.table.number)) # gtk handle to poker window
|
||||||
# window.window.reparent(self.table.gdkhandle, 0, 0)
|
# window.window.reparent(self.table.gdkhandle, 0, 0)
|
||||||
|
@ -723,11 +797,11 @@ class Popup_window:
|
||||||
self.window.set_title("popup")
|
self.window.set_title("popup")
|
||||||
self.window.set_property("skip-taskbar-hint", True)
|
self.window.set_property("skip-taskbar-hint", True)
|
||||||
self.window.set_focus_on_map(False)
|
self.window.set_focus_on_map(False)
|
||||||
self.window.set_accept_focus(False)
|
self.window.set_accept_focus(False)
|
||||||
self.window.set_transient_for(parent.get_toplevel())
|
self.window.set_transient_for(parent.get_toplevel())
|
||||||
|
|
||||||
self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
|
self.window.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
|
||||||
|
|
||||||
self.ebox = gtk.EventBox()
|
self.ebox = gtk.EventBox()
|
||||||
self.ebox.connect("button_press_event", self.button_press_cb)
|
self.ebox.connect("button_press_event", self.button_press_cb)
|
||||||
self.lab = gtk.Label("stuff\nstuff\nstuff")
|
self.lab = gtk.Label("stuff\nstuff\nstuff")
|
||||||
|
@ -735,14 +809,14 @@ class Popup_window:
|
||||||
# need an event box so we can respond to clicks
|
# need an event box so we can respond to clicks
|
||||||
self.window.add(self.ebox)
|
self.window.add(self.ebox)
|
||||||
self.ebox.add(self.lab)
|
self.ebox.add(self.lab)
|
||||||
|
|
||||||
self.ebox.modify_bg(gtk.STATE_NORMAL, stat_window.parent.backgroundcolor)
|
self.ebox.modify_bg(gtk.STATE_NORMAL, stat_window.parent.backgroundcolor)
|
||||||
self.ebox.modify_fg(gtk.STATE_NORMAL, stat_window.parent.foregroundcolor)
|
self.ebox.modify_fg(gtk.STATE_NORMAL, stat_window.parent.foregroundcolor)
|
||||||
self.window.modify_bg(gtk.STATE_NORMAL, stat_window.parent.backgroundcolor)
|
self.window.modify_bg(gtk.STATE_NORMAL, stat_window.parent.backgroundcolor)
|
||||||
self.window.modify_fg(gtk.STATE_NORMAL, stat_window.parent.foregroundcolor)
|
self.window.modify_fg(gtk.STATE_NORMAL, stat_window.parent.foregroundcolor)
|
||||||
self.lab.modify_bg(gtk.STATE_NORMAL, stat_window.parent.backgroundcolor)
|
self.lab.modify_bg(gtk.STATE_NORMAL, stat_window.parent.backgroundcolor)
|
||||||
self.lab.modify_fg(gtk.STATE_NORMAL, stat_window.parent.foregroundcolor)
|
self.lab.modify_fg(gtk.STATE_NORMAL, stat_window.parent.foregroundcolor)
|
||||||
|
|
||||||
# figure out the row, col address of the click that activated the popup
|
# figure out the row, col address of the click that activated the popup
|
||||||
row = 0
|
row = 0
|
||||||
col = 0
|
col = 0
|
||||||
|
@ -769,7 +843,7 @@ class Popup_window:
|
||||||
|
|
||||||
# get a database connection
|
# get a database connection
|
||||||
# db_connection = Database.Database(stat_window.parent.config, stat_window.parent.db_name, 'temp')
|
# db_connection = Database.Database(stat_window.parent.config, stat_window.parent.db_name, 'temp')
|
||||||
|
|
||||||
# calculate the stat_dict and then create the text for the pu
|
# calculate the stat_dict and then create the text for the pu
|
||||||
# stat_dict = db_connection.get_stats_from_hand(stat_window.parent.hand, stat_window.player_id)
|
# stat_dict = db_connection.get_stats_from_hand(stat_window.parent.hand, stat_window.player_id)
|
||||||
# stat_dict = self.db_connection.get_stats_from_hand(stat_window.parent.hand)
|
# stat_dict = self.db_connection.get_stats_from_hand(stat_window.parent.hand)
|
||||||
|
@ -781,16 +855,16 @@ class Popup_window:
|
||||||
number = Stats.do_stat(stat_dict, player = int(stat_window.player_id), stat = s)
|
number = Stats.do_stat(stat_dict, player = int(stat_window.player_id), stat = s)
|
||||||
mo_text += number[5] + " " + number[4] + "\n"
|
mo_text += number[5] + " " + number[4] + "\n"
|
||||||
pu_text += number[3] + "\n"
|
pu_text += number[3] + "\n"
|
||||||
|
|
||||||
|
|
||||||
self.lab.set_text(pu_text)
|
self.lab.set_text(pu_text)
|
||||||
Stats.do_tip(self.lab, mo_text)
|
Stats.do_tip(self.lab, mo_text)
|
||||||
self.window.show_all()
|
self.window.show_all()
|
||||||
|
|
||||||
self.window.set_transient_for(stat_window.window)
|
self.window.set_transient_for(stat_window.window)
|
||||||
|
|
||||||
def button_press_cb(self, widget, event, *args):
|
def button_press_cb(self, widget, event, *args):
|
||||||
# This handles all callbacks from button presses on the event boxes in
|
# This handles all callbacks from button presses on the event boxes in
|
||||||
# the popup windows. There is a bit of an ugly kludge to separate single-
|
# the popup windows. There is a bit of an ugly kludge to separate single-
|
||||||
# and double-clicks. This is the same code as in the Stat_window class
|
# and double-clicks. This is the same code as in the Stat_window class
|
||||||
if event.button == 1: # left button event
|
if event.button == 1: # left button event
|
||||||
|
@ -808,7 +882,7 @@ class Popup_window:
|
||||||
def toggle_decorated(self, widget):
|
def toggle_decorated(self, widget):
|
||||||
top = widget.get_toplevel()
|
top = widget.get_toplevel()
|
||||||
(x, y) = top.get_position()
|
(x, y) = top.get_position()
|
||||||
|
|
||||||
if top.get_decorated():
|
if top.get_decorated():
|
||||||
top.set_decorated(0)
|
top.set_decorated(0)
|
||||||
top.move(x, y)
|
top.move(x, y)
|
||||||
|
@ -819,7 +893,7 @@ class Popup_window:
|
||||||
def topify_window(self, window):
|
def topify_window(self, window):
|
||||||
window.set_focus_on_map(False)
|
window.set_focus_on_map(False)
|
||||||
window.set_accept_focus(False)
|
window.set_accept_focus(False)
|
||||||
|
|
||||||
if not self.table.gdkhandle:
|
if not self.table.gdkhandle:
|
||||||
self.table.gdkhandle = gtk.gdk.window_foreign_new(int(self.table.number)) # gtk handle to poker window
|
self.table.gdkhandle = gtk.gdk.window_foreign_new(int(self.table.number)) # gtk handle to poker window
|
||||||
# window.window.reparent(self.table.gdkhandle, 0, 0)
|
# window.window.reparent(self.table.gdkhandle, 0, 0)
|
||||||
|
@ -833,14 +907,14 @@ if __name__== "__main__":
|
||||||
label = gtk.Label('Fake main window, blah blah, blah\nblah, blah')
|
label = gtk.Label('Fake main window, blah blah, blah\nblah, blah')
|
||||||
main_window.add(label)
|
main_window.add(label)
|
||||||
main_window.show_all()
|
main_window.show_all()
|
||||||
|
|
||||||
c = Configuration.Config()
|
c = Configuration.Config()
|
||||||
#tables = Tables.discover(c)
|
#tables = Tables.discover(c)
|
||||||
t = Tables.discover_table_by_name(c, "Corona")
|
t = Tables.discover_table_by_name(c, "Corona")
|
||||||
if t is None:
|
if t is None:
|
||||||
print "Table not found."
|
print "Table not found."
|
||||||
db = Database.Database(c, 'fpdb', 'holdem')
|
db = Database.Database(c, 'fpdb', 'holdem')
|
||||||
|
|
||||||
stat_dict = db.get_stats_from_hand(1)
|
stat_dict = db.get_stats_from_hand(1)
|
||||||
|
|
||||||
# for t in tables:
|
# for t in tables:
|
||||||
|
|
|
@ -23,26 +23,29 @@ def fpdb_options():
|
||||||
|
|
||||||
"""Process command line options for fpdb and HUD_main."""
|
"""Process command line options for fpdb and HUD_main."""
|
||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
parser.add_option("-x", "--errorsToConsole",
|
parser.add_option("-x", "--errorsToConsole",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="If passed error output will go to the console rather than .")
|
help="If passed error output will go to the console rather than .")
|
||||||
parser.add_option("-d", "--databaseName",
|
parser.add_option("-d", "--databaseName",
|
||||||
dest="dbname", default="fpdb",
|
dest="dbname", default="fpdb",
|
||||||
help="Overrides the default database name")
|
help="Overrides the default database name")
|
||||||
parser.add_option("-c", "--configFile",
|
parser.add_option("-c", "--configFile",
|
||||||
dest="config", default=None,
|
dest="config", default=None,
|
||||||
help="Specifies a configuration file.")
|
help="Specifies a configuration file.")
|
||||||
parser.add_option("-r", "--rerunPython",
|
parser.add_option("-r", "--rerunPython",
|
||||||
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).")
|
||||||
(options, sys.argv) = parser.parse_args()
|
parser.add_option("-i", "--infile",
|
||||||
return (options, sys.argv)
|
dest="config", default=None,
|
||||||
|
help="Input file")
|
||||||
|
(options, argv) = parser.parse_args()
|
||||||
|
return (options, argv)
|
||||||
|
|
||||||
if __name__== "__main__":
|
if __name__== "__main__":
|
||||||
(options, sys.argv) = fpdb_options()
|
(options, argv) = fpdb_options()
|
||||||
print "errorsToConsole =", options.errorsToConsole
|
print "errorsToConsole =", options.errorsToConsole
|
||||||
print "database name =", options.dbname
|
print "database name =", options.dbname
|
||||||
print "config file =", options.config
|
print "config file =", options.config
|
||||||
|
|
||||||
print "press enter to end"
|
print "press enter to end"
|
||||||
sys.stdin.readline()
|
sys.stdin.readline()
|
||||||
|
|
|
@ -31,18 +31,18 @@ class PokerStars(HandHistoryConverter):
|
||||||
|
|
||||||
sitename = "PokerStars"
|
sitename = "PokerStars"
|
||||||
filetype = "text"
|
filetype = "text"
|
||||||
codepage = "cp1252"
|
codepage = ("utf8", "cp1252")
|
||||||
siteId = 2 # Needs to match id entry in Sites database
|
siteId = 2 # Needs to match id entry in Sites database
|
||||||
|
|
||||||
mixes = { 'HORSE': 'horse', '8-Game': '8game', 'HOSE': 'hose'} # Legal mixed games
|
mixes = { 'HORSE': 'horse', '8-Game': '8game', 'HOSE': 'hose'} # Legal mixed games
|
||||||
sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\x80", "GBP": "\xa3"} # ADD Euro, Sterling, etc HERE
|
sym = {'USD': "\$", 'CAD': "\$", 'T$': "", "EUR": "\xe2\x82\xac", "GBP": "\xa3"} # ADD Euro, Sterling, etc HERE
|
||||||
substitutions = {
|
substitutions = {
|
||||||
'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes
|
'LEGAL_ISO' : "USD|EUR|GBP|CAD|FPP", # legal ISO currency codes
|
||||||
'LS' : "\$|\x80|\xa3" # legal currency symbols ADD Euro, Sterling, etc HERE
|
'LS' : "\$|\xe2\x82\xac|" # legal currency symbols - Euro(cp1252, utf-8)
|
||||||
}
|
}
|
||||||
|
|
||||||
# Static regexes
|
# Static regexes
|
||||||
re_GameInfo = re.compile("""
|
re_GameInfo = re.compile(u"""
|
||||||
PokerStars\sGame\s\#(?P<HID>[0-9]+):\s+
|
PokerStars\sGame\s\#(?P<HID>[0-9]+):\s+
|
||||||
(Tournament\s\# # open paren of tournament info
|
(Tournament\s\# # open paren of tournament info
|
||||||
(?P<TOURNO>\d+),\s
|
(?P<TOURNO>\d+),\s
|
||||||
|
@ -50,7 +50,7 @@ class PokerStars(HandHistoryConverter):
|
||||||
\s?(?P<TOUR_ISO>%(LEGAL_ISO)s)?
|
\s?(?P<TOUR_ISO>%(LEGAL_ISO)s)?
|
||||||
)\s)? # close paren of tournament info
|
)\s)? # close paren of tournament info
|
||||||
(?P<MIXED>HORSE|8\-Game|HOSE)?\s?\(?
|
(?P<MIXED>HORSE|8\-Game|HOSE)?\s?\(?
|
||||||
(?P<GAME>Hold\'em|Razz|7\sCard\sStud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball)\s
|
(?P<GAME>Hold\'em|Razz|7\sCard\sStud|7\sCard\sStud\sHi/Lo|Omaha|Omaha\sHi/Lo|Badugi|Triple\sDraw\s2\-7\sLowball|5\sCard\sDraw)\s
|
||||||
(?P<LIMIT>No\sLimit|Limit|Pot\sLimit)\)?,?\s
|
(?P<LIMIT>No\sLimit|Limit|Pot\sLimit)\)?,?\s
|
||||||
(-\sLevel\s(?P<LEVEL>[IVXLC]+)\s)?
|
(-\sLevel\s(?P<LEVEL>[IVXLC]+)\s)?
|
||||||
\(? # open paren of the stakes
|
\(? # open paren of the stakes
|
||||||
|
@ -62,7 +62,7 @@ class PokerStars(HandHistoryConverter):
|
||||||
(?P<DATETIME>.*$)""" % substitutions,
|
(?P<DATETIME>.*$)""" % substitutions,
|
||||||
re.MULTILINE|re.VERBOSE)
|
re.MULTILINE|re.VERBOSE)
|
||||||
|
|
||||||
re_PlayerInfo = re.compile("""
|
re_PlayerInfo = re.compile(u"""
|
||||||
^Seat\s(?P<SEAT>[0-9]+):\s
|
^Seat\s(?P<SEAT>[0-9]+):\s
|
||||||
(?P<PNAME>.*)\s
|
(?P<PNAME>.*)\s
|
||||||
\((%(LS)s)?(?P<CASH>[.0-9]+)\sin\schips\)""" % substitutions,
|
\((%(LS)s)?(?P<CASH>[.0-9]+)\sin\schips\)""" % substitutions,
|
||||||
|
@ -92,7 +92,7 @@ class PokerStars(HandHistoryConverter):
|
||||||
self.compiledPlayers = players
|
self.compiledPlayers = players
|
||||||
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
|
player_re = "(?P<PNAME>" + "|".join(map(re.escape, players)) + ")"
|
||||||
subst = {'PLYR': player_re, 'CUR': self.sym[hand.gametype['currency']]}
|
subst = {'PLYR': player_re, 'CUR': self.sym[hand.gametype['currency']]}
|
||||||
logging.debug("player_re: " + player_re)
|
log.debug("player_re: " + player_re)
|
||||||
self.re_PostSB = re.compile(r"^%(PLYR)s: posts small blind %(CUR)s(?P<SB>[.0-9]+)" % subst, re.MULTILINE)
|
self.re_PostSB = re.compile(r"^%(PLYR)s: posts small blind %(CUR)s(?P<SB>[.0-9]+)" % subst, re.MULTILINE)
|
||||||
self.re_PostBB = re.compile(r"^%(PLYR)s: posts big blind %(CUR)s(?P<BB>[.0-9]+)" % subst, re.MULTILINE)
|
self.re_PostBB = re.compile(r"^%(PLYR)s: posts big blind %(CUR)s(?P<BB>[.0-9]+)" % subst, re.MULTILINE)
|
||||||
self.re_Antes = re.compile(r"^%(PLYR)s: posts the ante %(CUR)s(?P<ANTE>[.0-9]+)" % subst, re.MULTILINE)
|
self.re_Antes = re.compile(r"^%(PLYR)s: posts the ante %(CUR)s(?P<ANTE>[.0-9]+)" % subst, re.MULTILINE)
|
||||||
|
@ -101,7 +101,7 @@ class PokerStars(HandHistoryConverter):
|
||||||
self.re_HeroCards = re.compile(r"^Dealt to %(PLYR)s(?: \[(?P<OLDCARDS>.+?)\])?( \[(?P<NEWCARDS>.+?)\])" % subst, re.MULTILINE)
|
self.re_HeroCards = re.compile(r"^Dealt to %(PLYR)s(?: \[(?P<OLDCARDS>.+?)\])?( \[(?P<NEWCARDS>.+?)\])" % subst, re.MULTILINE)
|
||||||
self.re_Action = re.compile(r"""
|
self.re_Action = re.compile(r"""
|
||||||
^%(PLYR)s:(?P<ATYPE>\sbets|\schecks|\sraises|\scalls|\sfolds|\sdiscards|\sstands\spat)
|
^%(PLYR)s:(?P<ATYPE>\sbets|\schecks|\sraises|\scalls|\sfolds|\sdiscards|\sstands\spat)
|
||||||
(\s%(CUR)s(?P<BET>[.\d]+))?(\sto\s%(CUR)s(?P<BETTO>[.\d]+))? # the number discarded goes in <BET>
|
(\s(%(CUR)s)?(?P<BET>[.\d]+))?(\sto\s%(CUR)s(?P<BETTO>[.\d]+))? # the number discarded goes in <BET>
|
||||||
(\scards?(\s\[(?P<DISCARDED>.+?)\])?)?"""
|
(\scards?(\s\[(?P<DISCARDED>.+?)\])?)?"""
|
||||||
% subst, re.MULTILINE|re.VERBOSE)
|
% subst, re.MULTILINE|re.VERBOSE)
|
||||||
self.re_ShowdownAction = re.compile(r"^%s: shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
|
self.re_ShowdownAction = re.compile(r"^%s: shows \[(?P<CARDS>.*)\]" % player_re, re.MULTILINE)
|
||||||
|
@ -133,6 +133,7 @@ class PokerStars(HandHistoryConverter):
|
||||||
info = {}
|
info = {}
|
||||||
m = self.re_GameInfo.search(handText)
|
m = self.re_GameInfo.search(handText)
|
||||||
if not m:
|
if not m:
|
||||||
|
print "DEBUG: determineGameType(): did not match"
|
||||||
return None
|
return None
|
||||||
|
|
||||||
mg = m.groupdict()
|
mg = m.groupdict()
|
||||||
|
@ -147,6 +148,7 @@ class PokerStars(HandHistoryConverter):
|
||||||
'7 Card Stud Hi/Lo' : ('stud','studhilo'),
|
'7 Card Stud Hi/Lo' : ('stud','studhilo'),
|
||||||
'Badugi' : ('draw','badugi'),
|
'Badugi' : ('draw','badugi'),
|
||||||
'Triple Draw 2-7 Lowball' : ('draw','27_3draw'),
|
'Triple Draw 2-7 Lowball' : ('draw','27_3draw'),
|
||||||
|
'5 Card Draw' : ('draw','fivedraw')
|
||||||
}
|
}
|
||||||
currencies = { u'€':'EUR', '$':'USD', '':'T$' }
|
currencies = { u'€':'EUR', '$':'USD', '':'T$' }
|
||||||
# I don't think this is doing what we think. mg will always have all
|
# I don't think this is doing what we think. mg will always have all
|
||||||
|
@ -186,7 +188,7 @@ class PokerStars(HandHistoryConverter):
|
||||||
# m = self.re_Button.search(hand.handText)
|
# m = self.re_Button.search(hand.handText)
|
||||||
# if m: info.update(m.groupdict())
|
# if m: info.update(m.groupdict())
|
||||||
# TODO : I rather like the idea of just having this dict as hand.info
|
# TODO : I rather like the idea of just having this dict as hand.info
|
||||||
logging.debug("readHandInfo: %s" % info)
|
log.debug("readHandInfo: %s" % info)
|
||||||
for key in info:
|
for key in info:
|
||||||
if key == 'DATETIME':
|
if key == 'DATETIME':
|
||||||
#2008/11/12 10:00:48 CET [2008/11/12 4:00:48 ET]
|
#2008/11/12 10:00:48 CET [2008/11/12 4:00:48 ET]
|
||||||
|
@ -226,10 +228,10 @@ class PokerStars(HandHistoryConverter):
|
||||||
if m:
|
if m:
|
||||||
hand.buttonpos = int(m.group('BUTTON'))
|
hand.buttonpos = int(m.group('BUTTON'))
|
||||||
else:
|
else:
|
||||||
logging.info('readButton: not found')
|
log.info('readButton: not found')
|
||||||
|
|
||||||
def readPlayerStacks(self, hand):
|
def readPlayerStacks(self, hand):
|
||||||
logging.debug("readPlayerStacks")
|
log.debug("readPlayerStacks")
|
||||||
m = self.re_PlayerInfo.finditer(hand.handText)
|
m = self.re_PlayerInfo.finditer(hand.handText)
|
||||||
players = []
|
players = []
|
||||||
for a in m:
|
for a in m:
|
||||||
|
@ -265,7 +267,7 @@ class PokerStars(HandHistoryConverter):
|
||||||
hand.setCommunityCards(street, m.group('CARDS').split(' '))
|
hand.setCommunityCards(street, m.group('CARDS').split(' '))
|
||||||
|
|
||||||
def readAntes(self, hand):
|
def readAntes(self, hand):
|
||||||
logging.debug("reading antes")
|
log.debug("reading antes")
|
||||||
m = self.re_Antes.finditer(hand.handText)
|
m = self.re_Antes.finditer(hand.handText)
|
||||||
for player in m:
|
for player in m:
|
||||||
#~ logging.debug("hand.addAnte(%s,%s)" %(player.group('PNAME'), player.group('ANTE')))
|
#~ logging.debug("hand.addAnte(%s,%s)" %(player.group('PNAME'), player.group('ANTE')))
|
||||||
|
@ -373,12 +375,9 @@ if __name__ == "__main__":
|
||||||
parser.add_option("-i", "--input", dest="ipath", help="parse input hand history", default="regression-test-files/stars/horse/HH20090226 Natalie V - $0.10-$0.20 - HORSE.txt")
|
parser.add_option("-i", "--input", dest="ipath", help="parse input hand history", default="regression-test-files/stars/horse/HH20090226 Natalie V - $0.10-$0.20 - HORSE.txt")
|
||||||
parser.add_option("-o", "--output", dest="opath", help="output translation to", default="-")
|
parser.add_option("-o", "--output", dest="opath", help="output translation to", default="-")
|
||||||
parser.add_option("-f", "--follow", dest="follow", help="follow (tail -f) the input", action="store_true", default=False)
|
parser.add_option("-f", "--follow", dest="follow", help="follow (tail -f) the input", action="store_true", default=False)
|
||||||
parser.add_option("-q", "--quiet",
|
#parser.add_option("-q", "--quiet", action="store_const", const=logging.CRITICAL, dest="verbosity", default=logging.INFO)
|
||||||
action="store_const", const=logging.CRITICAL, dest="verbosity", default=logging.INFO)
|
#parser.add_option("-v", "--verbose", action="store_const", const=logging.INFO, dest="verbosity")
|
||||||
parser.add_option("-v", "--verbose",
|
#parser.add_option("--vv", action="store_const", const=logging.DEBUG, dest="verbosity")
|
||||||
action="store_const", const=logging.INFO, dest="verbosity")
|
|
||||||
parser.add_option("--vv",
|
|
||||||
action="store_const", const=logging.DEBUG, dest="verbosity")
|
|
||||||
|
|
||||||
(options, args) = parser.parse_args()
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
|
6240
pyfpdb/SQL.py
6240
pyfpdb/SQL.py
File diff suppressed because it is too large
Load Diff
|
@ -82,18 +82,19 @@ if __name__=="__main__":
|
||||||
(tour_no, tab_no) = table_name.split(",", 1)
|
(tour_no, tab_no) = table_name.split(",", 1)
|
||||||
tour_no = tour_no.rstrip()
|
tour_no = tour_no.rstrip()
|
||||||
tab_no = tab_no.rstrip()
|
tab_no = tab_no.rstrip()
|
||||||
table = Tables.Table(tournament = tour_no, table_number = tab_no)
|
table = Tables.Table(None, tournament = tour_no, table_number = tab_no)
|
||||||
else: # not a tournament
|
else: # not a tournament
|
||||||
print "cash game"
|
print "cash game"
|
||||||
table_name = table_name.rstrip()
|
table_name = table_name.rstrip()
|
||||||
table = Tables.Table(table_name = table_name)
|
table = Tables.Table(None, table_name = table_name)
|
||||||
|
table.gdk_handle = gtk.gdk.window_foreign_new(table.number)
|
||||||
|
|
||||||
print "table =", table
|
print "table =", table
|
||||||
print "game =", table.get_game()
|
# print "game =", table.get_game()
|
||||||
|
|
||||||
fake = fake_hud(table)
|
fake = fake_hud(table)
|
||||||
print "fake =", fake
|
print "fake =", fake
|
||||||
gobject.timeout_add(100, check_on_table, table, fake)
|
# gobject.timeout_add(100, check_on_table, table, fake)
|
||||||
print "calling main"
|
print "calling main"
|
||||||
gtk.main()
|
gtk.main()
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,17 @@
|
||||||
Based on HUD_main .. who knows if we want to actually use this or not
|
Based on HUD_main .. who knows if we want to actually use this or not
|
||||||
"""
|
"""
|
||||||
# Copyright 2008, 2009, Eric Blade
|
# Copyright 2008, 2009, Eric Blade
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
@ -31,7 +31,7 @@ import os
|
||||||
import Options
|
import Options
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
(options, sys.argv) = Options.fpdb_options()
|
(options, argv) = Options.fpdb_options()
|
||||||
|
|
||||||
if not options.errorsToConsole:
|
if not options.errorsToConsole:
|
||||||
print "Note: error output is being diverted to fpdb-error-log.txt and HUD-error.txt. Any major error will be reported there _only_."
|
print "Note: error output is being diverted to fpdb-error-log.txt and HUD-error.txt. Any major error will be reported there _only_."
|
||||||
|
@ -55,7 +55,7 @@ import SummaryEverleaf
|
||||||
|
|
||||||
class Tournament:
|
class Tournament:
|
||||||
"""Tournament will hold the information about a tournament, I guess ? Remember I'm new to this language, so I don't know the best ways to do things"""
|
"""Tournament will hold the information about a tournament, I guess ? Remember I'm new to this language, so I don't know the best ways to do things"""
|
||||||
|
|
||||||
def __init__(self, parent, site, tid): # site should probably be something in the config object, but i don't know how the config object works right now, so we're going to make it a str ..
|
def __init__(self, parent, site, tid): # site should probably be something in the config object, but i don't know how the config object works right now, so we're going to make it a str ..
|
||||||
print "Tournament init"
|
print "Tournament init"
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
@ -74,7 +74,7 @@ class Tournament:
|
||||||
self.prizepool = 0
|
self.prizepool = 0
|
||||||
self.players = {} # eventually i'd guess we'd probably want to fill this with playername:playerid's
|
self.players = {} # eventually i'd guess we'd probably want to fill this with playername:playerid's
|
||||||
self.results = {} # i'd guess we'd want to load this up with playerid's instead of playernames, too, as well, also
|
self.results = {} # i'd guess we'd want to load this up with playerid's instead of playernames, too, as well, also
|
||||||
|
|
||||||
# if site == "Everleaf": # this should be attached to a button that says "retrieve tournament info" or something for sites that we know how to do it for
|
# if site == "Everleaf": # this should be attached to a button that says "retrieve tournament info" or something for sites that we know how to do it for
|
||||||
summary = SummaryEverleaf.EverleafSummary()
|
summary = SummaryEverleaf.EverleafSummary()
|
||||||
self.site = summary.parser.SiteName
|
self.site = summary.parser.SiteName
|
||||||
|
@ -87,9 +87,9 @@ class Tournament:
|
||||||
self.rebuys = (summary.parser.TourneyRebuys == "yes")
|
self.rebuys = (summary.parser.TourneyRebuys == "yes")
|
||||||
self.prizepool = summary.parser.TourneyPool
|
self.prizepool = summary.parser.TourneyPool
|
||||||
self.numplayers = summary.parser.TourneyPlayers
|
self.numplayers = summary.parser.TourneyPlayers
|
||||||
|
|
||||||
self.openwindow() # let's start by getting any info we need.. meh
|
self.openwindow() # let's start by getting any info we need.. meh
|
||||||
|
|
||||||
def openwindow(self, widget=None):
|
def openwindow(self, widget=None):
|
||||||
if self.window is not None:
|
if self.window is not None:
|
||||||
self.window.show() # isn't there a better way to bring something to the front? not that GTK focus works right anyway, ever
|
self.window.show() # isn't there a better way to bring something to the front? not that GTK focus works right anyway, ever
|
||||||
|
@ -102,24 +102,24 @@ class Tournament:
|
||||||
self.window.set_border_width(1)
|
self.window.set_border_width(1)
|
||||||
self.window.set_default_size(480,640)
|
self.window.set_default_size(480,640)
|
||||||
self.window.set_resizable(True)
|
self.window.set_resizable(True)
|
||||||
|
|
||||||
self.main_vbox = gtk.VBox(False, 1)
|
self.main_vbox = gtk.VBox(False, 1)
|
||||||
self.main_vbox.set_border_width(1)
|
self.main_vbox.set_border_width(1)
|
||||||
self.window.add(self.main_vbox)
|
self.window.add(self.main_vbox)
|
||||||
self.window.show()
|
self.window.show()
|
||||||
|
|
||||||
def addrebuy(self, widget=None):
|
def addrebuy(self, widget=None):
|
||||||
t = self
|
t = self
|
||||||
t.numrebuys += 1
|
t.numrebuys += 1
|
||||||
t.mylabel.set_label("%s - %s - %s - %s - %s %s - %s - %s - %s - %s - %s" % (t.site, t.id, t.starttime, t.endtime, t.structure, t.game, t.buyin, t.fee, t.numrebuys, t.numplayers, t.prizepool))
|
t.mylabel.set_label("%s - %s - %s - %s - %s %s - %s - %s - %s - %s - %s" % (t.site, t.id, t.starttime, t.endtime, t.structure, t.game, t.buyin, t.fee, t.numrebuys, t.numplayers, t.prizepool))
|
||||||
|
|
||||||
def delete_event(self, widget, event, data=None):
|
def delete_event(self, widget, event, data=None):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def destroy(self, widget, data=None):
|
def destroy(self, widget, data=None):
|
||||||
return False
|
return False
|
||||||
#end def destroy
|
#end def destroy
|
||||||
|
|
||||||
|
|
||||||
class ttracker_main(object):
|
class ttracker_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."""
|
||||||
|
@ -143,11 +143,11 @@ class ttracker_main(object):
|
||||||
self.addbutton = gtk.Button(label="Enter Tournament")
|
self.addbutton = gtk.Button(label="Enter Tournament")
|
||||||
self.addbutton.connect("clicked", self.addClicked, "add tournament")
|
self.addbutton.connect("clicked", self.addClicked, "add tournament")
|
||||||
self.vb.add(self.addbutton)
|
self.vb.add(self.addbutton)
|
||||||
|
|
||||||
self.main_window.add(self.vb)
|
self.main_window.add(self.vb)
|
||||||
self.main_window.set_title("FPDB Tournament Tracker")
|
self.main_window.set_title("FPDB Tournament Tracker")
|
||||||
self.main_window.show_all()
|
self.main_window.show_all()
|
||||||
|
|
||||||
def addClicked(self, widget, data): # what is "data"? i'm guessing anything i pass in after the function name in connect() but unsure because the documentation sucks
|
def addClicked(self, widget, data): # what is "data"? i'm guessing anything i pass in after the function name in connect() but unsure because the documentation sucks
|
||||||
print "addClicked", widget, data
|
print "addClicked", widget, data
|
||||||
t = Tournament(self, None, None)
|
t = Tournament(self, None, None)
|
||||||
|
@ -162,7 +162,7 @@ class ttracker_main(object):
|
||||||
rebuybutton = gtk.Button(label="Rebuy")
|
rebuybutton = gtk.Button(label="Rebuy")
|
||||||
rebuybutton.connect("clicked", t.addrebuy)
|
rebuybutton.connect("clicked", t.addrebuy)
|
||||||
self.vb.add(rebuybutton)
|
self.vb.add(rebuybutton)
|
||||||
self.vb.add(editbutton) # These should probably be put in.. a.. h-box? i don't know..
|
self.vb.add(editbutton) # These should probably be put in.. a.. h-box? i don't know..
|
||||||
self.vb.add(mylabel)
|
self.vb.add(mylabel)
|
||||||
self.main_window.resize_children()
|
self.main_window.resize_children()
|
||||||
self.main_window.show()
|
self.main_window.show()
|
||||||
|
@ -172,29 +172,29 @@ class ttracker_main(object):
|
||||||
t.mylabel = mylabel
|
t.mylabel = mylabel
|
||||||
t.editbutton = editbutton
|
t.editbutton = editbutton
|
||||||
t.rebuybutton = rebuybutton
|
t.rebuybutton = rebuybutton
|
||||||
self.vb.show()
|
self.vb.show()
|
||||||
print self.tourney_list
|
print self.tourney_list
|
||||||
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
# when we move the start command over to the main program, we can have the main program ask for the tourney id, and pipe it into the stdin here
|
# when we move the start command over to the main program, we can have the main program ask for the tourney id, and pipe it into the stdin here
|
||||||
# at least that was my initial thought on it
|
# at least that was my initial thought on it
|
||||||
|
|
||||||
def destroy(*args): # call back for terminating the main eventloop
|
def destroy(*args): # call back for terminating the main eventloop
|
||||||
gtk.main_quit()
|
gtk.main_quit()
|
||||||
|
|
||||||
def create_HUD(self, new_hand_id, table, table_name, max, poker_game, stat_dict, cards):
|
def create_HUD(self, new_hand_id, table, table_name, max, poker_game, stat_dict, cards):
|
||||||
|
|
||||||
def idle_func():
|
def idle_func():
|
||||||
|
|
||||||
gtk.gdk.threads_enter()
|
gtk.gdk.threads_enter()
|
||||||
try:
|
try:
|
||||||
newlabel = gtk.Label("%s - %s" % (table.site, table_name))
|
newlabel = gtk.Label("%s - %s" % (table.site, table_name))
|
||||||
self.vb.add(newlabel)
|
self.vb.add(newlabel)
|
||||||
newlabel.show()
|
newlabel.show()
|
||||||
self.main_window.resize_children()
|
self.main_window.resize_children()
|
||||||
|
|
||||||
self.hud_dict[table_name].tablehudlabel = newlabel
|
self.hud_dict[table_name].tablehudlabel = newlabel
|
||||||
self.hud_dict[table_name].create(new_hand_id, self.config, stat_dict, cards)
|
self.hud_dict[table_name].create(new_hand_id, self.config, stat_dict, cards)
|
||||||
for m in self.hud_dict[table_name].aux_windows:
|
for m in self.hud_dict[table_name].aux_windows:
|
||||||
|
@ -212,11 +212,11 @@ class ttracker_main(object):
|
||||||
self.hud_dict[table_name].cards = cards
|
self.hud_dict[table_name].cards = cards
|
||||||
[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_name].aux_windows]
|
||||||
gobject.idle_add(idle_func)
|
gobject.idle_add(idle_func)
|
||||||
|
|
||||||
def update_HUD(self, new_hand_id, table_name, config):
|
def update_HUD(self, new_hand_id, table_name, config):
|
||||||
"""Update a HUD gui from inside the non-gui read_stdin thread."""
|
"""Update a HUD gui from inside the non-gui read_stdin thread."""
|
||||||
# This is written so that only 1 thread can touch the gui--mainly
|
# This is written so that only 1 thread can touch the gui--mainly
|
||||||
# for compatibility with Windows. This method dispatches the
|
# for compatibility with Windows. This method dispatches the
|
||||||
# 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()
|
||||||
|
@ -227,7 +227,7 @@ class ttracker_main(object):
|
||||||
finally:
|
finally:
|
||||||
gtk.gdk.threads_leave()
|
gtk.gdk.threads_leave()
|
||||||
gobject.idle_add(idle_func)
|
gobject.idle_add(idle_func)
|
||||||
|
|
||||||
def read_stdin(self): # This is the thread function
|
def read_stdin(self): # This is the thread function
|
||||||
"""Do all the non-gui heavy lifting for the HUD program."""
|
"""Do all the non-gui heavy lifting for the HUD program."""
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ class ttracker_main(object):
|
||||||
self.db_connection = Database.Database(self.config, self.db_name, 'temp')
|
self.db_connection = Database.Database(self.config, self.db_name, 'temp')
|
||||||
# self.db_connection.init_hud_stat_vars(hud_days)
|
# self.db_connection.init_hud_stat_vars(hud_days)
|
||||||
tourny_finder = re.compile('(\d+) (\d+)')
|
tourny_finder = re.compile('(\d+) (\d+)')
|
||||||
|
|
||||||
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()
|
||||||
new_hand_id = string.rstrip(new_hand_id)
|
new_hand_id = string.rstrip(new_hand_id)
|
||||||
|
@ -248,7 +248,7 @@ class ttracker_main(object):
|
||||||
# get basic info about the new hand from the db
|
# get basic info about the new hand from the db
|
||||||
# if there is a db error, complain, skip hand, and proceed
|
# if there is a db error, complain, skip hand, and proceed
|
||||||
try:
|
try:
|
||||||
(table_name, max, poker_game, type, site_id) = self.db_connection.get_table_name(new_hand_id)
|
(table_name, max, poker_game, type, site_id, numseats) = self.db_connection.get_table_name(new_hand_id)
|
||||||
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, aggregate_stats[type]
|
stat_dict = self.db_connection.get_stats_from_hand(new_hand_id, aggregate_stats[type]
|
||||||
,hud_style, agg_bb_mult)
|
,hud_style, agg_bb_mult)
|
||||||
|
|
||||||
|
@ -272,7 +272,7 @@ class ttracker_main(object):
|
||||||
print "could not find tournament: skipping "
|
print "could not find tournament: skipping "
|
||||||
sys.stderr.write("Could not find tournament %d in hand %d. Skipping.\n" % (int(tour_number), int(new_hand_id)))
|
sys.stderr.write("Could not find tournament %d in hand %d. Skipping.\n" % (int(tour_number), int(new_hand_id)))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
else:
|
else:
|
||||||
temp_key = table_name
|
temp_key = table_name
|
||||||
|
|
||||||
|
@ -282,7 +282,7 @@ class ttracker_main(object):
|
||||||
self.hud_dict[temp_key].cards = cards
|
self.hud_dict[temp_key].cards = cards
|
||||||
[aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[temp_key].aux_windows]
|
[aw.update_data(new_hand_id, self.db_connection) for aw in self.hud_dict[temp_key].aux_windows]
|
||||||
self.update_HUD(new_hand_id, temp_key, self.config)
|
self.update_HUD(new_hand_id, temp_key, self.config)
|
||||||
|
|
||||||
# Or create a new HUD
|
# Or create a new HUD
|
||||||
else:
|
else:
|
||||||
if type == "tour":
|
if type == "tour":
|
||||||
|
|
|
@ -9,12 +9,12 @@ Routines for detecting and handling poker client windows for MS Windows.
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
# the Free Software Foundation; either version 2 of the License, or
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program; if not, write to the Free Software
|
# along with this program; if not, write to the Free Software
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
@ -56,9 +56,13 @@ class Table(Table_Window):
|
||||||
if 'Chat:' in titles[hwnd]: continue # Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows
|
if 'Chat:' in titles[hwnd]: continue # Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows
|
||||||
self.window = hwnd
|
self.window = hwnd
|
||||||
break
|
break
|
||||||
|
|
||||||
if self.window == None:
|
try:
|
||||||
print "Window %s not found. Skipping." % search_string
|
if self.window == None:
|
||||||
|
print "Window %s not found. Skipping." % search_string
|
||||||
|
return None
|
||||||
|
except AttributeError:
|
||||||
|
print "self.window doesn't exist? why?"
|
||||||
return None
|
return None
|
||||||
|
|
||||||
(x, y, width, height) = win32gui.GetWindowRect(hwnd)
|
(x, y, width, height) = win32gui.GetWindowRect(hwnd)
|
||||||
|
@ -70,7 +74,7 @@ class Table(Table_Window):
|
||||||
print "x = %s y = %s width = %s height = %s" % (self.x, self.y, self.width, self.height)
|
print "x = %s y = %s width = %s height = %s" % (self.x, self.y, self.width, self.height)
|
||||||
#self.height = int(height) - b_width - tb_height
|
#self.height = int(height) - b_width - tb_height
|
||||||
#self.width = int(width) - 2*b_width
|
#self.width = int(width) - 2*b_width
|
||||||
|
|
||||||
self.exe = self.get_nt_exe(hwnd)
|
self.exe = self.get_nt_exe(hwnd)
|
||||||
self.title = titles[hwnd]
|
self.title = titles[hwnd]
|
||||||
self.site = ""
|
self.site = ""
|
||||||
|
@ -99,37 +103,37 @@ class Table(Table_Window):
|
||||||
|
|
||||||
def get_nt_exe(self, hwnd):
|
def get_nt_exe(self, hwnd):
|
||||||
"""Finds the name of the executable that the given window handle belongs to."""
|
"""Finds the name of the executable that the given window handle belongs to."""
|
||||||
|
|
||||||
# Request privileges to enable "debug process", so we can later use PROCESS_VM_READ, retardedly required to GetModuleFileNameEx()
|
# Request privileges to enable "debug process", so we can later use PROCESS_VM_READ, retardedly required to GetModuleFileNameEx()
|
||||||
priv_flags = win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY
|
priv_flags = win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY
|
||||||
hToken = win32security.OpenProcessToken (win32api.GetCurrentProcess(), priv_flags)
|
hToken = win32security.OpenProcessToken (win32api.GetCurrentProcess(), priv_flags)
|
||||||
# enable "debug process"
|
# enable "debug process"
|
||||||
privilege_id = win32security.LookupPrivilegeValue (None, win32security.SE_DEBUG_NAME)
|
privilege_id = win32security.LookupPrivilegeValue (None, win32security.SE_DEBUG_NAME)
|
||||||
old_privs = win32security.AdjustTokenPrivileges (hToken, 0, [(privilege_id, win32security.SE_PRIVILEGE_ENABLED)])
|
old_privs = win32security.AdjustTokenPrivileges (hToken, 0, [(privilege_id, win32security.SE_PRIVILEGE_ENABLED)])
|
||||||
|
|
||||||
# Open the process, and query it's filename
|
# Open the process, and query it's filename
|
||||||
processid = win32process.GetWindowThreadProcessId(hwnd)
|
processid = win32process.GetWindowThreadProcessId(hwnd)
|
||||||
pshandle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, False, processid[1])
|
pshandle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, False, processid[1])
|
||||||
exename = win32process.GetModuleFileNameEx(pshandle, 0)
|
exename = win32process.GetModuleFileNameEx(pshandle, 0)
|
||||||
|
|
||||||
# clean up
|
# clean up
|
||||||
win32api.CloseHandle(pshandle)
|
win32api.CloseHandle(pshandle)
|
||||||
win32api.CloseHandle(hToken)
|
win32api.CloseHandle(hToken)
|
||||||
|
|
||||||
return exename
|
return exename
|
||||||
def topify(self, hud):
|
def topify(self, hud):
|
||||||
"""Set the specified gtk window to stayontop in MS Windows."""
|
"""Set the specified gtk window to stayontop in MS Windows."""
|
||||||
|
|
||||||
# def windowEnumerationHandler(hwnd, resultList):
|
# def windowEnumerationHandler(hwnd, resultList):
|
||||||
# '''Callback for win32gui.EnumWindows() to generate list of window handles.'''
|
# '''Callback for win32gui.EnumWindows() to generate list of window handles.'''
|
||||||
# resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
|
# resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
|
||||||
#
|
#
|
||||||
# unique_name = 'unique name for finding this window'
|
# unique_name = 'unique name for finding this window'
|
||||||
# real_name = hud.main_window.get_title()
|
# real_name = hud.main_window.get_title()
|
||||||
# hud.main_window.set_title(unique_name)
|
# hud.main_window.set_title(unique_name)
|
||||||
# tl_windows = []
|
# tl_windows = []
|
||||||
# win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
|
# win32gui.EnumWindows(windowEnumerationHandler, tl_windows)
|
||||||
#
|
#
|
||||||
# for w in tl_windows:
|
# for w in tl_windows:
|
||||||
# if w[1] == unique_name:
|
# if w[1] == unique_name:
|
||||||
# hud.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0])
|
# hud.main_window.gdkhandle = gtk.gdk.window_foreign_new(w[0])
|
||||||
|
@ -139,14 +143,13 @@ class Table(Table_Window):
|
||||||
(innerx, innery) = self.gdkhandle.get_origin()
|
(innerx, innery) = self.gdkhandle.get_origin()
|
||||||
b_width = rect.x - innerx
|
b_width = rect.x - innerx
|
||||||
tb_height = rect.y - innery
|
tb_height = rect.y - innery
|
||||||
#
|
#
|
||||||
# style = win32gui.GetWindowLong(self.number, win32con.GWL_EXSTYLE)
|
# style = win32gui.GetWindowLong(self.number, win32con.GWL_EXSTYLE)
|
||||||
# style |= win32con.WS_CLIPCHILDREN
|
# style |= win32con.WS_CLIPCHILDREN
|
||||||
# win32gui.SetWindowLong(self.number, win32con.GWL_EXSTYLE, style)
|
# win32gui.SetWindowLong(self.number, win32con.GWL_EXSTYLE, style)
|
||||||
# break
|
# break
|
||||||
|
|
||||||
# hud.main_window.set_title(real_name)
|
# hud.main_window.set_title(real_name)
|
||||||
|
|
||||||
def win_enum_handler(hwnd, titles):
|
def win_enum_handler(hwnd, titles):
|
||||||
titles[hwnd] = win32gui.GetWindowText(hwnd)
|
titles[hwnd] = win32gui.GetWindowText(hwnd)
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ of Table_Window objects representing the windows found.
|
||||||
|
|
||||||
# Standard Library modules
|
# Standard Library modules
|
||||||
import re
|
import re
|
||||||
|
import os
|
||||||
|
|
||||||
# pyGTK modules
|
# pyGTK modules
|
||||||
import pygtk
|
import pygtk
|
||||||
|
@ -40,39 +41,70 @@ from TableWindow import Table_Window
|
||||||
# We might as well do this once and make them globals
|
# We might as well do this once and make them globals
|
||||||
disp = Xlib.display.Display()
|
disp = Xlib.display.Display()
|
||||||
root = disp.screen().root
|
root = disp.screen().root
|
||||||
|
name_atom = disp.get_atom("WM_NAME", 1)
|
||||||
|
|
||||||
class Table(Table_Window):
|
class Table(Table_Window):
|
||||||
|
|
||||||
def find_table_parameters(self, search_string):
|
def find_table_parameters(self, search_string):
|
||||||
self.window = None
|
# self.window = None
|
||||||
done_looping = False
|
# done_looping = False
|
||||||
for outside in root.query_tree().children:
|
# for outside in root.query_tree().children:
|
||||||
for inside in outside.query_tree().children:
|
# for inside in outside.query_tree().children:
|
||||||
if done_looping: break
|
# if done_looping: break
|
||||||
if inside.get_wm_name() and re.search(search_string, inside.get_wm_name()):
|
# prop = inside.get_property(name_atom, Xlib.Xatom.STRING, 0, 1000)
|
||||||
if self.check_bad_words(inside.get_wm_name()): continue
|
# print prop
|
||||||
self.window = inside
|
# if prop is None: continue
|
||||||
self.parent = outside
|
# if prop.value and re.search(search_string, prop.value):
|
||||||
done_looping = True
|
# if self.check_bad_words(prop.value): continue
|
||||||
break
|
## if inside.get_wm_name() and re.search(search_string, inside.get_wm_name()):
|
||||||
|
## if self.check_bad_words(inside.get_wm_name()):
|
||||||
|
## print "bad word =", inside.get_wm_name()
|
||||||
|
## continue
|
||||||
|
# self.window = inside
|
||||||
|
# self.parent = outside
|
||||||
|
# done_looping = True
|
||||||
|
# break
|
||||||
|
|
||||||
if self.window == None or self.parent == None:
|
window_number = None
|
||||||
|
for listing in os.popen('xwininfo -root -tree').readlines():
|
||||||
|
if re.search(search_string, listing):
|
||||||
|
print listing
|
||||||
|
mo = re.match('\s+([\dxabcdef]+) (.+):\s\(\"([a-zA-Z.]+)\".+ (\d+)x(\d+)\+\d+\+\d+ \+(\d+)\+(\d+)', listing)
|
||||||
|
self.number = int( mo.group(1), 0)
|
||||||
|
self.width = int( mo.group(4) )
|
||||||
|
self.height = int( mo.group(5) )
|
||||||
|
self.x = int( mo.group(6) )
|
||||||
|
self.y = int( mo.group(7) )
|
||||||
|
self.title = re.sub('\"', '', mo.group(2))
|
||||||
|
self.exe = "" # not used?
|
||||||
|
self.hud = None
|
||||||
|
# done_looping = False
|
||||||
|
# for outside in root.query_tree().children:
|
||||||
|
# for inside in outside.query_tree().children:
|
||||||
|
# if done_looping: break
|
||||||
|
# if inside.id == window_number:
|
||||||
|
# self.window = inside
|
||||||
|
# self.parent = outside
|
||||||
|
# done_looping = True
|
||||||
|
# break
|
||||||
|
|
||||||
|
if window_number is None:
|
||||||
print "Window %s not found. Skipping." % search_string
|
print "Window %s not found. Skipping." % search_string
|
||||||
return None
|
return None
|
||||||
|
|
||||||
my_geo = self.window.get_geometry()
|
# my_geo = self.window.get_geometry()
|
||||||
pa_geo = self.parent.get_geometry()
|
# pa_geo = self.parent.get_geometry()
|
||||||
|
#
|
||||||
|
# self.x = pa_geo.x + my_geo.x
|
||||||
|
# self.y = pa_geo.y + my_geo.y
|
||||||
|
# self.width = my_geo.width
|
||||||
|
# self.height = my_geo.height
|
||||||
|
# self.exe = self.window.get_wm_class()[0]
|
||||||
|
# self.title = self.window.get_wm_name()
|
||||||
|
# self.site = ""
|
||||||
|
# self.hud = None
|
||||||
|
|
||||||
self.x = pa_geo.x + my_geo.x
|
# window_string = str(self.window)
|
||||||
self.y = pa_geo.y + my_geo.y
|
|
||||||
self.width = my_geo.width
|
|
||||||
self.height = my_geo.height
|
|
||||||
self.exe = self.window.get_wm_class()[0]
|
|
||||||
self.title = self.window.get_wm_name()
|
|
||||||
self.site = ""
|
|
||||||
self.hud = None
|
|
||||||
|
|
||||||
window_string = str(self.window)
|
|
||||||
mo = re.match('Xlib\.display\.Window\(([\dxabcdef]+)', window_string)
|
mo = re.match('Xlib\.display\.Window\(([\dxabcdef]+)', window_string)
|
||||||
if not mo:
|
if not mo:
|
||||||
print "Not matched"
|
print "Not matched"
|
||||||
|
|
244
pyfpdb/fpdb.py
244
pyfpdb/fpdb.py
|
@ -41,7 +41,7 @@ if os.name == 'nt' and sys.version[0:3] not in ('2.5', '2.6') and '-r' not in sy
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
#print "debug - not changing path"
|
#print "debug - not changing path"
|
||||||
|
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
import win32api
|
import win32api
|
||||||
import win32con
|
import win32con
|
||||||
|
@ -53,7 +53,7 @@ import threading
|
||||||
import Options
|
import Options
|
||||||
import string
|
import string
|
||||||
cl_options = string.join(sys.argv[1:])
|
cl_options = string.join(sys.argv[1:])
|
||||||
(options, sys.argv) = Options.fpdb_options()
|
(options, argv) = Options.fpdb_options()
|
||||||
|
|
||||||
if not options.errorsToConsole:
|
if not options.errorsToConsole:
|
||||||
print "Note: error output is being diverted to fpdb-error-log.txt and HUD-error.txt. Any major error will be reported there _only_."
|
print "Note: error output is being diverted to fpdb-error-log.txt and HUD-error.txt. Any major error will be reported there _only_."
|
||||||
|
@ -69,6 +69,7 @@ import gtk
|
||||||
import interlocks
|
import interlocks
|
||||||
|
|
||||||
|
|
||||||
|
import GuiPrefs
|
||||||
import GuiBulkImport
|
import GuiBulkImport
|
||||||
import GuiPlayerStats
|
import GuiPlayerStats
|
||||||
import GuiPositionalStats
|
import GuiPositionalStats
|
||||||
|
@ -80,7 +81,7 @@ import SQL
|
||||||
import Database
|
import Database
|
||||||
import FpdbSQLQueries
|
import FpdbSQLQueries
|
||||||
import Configuration
|
import Configuration
|
||||||
from Exceptions import *
|
import Exceptions
|
||||||
|
|
||||||
VERSION = "0.12"
|
VERSION = "0.12"
|
||||||
|
|
||||||
|
@ -94,37 +95,97 @@ class fpdb:
|
||||||
self.add_tab(new_tab, new_tab_name)
|
self.add_tab(new_tab, new_tab_name)
|
||||||
self.display_tab(new_tab_name)
|
self.display_tab(new_tab_name)
|
||||||
|
|
||||||
def add_tab(self, new_tab, new_tab_name):
|
def add_tab(self, new_page, new_tab_name):
|
||||||
"""adds a tab, namely creates the button and displays it and appends all the relevant arrays"""
|
"""adds a tab, namely creates the button and displays it and appends all the relevant arrays"""
|
||||||
for i in self.tab_names: #todo: check this is valid
|
for name in self.nb_tabs: #todo: check this is valid
|
||||||
if i == new_tab_name:
|
if name == new_tab_name:
|
||||||
return # if tab already exists, just go to it
|
return # if tab already exists, just go to it
|
||||||
|
|
||||||
self.tabs.append(new_tab)
|
used_before = False
|
||||||
self.tab_names.append(new_tab_name)
|
for i, name in enumerate(self.tab_names): #todo: check this is valid
|
||||||
|
if name == new_tab_name:
|
||||||
|
used_before = True
|
||||||
|
event_box = self.tabs[i]
|
||||||
|
page = self.pages[i]
|
||||||
|
break
|
||||||
|
|
||||||
new_tab_sel_button = gtk.ToggleButton(new_tab_name)
|
if not used_before:
|
||||||
new_tab_sel_button.connect("clicked", self.tab_clicked, new_tab_name)
|
event_box = self.create_custom_tab(new_tab_name, self.nb)
|
||||||
self.tab_box.add(new_tab_sel_button)
|
page = new_page
|
||||||
new_tab_sel_button.show()
|
self.pages.append(new_page)
|
||||||
self.tab_buttons.append(new_tab_sel_button)
|
self.tabs.append(event_box)
|
||||||
|
self.tab_names.append(new_tab_name)
|
||||||
|
|
||||||
|
#self.nb.append_page(new_page, gtk.Label(new_tab_name))
|
||||||
|
self.nb.append_page(page, event_box)
|
||||||
|
self.nb_tabs.append(new_tab_name)
|
||||||
|
page.show()
|
||||||
|
|
||||||
def display_tab(self, new_tab_name):
|
def display_tab(self, new_tab_name):
|
||||||
"""displays the indicated tab"""
|
"""displays the indicated tab"""
|
||||||
tab_no = -1
|
tab_no = -1
|
||||||
for i, name in enumerate(self.tab_names):
|
for i, name in enumerate(self.nb_tabs):
|
||||||
if name == new_tab_name:
|
if new_tab_name == name:
|
||||||
tab_no = i
|
tab_no = i
|
||||||
break
|
break
|
||||||
|
|
||||||
if tab_no == -1:
|
if tab_no < 0 or tab_no >= self.nb.get_n_pages():
|
||||||
raise FpdbError("invalid tab_no")
|
raise FpdbError("invalid tab_no " + str(tab_no))
|
||||||
else:
|
else:
|
||||||
self.main_vbox.remove(self.current_tab)
|
self.nb.set_current_page(tab_no)
|
||||||
self.current_tab=self.tabs[tab_no]
|
|
||||||
self.main_vbox.add(self.current_tab)
|
def create_custom_tab(self, text, nb):
|
||||||
self.tab_buttons[tab_no].set_active(True)
|
#create a custom tab for notebook containing a
|
||||||
self.current_tab.show()
|
#label and a button with STOCK_ICON
|
||||||
|
eventBox = gtk.EventBox()
|
||||||
|
tabBox = gtk.HBox(False, 2)
|
||||||
|
tabLabel = gtk.Label(text)
|
||||||
|
tabBox.pack_start(tabLabel, False)
|
||||||
|
eventBox.add(tabBox)
|
||||||
|
|
||||||
|
if nb.get_n_pages() > 0:
|
||||||
|
tabButton = gtk.Button()
|
||||||
|
|
||||||
|
tabButton.connect('clicked', self.remove_tab, (nb, text))
|
||||||
|
#Add a picture on a button
|
||||||
|
self.add_icon_to_button(tabButton)
|
||||||
|
tabBox.pack_start(tabButton, False)
|
||||||
|
|
||||||
|
# needed, otherwise even calling show_all on the notebook won't
|
||||||
|
# make the hbox contents appear.
|
||||||
|
tabBox.show_all()
|
||||||
|
return eventBox
|
||||||
|
|
||||||
|
def add_icon_to_button(self, button):
|
||||||
|
iconBox = gtk.HBox(False, 0)
|
||||||
|
image = gtk.Image()
|
||||||
|
image.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_SMALL_TOOLBAR)
|
||||||
|
gtk.Button.set_relief(button, gtk.RELIEF_NONE)
|
||||||
|
settings = gtk.Widget.get_settings(button);
|
||||||
|
(w,h) = gtk.icon_size_lookup_for_settings(settings, gtk.ICON_SIZE_SMALL_TOOLBAR);
|
||||||
|
gtk.Widget.set_size_request (button, w + 4, h + 4);
|
||||||
|
image.show()
|
||||||
|
iconBox.pack_start(image, True, False, 0)
|
||||||
|
button.add(iconBox)
|
||||||
|
iconBox.show()
|
||||||
|
return
|
||||||
|
|
||||||
|
# Remove a page from the notebook
|
||||||
|
def remove_tab(self, button, data):
|
||||||
|
(nb, text) = data
|
||||||
|
page = -1
|
||||||
|
#print "\n remove_tab: start", text
|
||||||
|
for i, tab in enumerate(self.nb_tabs):
|
||||||
|
if text == tab:
|
||||||
|
page = i
|
||||||
|
#print " page =", page
|
||||||
|
if page >= 0 and page < self.nb.get_n_pages():
|
||||||
|
#print " removing page", page
|
||||||
|
del self.nb_tabs[page]
|
||||||
|
nb.remove_page(page)
|
||||||
|
# Need to refresh the widget --
|
||||||
|
# This forces the widget to redraw itself.
|
||||||
|
#nb.queue_draw_area(0,0,-1,-1) needed or not??
|
||||||
|
|
||||||
def delete_event(self, widget, event, data=None):
|
def delete_event(self, widget, event, data=None):
|
||||||
return False
|
return False
|
||||||
|
@ -146,6 +207,20 @@ class fpdb:
|
||||||
dia.run()
|
dia.run()
|
||||||
dia.destroy()
|
dia.destroy()
|
||||||
|
|
||||||
|
def dia_preferences(self, widget, data=None):
|
||||||
|
dia = gtk.Dialog("Preferences",
|
||||||
|
self.window,
|
||||||
|
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
|
||||||
|
gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT))
|
||||||
|
dia.set_default_size(500, 500)
|
||||||
|
prefs = GuiPrefs.GuiPrefs(self.config, self.window, dia.vbox)
|
||||||
|
response = dia.run()
|
||||||
|
if response == gtk.RESPONSE_ACCEPT:
|
||||||
|
# save updated config
|
||||||
|
self.config.save()
|
||||||
|
dia.destroy()
|
||||||
|
|
||||||
def dia_create_del_database(self, widget, data=None):
|
def dia_create_del_database(self, widget, data=None):
|
||||||
self.warning_box("Unimplemented: Create/Delete Database")
|
self.warning_box("Unimplemented: Create/Delete Database")
|
||||||
self.obtain_global_lock()
|
self.obtain_global_lock()
|
||||||
|
@ -178,23 +253,23 @@ class fpdb:
|
||||||
"""obtains db root credentials from user"""
|
"""obtains db root credentials from user"""
|
||||||
self.warning_box("Unimplemented: Get Root Database Credentials")
|
self.warning_box("Unimplemented: Get Root Database Credentials")
|
||||||
# user, pw=None, None
|
# user, pw=None, None
|
||||||
#
|
#
|
||||||
# dialog=gtk.Dialog(title="DB Credentials needed", parent=None, flags=0,
|
# dialog=gtk.Dialog(title="DB Credentials needed", parent=None, flags=0,
|
||||||
# buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,"Connect and recreate",gtk.RESPONSE_OK))
|
# buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,"Connect and recreate",gtk.RESPONSE_OK))
|
||||||
#
|
#
|
||||||
# label_warning1=gtk.Label("Please enter credentials for a database user for "+self.host+" that has permissions to create a database.")
|
# label_warning1=gtk.Label("Please enter credentials for a database user for "+self.host+" that has permissions to create a database.")
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# label_user=gtk.Label("Username")
|
# label_user=gtk.Label("Username")
|
||||||
# dialog.vbox.add(label_user)
|
# dialog.vbox.add(label_user)
|
||||||
# label_user.show()
|
# label_user.show()
|
||||||
#
|
#
|
||||||
# response=dialog.run()
|
# response=dialog.run()
|
||||||
# dialog.destroy()
|
# dialog.destroy()
|
||||||
# return (user, pw, response)
|
# return (user, pw, response)
|
||||||
|
|
||||||
def dia_import_db(self, widget, data=None):
|
def dia_import_db(self, widget, data=None):
|
||||||
self.warning_box("Unimplemented: Import Database")
|
self.warning_box("Unimplemented: Import Database")
|
||||||
self.obtain_global_lock()
|
self.obtain_global_lock()
|
||||||
self.release_global_lock()
|
self.release_global_lock()
|
||||||
|
|
||||||
|
@ -211,7 +286,7 @@ class fpdb:
|
||||||
# chooser.set_filename(self.profile)
|
# chooser.set_filename(self.profile)
|
||||||
|
|
||||||
# response = chooser.run()
|
# response = chooser.run()
|
||||||
# chooser.destroy()
|
# chooser.destroy()
|
||||||
# if response == gtk.RESPONSE_OK:
|
# if response == gtk.RESPONSE_OK:
|
||||||
# self.load_profile(chooser.get_filename())
|
# self.load_profile(chooser.get_filename())
|
||||||
# elif response == gtk.RESPONSE_CANCEL:
|
# elif response == gtk.RESPONSE_CANCEL:
|
||||||
|
@ -239,7 +314,7 @@ class fpdb:
|
||||||
dia_confirm.destroy()
|
dia_confirm.destroy()
|
||||||
if response == gtk.RESPONSE_YES:
|
if response == gtk.RESPONSE_YES:
|
||||||
#if self.db.backend == self.fdb_lock.fdb.MYSQL_INNODB:
|
#if self.db.backend == self.fdb_lock.fdb.MYSQL_INNODB:
|
||||||
# mysql requires locks on all tables or none - easier to release this lock
|
# mysql requires locks on all tables or none - easier to release this lock
|
||||||
# than lock all the other tables
|
# than lock all the other tables
|
||||||
# ToDo: lock all other tables so that lock doesn't have to be released
|
# ToDo: lock all other tables so that lock doesn't have to be released
|
||||||
# self.release_global_lock()
|
# self.release_global_lock()
|
||||||
|
@ -252,7 +327,7 @@ class fpdb:
|
||||||
print 'User cancelled recreating tables'
|
print 'User cancelled recreating tables'
|
||||||
#if not lock_released:
|
#if not lock_released:
|
||||||
self.release_global_lock()
|
self.release_global_lock()
|
||||||
|
|
||||||
def dia_recreate_hudcache(self, widget, data=None):
|
def dia_recreate_hudcache(self, widget, data=None):
|
||||||
if self.obtain_global_lock():
|
if self.obtain_global_lock():
|
||||||
self.dia_confirm = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING, buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm recreating HUD cache")
|
self.dia_confirm = gtk.MessageDialog(parent=None, flags=0, type=gtk.MESSAGE_WARNING, buttons=(gtk.BUTTONS_YES_NO), message_format="Confirm recreating HUD cache")
|
||||||
|
@ -282,6 +357,27 @@ class fpdb:
|
||||||
|
|
||||||
self.release_global_lock()
|
self.release_global_lock()
|
||||||
|
|
||||||
|
def dia_rebuild_indexes(self, widget, data=None):
|
||||||
|
if self.obtain_global_lock():
|
||||||
|
self.dia_confirm = gtk.MessageDialog(parent=None
|
||||||
|
,flags=0
|
||||||
|
,type=gtk.MESSAGE_WARNING
|
||||||
|
,buttons=(gtk.BUTTONS_YES_NO)
|
||||||
|
,message_format="Confirm rebuilding database indexes")
|
||||||
|
diastring = "Please confirm that you want to rebuild the database indexes."
|
||||||
|
self.dia_confirm.format_secondary_text(diastring)
|
||||||
|
|
||||||
|
response = self.dia_confirm.run()
|
||||||
|
self.dia_confirm.destroy()
|
||||||
|
if response == gtk.RESPONSE_YES:
|
||||||
|
self.db.rebuild_indexes()
|
||||||
|
self.db.vacuumDB()
|
||||||
|
self.db.analyzeDB()
|
||||||
|
elif response == gtk.RESPONSE_NO:
|
||||||
|
print 'User cancelled rebuilding db indexes'
|
||||||
|
|
||||||
|
self.release_global_lock()
|
||||||
|
|
||||||
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)
|
||||||
|
@ -314,7 +410,7 @@ class fpdb:
|
||||||
entry.set_text(ds)
|
entry.set_text(ds)
|
||||||
win.destroy()
|
win.destroy()
|
||||||
self.dia_confirm.set_modal(True)
|
self.dia_confirm.set_modal(True)
|
||||||
|
|
||||||
def dia_regression_test(self, widget, data=None):
|
def dia_regression_test(self, widget, data=None):
|
||||||
self.warning_box("Unimplemented: Regression Test")
|
self.warning_box("Unimplemented: Regression Test")
|
||||||
self.obtain_global_lock()
|
self.obtain_global_lock()
|
||||||
|
@ -322,7 +418,7 @@ class fpdb:
|
||||||
|
|
||||||
def dia_save_profile(self, widget, data=None):
|
def dia_save_profile(self, widget, data=None):
|
||||||
self.warning_box("Unimplemented: Save Profile (try saving a HUD layout, that should do it)")
|
self.warning_box("Unimplemented: Save Profile (try saving a HUD layout, that should do it)")
|
||||||
|
|
||||||
def diaSetupWizard(self, path):
|
def diaSetupWizard(self, path):
|
||||||
diaSetupWizard = gtk.Dialog(title="Fatal Error - Config File Missing", parent=None, flags=0, buttons=(gtk.STOCK_QUIT,gtk.RESPONSE_OK))
|
diaSetupWizard = gtk.Dialog(title="Fatal Error - Config File Missing", parent=None, flags=0, buttons=(gtk.STOCK_QUIT,gtk.RESPONSE_OK))
|
||||||
|
|
||||||
|
@ -350,6 +446,7 @@ class fpdb:
|
||||||
<menuitem action="LoadProf"/>
|
<menuitem action="LoadProf"/>
|
||||||
<menuitem action="EditProf"/>
|
<menuitem action="EditProf"/>
|
||||||
<menuitem action="SaveProf"/>
|
<menuitem action="SaveProf"/>
|
||||||
|
<menuitem action="Preferences"/>
|
||||||
<separator/>
|
<separator/>
|
||||||
<menuitem action="Quit"/>
|
<menuitem action="Quit"/>
|
||||||
</menu>
|
</menu>
|
||||||
|
@ -375,6 +472,7 @@ class fpdb:
|
||||||
<menuitem action="createuser"/>
|
<menuitem action="createuser"/>
|
||||||
<menuitem action="createtabs"/>
|
<menuitem action="createtabs"/>
|
||||||
<menuitem action="rebuildhudcache"/>
|
<menuitem action="rebuildhudcache"/>
|
||||||
|
<menuitem action="rebuildindexes"/>
|
||||||
<menuitem action="stats"/>
|
<menuitem action="stats"/>
|
||||||
</menu>
|
</menu>
|
||||||
<menu action="help">
|
<menu action="help">
|
||||||
|
@ -396,6 +494,7 @@ class fpdb:
|
||||||
('LoadProf', None, '_Load Profile (broken)', '<control>L', 'Load your profile', self.dia_load_profile),
|
('LoadProf', None, '_Load Profile (broken)', '<control>L', 'Load your profile', self.dia_load_profile),
|
||||||
('EditProf', None, '_Edit Profile (todo)', '<control>E', 'Edit your profile', self.dia_edit_profile),
|
('EditProf', None, '_Edit Profile (todo)', '<control>E', 'Edit your profile', self.dia_edit_profile),
|
||||||
('SaveProf', None, '_Save Profile (todo)', '<control>S', 'Save your profile', self.dia_save_profile),
|
('SaveProf', None, '_Save Profile (todo)', '<control>S', 'Save your profile', self.dia_save_profile),
|
||||||
|
('Preferences', None, '_Preferences', None, 'Edit your preferences', self.dia_preferences),
|
||||||
('import', None, '_Import'),
|
('import', None, '_Import'),
|
||||||
('sethharchive', None, '_Set HandHistory Archive Directory', None, 'Set HandHistory Archive Directory', self.select_hhArchiveBase),
|
('sethharchive', None, '_Set HandHistory Archive Directory', None, 'Set HandHistory Archive Directory', self.select_hhArchiveBase),
|
||||||
('bulkimp', None, '_Bulk Import', '<control>B', 'Bulk Import', self.tab_bulk_import),
|
('bulkimp', None, '_Bulk Import', '<control>B', 'Bulk Import', self.tab_bulk_import),
|
||||||
|
@ -415,6 +514,7 @@ class fpdb:
|
||||||
('createuser', None, 'Create or Delete _User (todo)', None, 'Create or Delete User', self.dia_create_del_user),
|
('createuser', None, 'Create or Delete _User (todo)', None, 'Create or Delete User', self.dia_create_del_user),
|
||||||
('createtabs', None, 'Create or Recreate _Tables', None, 'Create or Recreate Tables ', self.dia_recreate_tables),
|
('createtabs', None, 'Create or Recreate _Tables', None, 'Create or Recreate Tables ', self.dia_recreate_tables),
|
||||||
('rebuildhudcache', None, 'Rebuild HUD Cache', None, 'Rebuild HUD Cache', self.dia_recreate_hudcache),
|
('rebuildhudcache', None, 'Rebuild HUD Cache', None, 'Rebuild HUD Cache', self.dia_recreate_hudcache),
|
||||||
|
('rebuildindexes', None, 'Rebuild DB Indexes', None, 'Rebuild DB Indexes', self.dia_rebuild_indexes),
|
||||||
('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),
|
||||||
|
@ -450,24 +550,32 @@ class fpdb:
|
||||||
if self.db is not None and self.db.fdb is not None:
|
if self.db is not None and self.db.fdb is not None:
|
||||||
self.db.disconnect()
|
self.db.disconnect()
|
||||||
|
|
||||||
self.sql = SQL.Sql(type = self.settings['db-type'], db_server = self.settings['db-server'])
|
self.sql = SQL.Sql(db_server = self.settings['db-server'])
|
||||||
try:
|
try:
|
||||||
self.db = Database.Database(self.config, sql = self.sql)
|
self.db = Database.Database(self.config, sql = self.sql)
|
||||||
except FpdbMySQLFailedError:
|
except Exceptions.FpdbMySQLAccessDenied:
|
||||||
self.warning_box("Unable to connect to MySQL! Is the MySQL server running?!", "FPDB ERROR")
|
self.warning_box("MySQL Server reports: Access denied. Are your permissions set correctly?")
|
||||||
exit()
|
exit()
|
||||||
except FpdbError:
|
except Exceptions.FpdbMySQLNoDatabase:
|
||||||
#print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user'])
|
msg = "MySQL client reports: 2002 error. Unable to connect - Please check that the MySQL service has been started"
|
||||||
self.warning_box("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']), "FPDB ERROR")
|
self.warning_box(msg)
|
||||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
exit
|
||||||
print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
|
|
||||||
sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']))
|
# except FpdbMySQLFailedError:
|
||||||
except:
|
# self.warning_box("Unable to connect to MySQL! Is the MySQL server running?!", "FPDB ERROR")
|
||||||
#print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user'])
|
# exit()
|
||||||
self.warning_box("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']), "FPDB ERROR")
|
# except FpdbError:
|
||||||
err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
# #print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user'])
|
||||||
print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
|
# self.warning_box("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']), "FPDB ERROR")
|
||||||
sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']))
|
# err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||||
|
# print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
|
||||||
|
# sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']))
|
||||||
|
# except:
|
||||||
|
# #print "Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user'])
|
||||||
|
# self.warning_box("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']), "FPDB ERROR")
|
||||||
|
# err = traceback.extract_tb(sys.exc_info()[2])[-1]
|
||||||
|
# print "*** Error: " + err[2] + "(" + str(err[1]) + "): " + str(sys.exc_info()[1])
|
||||||
|
# sys.stderr.write("Failed to connect to %s database with username %s." % (self.settings['db-server'], self.settings['db-user']))
|
||||||
|
|
||||||
if self.db.wrongDbVersion:
|
if self.db.wrongDbVersion:
|
||||||
diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
|
diaDbVersionWarning = gtk.Dialog(title="Strong Warning - Invalid database version", parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
|
||||||
|
@ -496,7 +604,7 @@ class fpdb:
|
||||||
|
|
||||||
# Database connected to successfully, load queries to pass on to other classes
|
# Database connected to successfully, load queries to pass on to other classes
|
||||||
self.db.rollback()
|
self.db.rollback()
|
||||||
|
|
||||||
self.validate_config()
|
self.validate_config()
|
||||||
|
|
||||||
def not_implemented(self, widget, data=None):
|
def not_implemented(self, widget, data=None):
|
||||||
|
@ -607,24 +715,20 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||||
menubar.show()
|
menubar.show()
|
||||||
#done menubar
|
#done menubar
|
||||||
|
|
||||||
|
self.nb = gtk.Notebook()
|
||||||
|
self.nb.set_show_tabs(True)
|
||||||
|
self.nb.show()
|
||||||
|
self.main_vbox.pack_start(self.nb, True, True, 0)
|
||||||
|
self.pages=[]
|
||||||
self.tabs=[]
|
self.tabs=[]
|
||||||
self.tab_names=[]
|
self.tab_names=[]
|
||||||
self.tab_buttons=[]
|
self.nb_tabs=[]
|
||||||
self.tab_box = gtk.HBox(True,1)
|
|
||||||
self.main_vbox.pack_start(self.tab_box, False, True, 0)
|
|
||||||
self.tab_box.show()
|
|
||||||
#done tab bar
|
|
||||||
|
|
||||||
self.current_tab = gtk.VBox(False,1)
|
|
||||||
self.current_tab.set_border_width(1)
|
|
||||||
self.main_vbox.add(self.current_tab)
|
|
||||||
self.current_tab.show()
|
|
||||||
|
|
||||||
self.tab_main_help(None, None)
|
self.tab_main_help(None, None)
|
||||||
|
|
||||||
self.window.show()
|
self.window.show()
|
||||||
self.load_profile()
|
self.load_profile()
|
||||||
|
|
||||||
self.statusIcon = gtk.StatusIcon()
|
self.statusIcon = gtk.StatusIcon()
|
||||||
if os.path.exists('../gfx/fpdb-cards.png'):
|
if os.path.exists('../gfx/fpdb-cards.png'):
|
||||||
self.statusIcon.set_from_file('../gfx/fpdb-cards.png')
|
self.statusIcon.set_from_file('../gfx/fpdb-cards.png')
|
||||||
|
@ -643,19 +747,19 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||||
self.statusMenu.append(menuItem)
|
self.statusMenu.append(menuItem)
|
||||||
self.statusIcon.connect('popup-menu', self.statusicon_menu, self.statusMenu)
|
self.statusIcon.connect('popup-menu', self.statusicon_menu, self.statusMenu)
|
||||||
self.statusIcon.set_visible(True)
|
self.statusIcon.set_visible(True)
|
||||||
|
|
||||||
self.window.connect('window-state-event', self.window_state_event_cb)
|
self.window.connect('window-state-event', self.window_state_event_cb)
|
||||||
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
|
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)
|
||||||
#bits = bits ^ (win32con.WS_EX_TOOLWINDOW | win32con.WS_EX_APPWINDOW)
|
#bits = bits ^ (win32con.WS_EX_TOOLWINDOW | win32con.WS_EX_APPWINDOW)
|
||||||
|
|
||||||
#win32api.SetWindowLong(self.window.window.handle, -20, bits)
|
#win32api.SetWindowLong(self.window.window.handle, -20, bits)
|
||||||
|
|
||||||
if event.new_window_state & gtk.gdk.WINDOW_STATE_ICONIFIED:
|
if event.new_window_state & gtk.gdk.WINDOW_STATE_ICONIFIED:
|
||||||
self.window.hide()
|
self.window.hide()
|
||||||
self.window.set_skip_taskbar_hint(True)
|
self.window.set_skip_taskbar_hint(True)
|
||||||
|
@ -665,7 +769,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||||
self.window.set_skip_pager_hint(False)
|
self.window.set_skip_pager_hint(False)
|
||||||
# Tell GTK not to propagate this signal any further
|
# Tell GTK not to propagate this signal any further
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def statusicon_menu(self, widget, button, time, data = None):
|
def statusicon_menu(self, widget, button, time, data = None):
|
||||||
# we don't need to pass data here, since we do keep track of most all
|
# we don't need to pass data here, since we do keep track of most all
|
||||||
# our variables .. the example code that i looked at for this
|
# our variables .. the example code that i looked at for this
|
||||||
|
@ -676,7 +780,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||||
data.show_all()
|
data.show_all()
|
||||||
data.popup(None, None, None, 3, time)
|
data.popup(None, None, None, 3, time)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def statusicon_activate(self, widget, data = None):
|
def statusicon_activate(self, widget, data = None):
|
||||||
# Let's allow the tray icon to toggle window visibility, the way
|
# Let's allow the tray icon to toggle window visibility, the way
|
||||||
# most other apps work
|
# most other apps work
|
||||||
|
@ -686,7 +790,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||||
else:
|
else:
|
||||||
self.window.show()
|
self.window.show()
|
||||||
self.window.present()
|
self.window.present()
|
||||||
|
|
||||||
def warning_box(self, str, diatitle="FPDB WARNING"):
|
def warning_box(self, str, diatitle="FPDB WARNING"):
|
||||||
diaWarning = gtk.Dialog(title=diatitle, parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
|
diaWarning = gtk.Dialog(title=diatitle, parent=None, flags=0, buttons=(gtk.STOCK_OK,gtk.RESPONSE_OK))
|
||||||
|
|
||||||
|
@ -697,7 +801,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||||
response = diaWarning.run()
|
response = diaWarning.run()
|
||||||
diaWarning.destroy()
|
diaWarning.destroy()
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def validate_config(self):
|
def validate_config(self):
|
||||||
hhbase = self.config.get_import_parameters().get("hhArchiveBase")
|
hhbase = self.config.get_import_parameters().get("hhArchiveBase")
|
||||||
hhbase = os.path.expanduser(hhbase)
|
hhbase = os.path.expanduser(hhbase)
|
||||||
|
@ -716,7 +820,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||||
self.warning_box("WARNING: Unable to create hand output directory. Importing is not likely to work until this is fixed.")
|
self.warning_box("WARNING: Unable to create hand output directory. Importing is not likely to work until this is fixed.")
|
||||||
elif response == gtk.RESPONSE_NO:
|
elif response == gtk.RESPONSE_NO:
|
||||||
self.select_hhArchiveBase()
|
self.select_hhArchiveBase()
|
||||||
|
|
||||||
def select_hhArchiveBase(self, widget=None):
|
def select_hhArchiveBase(self, widget=None):
|
||||||
fc = gtk.FileChooserDialog(title="Select HH Output Directory", parent=None, action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_OPEN,gtk.RESPONSE_OK), backend=None)
|
fc = gtk.FileChooserDialog(title="Select HH Output Directory", parent=None, action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, buttons=(gtk.STOCK_OPEN,gtk.RESPONSE_OK), backend=None)
|
||||||
fc.run()
|
fc.run()
|
||||||
|
@ -726,7 +830,7 @@ This program is licensed under the AGPL3, see docs"""+os.sep+"agpl-3.0.txt")
|
||||||
self.config.save()
|
self.config.save()
|
||||||
self.load_profile() # we can't do this at the end of this func because load_profile calls this func
|
self.load_profile() # we can't do this at the end of this func because load_profile calls this func
|
||||||
fc.destroy() # TODO: loop this to make sure we get valid data back from it, because the open directory thing in GTK lets you select files and not select things and other stupid bullshit
|
fc.destroy() # TODO: loop this to make sure we get valid data back from it, because the open directory thing in GTK lets you select files and not select things and other stupid bullshit
|
||||||
|
|
||||||
def main(self):
|
def main(self):
|
||||||
gtk.main()
|
gtk.main()
|
||||||
return 0
|
return 0
|
||||||
|
|
|
@ -20,6 +20,7 @@ import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
|
import math
|
||||||
from time import time, strftime
|
from time import time, strftime
|
||||||
from Exceptions import *
|
from Exceptions import *
|
||||||
|
|
||||||
|
@ -30,15 +31,37 @@ except ImportError:
|
||||||
logging.info("Not using sqlalchemy connection pool.")
|
logging.info("Not using sqlalchemy connection pool.")
|
||||||
use_pool = False
|
use_pool = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
from numpy import var
|
||||||
|
use_numpy = True
|
||||||
|
except ImportError:
|
||||||
|
logging.info("Not using numpy to define variance in sqlite.")
|
||||||
|
use_numpy = False
|
||||||
|
|
||||||
import fpdb_simple
|
import fpdb_simple
|
||||||
import FpdbSQLQueries
|
import FpdbSQLQueries
|
||||||
|
import Configuration
|
||||||
|
|
||||||
|
# Variance created as sqlite has a bunch of undefined aggregate functions.
|
||||||
|
|
||||||
|
class VARIANCE:
|
||||||
|
def __init__(self):
|
||||||
|
self.store = []
|
||||||
|
|
||||||
|
def step(self, value):
|
||||||
|
self.store.append(value)
|
||||||
|
|
||||||
|
def finalize(self):
|
||||||
|
return float(var(self.store))
|
||||||
|
|
||||||
|
class sqlitemath:
|
||||||
|
def mod(self, a, b):
|
||||||
|
return a%b
|
||||||
|
|
||||||
class fpdb_db:
|
class fpdb_db:
|
||||||
MYSQL_INNODB = 2
|
MYSQL_INNODB = 2
|
||||||
PGSQL = 3
|
PGSQL = 3
|
||||||
SQLITE = 4
|
SQLITE = 4
|
||||||
sqlite_db_dir = ".." + os.sep + "database"
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""Simple constructor, doesnt really do anything"""
|
"""Simple constructor, doesnt really do anything"""
|
||||||
|
@ -59,10 +82,10 @@ class fpdb_db:
|
||||||
self.connect(backend=db['db-backend'],
|
self.connect(backend=db['db-backend'],
|
||||||
host=db['db-host'],
|
host=db['db-host'],
|
||||||
database=db['db-databaseName'],
|
database=db['db-databaseName'],
|
||||||
user=db['db-user'],
|
user=db['db-user'],
|
||||||
password=db['db-password'])
|
password=db['db-password'])
|
||||||
#end def do_connect
|
#end def do_connect
|
||||||
|
|
||||||
def connect(self, backend=None, host=None, database=None,
|
def connect(self, backend=None, host=None, database=None,
|
||||||
user=None, password=None):
|
user=None, password=None):
|
||||||
"""Connects a database with the given parameters"""
|
"""Connects a database with the given parameters"""
|
||||||
|
@ -77,12 +100,17 @@ class fpdb_db:
|
||||||
import MySQLdb
|
import MySQLdb
|
||||||
if use_pool:
|
if use_pool:
|
||||||
MySQLdb = pool.manage(MySQLdb, pool_size=5)
|
MySQLdb = pool.manage(MySQLdb, pool_size=5)
|
||||||
# try:
|
try:
|
||||||
self.db = MySQLdb.connect(host=host, user=user, passwd=password, db=database, use_unicode=True)
|
self.db = MySQLdb.connect(host=host, user=user, passwd=password, db=database, use_unicode=True)
|
||||||
#TODO: Add port option
|
#TODO: Add port option
|
||||||
# except:
|
except MySQLdb.Error, ex:
|
||||||
# raise FpdbMySQLFailedError("MySQL connection failed")
|
if ex.args[0] == 1045:
|
||||||
elif backend==fpdb_db.PGSQL:
|
raise FpdbMySQLAccessDenied(ex.args[0], ex.args[1])
|
||||||
|
elif ex.args[0] == 2002:
|
||||||
|
raise FpdbMySQLNoDatabase(ex.args[0], ex.args[1])
|
||||||
|
else:
|
||||||
|
print "*** WARNING UNKNOWN MYSQL ERROR", ex
|
||||||
|
elif backend == fpdb_db.PGSQL:
|
||||||
import psycopg2
|
import psycopg2
|
||||||
import psycopg2.extensions
|
import psycopg2.extensions
|
||||||
if use_pool:
|
if use_pool:
|
||||||
|
@ -108,8 +136,8 @@ class fpdb_db:
|
||||||
if not connected:
|
if not connected:
|
||||||
try:
|
try:
|
||||||
self.db = psycopg2.connect(host = host,
|
self.db = psycopg2.connect(host = host,
|
||||||
user = user,
|
user = user,
|
||||||
password = password,
|
password = password,
|
||||||
database = database)
|
database = database)
|
||||||
except:
|
except:
|
||||||
msg = "PostgreSQL connection to database (%s) user (%s) failed. Are you sure the DB is running?" % (database, user)
|
msg = "PostgreSQL connection to database (%s) user (%s) failed. Are you sure the DB is running?" % (database, user)
|
||||||
|
@ -123,13 +151,20 @@ class fpdb_db:
|
||||||
else:
|
else:
|
||||||
logging.warning("SQLite won't work well without 'sqlalchemy' installed.")
|
logging.warning("SQLite won't work well without 'sqlalchemy' installed.")
|
||||||
|
|
||||||
if not os.path.isdir(self.sqlite_db_dir):
|
if not os.path.isdir(Configuration.DIR_DATABASES) and not database == ":memory:":
|
||||||
print "Creating directory: '%s'" % (self.sqlite_db_dir)
|
print "Creating directory: '%s'" % (Configuration.DIR_DATABASES)
|
||||||
os.mkdir(self.sqlite_db_dir)
|
os.mkdir(Configuration.DIR_DATABASES)
|
||||||
self.db = sqlite3.connect( self.sqlite_db_dir + os.sep + database
|
database = os.path.join(Configuration.DIR_DATABASE, database)
|
||||||
, detect_types=sqlite3.PARSE_DECLTYPES )
|
self.db = sqlite3.connect(database, detect_types=sqlite3.PARSE_DECLTYPES )
|
||||||
sqlite3.register_converter("bool", lambda x: bool(int(x)))
|
sqlite3.register_converter("bool", lambda x: bool(int(x)))
|
||||||
sqlite3.register_adapter(bool, lambda x: "1" if x else "0")
|
sqlite3.register_adapter(bool, lambda x: "1" if x else "0")
|
||||||
|
self.db.create_function("floor", 1, math.floor)
|
||||||
|
tmp = sqlitemath()
|
||||||
|
self.db.create_function("mod", 2, tmp.mod)
|
||||||
|
if use_numpy:
|
||||||
|
self.db.create_aggregate("variance", 1, VARIANCE)
|
||||||
|
else:
|
||||||
|
logging.warning("Some database functions will not work without NumPy support")
|
||||||
else:
|
else:
|
||||||
raise FpdbError("unrecognised database backend:"+backend)
|
raise FpdbError("unrecognised database backend:"+backend)
|
||||||
self.cursor = self.db.cursor()
|
self.cursor = self.db.cursor()
|
||||||
|
@ -157,13 +192,13 @@ class fpdb_db:
|
||||||
self.cursor.close()
|
self.cursor.close()
|
||||||
self.db.close()
|
self.db.close()
|
||||||
#end def disconnect
|
#end def disconnect
|
||||||
|
|
||||||
def reconnect(self, due_to_error=False):
|
def reconnect(self, due_to_error=False):
|
||||||
"""Reconnects the DB"""
|
"""Reconnects the DB"""
|
||||||
#print "started fpdb_db.reconnect"
|
#print "started fpdb_db.reconnect"
|
||||||
self.disconnect(due_to_error)
|
self.disconnect(due_to_error)
|
||||||
self.connect(self.backend, self.host, self.database, self.user, self.password)
|
self.connect(self.backend, self.host, self.database, self.user, self.password)
|
||||||
|
|
||||||
def get_backend_name(self):
|
def get_backend_name(self):
|
||||||
"""Returns the name of the currently used backend"""
|
"""Returns the name of the currently used backend"""
|
||||||
if self.backend==2:
|
if self.backend==2:
|
||||||
|
@ -175,7 +210,7 @@ class fpdb_db:
|
||||||
else:
|
else:
|
||||||
raise FpdbError("invalid backend")
|
raise FpdbError("invalid backend")
|
||||||
#end def get_backend_name
|
#end def get_backend_name
|
||||||
|
|
||||||
def get_db_info(self):
|
def get_db_info(self):
|
||||||
return (self.host, self.database, self.user, self.password)
|
return (self.host, self.database, self.user, self.password)
|
||||||
#end def get_db_info
|
#end def get_db_info
|
||||||
|
|
|
@ -42,15 +42,7 @@ import fpdb_parse_logic
|
||||||
import Configuration
|
import Configuration
|
||||||
import Exceptions
|
import Exceptions
|
||||||
|
|
||||||
import logging, logging.config
|
log = Configuration.get_logger("logging.conf", "importer")
|
||||||
import ConfigParser
|
|
||||||
|
|
||||||
try:
|
|
||||||
logging.config.fileConfig(os.path.join(sys.path[0],"logging.conf"))
|
|
||||||
except ConfigParser.NoSectionError: # debian package path
|
|
||||||
logging.config.fileConfig('/usr/share/python-fpdb/logging.conf')
|
|
||||||
|
|
||||||
log = logging.getLogger('importer')
|
|
||||||
|
|
||||||
# database interface modules
|
# database interface modules
|
||||||
try:
|
try:
|
||||||
|
@ -59,7 +51,7 @@ except ImportError:
|
||||||
log.debug("Import database module: MySQLdb not found")
|
log.debug("Import database module: MySQLdb not found")
|
||||||
else:
|
else:
|
||||||
mysqlLibFound = True
|
mysqlLibFound = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import psycopg2
|
import psycopg2
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -89,7 +81,7 @@ class Importer:
|
||||||
self.pos_in_file = {} # dict to remember how far we have read in the file
|
self.pos_in_file = {} # dict to remember how far we have read in the file
|
||||||
#Set defaults
|
#Set defaults
|
||||||
self.callHud = self.config.get_import_parameters().get("callFpdbHud")
|
self.callHud = self.config.get_import_parameters().get("callFpdbHud")
|
||||||
|
|
||||||
# CONFIGURATION OPTIONS
|
# CONFIGURATION OPTIONS
|
||||||
self.settings.setdefault("minPrint", 30)
|
self.settings.setdefault("minPrint", 30)
|
||||||
self.settings.setdefault("handCount", 0)
|
self.settings.setdefault("handCount", 0)
|
||||||
|
@ -107,7 +99,7 @@ class Importer:
|
||||||
for i in xrange(self.settings['threads']):
|
for i in xrange(self.settings['threads']):
|
||||||
self.writerdbs.append( Database.Database(self.config, sql = self.sql) )
|
self.writerdbs.append( Database.Database(self.config, sql = self.sql) )
|
||||||
|
|
||||||
self.NEWIMPORT = False
|
self.NEWIMPORT = Configuration.NEWIMPORT
|
||||||
|
|
||||||
#Set functions
|
#Set functions
|
||||||
def setCallHud(self, value):
|
def setCallHud(self, value):
|
||||||
|
@ -251,9 +243,9 @@ class Importer:
|
||||||
#self.writeq.join()
|
#self.writeq.join()
|
||||||
#using empty() might be more reliable:
|
#using empty() might be more reliable:
|
||||||
while not self.writeq.empty() and len(threading.enumerate()) > 1:
|
while not self.writeq.empty() and len(threading.enumerate()) > 1:
|
||||||
# TODO: Do we need to actually tell the progress indicator to move, or is it already moving, and we just need to process events...
|
# TODO: Do we need to actually tell the progress indicator to move, or is it already moving, and we just need to process events...
|
||||||
while gtk.events_pending(): # see http://faq.pygtk.org/index.py?req=index for more hints (3.7)
|
while gtk.events_pending(): # see http://faq.pygtk.org/index.py?req=index for more hints (3.7)
|
||||||
gtk.main_iteration(False)
|
gtk.main_iteration(False)
|
||||||
sleep(0.5)
|
sleep(0.5)
|
||||||
print " ... writers finished"
|
print " ... writers finished"
|
||||||
|
|
||||||
|
@ -275,7 +267,7 @@ class Importer:
|
||||||
""""Read filenames in self.filelist and pass to import_file_dict().
|
""""Read filenames in self.filelist and pass to import_file_dict().
|
||||||
Uses a separate database connection if created as a thread (caller
|
Uses a separate database connection if created as a thread (caller
|
||||||
passes None or no param as db)."""
|
passes None or no param as db)."""
|
||||||
|
|
||||||
totstored = 0
|
totstored = 0
|
||||||
totdups = 0
|
totdups = 0
|
||||||
totpartial = 0
|
totpartial = 0
|
||||||
|
@ -308,7 +300,7 @@ class Importer:
|
||||||
except:
|
except:
|
||||||
pass # if this fails we're probably doomed anyway
|
pass # if this fails we're probably doomed anyway
|
||||||
if self.settings['handsInDB'] < 5000: return "drop"
|
if self.settings['handsInDB'] < 5000: return "drop"
|
||||||
if len(self.filelist) < 50: return "don't drop"
|
if len(self.filelist) < 50: return "don't drop"
|
||||||
if self.settings['handsInDB'] > 50000: return "don't drop"
|
if self.settings['handsInDB'] > 50000: return "don't drop"
|
||||||
return "drop"
|
return "drop"
|
||||||
|
|
||||||
|
@ -321,7 +313,7 @@ class Importer:
|
||||||
size_per_hand = 1300.0 # wag based on a PS 6-up FLHE file. Actual value not hugely important
|
size_per_hand = 1300.0 # wag based on a PS 6-up FLHE file. Actual value not hugely important
|
||||||
# as values of scale and increment compensate for it anyway.
|
# as values of scale and increment compensate for it anyway.
|
||||||
# decimal used to force float arithmetic
|
# decimal used to force float arithmetic
|
||||||
|
|
||||||
# get number of hands in db
|
# get number of hands in db
|
||||||
if 'handsInDB' not in self.settings:
|
if 'handsInDB' not in self.settings:
|
||||||
try:
|
try:
|
||||||
|
@ -330,7 +322,7 @@ class Importer:
|
||||||
self.settings['handsInDB'] = tmpcursor.fetchone()[0]
|
self.settings['handsInDB'] = tmpcursor.fetchone()[0]
|
||||||
except:
|
except:
|
||||||
pass # if this fails we're probably doomed anyway
|
pass # if this fails we're probably doomed anyway
|
||||||
|
|
||||||
# add up size of import files
|
# add up size of import files
|
||||||
total_size = 0.0
|
total_size = 0.0
|
||||||
for file in self.filelist:
|
for file in self.filelist:
|
||||||
|
@ -352,12 +344,12 @@ class Importer:
|
||||||
#Check for new files in monitored directories
|
#Check for new files in monitored directories
|
||||||
#todo: make efficient - always checks for new file, should be able to use mtime of directory
|
#todo: make efficient - always checks for new file, should be able to use mtime of directory
|
||||||
# ^^ May not work on windows
|
# ^^ May not work on windows
|
||||||
|
|
||||||
#rulog = open('runUpdated.txt', 'a')
|
#rulog = open('runUpdated.txt', 'a')
|
||||||
#rulog.writelines("runUpdated ... ")
|
#rulog.writelines("runUpdated ... ")
|
||||||
for site in self.dirlist:
|
for site in self.dirlist:
|
||||||
self.addImportDirectory(self.dirlist[site][0], False, site, self.dirlist[site][1])
|
self.addImportDirectory(self.dirlist[site][0], False, site, self.dirlist[site][1])
|
||||||
|
|
||||||
for file in self.filelist:
|
for file in self.filelist:
|
||||||
if os.path.exists(file):
|
if os.path.exists(file):
|
||||||
stat_info = os.stat(file)
|
stat_info = os.stat(file)
|
||||||
|
@ -365,6 +357,11 @@ class Importer:
|
||||||
if file in self.updatedsize: # we should be able to assume that if we're in size, we're in time as well
|
if file in self.updatedsize: # we should be able to assume that if we're in size, we're in time as well
|
||||||
if stat_info.st_size > self.updatedsize[file] or stat_info.st_mtime > self.updatedtime[file]:
|
if stat_info.st_size > self.updatedsize[file] or 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]
|
# print "file",counter," updated", os.path.basename(file), stat_info.st_size, self.updatedsize[file], stat_info.st_mtime, self.updatedtime[file]
|
||||||
|
try:
|
||||||
|
if not os.path.isdir(file):
|
||||||
|
self.caller.addText("\n"+file)
|
||||||
|
except KeyError: # TODO: What error happens here?
|
||||||
|
pass
|
||||||
self.import_file_dict(self.database, file, self.filelist[file][0], self.filelist[file][1], None)
|
self.import_file_dict(self.database, file, self.filelist[file][0], self.filelist[file][1], None)
|
||||||
self.updatedsize[file] = stat_info.st_size
|
self.updatedsize[file] = stat_info.st_size
|
||||||
self.updatedtime[file] = time()
|
self.updatedtime[file] = time()
|
||||||
|
@ -377,13 +374,13 @@ class Importer:
|
||||||
self.updatedtime[file] = time()
|
self.updatedtime[file] = time()
|
||||||
else:
|
else:
|
||||||
self.removeFromFileList[file] = True
|
self.removeFromFileList[file] = True
|
||||||
|
|
||||||
self.addToDirList = filter(lambda x: self.addImportDirectory(x, True, self.addToDirList[x][0], self.addToDirList[x][1]), self.addToDirList)
|
self.addToDirList = filter(lambda x: self.addImportDirectory(x, True, self.addToDirList[x][0], self.addToDirList[x][1]), self.addToDirList)
|
||||||
|
|
||||||
for file in self.removeFromFileList:
|
for file in self.removeFromFileList:
|
||||||
if file in self.filelist:
|
if file in self.filelist:
|
||||||
del self.filelist[file]
|
del self.filelist[file]
|
||||||
|
|
||||||
self.addToDirList = {}
|
self.addToDirList = {}
|
||||||
self.removeFromFileList = {}
|
self.removeFromFileList = {}
|
||||||
self.database.rollback()
|
self.database.rollback()
|
||||||
|
@ -393,7 +390,7 @@ class Importer:
|
||||||
# This is now an internal function that should not be called directly.
|
# This is now an internal function that should not be called directly.
|
||||||
def import_file_dict(self, db, file, site, filter, q=None):
|
def import_file_dict(self, db, file, site, filter, q=None):
|
||||||
#print "import_file_dict"
|
#print "import_file_dict"
|
||||||
|
|
||||||
if os.path.isdir(file):
|
if os.path.isdir(file):
|
||||||
self.addToDirList[file] = [site] + [filter]
|
self.addToDirList[file] = [site] + [filter]
|
||||||
return
|
return
|
||||||
|
@ -401,7 +398,7 @@ class Importer:
|
||||||
conv = None
|
conv = None
|
||||||
(stored, duplicates, partial, errors, ttime) = (0, 0, 0, 0, 0)
|
(stored, duplicates, partial, errors, ttime) = (0, 0, 0, 0, 0)
|
||||||
|
|
||||||
file = file.decode(fpdb_simple.LOCALE_ENCODING)
|
file = file.decode(fpdb_simple.LOCALE_ENCODING)
|
||||||
|
|
||||||
# Load filter, process file, pass returned filename to import_fpdb_file
|
# Load filter, process file, pass returned filename to import_fpdb_file
|
||||||
if self.settings['threads'] > 0 and self.writeq is not None:
|
if self.settings['threads'] > 0 and self.writeq is not None:
|
||||||
|
@ -481,7 +478,7 @@ class Importer:
|
||||||
ttime = time() - starttime
|
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())
|
||||||
|
|
||||||
if not stored:
|
if not stored:
|
||||||
if duplicates:
|
if duplicates:
|
||||||
for line_no in xrange(len(self.lines)):
|
for line_no in xrange(len(self.lines)):
|
||||||
|
@ -496,7 +493,7 @@ class Importer:
|
||||||
|
|
||||||
return (stored, duplicates, partial, errors, ttime)
|
return (stored, duplicates, partial, errors, ttime)
|
||||||
# end def import_fpdb_file
|
# end def import_fpdb_file
|
||||||
|
|
||||||
|
|
||||||
def import_fpdb_lines(self, db, lines, starttime, file, site, q = None):
|
def import_fpdb_lines(self, db, lines, starttime, file, site, q = None):
|
||||||
"""Import an fpdb hand history held in the list lines, could be one hand or many"""
|
"""Import an fpdb hand history held in the list lines, could be one hand or many"""
|
||||||
|
@ -504,7 +501,7 @@ class Importer:
|
||||||
#db.lock_for_insert() # should be ok when using one thread, but doesn't help??
|
#db.lock_for_insert() # should be ok when using one thread, but doesn't help??
|
||||||
while gtk.events_pending():
|
while gtk.events_pending():
|
||||||
gtk.main_iteration(False)
|
gtk.main_iteration(False)
|
||||||
|
|
||||||
try: # sometimes we seem to be getting an empty self.lines, in which case, we just want to return.
|
try: # sometimes we seem to be getting an empty self.lines, in which case, we just want to return.
|
||||||
firstline = lines[0]
|
firstline = lines[0]
|
||||||
except:
|
except:
|
||||||
|
@ -532,7 +529,7 @@ class Importer:
|
||||||
if len(lines[i]) < 2: #Wierd way to detect for '\r\n' or '\n'
|
if len(lines[i]) < 2: #Wierd way to detect for '\r\n' or '\n'
|
||||||
endpos = i
|
endpos = i
|
||||||
hand = lines[startpos:endpos]
|
hand = lines[startpos:endpos]
|
||||||
|
|
||||||
if len(hand[0]) < 2:
|
if len(hand[0]) < 2:
|
||||||
hand=hand[1:]
|
hand=hand[1:]
|
||||||
|
|
||||||
|
@ -556,7 +553,7 @@ class Importer:
|
||||||
if self.callHud:
|
if self.callHud:
|
||||||
#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)
|
self.caller.pipe_to_hud.stdin.write("%s" % (handsId) + os.linesep)
|
||||||
except Exceptions.DuplicateError:
|
except Exceptions.DuplicateError:
|
||||||
duplicates += 1
|
duplicates += 1
|
||||||
|
@ -582,7 +579,7 @@ class Importer:
|
||||||
if self.settings['minPrint']:
|
if self.settings['minPrint']:
|
||||||
if not ((stored+duplicates+errors) % self.settings['minPrint']):
|
if not ((stored+duplicates+errors) % self.settings['minPrint']):
|
||||||
print "stored:", stored, " duplicates:", duplicates, "errors:", errors
|
print "stored:", stored, " duplicates:", duplicates, "errors:", errors
|
||||||
|
|
||||||
if self.settings['handCount']:
|
if self.settings['handCount']:
|
||||||
if ((stored+duplicates+errors) >= self.settings['handCount']):
|
if ((stored+duplicates+errors) >= self.settings['handCount']):
|
||||||
if not self.settings['quiet']:
|
if not self.settings['quiet']:
|
||||||
|
|
|
@ -927,7 +927,7 @@ def recogniseTourneyTypeId(db, siteId, tourneySiteId, buyin, fee, knockout, rebu
|
||||||
except:
|
except:
|
||||||
cursor.execute( """SELECT id FROM TourneyTypes
|
cursor.execute( """SELECT id FROM TourneyTypes
|
||||||
WHERE siteId=%s AND buyin=%s AND fee=%s
|
WHERE siteId=%s AND buyin=%s AND fee=%s
|
||||||
AND knockout=%s AND rebuyOrAddon=%s"""
|
AND knockout=%s AND rebuyOrAddon=%s""".replace('%s', db.sql.query['placeholder'])
|
||||||
, (siteId, buyin, fee, knockout, rebuyOrAddon) )
|
, (siteId, buyin, fee, knockout, rebuyOrAddon) )
|
||||||
result = cursor.fetchone()
|
result = cursor.fetchone()
|
||||||
#print "tried selecting tourneytypes.id, result:", result
|
#print "tried selecting tourneytypes.id, result:", result
|
||||||
|
@ -939,14 +939,14 @@ def recogniseTourneyTypeId(db, siteId, tourneySiteId, buyin, fee, knockout, rebu
|
||||||
#print "insert new tourneytype record ..."
|
#print "insert new tourneytype record ..."
|
||||||
try:
|
try:
|
||||||
cursor.execute( """INSERT INTO TourneyTypes (siteId, buyin, fee, knockout, rebuyOrAddon)
|
cursor.execute( """INSERT INTO TourneyTypes (siteId, buyin, fee, knockout, rebuyOrAddon)
|
||||||
VALUES (%s, %s, %s, %s, %s)"""
|
VALUES (%s, %s, %s, %s, %s)""".replace('%s', db.sql.query['placeholder'])
|
||||||
, (siteId, buyin, fee, knockout, rebuyOrAddon) )
|
, (siteId, buyin, fee, knockout, rebuyOrAddon) )
|
||||||
ret = db.get_last_insert_id(cursor)
|
ret = db.get_last_insert_id(cursor)
|
||||||
except:
|
except:
|
||||||
#print "maybe tourneytype was created since select, try selecting again ..."
|
#print "maybe tourneytype was created since select, try selecting again ..."
|
||||||
cursor.execute( """SELECT id FROM TourneyTypes
|
cursor.execute( """SELECT id FROM TourneyTypes
|
||||||
WHERE siteId=%s AND buyin=%s AND fee=%s
|
WHERE siteId=%s AND buyin=%s AND fee=%s
|
||||||
AND knockout=%s AND rebuyOrAddon=%s"""
|
AND knockout=%s AND rebuyOrAddon=%s""".replace('%s', db.sql.query['placeholder'])
|
||||||
, (siteId, buyin, fee, knockout, rebuyOrAddon) )
|
, (siteId, buyin, fee, knockout, rebuyOrAddon) )
|
||||||
result = cursor.fetchone()
|
result = cursor.fetchone()
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -60,14 +60,10 @@ class InterProcessLockBase:
|
||||||
self._has_lock = False
|
self._has_lock = False
|
||||||
|
|
||||||
def locked(self):
|
def locked(self):
|
||||||
if self._has_lock:
|
if self.acquire():
|
||||||
return True
|
|
||||||
try:
|
|
||||||
self.acquire()
|
|
||||||
self.release()
|
self.release()
|
||||||
return False
|
return False
|
||||||
except SingleInstanceError:
|
return True
|
||||||
return True
|
|
||||||
|
|
||||||
LOCK_FILE_DIRECTORY = '/tmp'
|
LOCK_FILE_DIRECTORY = '/tmp'
|
||||||
|
|
||||||
|
@ -162,38 +158,33 @@ def test_construct():
|
||||||
|
|
||||||
>>> lock1 = InterProcessLock(name=test_name)
|
>>> lock1 = InterProcessLock(name=test_name)
|
||||||
>>> lock1.acquire()
|
>>> lock1.acquire()
|
||||||
|
True
|
||||||
|
|
||||||
>>> lock2 = InterProcessLock(name=test_name)
|
>>> lock2 = InterProcessLock(name=test_name)
|
||||||
>>> lock3 = InterProcessLock(name=test_name)
|
>>> lock3 = InterProcessLock(name=test_name)
|
||||||
|
|
||||||
# Since lock1 is locked, other attempts to acquire it fail.
|
# Since lock1 is locked, other attempts to acquire it fail.
|
||||||
>>> lock2.acquire()
|
>>> lock2.acquire()
|
||||||
Traceback (most recent call last):
|
False
|
||||||
...
|
|
||||||
SingleInstanceError: Could not acquire exclusive lock on /tmp/test.lck
|
|
||||||
|
|
||||||
>>> lock3.acquire()
|
>>> lock3.acquire()
|
||||||
Traceback (most recent call last):
|
False
|
||||||
...
|
|
||||||
SingleInstanceError: Could not acquire exclusive lock on /tmp/test.lck
|
|
||||||
|
|
||||||
# Release the lock and let lock2 have it.
|
# Release the lock and let lock2 have it.
|
||||||
>>> lock1.release()
|
>>> lock1.release()
|
||||||
>>> lock2.acquire()
|
>>> lock2.acquire()
|
||||||
|
True
|
||||||
|
|
||||||
>>> lock3.acquire()
|
>>> lock3.acquire()
|
||||||
Traceback (most recent call last):
|
False
|
||||||
...
|
|
||||||
SingleInstanceError: Could not acquire exclusive lock on /tmp/test.lck
|
|
||||||
|
|
||||||
# Release it and give it back to lock1
|
# Release it and give it back to lock1
|
||||||
>>> lock2.release()
|
>>> lock2.release()
|
||||||
>>> lock1.acquire()
|
>>> lock1.acquire()
|
||||||
|
True
|
||||||
|
|
||||||
>>> lock2.acquire()
|
>>> lock2.acquire()
|
||||||
Traceback (most recent call last):
|
False
|
||||||
...
|
|
||||||
SingleInstanceError: Could not acquire exclusive lock on /tmp/test.lck
|
|
||||||
|
|
||||||
# Test lock status
|
# Test lock status
|
||||||
>>> lock2.locked()
|
>>> lock2.locked()
|
||||||
|
@ -224,7 +215,7 @@ def test_construct():
|
||||||
... import win32con
|
... import win32con
|
||||||
... import pywintypes
|
... import pywintypes
|
||||||
... handle = win32api.OpenProcess(win32con.PROCESS_TERMINATE , pywintypes.FALSE, pid)
|
... handle = win32api.OpenProcess(win32con.PROCESS_TERMINATE , pywintypes.FALSE, pid)
|
||||||
... return (0 != win32api.TerminateProcess(handle, 0))
|
... #return (0 != win32api.TerminateProcess(handle, 0))
|
||||||
|
|
||||||
# Test to acquire the lock in another process.
|
# Test to acquire the lock in another process.
|
||||||
>>> def execute(cmd):
|
>>> def execute(cmd):
|
||||||
|
@ -237,15 +228,14 @@ def test_construct():
|
||||||
>>> pid = execute('import interlocks;a=interlocks.InterProcessLock(name=\\''+test_name+ '\\');a.acquire();')
|
>>> pid = execute('import interlocks;a=interlocks.InterProcessLock(name=\\''+test_name+ '\\');a.acquire();')
|
||||||
|
|
||||||
>>> lock1.acquire()
|
>>> lock1.acquire()
|
||||||
Traceback (most recent call last):
|
False
|
||||||
...
|
|
||||||
SingleInstanceError: Could not acquire exclusive lock on /tmp/test.lck
|
|
||||||
|
|
||||||
>>> os_independent_kill(pid)
|
>>> os_independent_kill(pid)
|
||||||
|
|
||||||
>>> time.sleep(1)
|
>>> time.sleep(1)
|
||||||
|
|
||||||
>>> lock1.acquire()
|
>>> lock1.acquire()
|
||||||
|
True
|
||||||
>>> lock1.release()
|
>>> lock1.release()
|
||||||
|
|
||||||
# Testing wait
|
# Testing wait
|
||||||
|
@ -253,13 +243,12 @@ def test_construct():
|
||||||
>>> pid = execute('import interlocks;a=interlocks.InterProcessLock(name=\\''+test_name+ '\\');a.acquire();')
|
>>> pid = execute('import interlocks;a=interlocks.InterProcessLock(name=\\''+test_name+ '\\');a.acquire();')
|
||||||
|
|
||||||
>>> lock1.acquire()
|
>>> lock1.acquire()
|
||||||
Traceback (most recent call last):
|
False
|
||||||
...
|
|
||||||
SingleInstanceError: Could not acquire exclusive lock on /tmp/test.lck
|
|
||||||
|
|
||||||
>>> os_independent_kill(pid)
|
>>> os_independent_kill(pid)
|
||||||
|
|
||||||
>>> lock1.acquire(True)
|
>>> lock1.acquire(True)
|
||||||
|
True
|
||||||
>>> lock1.release()
|
>>> lock1.release()
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -27,6 +27,22 @@ Py2exe script for fpdb.
|
||||||
# get rid of all the uneeded libraries (e.g., pyQT)
|
# get rid of all the uneeded libraries (e.g., pyQT)
|
||||||
# think about an installer
|
# think about an installer
|
||||||
|
|
||||||
|
#HOW TO USE this script:
|
||||||
|
#
|
||||||
|
# cd to the folder where this script is stored, usually .../pyfpdb.
|
||||||
|
# If there are build and dist subfolders present , delete them to get
|
||||||
|
# rid of earlier builds.
|
||||||
|
# Run the script with "py2exe_setup.py py2exe"
|
||||||
|
# You will frequently get messages about missing .dll files. E. g.,
|
||||||
|
# MSVCP90.dll. These are somewhere in your windows install, so you
|
||||||
|
# can just copy them to your working folder.
|
||||||
|
# If it works, you'll have 2 new folders, build and dist. Build is
|
||||||
|
# working space and should be deleted. Dist contains the files to be
|
||||||
|
# distributed. Last, you must copy the etc/, lib/ and share/ folders
|
||||||
|
# from your gtk/bin/ folder to the dist folder. (the whole folders, not
|
||||||
|
# just the contents) You can (should) then prune the etc/, lib/ and
|
||||||
|
# share/ folders to remove components we don't need.
|
||||||
|
|
||||||
from distutils.core import setup
|
from distutils.core import setup
|
||||||
import py2exe
|
import py2exe
|
||||||
|
|
||||||
|
@ -36,7 +52,8 @@ setup(
|
||||||
version = '0.12',
|
version = '0.12',
|
||||||
|
|
||||||
console = [ {'script': 'fpdb.py', },
|
console = [ {'script': 'fpdb.py', },
|
||||||
{'script': 'HUD_main.py', }
|
{'script': 'HUD_main.py', },
|
||||||
|
{'script': 'Configuration.py', }
|
||||||
],
|
],
|
||||||
|
|
||||||
options = {'py2exe': {
|
options = {'py2exe': {
|
||||||
|
@ -47,8 +64,10 @@ setup(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
data_files = ['HUD_config.xml',
|
data_files = ['HUD_config.xml.example',
|
||||||
'Cards01.png'
|
'Cards01.png',
|
||||||
|
'logging.conf',
|
||||||
|
(r'matplotlibdata', glob.glob(r'c:\python26\Lib\site-packages\matplotlib\mpl-data\*'))
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,971 @@
|
||||||
|
PokerStars Game #35839001292: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:12:58 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #5 is the button
|
||||||
|
Seat 1: s0rrow ($4 in chips)
|
||||||
|
Seat 2: rumble1111 ($4.58 in chips)
|
||||||
|
Seat 3: Eisenherz73 ($7.54 in chips)
|
||||||
|
Seat 4: cypis28 ($1.40 in chips)
|
||||||
|
Seat 5: bakter9 ($0.78 in chips)
|
||||||
|
Seat 6: TheLabman ($6.31 in chips)
|
||||||
|
TheLabman: posts small blind $0.05
|
||||||
|
s0rrow: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [8s Ts 8h 2s 3s]
|
||||||
|
rumble1111: calls $0.10
|
||||||
|
Eisenherz73: folds
|
||||||
|
cypis28: raises $0.10 to $0.20
|
||||||
|
bakter9: raises $0.10 to $0.30
|
||||||
|
TheLabman: folds
|
||||||
|
s0rrow: folds
|
||||||
|
rumble1111: calls $0.20
|
||||||
|
cypis28: raises $0.10 to $0.40
|
||||||
|
Betting is capped
|
||||||
|
bakter9: calls $0.10
|
||||||
|
rumble1111: calls $0.10
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
rumble1111: discards 2 cards
|
||||||
|
cypis28: discards 2 cards
|
||||||
|
bakter9: discards 1 card
|
||||||
|
rumble1111: checks
|
||||||
|
cypis28: bets $0.10
|
||||||
|
bakter9: raises $0.10 to $0.20
|
||||||
|
rumble1111: folds
|
||||||
|
cypis28: calls $0.10
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
cypis28: discards 1 card
|
||||||
|
bakter9: stands pat
|
||||||
|
cypis28: bets $0.20
|
||||||
|
bakter9: calls $0.18 and is all-in
|
||||||
|
Uncalled bet ($0.02) returned to cypis28
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
cypis28: stands pat
|
||||||
|
bakter9: stands pat
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
cypis28: shows [7c 6d 9c 4s 2c] (Lo: 9,7,6,4,2)
|
||||||
|
bakter9: shows [7s 5s 8d 4h 3c] (Lo: 8,7,5,4,3)
|
||||||
|
bakter9 collected $2.01 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $2.11 | Rake $0.10
|
||||||
|
Seat 1: s0rrow (big blind) folded before the Draw
|
||||||
|
Seat 2: rumble1111 folded after the 1st Draw
|
||||||
|
Seat 3: Eisenherz73 folded before the Draw (didn't bet)
|
||||||
|
Seat 4: cypis28 showed [7c 6d 9c 4s 2c] and lost with Lo: 9,7,6,4,2
|
||||||
|
Seat 5: bakter9 (button) showed [7s 5s 8d 4h 3c] and won ($2.01) with Lo: 8,7,5,4,3
|
||||||
|
Seat 6: TheLabman (small blind) folded before the Draw
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839050562: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:14:02 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #6 is the button
|
||||||
|
Seat 1: s0rrow ($3.90 in chips)
|
||||||
|
Seat 2: rumble1111 ($4.18 in chips)
|
||||||
|
Seat 3: Eisenherz73 ($7.54 in chips)
|
||||||
|
Seat 4: cypis28 ($0.62 in chips)
|
||||||
|
Seat 5: bakter9 ($2.01 in chips)
|
||||||
|
Seat 6: TheLabman ($6.26 in chips)
|
||||||
|
s0rrow: posts small blind $0.05
|
||||||
|
rumble1111: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [Kh Th 3d Tc 7c]
|
||||||
|
Eisenherz73: folds
|
||||||
|
cypis28: folds
|
||||||
|
bakter9: calls $0.10
|
||||||
|
TheLabman: folds
|
||||||
|
s0rrow: calls $0.05
|
||||||
|
rumble1111: checks
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
s0rrow: discards 2 cards [Kh Th]
|
||||||
|
Dealt to s0rrow [3d Tc 7c] [5c Qs]
|
||||||
|
rumble1111: discards 2 cards
|
||||||
|
bakter9: discards 2 cards
|
||||||
|
s0rrow: checks
|
||||||
|
rumble1111: bets $0.10
|
||||||
|
bakter9: folds
|
||||||
|
s0rrow: calls $0.10
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
s0rrow: discards 2 cards [Qs Tc]
|
||||||
|
Dealt to s0rrow [3d 7c 5c] [4c 2s]
|
||||||
|
rumble1111: stands pat
|
||||||
|
s0rrow: bets $0.20
|
||||||
|
rumble1111: calls $0.20
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
s0rrow: stands pat on [3d 7c 5c 4c 2s]
|
||||||
|
rumble1111: discards 1 card
|
||||||
|
s0rrow: bets $0.20
|
||||||
|
rumble1111: calls $0.20
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
s0rrow: shows [5c 4c 3d 2s 7c] (Lo: 7,5,4,3,2)
|
||||||
|
rumble1111: mucks hand
|
||||||
|
s0rrow collected $1.24 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $1.30 | Rake $0.06
|
||||||
|
Seat 1: s0rrow (small blind) showed [5c 4c 3d 2s 7c] and won ($1.24) with Lo: 7,5,4,3,2
|
||||||
|
Seat 2: rumble1111 (big blind) mucked [8s 7d 3c 6d 2h]
|
||||||
|
Seat 3: Eisenherz73 folded before the Draw (didn't bet)
|
||||||
|
Seat 4: cypis28 folded before the Draw (didn't bet)
|
||||||
|
Seat 5: bakter9 folded after the 1st Draw
|
||||||
|
Seat 6: TheLabman (button) folded before the Draw (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839109592: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:15:18 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #1 is the button
|
||||||
|
Seat 1: s0rrow ($4.54 in chips)
|
||||||
|
Seat 2: rumble1111 ($3.58 in chips)
|
||||||
|
Seat 3: Eisenherz73 ($7.54 in chips)
|
||||||
|
Seat 4: cypis28 ($0.62 in chips)
|
||||||
|
Seat 5: bakter9 ($1.91 in chips)
|
||||||
|
Seat 6: TheLabman ($6.26 in chips)
|
||||||
|
rumble1111: posts small blind $0.05
|
||||||
|
Eisenherz73: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [Tc 9s Qc 8h 3d]
|
||||||
|
cypis28: folds
|
||||||
|
bakter9: folds
|
||||||
|
TheLabman: folds
|
||||||
|
s0rrow: folds
|
||||||
|
rumble1111: folds
|
||||||
|
Uncalled bet ($0.05) returned to Eisenherz73
|
||||||
|
Eisenherz73 collected $0.10 from pot
|
||||||
|
Eisenherz73: doesn't show hand
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.10 | Rake $0
|
||||||
|
Seat 1: s0rrow (button) folded before the Draw (didn't bet)
|
||||||
|
Seat 2: rumble1111 (small blind) folded before the Draw
|
||||||
|
Seat 3: Eisenherz73 (big blind) collected ($0.10)
|
||||||
|
Seat 4: cypis28 folded before the Draw (didn't bet)
|
||||||
|
Seat 5: bakter9 folded before the Draw (didn't bet)
|
||||||
|
Seat 6: TheLabman folded before the Draw (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839118248: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:15:29 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #2 is the button
|
||||||
|
Seat 1: s0rrow ($4.54 in chips)
|
||||||
|
Seat 2: rumble1111 ($3.53 in chips)
|
||||||
|
Seat 3: Eisenherz73 ($7.59 in chips)
|
||||||
|
Seat 4: cypis28 ($0.62 in chips)
|
||||||
|
Seat 5: bakter9 ($1.91 in chips)
|
||||||
|
Seat 6: TheLabman ($6.26 in chips)
|
||||||
|
Eisenherz73: posts small blind $0.05
|
||||||
|
cypis28: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [Js 3d Qc 9s 5h]
|
||||||
|
bakter9: raises $0.10 to $0.20
|
||||||
|
TheLabman: folds
|
||||||
|
s0rrow: folds
|
||||||
|
rumble1111: folds
|
||||||
|
Eisenherz73: folds
|
||||||
|
cypis28: raises $0.10 to $0.30
|
||||||
|
bakter9: raises $0.10 to $0.40
|
||||||
|
Betting is capped
|
||||||
|
cypis28: calls $0.10
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
cypis28: discards 2 cards
|
||||||
|
bakter9: discards 1 card
|
||||||
|
cypis28: bets $0.10
|
||||||
|
bakter9: raises $0.10 to $0.20
|
||||||
|
cypis28: raises $0.02 to $0.22 and is all-in
|
||||||
|
bakter9: calls $0.02
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
cypis28: discards 1 card
|
||||||
|
bakter9: stands pat
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
cypis28: stands pat
|
||||||
|
bakter9: stands pat
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
cypis28: shows [7h 3s 2h 8h 6h] (Lo: 8,7,6,3,2)
|
||||||
|
bakter9: shows [4d 7c 2c 5s 6d] (Lo: 7,6,5,4,2)
|
||||||
|
bakter9 collected $1.23 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $1.29 | Rake $0.06
|
||||||
|
Seat 1: s0rrow folded before the Draw (didn't bet)
|
||||||
|
Seat 2: rumble1111 (button) folded before the Draw (didn't bet)
|
||||||
|
Seat 3: Eisenherz73 (small blind) folded before the Draw
|
||||||
|
Seat 4: cypis28 (big blind) showed [7h 3s 2h 8h 6h] and lost with Lo: 8,7,6,3,2
|
||||||
|
Seat 5: bakter9 showed [4d 7c 2c 5s 6d] and won ($1.23) with Lo: 7,6,5,4,2
|
||||||
|
Seat 6: TheLabman folded before the Draw (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839149377: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:16:10 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #3 is the button
|
||||||
|
Seat 1: s0rrow ($4.54 in chips)
|
||||||
|
Seat 2: rumble1111 ($3.53 in chips)
|
||||||
|
Seat 3: Eisenherz73 ($7.54 in chips)
|
||||||
|
Seat 5: bakter9 ($2.52 in chips)
|
||||||
|
Seat 6: TheLabman ($6.26 in chips)
|
||||||
|
bakter9: posts small blind $0.05
|
||||||
|
TheLabman: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [2c 3c Ts Jc Kc]
|
||||||
|
cypis28 leaves the table
|
||||||
|
s0rrow: folds
|
||||||
|
rumble1111: folds
|
||||||
|
Eisenherz73: folds
|
||||||
|
bakter9: calls $0.05
|
||||||
|
TheLabman: checks
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
bakter9: discards 2 cards
|
||||||
|
tom1206 joins the table at seat #4
|
||||||
|
TheLabman: discards 4 cards
|
||||||
|
bakter9: checks
|
||||||
|
TheLabman: checks
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
bakter9: discards 1 card
|
||||||
|
TheLabman: discards 3 cards
|
||||||
|
bakter9: checks
|
||||||
|
TheLabman: checks
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
bakter9: discards 1 card
|
||||||
|
TheLabman: discards 1 card
|
||||||
|
bakter9: bets $0.20
|
||||||
|
TheLabman: calls $0.20
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
bakter9: shows [5d 4h 8h 7d 6h] (Lo: a straight, Four to Eight)
|
||||||
|
TheLabman: shows [3h 6d 7h 5h 8d] (Lo: 8,7,6,5,3)
|
||||||
|
TheLabman collected $0.58 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.60 | Rake $0.02
|
||||||
|
Seat 1: s0rrow folded before the Draw (didn't bet)
|
||||||
|
Seat 2: rumble1111 folded before the Draw (didn't bet)
|
||||||
|
Seat 3: Eisenherz73 (button) folded before the Draw (didn't bet)
|
||||||
|
Seat 5: bakter9 (small blind) showed [5d 4h 8h 7d 6h] and lost with Lo: a straight, Four to Eight
|
||||||
|
Seat 6: TheLabman (big blind) showed [3h 6d 7h 5h 8d] and won ($0.58) with Lo: 8,7,6,5,3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839176665: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:16:46 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #5 is the button
|
||||||
|
Seat 1: s0rrow ($4.54 in chips)
|
||||||
|
Seat 2: rumble1111 ($3.53 in chips)
|
||||||
|
Seat 3: Eisenherz73 ($7.54 in chips)
|
||||||
|
Seat 4: tom1206 ($4 in chips)
|
||||||
|
Seat 5: bakter9 ($2.22 in chips)
|
||||||
|
Seat 6: TheLabman ($6.54 in chips)
|
||||||
|
TheLabman: posts small blind $0.05
|
||||||
|
s0rrow: posts big blind $0.10
|
||||||
|
tom1206: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [5d Js 7d Jd 4d]
|
||||||
|
rumble1111: calls $0.10
|
||||||
|
Eisenherz73: calls $0.10
|
||||||
|
tom1206: checks
|
||||||
|
bakter9: folds
|
||||||
|
TheLabman: calls $0.05
|
||||||
|
s0rrow: checks
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
TheLabman: discards 3 cards
|
||||||
|
s0rrow: discards 2 cards [Js Jd]
|
||||||
|
Dealt to s0rrow [5d 7d 4d] [6d 2s]
|
||||||
|
rumble1111: discards 2 cards
|
||||||
|
Eisenherz73: discards 2 cards
|
||||||
|
tom1206: discards 2 cards
|
||||||
|
TheLabman: checks
|
||||||
|
s0rrow: checks
|
||||||
|
rumble1111: checks
|
||||||
|
Eisenherz73: checks
|
||||||
|
tom1206: checks
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
TheLabman: discards 3 cards
|
||||||
|
s0rrow: stands pat on [5d 7d 4d 6d 2s]
|
||||||
|
rumble1111: discards 2 cards
|
||||||
|
Eisenherz73: discards 1 card
|
||||||
|
tom1206: discards 2 cards
|
||||||
|
TheLabman: checks
|
||||||
|
s0rrow: checks
|
||||||
|
rumble1111: checks
|
||||||
|
Eisenherz73: checks
|
||||||
|
tom1206: checks
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
TheLabman: discards 2 cards
|
||||||
|
s0rrow: stands pat on [5d 7d 4d 6d 2s]
|
||||||
|
rumble1111: discards 1 card
|
||||||
|
The deck is reshuffled
|
||||||
|
Eisenherz73: discards 1 card
|
||||||
|
tom1206: discards 2 cards
|
||||||
|
TheLabman: checks
|
||||||
|
s0rrow: bets $0.20
|
||||||
|
rumble1111: folds
|
||||||
|
Eisenherz73: folds
|
||||||
|
Eisenherz73 is sitting out
|
||||||
|
Eisenherz73 leaves the table
|
||||||
|
tom1206: folds
|
||||||
|
TheLabman: folds
|
||||||
|
Uncalled bet ($0.20) returned to s0rrow
|
||||||
|
X USN-USMC joins the table at seat #3
|
||||||
|
s0rrow collected $0.48 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.50 | Rake $0.02
|
||||||
|
Seat 1: s0rrow (big blind) collected ($0.48)
|
||||||
|
Seat 2: rumble1111 folded after the 3rd Draw
|
||||||
|
Seat 3: Eisenherz73 folded after the 3rd Draw
|
||||||
|
Seat 4: tom1206 folded after the 3rd Draw
|
||||||
|
Seat 5: bakter9 (button) folded before the Draw (didn't bet)
|
||||||
|
Seat 6: TheLabman (small blind) folded after the 3rd Draw
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839272371: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:18:50 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #6 is the button
|
||||||
|
Seat 1: s0rrow ($4.92 in chips)
|
||||||
|
Seat 2: rumble1111 ($3.43 in chips)
|
||||||
|
Seat 3: X USN-USMC ($4 in chips)
|
||||||
|
Seat 4: tom1206 ($3.90 in chips)
|
||||||
|
Seat 5: bakter9 ($2.22 in chips)
|
||||||
|
Seat 6: TheLabman ($6.44 in chips)
|
||||||
|
s0rrow: posts small blind $0.05
|
||||||
|
rumble1111: posts big blind $0.10
|
||||||
|
X USN-USMC: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [Th Js Kd 2h Qc]
|
||||||
|
X USN-USMC: checks
|
||||||
|
tom1206 has timed out
|
||||||
|
tom1206: folds
|
||||||
|
tom1206 is sitting out
|
||||||
|
bakter9: folds
|
||||||
|
TheLabman: calls $0.10
|
||||||
|
s0rrow: folds
|
||||||
|
tom1206 has returned
|
||||||
|
rumble1111: checks
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
rumble1111: discards 3 cards
|
||||||
|
X USN-USMC: discards 1 card
|
||||||
|
TheLabman: discards 2 cards
|
||||||
|
rumble1111: checks
|
||||||
|
X USN-USMC: bets $0.10
|
||||||
|
TheLabman: calls $0.10
|
||||||
|
rumble1111: calls $0.10
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
rumble1111 said, "other fckers"
|
||||||
|
rumble1111: discards 1 card
|
||||||
|
X USN-USMC: discards 1 card
|
||||||
|
TheLabman: discards 1 card
|
||||||
|
rumble1111: checks
|
||||||
|
X USN-USMC: bets $0.20
|
||||||
|
TheLabman: calls $0.20
|
||||||
|
rumble1111: calls $0.20
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
rumble1111: discards 1 card
|
||||||
|
X USN-USMC: discards 1 card
|
||||||
|
TheLabman: discards 1 card
|
||||||
|
rumble1111: checks
|
||||||
|
X USN-USMC: bets $0.20
|
||||||
|
TheLabman: folds
|
||||||
|
rumble1111: folds
|
||||||
|
Uncalled bet ($0.20) returned to X USN-USMC
|
||||||
|
X USN-USMC collected $1.19 from pot
|
||||||
|
X USN-USMC: doesn't show hand
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $1.25 | Rake $0.06
|
||||||
|
Seat 1: s0rrow (small blind) folded before the Draw
|
||||||
|
Seat 2: rumble1111 (big blind) folded after the 3rd Draw
|
||||||
|
Seat 3: X USN-USMC collected ($1.19)
|
||||||
|
Seat 4: tom1206 folded before the Draw (didn't bet)
|
||||||
|
Seat 5: bakter9 folded before the Draw (didn't bet)
|
||||||
|
Seat 6: TheLabman (button) folded after the 3rd Draw
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839360555: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:20:53 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #1 is the button
|
||||||
|
Seat 1: s0rrow ($4.87 in chips)
|
||||||
|
Seat 2: rumble1111 ($3.03 in chips)
|
||||||
|
Seat 3: X USN-USMC ($4.79 in chips)
|
||||||
|
Seat 4: tom1206 ($3.90 in chips)
|
||||||
|
Seat 5: bakter9 ($2.22 in chips)
|
||||||
|
Seat 6: TheLabman ($6.04 in chips)
|
||||||
|
rumble1111: posts small blind $0.05
|
||||||
|
X USN-USMC: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [9s Kh 2d Ks 4c]
|
||||||
|
tom1206: raises $0.10 to $0.20
|
||||||
|
bakter9: folds
|
||||||
|
TheLabman: folds
|
||||||
|
s0rrow: folds
|
||||||
|
rumble1111: calls $0.15
|
||||||
|
X USN-USMC: calls $0.10
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
rumble1111: discards 3 cards
|
||||||
|
X USN-USMC: discards 2 cards
|
||||||
|
tom1206: discards 2 cards
|
||||||
|
rumble1111: checks
|
||||||
|
X USN-USMC: bets $0.10
|
||||||
|
tom1206: calls $0.10
|
||||||
|
rumble1111: calls $0.10
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
rumble1111: discards 3 cards
|
||||||
|
X USN-USMC: stands pat
|
||||||
|
tom1206: discards 1 card
|
||||||
|
rumble1111: checks
|
||||||
|
X USN-USMC: bets $0.20
|
||||||
|
tom1206: raises $0.20 to $0.40
|
||||||
|
rumble1111: calls $0.40
|
||||||
|
X USN-USMC: calls $0.20
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
rumble1111: discards 2 cards
|
||||||
|
X USN-USMC: stands pat
|
||||||
|
tom1206: stands pat
|
||||||
|
rumble1111: bets $0.20
|
||||||
|
X USN-USMC: folds
|
||||||
|
tom1206: calls $0.20
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
rumble1111: shows [7d 4s 2s 3s 6c] (Lo: 7,6,4,3,2)
|
||||||
|
tom1206: mucks hand
|
||||||
|
rumble1111 collected $2.38 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $2.50 | Rake $0.12
|
||||||
|
Seat 1: s0rrow (button) folded before the Draw (didn't bet)
|
||||||
|
Seat 2: rumble1111 (small blind) showed [7d 4s 2s 3s 6c] and won ($2.38) with Lo: 7,6,4,3,2
|
||||||
|
Seat 3: X USN-USMC (big blind) folded after the 3rd Draw
|
||||||
|
Seat 4: tom1206 mucked [4h 6d 8d 5c 3d]
|
||||||
|
Seat 5: bakter9 folded before the Draw (didn't bet)
|
||||||
|
Seat 6: TheLabman folded before the Draw (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839412131: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:21:58 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #2 is the button
|
||||||
|
Seat 1: s0rrow ($4.87 in chips)
|
||||||
|
Seat 2: rumble1111 ($4.51 in chips)
|
||||||
|
Seat 3: X USN-USMC ($4.09 in chips)
|
||||||
|
Seat 4: tom1206 ($3 in chips)
|
||||||
|
Seat 5: bakter9 ($2.22 in chips)
|
||||||
|
Seat 6: TheLabman ($6.04 in chips)
|
||||||
|
X USN-USMC: posts small blind $0.05
|
||||||
|
tom1206: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [8c 3s Tc Ac Qd]
|
||||||
|
bakter9: calls $0.10
|
||||||
|
TheLabman: calls $0.10
|
||||||
|
s0rrow: folds
|
||||||
|
rumble1111: calls $0.10
|
||||||
|
X USN-USMC: calls $0.05
|
||||||
|
tom1206: checks
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
X USN-USMC: discards 4 cards
|
||||||
|
tom1206: discards 3 cards
|
||||||
|
bakter9: discards 2 cards
|
||||||
|
TheLabman: discards 3 cards
|
||||||
|
rumble1111: discards 3 cards
|
||||||
|
X USN-USMC: checks
|
||||||
|
tom1206: checks
|
||||||
|
bakter9: checks
|
||||||
|
TheLabman: checks
|
||||||
|
rumble1111: checks
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
X USN-USMC: discards 2 cards
|
||||||
|
tom1206: discards 2 cards
|
||||||
|
bakter9: discards 1 card
|
||||||
|
TheLabman: discards 2 cards
|
||||||
|
The deck is reshuffled
|
||||||
|
rumble1111: discards 1 card
|
||||||
|
X USN-USMC: bets $0.20
|
||||||
|
tom1206: calls $0.20
|
||||||
|
bakter9: calls $0.20
|
||||||
|
TheLabman: folds
|
||||||
|
rumble1111: calls $0.20
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
X USN-USMC: discards 1 card
|
||||||
|
tom1206: discards 1 card
|
||||||
|
bakter9: discards 1 card
|
||||||
|
rumble1111: stands pat
|
||||||
|
X USN-USMC: checks
|
||||||
|
tom1206: bets $0.20
|
||||||
|
bakter9: calls $0.20
|
||||||
|
rumble1111: folds
|
||||||
|
X USN-USMC: folds
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
tom1206: shows [4s 3h 7d 8s 2c] (Lo: 8,7,4,3,2)
|
||||||
|
bakter9: shows [8d 5c 7c 2d 6h] (Lo: 8,7,6,5,2)
|
||||||
|
tom1206 collected $1.62 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $1.70 | Rake $0.08
|
||||||
|
Seat 1: s0rrow folded before the Draw (didn't bet)
|
||||||
|
Seat 2: rumble1111 (button) folded after the 3rd Draw
|
||||||
|
Seat 3: X USN-USMC (small blind) folded after the 3rd Draw
|
||||||
|
Seat 4: tom1206 (big blind) showed [4s 3h 7d 8s 2c] and won ($1.62) with Lo: 8,7,4,3,2
|
||||||
|
Seat 5: bakter9 showed [8d 5c 7c 2d 6h] and lost with Lo: 8,7,6,5,2
|
||||||
|
Seat 6: TheLabman folded after the 2nd Draw
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839484932: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:23:30 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #3 is the button
|
||||||
|
Seat 1: s0rrow ($4.87 in chips)
|
||||||
|
Seat 2: rumble1111 ($4.21 in chips)
|
||||||
|
Seat 3: X USN-USMC ($3.79 in chips)
|
||||||
|
Seat 4: tom1206 ($4.12 in chips)
|
||||||
|
Seat 5: bakter9 ($1.72 in chips)
|
||||||
|
Seat 6: TheLabman ($5.94 in chips)
|
||||||
|
tom1206: posts small blind $0.05
|
||||||
|
bakter9: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [3d 7h 7c Jh 5s]
|
||||||
|
TheLabman: folds
|
||||||
|
s0rrow: calls $0.10
|
||||||
|
rumble1111: folds
|
||||||
|
rumble1111 leaves the table
|
||||||
|
X USN-USMC: folds
|
||||||
|
tom1206: calls $0.05
|
||||||
|
bakter9: raises $0.10 to $0.20
|
||||||
|
s0rrow: calls $0.10
|
||||||
|
tom1206: calls $0.10
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
tom1206: discards 3 cards
|
||||||
|
bakter9: discards 2 cards
|
||||||
|
s0rrow: discards 2 cards [7c Jh]
|
||||||
|
Dealt to s0rrow [3d 7h 5s] [9h Ad]
|
||||||
|
tom1206: checks
|
||||||
|
bakter9: bets $0.10
|
||||||
|
s0rrow: calls $0.10
|
||||||
|
tom1206: calls $0.10
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
tom1206: discards 2 cards
|
||||||
|
bakter9: discards 1 card
|
||||||
|
s0rrow: discards 1 card [9h]
|
||||||
|
Dealt to s0rrow [3d 7h 5s Ad] [4c]
|
||||||
|
tom1206: bets $0.20
|
||||||
|
bakter9: raises $0.20 to $0.40
|
||||||
|
bakter9 said, "zzzzzzzzzzzzzzzzzzz"
|
||||||
|
s0rrow: calls $0.40
|
||||||
|
tom1206: calls $0.20
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
tom1206: discards 1 card
|
||||||
|
bakter9: stands pat
|
||||||
|
s0rrow: stands pat on [3d 7h 5s Ad 4c]
|
||||||
|
tom1206: checks
|
||||||
|
bakter9: bets $0.20
|
||||||
|
s0rrow: calls $0.20
|
||||||
|
tom1206: raises $0.20 to $0.40
|
||||||
|
bakter9: calls $0.20
|
||||||
|
s0rrow: calls $0.20
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
tom1206: shows [4h 3c Qc 2c 6c] (Lo: Q,6,4,3,2)
|
||||||
|
bakter9: shows [3h 5d 2s 8c 6s] (Lo: 8,6,5,3,2)
|
||||||
|
s0rrow: mucks hand
|
||||||
|
bakter9 collected $3.14 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $3.30 | Rake $0.16
|
||||||
|
Seat 1: s0rrow mucked [3d 7h 4c Ad 5s]
|
||||||
|
Seat 2: rumble1111 folded before the Draw (didn't bet)
|
||||||
|
Seat 3: X USN-USMC (button) folded before the Draw (didn't bet)
|
||||||
|
Seat 4: tom1206 (small blind) showed [4h 3c Qc 2c 6c] and lost with Lo: Q,6,4,3,2
|
||||||
|
Seat 5: bakter9 (big blind) showed [3h 5d 2s 8c 6s] and won ($3.14) with Lo: 8,6,5,3,2
|
||||||
|
Seat 6: TheLabman folded before the Draw (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839619404: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:26:21 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #4 is the button
|
||||||
|
Seat 1: s0rrow ($3.77 in chips)
|
||||||
|
Seat 3: X USN-USMC ($3.79 in chips)
|
||||||
|
Seat 4: tom1206 ($3.02 in chips)
|
||||||
|
Seat 5: bakter9 ($3.76 in chips)
|
||||||
|
Seat 6: TheLabman ($5.94 in chips)
|
||||||
|
bakter9: posts small blind $0.05
|
||||||
|
TheLabman: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [Ah 7s Ad 5d As]
|
||||||
|
bakter9 said, "ty"
|
||||||
|
s0rrow: raises $0.10 to $0.20
|
||||||
|
X USN-USMC: folds
|
||||||
|
tom1206: folds
|
||||||
|
bakter9: folds
|
||||||
|
TheLabman: calls $0.10
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
TheLabman: discards 2 cards
|
||||||
|
s0rrow: discards 2 cards [7s Ad]
|
||||||
|
Dealt to s0rrow [Ah 5d As] [5h 8s]
|
||||||
|
TheLabman: checks
|
||||||
|
Mamega joins the table at seat #2
|
||||||
|
s0rrow: bets $0.10
|
||||||
|
TheLabman: calls $0.10
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
TheLabman: discards 1 card
|
||||||
|
s0rrow: stands pat on [Ah 5d As 5h 8s]
|
||||||
|
TheLabman: checks
|
||||||
|
s0rrow: bets $0.20
|
||||||
|
TheLabman: calls $0.20
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
TheLabman: discards 1 card
|
||||||
|
s0rrow: stands pat on [Ah 5d As 5h 8s]
|
||||||
|
TheLabman: checks
|
||||||
|
s0rrow: bets $0.20
|
||||||
|
TheLabman: folds
|
||||||
|
Uncalled bet ($0.20) returned to s0rrow
|
||||||
|
s0rrow collected $1 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $1.05 | Rake $0.05
|
||||||
|
Seat 1: s0rrow collected ($1)
|
||||||
|
Seat 3: X USN-USMC folded before the Draw (didn't bet)
|
||||||
|
Seat 4: tom1206 (button) folded before the Draw (didn't bet)
|
||||||
|
Seat 5: bakter9 (small blind) folded before the Draw
|
||||||
|
Seat 6: TheLabman (big blind) folded after the 3rd Draw
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839669792: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:27:24 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #5 is the button
|
||||||
|
Seat 1: s0rrow ($4.27 in chips)
|
||||||
|
Seat 3: X USN-USMC ($3.79 in chips)
|
||||||
|
Seat 4: tom1206 ($3.02 in chips)
|
||||||
|
Seat 5: bakter9 ($3.71 in chips)
|
||||||
|
Seat 6: TheLabman ($5.44 in chips)
|
||||||
|
TheLabman: posts small blind $0.05
|
||||||
|
s0rrow: posts big blind $0.10
|
||||||
|
Mamega: sits out
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [3h 6d 9s 5s Kc]
|
||||||
|
X USN-USMC: calls $0.10
|
||||||
|
tom1206: calls $0.10
|
||||||
|
bakter9: folds
|
||||||
|
TheLabman: calls $0.05
|
||||||
|
s0rrow: checks
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
TheLabman: discards 1 card
|
||||||
|
s0rrow: discards 1 card [Kc]
|
||||||
|
Dealt to s0rrow [3h 6d 9s 5s] [Jh]
|
||||||
|
X USN-USMC: discards 2 cards
|
||||||
|
tom1206: discards 2 cards
|
||||||
|
TheLabman: checks
|
||||||
|
s0rrow: checks
|
||||||
|
X USN-USMC: bets $0.10
|
||||||
|
tom1206: raises $0.10 to $0.20
|
||||||
|
TheLabman: calls $0.20
|
||||||
|
s0rrow: folds
|
||||||
|
X USN-USMC: calls $0.10
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
TheLabman: discards 1 card
|
||||||
|
X USN-USMC: discards 1 card
|
||||||
|
tom1206: stands pat
|
||||||
|
TheLabman: checks
|
||||||
|
X USN-USMC: bets $0.20
|
||||||
|
tom1206: raises $0.20 to $0.40
|
||||||
|
TheLabman: calls $0.40
|
||||||
|
X USN-USMC: raises $0.20 to $0.60
|
||||||
|
tom1206: calls $0.20
|
||||||
|
TheLabman: calls $0.20
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
TheLabman: stands pat
|
||||||
|
X USN-USMC: stands pat
|
||||||
|
tom1206: stands pat
|
||||||
|
TheLabman: checks
|
||||||
|
X USN-USMC: bets $0.20
|
||||||
|
tom1206: calls $0.20
|
||||||
|
TheLabman: calls $0.20
|
||||||
|
bakter9 leaves the table
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
X USN-USMC: shows [3s 4s 7s 2d 6c] (Lo: 7,6,4,3,2)
|
||||||
|
tom1206: mucks hand
|
||||||
|
TheLabman: mucks hand
|
||||||
|
X USN-USMC collected $3.24 from pot
|
||||||
|
LumBita joins the table at seat #5
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $3.40 | Rake $0.16
|
||||||
|
Seat 1: s0rrow (big blind) folded after the 1st Draw
|
||||||
|
Seat 3: X USN-USMC showed [3s 4s 7s 2d 6c] and won ($3.24) with Lo: 7,6,4,3,2
|
||||||
|
Seat 4: tom1206 mucked [8d 7c 4h 5h 3d]
|
||||||
|
Seat 5: bakter9 (button) folded before the Draw (didn't bet)
|
||||||
|
Seat 6: TheLabman (small blind) mucked [4d 6h 7h 2s 5c]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839735773: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:28:48 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #6 is the button
|
||||||
|
Seat 1: s0rrow ($4.17 in chips)
|
||||||
|
Seat 2: Mamega ($4 in chips)
|
||||||
|
Seat 3: X USN-USMC ($5.93 in chips)
|
||||||
|
Seat 4: tom1206 ($1.92 in chips)
|
||||||
|
Seat 5: LumBita ($1 in chips)
|
||||||
|
Seat 6: TheLabman ($4.34 in chips)
|
||||||
|
s0rrow: posts small blind $0.05
|
||||||
|
Mamega: posts big blind $0.10
|
||||||
|
LumBita: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [5c Kc Js Ts Jc]
|
||||||
|
X USN-USMC: calls $0.10
|
||||||
|
tom1206: calls $0.10
|
||||||
|
LumBita: checks
|
||||||
|
TheLabman: folds
|
||||||
|
s0rrow: folds
|
||||||
|
Mamega: checks
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
Mamega: stands pat
|
||||||
|
X USN-USMC: discards 2 cards
|
||||||
|
tom1206: discards 3 cards
|
||||||
|
LumBita: discards 1 card
|
||||||
|
Mamega: checks
|
||||||
|
X USN-USMC: bets $0.10
|
||||||
|
tom1206: calls $0.10
|
||||||
|
LumBita: calls $0.10
|
||||||
|
Mamega: folds
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
X USN-USMC: discards 1 card
|
||||||
|
tom1206: discards 1 card
|
||||||
|
LumBita: stands pat
|
||||||
|
X USN-USMC: checks
|
||||||
|
tom1206: checks
|
||||||
|
LumBita: bets $0.20
|
||||||
|
X USN-USMC: calls $0.20
|
||||||
|
tom1206: calls $0.20
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
X USN-USMC: discards 1 card
|
||||||
|
tom1206: discards 1 card
|
||||||
|
LumBita: stands pat
|
||||||
|
X USN-USMC: checks
|
||||||
|
tom1206: checks
|
||||||
|
LumBita: checks
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
X USN-USMC: shows [2h 4h 7d 5s 6c] (Lo: 7,6,5,4,2)
|
||||||
|
tom1206: mucks hand
|
||||||
|
LumBita: mucks hand
|
||||||
|
X USN-USMC collected $1.29 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $1.35 | Rake $0.06
|
||||||
|
Seat 1: s0rrow (small blind) folded before the Draw
|
||||||
|
Seat 2: Mamega (big blind) folded after the 1st Draw
|
||||||
|
Seat 3: X USN-USMC showed [2h 4h 7d 5s 6c] and won ($1.29) with Lo: 7,6,5,4,2
|
||||||
|
Seat 4: tom1206 mucked [7h 8c 3s 4d 5h]
|
||||||
|
Seat 5: LumBita mucked [4s 8s 3h 6h 2d]
|
||||||
|
Seat 6: TheLabman (button) folded before the Draw (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839797257: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:30:09 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #1 is the button
|
||||||
|
Seat 1: s0rrow ($4.12 in chips)
|
||||||
|
Seat 2: Mamega ($3.90 in chips)
|
||||||
|
Seat 3: X USN-USMC ($6.82 in chips)
|
||||||
|
Seat 4: tom1206 ($1.52 in chips)
|
||||||
|
Seat 5: LumBita ($0.60 in chips)
|
||||||
|
Seat 6: TheLabman ($4.34 in chips)
|
||||||
|
Mamega: posts small blind $0.05
|
||||||
|
X USN-USMC: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [2c Ah 3h 8h 5s]
|
||||||
|
tom1206: calls $0.10
|
||||||
|
LumBita: calls $0.10
|
||||||
|
TheLabman: folds
|
||||||
|
s0rrow: raises $0.10 to $0.20
|
||||||
|
Mamega: folds
|
||||||
|
X USN-USMC: folds
|
||||||
|
tom1206: calls $0.10
|
||||||
|
LumBita: calls $0.10
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
tom1206: discards 2 cards
|
||||||
|
LumBita: discards 2 cards
|
||||||
|
s0rrow: discards 1 card [8h]
|
||||||
|
Dealt to s0rrow [2c Ah 3h 5s] [8d]
|
||||||
|
tom1206: checks
|
||||||
|
LumBita: checks
|
||||||
|
s0rrow: bets $0.10
|
||||||
|
tom1206: calls $0.10
|
||||||
|
LumBita: calls $0.10
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
tom1206: discards 2 cards
|
||||||
|
LumBita: stands pat
|
||||||
|
s0rrow: discards 1 card [8d]
|
||||||
|
Dealt to s0rrow [2c Ah 3h 5s] [2s]
|
||||||
|
tom1206: checks
|
||||||
|
LumBita: bets $0.20
|
||||||
|
s0rrow: calls $0.20
|
||||||
|
tom1206: calls $0.20
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
tom1206: discards 1 card
|
||||||
|
LumBita: stands pat
|
||||||
|
s0rrow: discards 1 card [2s]
|
||||||
|
Dealt to s0rrow [2c Ah 3h 5s] [Qd]
|
||||||
|
tom1206: checks
|
||||||
|
LumBita: bets $0.10 and is all-in
|
||||||
|
s0rrow: folds
|
||||||
|
tom1206: folds
|
||||||
|
Uncalled bet ($0.10) returned to LumBita
|
||||||
|
LumBita collected $1.57 from pot
|
||||||
|
LumBita: doesn't show hand
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $1.65 | Rake $0.08
|
||||||
|
Seat 1: s0rrow (button) folded after the 3rd Draw
|
||||||
|
Seat 2: Mamega (small blind) folded before the Draw
|
||||||
|
Seat 3: X USN-USMC (big blind) folded before the Draw
|
||||||
|
Seat 4: tom1206 folded after the 3rd Draw
|
||||||
|
Seat 5: LumBita collected ($1.57)
|
||||||
|
Seat 6: TheLabman folded before the Draw (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839866916: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:31:36 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #2 is the button
|
||||||
|
Seat 1: s0rrow ($3.62 in chips)
|
||||||
|
Seat 2: Mamega ($3.85 in chips)
|
||||||
|
Seat 3: X USN-USMC ($6.72 in chips)
|
||||||
|
Seat 4: tom1206 ($1.02 in chips)
|
||||||
|
Seat 5: LumBita ($1.67 in chips)
|
||||||
|
Seat 6: TheLabman ($4.34 in chips)
|
||||||
|
X USN-USMC: posts small blind $0.05
|
||||||
|
tom1206: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [Jd 5c 2s 5h Qs]
|
||||||
|
LumBita: calls $0.10
|
||||||
|
TheLabman: folds
|
||||||
|
s0rrow: folds
|
||||||
|
Mamega: folds
|
||||||
|
X USN-USMC: calls $0.05
|
||||||
|
tom1206: checks
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
X USN-USMC: discards 3 cards
|
||||||
|
tom1206: discards 4 cards
|
||||||
|
LumBita: discards 2 cards
|
||||||
|
X USN-USMC: checks
|
||||||
|
tom1206: checks
|
||||||
|
LumBita: checks
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
X USN-USMC: discards 2 cards
|
||||||
|
tom1206: discards 3 cards
|
||||||
|
LumBita: discards 2 cards
|
||||||
|
X USN-USMC: checks
|
||||||
|
tom1206: checks
|
||||||
|
LumBita: checks
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
X USN-USMC: discards 2 cards
|
||||||
|
tom1206: discards 2 cards
|
||||||
|
LumBita: discards 1 card
|
||||||
|
X USN-USMC: bets $0.20
|
||||||
|
tom1206: calls $0.20
|
||||||
|
LumBita: folds
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
X USN-USMC: shows [4h 3h 2d 7h 6d] (Lo: 7,6,4,3,2)
|
||||||
|
tom1206: mucks hand
|
||||||
|
X USN-USMC collected $0.67 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.70 | Rake $0.03
|
||||||
|
Seat 1: s0rrow folded before the Draw (didn't bet)
|
||||||
|
Seat 2: Mamega (button) folded before the Draw (didn't bet)
|
||||||
|
Seat 3: X USN-USMC (small blind) showed [4h 3h 2d 7h 6d] and won ($0.67) with Lo: 7,6,4,3,2
|
||||||
|
Seat 4: tom1206 (big blind) mucked [7c 5d 9s Th 8d]
|
||||||
|
Seat 5: LumBita folded after the 3rd Draw
|
||||||
|
Seat 6: TheLabman folded before the Draw (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839926911: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:32:52 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #3 is the button
|
||||||
|
Seat 1: s0rrow ($3.62 in chips)
|
||||||
|
Seat 2: Mamega ($3.85 in chips)
|
||||||
|
Seat 3: X USN-USMC ($7.09 in chips)
|
||||||
|
Seat 4: tom1206 ($0.72 in chips)
|
||||||
|
Seat 5: LumBita ($1.57 in chips)
|
||||||
|
Seat 6: TheLabman ($4.34 in chips)
|
||||||
|
tom1206: posts small blind $0.05
|
||||||
|
LumBita: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [Qd 2d 5s Ah 8d]
|
||||||
|
TheLabman: folds
|
||||||
|
s0rrow: calls $0.10
|
||||||
|
Mamega: folds
|
||||||
|
X USN-USMC: folds
|
||||||
|
tom1206: folds
|
||||||
|
LumBita: checks
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
LumBita: discards 3 cards
|
||||||
|
s0rrow: discards 2 cards [Qd 8d]
|
||||||
|
Dealt to s0rrow [2d 5s Ah] [Jc 8h]
|
||||||
|
LumBita: checks
|
||||||
|
s0rrow: checks
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
LumBita: discards 2 cards
|
||||||
|
s0rrow: discards 1 card [Jc]
|
||||||
|
Dealt to s0rrow [2d 5s Ah 8h] [9s]
|
||||||
|
LumBita: bets $0.20
|
||||||
|
s0rrow: calls $0.20
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
LumBita: stands pat
|
||||||
|
s0rrow: stands pat on [2d 5s Ah 8h 9s]
|
||||||
|
LumBita: checks
|
||||||
|
s0rrow: checks
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
LumBita: shows [7h 2s 5c 8c 6c] (Lo: 8,7,6,5,2)
|
||||||
|
s0rrow: mucks hand
|
||||||
|
LumBita collected $0.62 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.65 | Rake $0.03
|
||||||
|
Seat 1: s0rrow mucked [9s 2d 5s Ah 8h]
|
||||||
|
Seat 2: Mamega folded before the Draw (didn't bet)
|
||||||
|
Seat 3: X USN-USMC (button) folded before the Draw (didn't bet)
|
||||||
|
Seat 4: tom1206 (small blind) folded before the Draw
|
||||||
|
Seat 5: LumBita (big blind) showed [7h 2s 5c 8c 6c] and won ($0.62) with Lo: 8,7,6,5,2
|
||||||
|
Seat 6: TheLabman folded before the Draw (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35839959625: Triple Draw 2-7 Lowball Limit ($0.10/$0.20 USD) - 2009/11/25 14:33:33 ET
|
||||||
|
Table 'Theodora VI' 6-max Seat #4 is the button
|
||||||
|
Seat 1: s0rrow ($3.32 in chips)
|
||||||
|
Seat 2: Mamega ($3.85 in chips)
|
||||||
|
Seat 3: X USN-USMC ($7.09 in chips)
|
||||||
|
Seat 4: tom1206 ($0.67 in chips)
|
||||||
|
Seat 5: LumBita ($1.89 in chips)
|
||||||
|
Seat 6: TheLabman ($4.34 in chips)
|
||||||
|
LumBita: posts small blind $0.05
|
||||||
|
TheLabman: posts big blind $0.10
|
||||||
|
*** DEALING HANDS ***
|
||||||
|
Dealt to s0rrow [Jd As 8h 3s 7c]
|
||||||
|
s0rrow: calls $0.10
|
||||||
|
Mamega: folds
|
||||||
|
X USN-USMC: folds
|
||||||
|
tom1206: calls $0.10
|
||||||
|
LumBita: calls $0.05
|
||||||
|
TheLabman: checks
|
||||||
|
*** FIRST DRAW ***
|
||||||
|
LumBita: discards 2 cards
|
||||||
|
TheLabman: discards 1 card
|
||||||
|
s0rrow: discards 1 card [Jd]
|
||||||
|
Dealt to s0rrow [As 8h 3s 7c] [4h]
|
||||||
|
tom1206: discards 2 cards
|
||||||
|
LumBita: checks
|
||||||
|
TheLabman: bets $0.10
|
||||||
|
s0rrow: calls $0.10
|
||||||
|
tom1206: raises $0.10 to $0.20
|
||||||
|
LumBita: calls $0.20
|
||||||
|
TheLabman: calls $0.10
|
||||||
|
s0rrow: calls $0.10
|
||||||
|
*** SECOND DRAW ***
|
||||||
|
LumBita: discards 1 card
|
||||||
|
TheLabman: discards 1 card
|
||||||
|
s0rrow: discards 1 card [8h]
|
||||||
|
Dealt to s0rrow [As 3s 7c 4h] [8d]
|
||||||
|
tom1206: stands pat
|
||||||
|
LumBita: checks
|
||||||
|
TheLabman: checks
|
||||||
|
s0rrow: checks
|
||||||
|
tom1206: bets $0.20
|
||||||
|
LumBita: calls $0.20
|
||||||
|
TheLabman: calls $0.20
|
||||||
|
s0rrow: calls $0.20
|
||||||
|
*** THIRD DRAW ***
|
||||||
|
LumBita: discards 1 card
|
||||||
|
TheLabman: discards 1 card
|
||||||
|
s0rrow: stands pat on [As 3s 7c 4h 8d]
|
||||||
|
tom1206: stands pat
|
||||||
|
LumBita: checks
|
||||||
|
TheLabman: checks
|
||||||
|
s0rrow: checks
|
||||||
|
tom1206: bets $0.17 and is all-in
|
||||||
|
LumBita: calls $0.17
|
||||||
|
TheLabman: folds
|
||||||
|
s0rrow: calls $0.17
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
tom1206: shows [5c 6c 4d 2h 8c] (Lo: 8,6,5,4,2)
|
||||||
|
LumBita: mucks hand
|
||||||
|
s0rrow: mucks hand
|
||||||
|
tom1206 collected $2.39 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $2.51 | Rake $0.12
|
||||||
|
Seat 1: s0rrow mucked [4h As 8d 3s 7c]
|
||||||
|
Seat 2: Mamega folded before the Draw (didn't bet)
|
||||||
|
Seat 3: X USN-USMC folded before the Draw (didn't bet)
|
||||||
|
Seat 4: tom1206 (button) showed [5c 6c 4d 2h 8c] and won ($2.39) with Lo: 8,6,5,4,2
|
||||||
|
Seat 5: LumBita (small blind) mucked [4c 3d 9c 7h 6h]
|
||||||
|
Seat 6: TheLabman (big blind) folded after the 3rd Draw
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,835 @@
|
||||||
|
PokerStars Game #35874004239: 7 Card Stud Limit ($0.04/$0.08 USD) - 2009/11/26 10:08:43 ET
|
||||||
|
Table 'Atalante II' 8-max
|
||||||
|
Seat 1: s0rrow ($1.60 in chips)
|
||||||
|
Seat 3: Nikolay Zem ($1.84 in chips)
|
||||||
|
Seat 4: totof51 ($1.34 in chips)
|
||||||
|
Seat 5: trs2758 ($1.76 in chips)
|
||||||
|
Seat 8: MasterTrini1 ($2.49 in chips)
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
Nikolay Zem: posts the ante $0.01
|
||||||
|
totof51: posts the ante $0.01
|
||||||
|
trs2758: posts the ante $0.01
|
||||||
|
MasterTrini1: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to s0rrow [3d Th As]
|
||||||
|
Dealt to Nikolay Zem [9s]
|
||||||
|
Dealt to totof51 [Td]
|
||||||
|
Dealt to trs2758 [7d]
|
||||||
|
Dealt to MasterTrini1 [2c]
|
||||||
|
MasterTrini1: brings in for $0.02
|
||||||
|
s0rrow: calls $0.02
|
||||||
|
Nikolay Zem: calls $0.02
|
||||||
|
totof51: calls $0.02
|
||||||
|
trs2758: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to s0rrow [3d Th As] [Qc]
|
||||||
|
Dealt to Nikolay Zem [9s] [6h]
|
||||||
|
Dealt to totof51 [Td] [4s]
|
||||||
|
Dealt to trs2758 [7d] [8d]
|
||||||
|
Dealt to MasterTrini1 [2c] [8c]
|
||||||
|
s0rrow: checks
|
||||||
|
Nikolay Zem: checks
|
||||||
|
totof51: checks
|
||||||
|
trs2758: checks
|
||||||
|
MasterTrini1: bets $0.04
|
||||||
|
s0rrow: folds
|
||||||
|
Nikolay Zem: calls $0.04
|
||||||
|
totof51: folds
|
||||||
|
trs2758: calls $0.04
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to Nikolay Zem [9s 6h] [7s]
|
||||||
|
Dealt to trs2758 [7d 8d] [8h]
|
||||||
|
Dealt to MasterTrini1 [2c 8c] [7h]
|
||||||
|
RoadDevil joins the table at seat #6
|
||||||
|
trs2758: bets $0.08
|
||||||
|
MasterTrini1: calls $0.08
|
||||||
|
Nikolay Zem: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to Nikolay Zem [9s 6h 7s] [Qh]
|
||||||
|
Dealt to trs2758 [7d 8d 8h] [Ts]
|
||||||
|
Dealt to MasterTrini1 [2c 8c 7h] [5d]
|
||||||
|
trs2758: bets $0.08
|
||||||
|
MasterTrini1: calls $0.08
|
||||||
|
Nikolay Zem: folds
|
||||||
|
*** RIVER ***
|
||||||
|
trs2758: bets $0.08
|
||||||
|
MasterTrini1: folds
|
||||||
|
Uncalled bet ($0.08) returned to trs2758
|
||||||
|
trs2758 collected $0.64 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.67 | Rake $0.03
|
||||||
|
Seat 1: s0rrow folded on the 4th Street
|
||||||
|
Seat 3: Nikolay Zem folded on the 6th Street
|
||||||
|
Seat 4: totof51 folded on the 4th Street
|
||||||
|
Seat 5: trs2758 collected ($0.64)
|
||||||
|
Seat 8: MasterTrini1 folded on the River
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874039554: 7 Card Stud Limit ($0.04/$0.08 USD) - 2009/11/26 10:09:44 ET
|
||||||
|
Table 'Atalante II' 8-max
|
||||||
|
Seat 1: s0rrow ($1.57 in chips)
|
||||||
|
Seat 3: Nikolay Zem ($1.69 in chips)
|
||||||
|
Seat 4: totof51 ($1.31 in chips)
|
||||||
|
Seat 5: trs2758 ($2.17 in chips)
|
||||||
|
Seat 6: RoadDevil ($1.60 in chips)
|
||||||
|
Seat 8: MasterTrini1 ($2.26 in chips)
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
Nikolay Zem: posts the ante $0.01
|
||||||
|
totof51: posts the ante $0.01
|
||||||
|
trs2758: posts the ante $0.01
|
||||||
|
RoadDevil: posts the ante $0.01
|
||||||
|
MasterTrini1: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to s0rrow [3s Qd 9h]
|
||||||
|
Dealt to Nikolay Zem [7d]
|
||||||
|
Dealt to totof51 [7c]
|
||||||
|
Dealt to trs2758 [5h]
|
||||||
|
Dealt to RoadDevil [5d]
|
||||||
|
Dealt to MasterTrini1 [Ts]
|
||||||
|
RoadDevil: brings in for $0.02
|
||||||
|
MasterTrini1: calls $0.02
|
||||||
|
s0rrow: folds
|
||||||
|
Nikolay Zem: calls $0.02
|
||||||
|
totof51: calls $0.02
|
||||||
|
trs2758: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to Nikolay Zem [7d] [Td]
|
||||||
|
Dealt to totof51 [7c] [Th]
|
||||||
|
Dealt to trs2758 [5h] [8s]
|
||||||
|
Dealt to RoadDevil [5d] [Js]
|
||||||
|
Dealt to MasterTrini1 [Ts] [5c]
|
||||||
|
RoadDevil: checks
|
||||||
|
MasterTrini1: checks
|
||||||
|
Nikolay Zem: checks
|
||||||
|
totof51: bets $0.04
|
||||||
|
trs2758: calls $0.04
|
||||||
|
RoadDevil: folds
|
||||||
|
MasterTrini1: calls $0.04
|
||||||
|
Nikolay Zem: calls $0.04
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to Nikolay Zem [7d Td] [3d]
|
||||||
|
Dealt to totof51 [7c Th] [9s]
|
||||||
|
Dealt to trs2758 [5h 8s] [4s]
|
||||||
|
Dealt to MasterTrini1 [Ts 5c] [6h]
|
||||||
|
totof51: bets $0.08
|
||||||
|
trs2758: folds
|
||||||
|
MasterTrini1: calls $0.08
|
||||||
|
Nikolay Zem: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to Nikolay Zem [7d Td 3d] [Tc]
|
||||||
|
Dealt to totof51 [7c Th 9s] [Ah]
|
||||||
|
Dealt to MasterTrini1 [Ts 5c 6h] [Jh]
|
||||||
|
Nikolay Zem: checks
|
||||||
|
totof51: bets $0.08
|
||||||
|
MasterTrini1: calls $0.08
|
||||||
|
Nikolay Zem: calls $0.08
|
||||||
|
*** RIVER ***
|
||||||
|
Nikolay Zem: checks
|
||||||
|
totof51: checks
|
||||||
|
MasterTrini1: checks
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
Nikolay Zem: shows [Ac 4d 7d Td 3d Tc 2h] (a pair of Tens)
|
||||||
|
totof51: mucks hand
|
||||||
|
totof51 is sitting out
|
||||||
|
MasterTrini1: shows [4c 6d Ts 5c 6h Jh 9c] (a pair of Sixes)
|
||||||
|
totof51 leaves the table
|
||||||
|
Nikolay Zem collected $0.77 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.80 | Rake $0.03
|
||||||
|
Seat 1: s0rrow folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 3: Nikolay Zem showed [Ac 4d 7d Td 3d Tc 2h] and won ($0.77) with a pair of Tens
|
||||||
|
Seat 4: totof51 mucked [3c 7s 7c Th 9s Ah Qc]
|
||||||
|
Seat 5: trs2758 folded on the 5th Street
|
||||||
|
Seat 6: RoadDevil folded on the 4th Street
|
||||||
|
Seat 8: MasterTrini1 showed [4c 6d Ts 5c 6h Jh 9c] and lost with a pair of Sixes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874081088: 7 Card Stud Limit ($0.04/$0.08 USD) - 2009/11/26 10:10:56 ET
|
||||||
|
Table 'Atalante II' 8-max
|
||||||
|
Seat 1: s0rrow ($1.56 in chips)
|
||||||
|
Seat 3: Nikolay Zem ($2.23 in chips)
|
||||||
|
Seat 5: trs2758 ($2.10 in chips)
|
||||||
|
Seat 6: RoadDevil ($1.57 in chips)
|
||||||
|
Seat 8: MasterTrini1 ($2.03 in chips)
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
Nikolay Zem: posts the ante $0.01
|
||||||
|
trs2758: posts the ante $0.01
|
||||||
|
RoadDevil: posts the ante $0.01
|
||||||
|
MasterTrini1: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to s0rrow [5h 5c 2s]
|
||||||
|
Dealt to Nikolay Zem [Ad]
|
||||||
|
Dealt to trs2758 [6h]
|
||||||
|
Dealt to RoadDevil [4h]
|
||||||
|
Dealt to MasterTrini1 [8h]
|
||||||
|
s0rrow: bets $0.04
|
||||||
|
Nikolay Zem: calls $0.04
|
||||||
|
trs2758: folds
|
||||||
|
RoadDevil: calls $0.04
|
||||||
|
MasterTrini1: raises $0.04 to $0.08
|
||||||
|
s0rrow: calls $0.04
|
||||||
|
Nikolay Zem: calls $0.04
|
||||||
|
RoadDevil: calls $0.04
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to s0rrow [5h 5c 2s] [As]
|
||||||
|
Dealt to Nikolay Zem [Ad] [4s]
|
||||||
|
Dealt to RoadDevil [4h] [Tc]
|
||||||
|
Dealt to MasterTrini1 [8h] [6d]
|
||||||
|
Nikolay Zem: checks
|
||||||
|
RoadDevil: checks
|
||||||
|
MasterTrini1: bets $0.04
|
||||||
|
s0rrow: calls $0.04
|
||||||
|
Nikolay Zem: folds
|
||||||
|
RoadDevil: folds
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to s0rrow [5h 5c 2s As] [5d]
|
||||||
|
Dealt to MasterTrini1 [8h 6d] [Ac]
|
||||||
|
MasterTrini1: bets $0.08
|
||||||
|
s0rrow: raises $0.08 to $0.16
|
||||||
|
MasterTrini1: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to s0rrow [5h 5c 2s As 5d] [Ah]
|
||||||
|
Dealt to MasterTrini1 [8h 6d Ac] [Js]
|
||||||
|
s0rrow: bets $0.08
|
||||||
|
MasterTrini1: calls $0.08
|
||||||
|
*** RIVER ***
|
||||||
|
Dealt to s0rrow [5h 5c 2s As 5d Ah] [4d]
|
||||||
|
s0rrow: bets $0.08
|
||||||
|
MasterTrini1: calls $0.08
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
s0rrow: shows [5h 5c 2s As 5d Ah 4d] (a full house, Fives full of Aces)
|
||||||
|
MasterTrini1: mucks hand
|
||||||
|
s0rrow collected $1.04 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $1.09 | Rake $0.05
|
||||||
|
Seat 1: s0rrow showed [5h 5c 2s As 5d Ah 4d] and won ($1.04) with a full house, Fives full of Aces
|
||||||
|
Seat 3: Nikolay Zem folded on the 4th Street
|
||||||
|
Seat 5: trs2758 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 6: RoadDevil folded on the 4th Street
|
||||||
|
Seat 8: MasterTrini1 mucked [Qs Qd 8h 6d Ac Js Jc]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874124553: 7 Card Stud Limit ($0.04/$0.08 USD) - 2009/11/26 10:12:11 ET
|
||||||
|
Table 'Atalante II' 8-max
|
||||||
|
Seat 1: s0rrow ($2.15 in chips)
|
||||||
|
Seat 3: Nikolay Zem ($2.14 in chips)
|
||||||
|
Seat 5: trs2758 ($2.09 in chips)
|
||||||
|
Seat 6: RoadDevil ($1.48 in chips)
|
||||||
|
Seat 8: MasterTrini1 ($1.58 in chips)
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
Nikolay Zem: posts the ante $0.01
|
||||||
|
trs2758: posts the ante $0.01
|
||||||
|
RoadDevil: posts the ante $0.01
|
||||||
|
MasterTrini1: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to s0rrow [Js Kc 3d]
|
||||||
|
Dealt to Nikolay Zem [6c]
|
||||||
|
Dealt to trs2758 [4d]
|
||||||
|
Dealt to RoadDevil [6d]
|
||||||
|
Dealt to MasterTrini1 [9h]
|
||||||
|
s0rrow: brings in for $0.02
|
||||||
|
Nikolay Zem: folds
|
||||||
|
trs2758: folds
|
||||||
|
RoadDevil: calls $0.02
|
||||||
|
MasterTrini1: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to s0rrow [Js Kc 3d] [2h]
|
||||||
|
Dealt to RoadDevil [6d] [Ah]
|
||||||
|
Dealt to MasterTrini1 [9h] [8c]
|
||||||
|
RoadDevil: checks
|
||||||
|
MasterTrini1: bets $0.04
|
||||||
|
rv2020 joins the table at seat #4
|
||||||
|
s0rrow: folds
|
||||||
|
RoadDevil: calls $0.04
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to RoadDevil [6d Ah] [Td]
|
||||||
|
Dealt to MasterTrini1 [9h 8c] [5s]
|
||||||
|
RoadDevil: checks
|
||||||
|
MasterTrini1: bets $0.08
|
||||||
|
RoadDevil: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to RoadDevil [6d Ah Td] [4c]
|
||||||
|
Dealt to MasterTrini1 [9h 8c 5s] [5h]
|
||||||
|
MasterTrini1: bets $0.08
|
||||||
|
RoadDevil: calls $0.08
|
||||||
|
*** RIVER ***
|
||||||
|
MasterTrini1: bets $0.08
|
||||||
|
RoadDevil: calls $0.08
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
MasterTrini1: shows [6s 7d 9h 8c 5s 5h 9d] (a straight, Five to Nine)
|
||||||
|
RoadDevil: mucks hand
|
||||||
|
MasterTrini1 collected $0.64 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.67 | Rake $0.03
|
||||||
|
Seat 1: s0rrow folded on the 4th Street
|
||||||
|
Seat 3: Nikolay Zem folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 5: trs2758 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 6: RoadDevil mucked [4s 8d 6d Ah Td 4c 8h]
|
||||||
|
Seat 8: MasterTrini1 showed [6s 7d 9h 8c 5s 5h 9d] and won ($0.64) with a straight, Five to Nine
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874153086: 7 Card Stud Limit ($0.04/$0.08 USD) - 2009/11/26 10:13:01 ET
|
||||||
|
Table 'Atalante II' 8-max
|
||||||
|
Seat 1: s0rrow ($2.12 in chips)
|
||||||
|
Seat 3: Nikolay Zem ($2.13 in chips)
|
||||||
|
Seat 4: rv2020 ($1 in chips)
|
||||||
|
Seat 5: trs2758 ($2.08 in chips)
|
||||||
|
Seat 6: RoadDevil ($1.17 in chips)
|
||||||
|
Seat 8: MasterTrini1 ($1.91 in chips)
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
Nikolay Zem: posts the ante $0.01
|
||||||
|
rv2020: posts the ante $0.01
|
||||||
|
trs2758: posts the ante $0.01
|
||||||
|
RoadDevil: posts the ante $0.01
|
||||||
|
MasterTrini1: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to s0rrow [As 8s 6h]
|
||||||
|
Dealt to Nikolay Zem [4c]
|
||||||
|
Dealt to rv2020 [2s]
|
||||||
|
Dealt to trs2758 [7s]
|
||||||
|
Dealt to RoadDevil [7c]
|
||||||
|
Dealt to MasterTrini1 [Qd]
|
||||||
|
rv2020: brings in for $0.02
|
||||||
|
trs2758: calls $0.02
|
||||||
|
RoadDevil: calls $0.02
|
||||||
|
MasterTrini1: calls $0.02
|
||||||
|
s0rrow: calls $0.02
|
||||||
|
Nikolay Zem: folds
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to s0rrow [As 8s 6h] [3s]
|
||||||
|
Dealt to rv2020 [2s] [6d]
|
||||||
|
Dealt to trs2758 [7s] [Ah]
|
||||||
|
Dealt to RoadDevil [7c] [4h]
|
||||||
|
Dealt to MasterTrini1 [Qd] [Ad]
|
||||||
|
MasterTrini1: checks
|
||||||
|
s0rrow: checks
|
||||||
|
rv2020: checks
|
||||||
|
trs2758: checks
|
||||||
|
RoadDevil: checks
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to s0rrow [As 8s 6h 3s] [Jh]
|
||||||
|
Dealt to rv2020 [2s 6d] [Qh]
|
||||||
|
Dealt to trs2758 [7s Ah] [4d]
|
||||||
|
Dealt to RoadDevil [7c 4h] [7h]
|
||||||
|
Dealt to MasterTrini1 [Qd Ad] [5h]
|
||||||
|
RoadDevil: checks
|
||||||
|
MasterTrini1: checks
|
||||||
|
s0rrow: checks
|
||||||
|
rv2020: checks
|
||||||
|
trs2758: checks
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to s0rrow [As 8s 6h 3s Jh] [Tc]
|
||||||
|
Dealt to rv2020 [2s 6d Qh] [9h]
|
||||||
|
Dealt to trs2758 [7s Ah 4d] [3d]
|
||||||
|
Dealt to RoadDevil [7c 4h 7h] [5c]
|
||||||
|
Dealt to MasterTrini1 [Qd Ad 5h] [Td]
|
||||||
|
RoadDevil: checks
|
||||||
|
MasterTrini1: checks
|
||||||
|
s0rrow: checks
|
||||||
|
rv2020: checks
|
||||||
|
trs2758: checks
|
||||||
|
*** RIVER ***
|
||||||
|
Dealt to s0rrow [As 8s 6h 3s Jh Tc] [Qs]
|
||||||
|
RoadDevil: checks
|
||||||
|
MasterTrini1: checks
|
||||||
|
s0rrow: checks
|
||||||
|
rv2020: checks
|
||||||
|
trs2758: checks
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
s0rrow: shows [As 8s 6h 3s Jh Tc Qs] (high card Ace)
|
||||||
|
rv2020: shows [8c Ac 2s 6d Qh 9h 2d] (a pair of Deuces)
|
||||||
|
trs2758: mucks hand
|
||||||
|
RoadDevil: shows [Jd Qc 7c 4h 7h 5c Kc] (a pair of Sevens)
|
||||||
|
MasterTrini1: shows [Jc 2h Qd Ad 5h Td Ks] (a straight, Ten to Ace)
|
||||||
|
MasterTrini1 collected $0.16 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.16 | Rake $0
|
||||||
|
Seat 1: s0rrow showed [As 8s 6h 3s Jh Tc Qs] and lost with high card Ace
|
||||||
|
Seat 3: Nikolay Zem folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 4: rv2020 showed [8c Ac 2s 6d Qh 9h 2d] and lost with a pair of Deuces
|
||||||
|
Seat 5: trs2758 mucked [2c 9s 7s Ah 4d 3d 8d]
|
||||||
|
Seat 6: RoadDevil showed [Jd Qc 7c 4h 7h 5c Kc] and lost with a pair of Sevens
|
||||||
|
Seat 8: MasterTrini1 showed [Jc 2h Qd Ad 5h Td Ks] and won ($0.16) with a straight, Ten to Ace
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874195699: 7 Card Stud Limit ($0.04/$0.08 USD) - 2009/11/26 10:14:15 ET
|
||||||
|
Table 'Atalante II' 8-max
|
||||||
|
Seat 1: s0rrow ($2.09 in chips)
|
||||||
|
Seat 3: Nikolay Zem ($2.12 in chips)
|
||||||
|
Seat 4: rv2020 ($0.97 in chips)
|
||||||
|
Seat 5: trs2758 ($2.05 in chips)
|
||||||
|
Seat 6: RoadDevil ($1.14 in chips)
|
||||||
|
Seat 8: MasterTrini1 ($2.04 in chips)
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
Nikolay Zem: posts the ante $0.01
|
||||||
|
rv2020: posts the ante $0.01
|
||||||
|
trs2758: posts the ante $0.01
|
||||||
|
RoadDevil: posts the ante $0.01
|
||||||
|
MasterTrini1: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to s0rrow [6c 4c Th]
|
||||||
|
Dealt to Nikolay Zem [9d]
|
||||||
|
Dealt to rv2020 [4s]
|
||||||
|
Dealt to trs2758 [3h]
|
||||||
|
Dealt to RoadDevil [Ac]
|
||||||
|
Dealt to MasterTrini1 [5d]
|
||||||
|
trs2758: brings in for $0.02
|
||||||
|
RoadDevil: folds
|
||||||
|
MasterTrini1: calls $0.02
|
||||||
|
s0rrow: folds
|
||||||
|
Nikolay Zem: calls $0.02
|
||||||
|
rv2020: folds
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to Nikolay Zem [9d] [3s]
|
||||||
|
Dealt to trs2758 [3h] [Jd]
|
||||||
|
Dealt to MasterTrini1 [5d] [2d]
|
||||||
|
trs2758: checks
|
||||||
|
MasterTrini1: checks
|
||||||
|
Nikolay Zem: checks
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to Nikolay Zem [9d 3s] [9c]
|
||||||
|
Dealt to trs2758 [3h Jd] [2h]
|
||||||
|
Dealt to MasterTrini1 [5d 2d] [7d]
|
||||||
|
Nikolay Zem: bets $0.08
|
||||||
|
trs2758: folds
|
||||||
|
MasterTrini1: raises $0.08 to $0.16
|
||||||
|
Nikolay Zem: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to Nikolay Zem [9d 3s 9c] [Td]
|
||||||
|
Dealt to MasterTrini1 [5d 2d 7d] [5h]
|
||||||
|
Nikolay Zem: checks
|
||||||
|
MasterTrini1: checks
|
||||||
|
*** RIVER ***
|
||||||
|
Nikolay Zem: bets $0.08
|
||||||
|
MasterTrini1: folds
|
||||||
|
Uncalled bet ($0.08) returned to Nikolay Zem
|
||||||
|
Nikolay Zem collected $0.42 from pot
|
||||||
|
Nikolay Zem: doesn't show hand
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.44 | Rake $0.02
|
||||||
|
Seat 1: s0rrow folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 3: Nikolay Zem collected ($0.42)
|
||||||
|
Seat 4: rv2020 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 5: trs2758 folded on the 5th Street
|
||||||
|
Seat 6: RoadDevil folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 8: MasterTrini1 folded on the River
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874220204: 7 Card Stud Limit ($0.04/$0.08 USD) - 2009/11/26 10:14:58 ET
|
||||||
|
Table 'Atalante II' 8-max
|
||||||
|
Seat 1: s0rrow ($2.08 in chips)
|
||||||
|
Seat 3: Nikolay Zem ($2.35 in chips)
|
||||||
|
Seat 4: rv2020 ($0.96 in chips)
|
||||||
|
Seat 5: trs2758 ($2.02 in chips)
|
||||||
|
Seat 6: RoadDevil ($1.13 in chips)
|
||||||
|
Seat 8: MasterTrini1 ($1.85 in chips)
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
Nikolay Zem: posts the ante $0.01
|
||||||
|
rv2020: posts the ante $0.01
|
||||||
|
trs2758: posts the ante $0.01
|
||||||
|
RoadDevil: posts the ante $0.01
|
||||||
|
MasterTrini1: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to s0rrow [Jd 9d 2h]
|
||||||
|
Dealt to Nikolay Zem [Ad]
|
||||||
|
Dealt to rv2020 [2c]
|
||||||
|
Dealt to trs2758 [8c]
|
||||||
|
Dealt to RoadDevil [3s]
|
||||||
|
Dealt to MasterTrini1 [3h]
|
||||||
|
rv2020: brings in for $0.02
|
||||||
|
trs2758: calls $0.02
|
||||||
|
RoadDevil: folds
|
||||||
|
MasterTrini1: calls $0.02
|
||||||
|
s0rrow: folds
|
||||||
|
Nikolay Zem: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to Nikolay Zem [Ad] [9h]
|
||||||
|
Dealt to rv2020 [2c] [4d]
|
||||||
|
Dealt to trs2758 [8c] [Qd]
|
||||||
|
Dealt to MasterTrini1 [3h] [Qs]
|
||||||
|
Nikolay Zem: checks
|
||||||
|
rv2020: bets $0.04
|
||||||
|
trs2758: calls $0.04
|
||||||
|
MasterTrini1: calls $0.04
|
||||||
|
Nikolay Zem: folds
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to rv2020 [2c 4d] [Jh]
|
||||||
|
Dealt to trs2758 [8c Qd] [Js]
|
||||||
|
Dealt to MasterTrini1 [3h Qs] [4h]
|
||||||
|
trs2758: checks
|
||||||
|
MasterTrini1: bets $0.08
|
||||||
|
rv2020: raises $0.08 to $0.16
|
||||||
|
trs2758: calls $0.16
|
||||||
|
MasterTrini1: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to rv2020 [2c 4d Jh] [7c]
|
||||||
|
Dealt to trs2758 [8c Qd Js] [5c]
|
||||||
|
Dealt to MasterTrini1 [3h Qs 4h] [7h]
|
||||||
|
trs2758: checks
|
||||||
|
MasterTrini1: checks
|
||||||
|
rv2020: bets $0.08
|
||||||
|
trs2758: folds
|
||||||
|
MasterTrini1: calls $0.08
|
||||||
|
*** RIVER ***
|
||||||
|
MasterTrini1: checks
|
||||||
|
rv2020: checks
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
rv2020: shows [As Ac 2c 4d Jh 7c 3c] (a pair of Aces)
|
||||||
|
MasterTrini1: mucks hand
|
||||||
|
rv2020 collected $0.86 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.90 | Rake $0.04
|
||||||
|
Seat 1: s0rrow folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 3: Nikolay Zem folded on the 4th Street
|
||||||
|
Seat 4: rv2020 showed [As Ac 2c 4d Jh 7c 3c] and won ($0.86) with a pair of Aces
|
||||||
|
Seat 5: trs2758 folded on the 6th Street
|
||||||
|
Seat 6: RoadDevil folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 8: MasterTrini1 mucked [6s 8s 3h Qs 4h 7h 6d]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874259784: 7 Card Stud Limit ($0.04/$0.08 USD) - 2009/11/26 10:16:07 ET
|
||||||
|
Table 'Atalante II' 8-max
|
||||||
|
Seat 1: s0rrow ($2.07 in chips)
|
||||||
|
Seat 3: Nikolay Zem ($2.32 in chips)
|
||||||
|
Seat 4: rv2020 ($1.51 in chips)
|
||||||
|
Seat 5: trs2758 ($1.79 in chips)
|
||||||
|
Seat 6: RoadDevil ($1.12 in chips)
|
||||||
|
Seat 8: MasterTrini1 ($1.54 in chips)
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
Nikolay Zem: posts the ante $0.01
|
||||||
|
rv2020: posts the ante $0.01
|
||||||
|
trs2758: posts the ante $0.01
|
||||||
|
RoadDevil: posts the ante $0.01
|
||||||
|
MasterTrini1: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to s0rrow [7d 6h 9s]
|
||||||
|
Dealt to Nikolay Zem [Js]
|
||||||
|
Dealt to rv2020 [3d]
|
||||||
|
Dealt to trs2758 [7s]
|
||||||
|
Dealt to RoadDevil [Qh]
|
||||||
|
Dealt to MasterTrini1 [5d]
|
||||||
|
rv2020: brings in for $0.02
|
||||||
|
trs2758: folds
|
||||||
|
RoadDevil: calls $0.02
|
||||||
|
MasterTrini1: calls $0.02
|
||||||
|
s0rrow: calls $0.02
|
||||||
|
Nikolay Zem: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to s0rrow [7d 6h 9s] [Kc]
|
||||||
|
Dealt to Nikolay Zem [Js] [6s]
|
||||||
|
Dealt to rv2020 [3d] [Jd]
|
||||||
|
Dealt to RoadDevil [Qh] [Th]
|
||||||
|
Dealt to MasterTrini1 [5d] [8c]
|
||||||
|
Katica65 was removed from the table for failing to post
|
||||||
|
s0rrow: checks
|
||||||
|
Nikolay Zem: checks
|
||||||
|
danjr655 joins the table at seat #2
|
||||||
|
rv2020: checks
|
||||||
|
RoadDevil: checks
|
||||||
|
MasterTrini1: checks
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to s0rrow [7d 6h 9s Kc] [Ah]
|
||||||
|
Dealt to Nikolay Zem [Js 6s] [Ad]
|
||||||
|
Dealt to rv2020 [3d Jd] [Tc]
|
||||||
|
Dealt to RoadDevil [Qh Th] [Qc]
|
||||||
|
Dealt to MasterTrini1 [5d 8c] [3h]
|
||||||
|
RoadDevil: bets $0.08
|
||||||
|
MasterTrini1: folds
|
||||||
|
s0rrow: raises $0.08 to $0.16
|
||||||
|
Nikolay Zem: calls $0.16
|
||||||
|
rv2020: folds
|
||||||
|
RoadDevil: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to s0rrow [7d 6h 9s Kc Ah] [4d]
|
||||||
|
Dealt to Nikolay Zem [Js 6s Ad] [4s]
|
||||||
|
Dealt to RoadDevil [Qh Th Qc] [7h]
|
||||||
|
RoadDevil: checks
|
||||||
|
s0rrow: checks
|
||||||
|
Nikolay Zem: bets $0.08
|
||||||
|
RoadDevil: calls $0.08
|
||||||
|
s0rrow: folds
|
||||||
|
*** RIVER ***
|
||||||
|
RoadDevil: checks
|
||||||
|
Nikolay Zem: bets $0.08
|
||||||
|
RoadDevil: calls $0.08
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
Nikolay Zem: shows [Qs 3s Js 6s Ad 4s 2s] (a flush, Queen high)
|
||||||
|
RoadDevil: mucks hand
|
||||||
|
Nikolay Zem collected $0.92 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.96 | Rake $0.04
|
||||||
|
Seat 1: s0rrow folded on the 6th Street
|
||||||
|
Seat 3: Nikolay Zem showed [Qs 3s Js 6s Ad 4s 2s] and won ($0.92) with a flush, Queen high
|
||||||
|
Seat 4: rv2020 folded on the 5th Street
|
||||||
|
Seat 5: trs2758 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 6: RoadDevil mucked [2h Ts Qh Th Qc 7h Kd]
|
||||||
|
Seat 8: MasterTrini1 folded on the 5th Street
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874289931: 7 Card Stud Limit ($0.04/$0.08 USD) - 2009/11/26 10:16:59 ET
|
||||||
|
Table 'Atalante II' 8-max
|
||||||
|
Seat 1: s0rrow ($1.88 in chips)
|
||||||
|
Seat 2: danjr655 ($0.45 in chips)
|
||||||
|
Seat 3: Nikolay Zem ($2.89 in chips)
|
||||||
|
Seat 4: rv2020 ($1.48 in chips)
|
||||||
|
Seat 5: trs2758 ($1.78 in chips)
|
||||||
|
Seat 6: RoadDevil ($0.77 in chips)
|
||||||
|
Seat 8: MasterTrini1 ($1.51 in chips)
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
danjr655: posts the ante $0.01
|
||||||
|
Nikolay Zem: posts the ante $0.01
|
||||||
|
rv2020: posts the ante $0.01
|
||||||
|
trs2758: posts the ante $0.01
|
||||||
|
RoadDevil: posts the ante $0.01
|
||||||
|
MasterTrini1: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to s0rrow [2d Qs 8c]
|
||||||
|
Dealt to danjr655 [5d]
|
||||||
|
Dealt to Nikolay Zem [Jc]
|
||||||
|
Dealt to rv2020 [8d]
|
||||||
|
Dealt to trs2758 [Kd]
|
||||||
|
Dealt to RoadDevil [4s]
|
||||||
|
Dealt to MasterTrini1 [6h]
|
||||||
|
RoadDevil: brings in for $0.02
|
||||||
|
Trackr21 joins the table at seat #7
|
||||||
|
MasterTrini1: calls $0.02
|
||||||
|
s0rrow: folds
|
||||||
|
danjr655: folds
|
||||||
|
Nikolay Zem: calls $0.02
|
||||||
|
rv2020: calls $0.02
|
||||||
|
trs2758: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to Nikolay Zem [Jc] [2h]
|
||||||
|
Dealt to rv2020 [8d] [Jd]
|
||||||
|
Dealt to trs2758 [Kd] [Ks]
|
||||||
|
Dealt to RoadDevil [4s] [6c]
|
||||||
|
Dealt to MasterTrini1 [6h] [4c]
|
||||||
|
Pair on board - a double bet is allowed
|
||||||
|
trs2758: bets $0.04
|
||||||
|
RoadDevil: calls $0.04
|
||||||
|
MasterTrini1: calls $0.04
|
||||||
|
Nikolay Zem: folds
|
||||||
|
rv2020: folds
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to trs2758 [Kd Ks] [7c]
|
||||||
|
Dealt to RoadDevil [4s 6c] [9d]
|
||||||
|
Dealt to MasterTrini1 [6h 4c] [3h]
|
||||||
|
trs2758: bets $0.08
|
||||||
|
RoadDevil: folds
|
||||||
|
MasterTrini1: raises $0.08 to $0.16
|
||||||
|
trs2758: raises $0.08 to $0.24
|
||||||
|
MasterTrini1: raises $0.08 to $0.32
|
||||||
|
Betting is capped
|
||||||
|
trs2758: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to trs2758 [Kd Ks 7c] [9h]
|
||||||
|
Dealt to MasterTrini1 [6h 4c 3h] [3c]
|
||||||
|
trs2758: checks
|
||||||
|
MasterTrini1: bets $0.08
|
||||||
|
trs2758: calls $0.08
|
||||||
|
*** RIVER ***
|
||||||
|
trs2758: checks
|
||||||
|
MasterTrini1: checks
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
trs2758: shows [Ac 2c Kd Ks 7c 9h 9c] (two pair, Kings and Nines)
|
||||||
|
MasterTrini1: shows [5h 8h 6h 4c 3h 3c As] (a pair of Threes)
|
||||||
|
trs2758 collected $1.04 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $1.09 | Rake $0.05
|
||||||
|
Seat 1: s0rrow folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 2: danjr655 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 3: Nikolay Zem folded on the 4th Street
|
||||||
|
Seat 4: rv2020 folded on the 4th Street
|
||||||
|
Seat 5: trs2758 showed [Ac 2c Kd Ks 7c 9h 9c] and won ($1.04) with two pair, Kings and Nines
|
||||||
|
Seat 6: RoadDevil folded on the 5th Street
|
||||||
|
Seat 8: MasterTrini1 showed [5h 8h 6h 4c 3h 3c As] and lost with a pair of Threes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874334277: 7 Card Stud Limit ($0.04/$0.08 USD) - 2009/11/26 10:18:16 ET
|
||||||
|
Table 'Atalante II' 8-max
|
||||||
|
Seat 1: s0rrow ($1.87 in chips)
|
||||||
|
Seat 2: danjr655 ($0.44 in chips)
|
||||||
|
Seat 3: Nikolay Zem ($2.86 in chips)
|
||||||
|
Seat 4: rv2020 ($1.45 in chips)
|
||||||
|
Seat 5: trs2758 ($2.35 in chips)
|
||||||
|
Seat 6: RoadDevil ($0.70 in chips)
|
||||||
|
Seat 7: Trackr21 ($1.60 in chips)
|
||||||
|
Seat 8: MasterTrini1 ($1.04 in chips)
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
danjr655: posts the ante $0.01
|
||||||
|
Nikolay Zem: posts the ante $0.01
|
||||||
|
rv2020: posts the ante $0.01
|
||||||
|
trs2758: posts the ante $0.01
|
||||||
|
RoadDevil: posts the ante $0.01
|
||||||
|
Trackr21: posts the ante $0.01
|
||||||
|
MasterTrini1: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to s0rrow [7d Qs 8s]
|
||||||
|
Dealt to danjr655 [8d]
|
||||||
|
Dealt to Nikolay Zem [6d]
|
||||||
|
Dealt to rv2020 [4d]
|
||||||
|
Dealt to trs2758 [Ad]
|
||||||
|
Dealt to RoadDevil [Td]
|
||||||
|
Dealt to Trackr21 [Jh]
|
||||||
|
Dealt to MasterTrini1 [5s]
|
||||||
|
rv2020: brings in for $0.02
|
||||||
|
trs2758: calls $0.02
|
||||||
|
RoadDevil: folds
|
||||||
|
Trackr21: folds
|
||||||
|
MasterTrini1: calls $0.02
|
||||||
|
s0rrow: calls $0.02
|
||||||
|
danjr655: folds
|
||||||
|
Nikolay Zem: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to s0rrow [7d Qs 8s] [2s]
|
||||||
|
Dealt to Nikolay Zem [6d] [2h]
|
||||||
|
Dealt to rv2020 [4d] [Kd]
|
||||||
|
Dealt to trs2758 [Ad] [Kh]
|
||||||
|
Dealt to MasterTrini1 [5s] [5c]
|
||||||
|
Pair on board - a double bet is allowed
|
||||||
|
MasterTrini1: bets $0.08
|
||||||
|
s0rrow: calls $0.08
|
||||||
|
Nikolay Zem: folds
|
||||||
|
rv2020: calls $0.08
|
||||||
|
trs2758: calls $0.08
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to s0rrow [7d Qs 8s 2s] [As]
|
||||||
|
Dealt to rv2020 [4d Kd] [Qd]
|
||||||
|
Dealt to trs2758 [Ad Kh] [3h]
|
||||||
|
Dealt to MasterTrini1 [5s 5c] [Js]
|
||||||
|
MasterTrini1: checks
|
||||||
|
s0rrow: bets $0.08
|
||||||
|
rv2020: folds
|
||||||
|
trs2758: folds
|
||||||
|
MasterTrini1: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to s0rrow [7d Qs 8s 2s As] [5d]
|
||||||
|
Dealt to MasterTrini1 [5s 5c Js] [2c]
|
||||||
|
MasterTrini1: checks
|
||||||
|
s0rrow: bets $0.08
|
||||||
|
MasterTrini1: calls $0.08
|
||||||
|
*** RIVER ***
|
||||||
|
Dealt to s0rrow [7d Qs 8s 2s As 5d] [7h]
|
||||||
|
MasterTrini1: checks
|
||||||
|
s0rrow: bets $0.08
|
||||||
|
MasterTrini1: calls $0.08
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
s0rrow: shows [7d Qs 8s 2s As 5d 7h] (a pair of Sevens)
|
||||||
|
MasterTrini1: mucks hand
|
||||||
|
s0rrow collected $0.94 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.98 | Rake $0.04
|
||||||
|
Seat 1: s0rrow showed [7d Qs 8s 2s As 5d 7h] and won ($0.94) with a pair of Sevens
|
||||||
|
Seat 2: danjr655 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 3: Nikolay Zem folded on the 4th Street
|
||||||
|
Seat 4: rv2020 folded on the 5th Street
|
||||||
|
Seat 5: trs2758 folded on the 5th Street
|
||||||
|
Seat 6: RoadDevil folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 7: Trackr21 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 8: MasterTrini1 mucked [Ac 9d 5s 5c Js 2c Kc]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874382643: 7 Card Stud Limit ($0.04/$0.08 USD) - 2009/11/26 10:19:39 ET
|
||||||
|
Table 'Atalante II' 8-max
|
||||||
|
Seat 1: s0rrow ($2.46 in chips)
|
||||||
|
Seat 2: danjr655 ($0.43 in chips)
|
||||||
|
Seat 3: Nikolay Zem ($2.83 in chips)
|
||||||
|
Seat 4: rv2020 ($1.34 in chips)
|
||||||
|
Seat 5: trs2758 ($2.24 in chips)
|
||||||
|
Seat 6: RoadDevil ($0.69 in chips)
|
||||||
|
Seat 7: Trackr21 ($1.59 in chips)
|
||||||
|
Seat 8: MasterTrini1 ($0.69 in chips)
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
danjr655: posts the ante $0.01
|
||||||
|
Nikolay Zem: posts the ante $0.01
|
||||||
|
rv2020: posts the ante $0.01
|
||||||
|
trs2758: posts the ante $0.01
|
||||||
|
RoadDevil: posts the ante $0.01
|
||||||
|
Trackr21: posts the ante $0.01
|
||||||
|
MasterTrini1: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to s0rrow [8d 3d 8c]
|
||||||
|
Dealt to danjr655 [Kd]
|
||||||
|
Dealt to Nikolay Zem [9c]
|
||||||
|
Dealt to rv2020 [4h]
|
||||||
|
Dealt to trs2758 [6c]
|
||||||
|
Dealt to RoadDevil [6d]
|
||||||
|
Dealt to Trackr21 [5d]
|
||||||
|
Dealt to MasterTrini1 [8h]
|
||||||
|
rv2020: brings in for $0.02
|
||||||
|
trs2758: folds
|
||||||
|
RoadDevil: calls $0.02
|
||||||
|
Trackr21: calls $0.02
|
||||||
|
MasterTrini1: calls $0.02
|
||||||
|
s0rrow: calls $0.02
|
||||||
|
danjr655: calls $0.02
|
||||||
|
Nikolay Zem: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to s0rrow [8d 3d 8c] [Qc]
|
||||||
|
Dealt to danjr655 [Kd] [Kc]
|
||||||
|
Dealt to Nikolay Zem [9c] [Jd]
|
||||||
|
Dealt to rv2020 [4h] [8s]
|
||||||
|
Dealt to RoadDevil [6d] [4s]
|
||||||
|
Dealt to Trackr21 [5d] [4d]
|
||||||
|
Dealt to MasterTrini1 [8h] [As]
|
||||||
|
Pair on board - a double bet is allowed
|
||||||
|
danjr655: bets $0.04
|
||||||
|
Nikolay Zem: calls $0.04
|
||||||
|
rv2020: folds
|
||||||
|
RoadDevil: folds
|
||||||
|
Trackr21: calls $0.04
|
||||||
|
MasterTrini1: calls $0.04
|
||||||
|
s0rrow: folds
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to danjr655 [Kd Kc] [2h]
|
||||||
|
Dealt to Nikolay Zem [9c Jd] [Qs]
|
||||||
|
Dealt to Trackr21 [5d 4d] [3h]
|
||||||
|
Dealt to MasterTrini1 [8h As] [Th]
|
||||||
|
danjr655: bets $0.08
|
||||||
|
Nikolay Zem: calls $0.08
|
||||||
|
Trackr21: calls $0.08
|
||||||
|
s0rrow is sitting out
|
||||||
|
MasterTrini1: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to danjr655 [Kd Kc 2h] [7s]
|
||||||
|
Dealt to Nikolay Zem [9c Jd Qs] [9d]
|
||||||
|
Dealt to Trackr21 [5d 4d 3h] [5s]
|
||||||
|
Dealt to MasterTrini1 [8h As Th] [9h]
|
||||||
|
danjr655: checks
|
||||||
|
Nikolay Zem: checks
|
||||||
|
Trackr21: checks
|
||||||
|
MasterTrini1: checks
|
||||||
|
*** RIVER ***
|
||||||
|
danjr655: checks
|
||||||
|
Nikolay Zem: checks
|
||||||
|
Trackr21: bets $0.08
|
||||||
|
MasterTrini1: folds
|
||||||
|
danjr655: folds
|
||||||
|
Nikolay Zem: calls $0.08
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
Trackr21: shows [6h Ah 5d 4d 3h 5s 5c] (three of a kind, Fives)
|
||||||
|
Nikolay Zem: mucks hand
|
||||||
|
Trackr21 collected $0.82 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.86 | Rake $0.04
|
||||||
|
Seat 1: s0rrow folded on the 4th Street
|
||||||
|
Seat 2: danjr655 folded on the River
|
||||||
|
Seat 3: Nikolay Zem mucked [7c 7d 9c Jd Qs 9d Ad]
|
||||||
|
Seat 4: rv2020 folded on the 4th Street
|
||||||
|
Seat 5: trs2758 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 6: RoadDevil folded on the 4th Street
|
||||||
|
Seat 7: Trackr21 showed [6h Ah 5d 4d 3h 5s 5c] and won ($0.82) with three of a kind, Fives
|
||||||
|
Seat 8: MasterTrini1 folded on the River
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,611 @@
|
||||||
|
PokerStars Game #35874487284: 7 Card Stud Hi/Lo Limit ($0.04/$0.08 USD) - 2009/11/26 10:22:32 ET
|
||||||
|
Table 'Dawn II' 8-max
|
||||||
|
Seat 3: gashpor ($1.46 in chips)
|
||||||
|
Seat 4: denny501 ($0.93 in chips)
|
||||||
|
Seat 5: s0rrow ($1.60 in chips)
|
||||||
|
Seat 8: rdiezchang ($1.16 in chips)
|
||||||
|
gashpor: posts the ante $0.01
|
||||||
|
denny501: posts the ante $0.01
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
rdiezchang: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to gashpor [Kc]
|
||||||
|
Dealt to denny501 [7c]
|
||||||
|
Dealt to s0rrow [5d Ks 2h]
|
||||||
|
Dealt to rdiezchang [3d]
|
||||||
|
s0rrow: brings in for $0.02
|
||||||
|
rdiezchang: calls $0.02
|
||||||
|
gashpor: calls $0.02
|
||||||
|
denny501: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to gashpor [Kc] [4d]
|
||||||
|
Dealt to denny501 [7c] [Qh]
|
||||||
|
Dealt to s0rrow [5d Ks 2h] [9h]
|
||||||
|
Dealt to rdiezchang [3d] [7s]
|
||||||
|
Soroka69 joins the table at seat #7
|
||||||
|
gashpor: checks
|
||||||
|
poconoman is connected
|
||||||
|
denny501: checks
|
||||||
|
s0rrow: checks
|
||||||
|
rdiezchang: checks
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to gashpor [Kc 4d] [Qd]
|
||||||
|
Dealt to denny501 [7c Qh] [9s]
|
||||||
|
Dealt to s0rrow [5d Ks 2h 9h] [Js]
|
||||||
|
Dealt to rdiezchang [3d 7s] [Jh]
|
||||||
|
gashpor: checks
|
||||||
|
denny501: checks
|
||||||
|
s0rrow: checks
|
||||||
|
rdiezchang: checks
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to gashpor [Kc 4d Qd] [5s]
|
||||||
|
Dealt to denny501 [7c Qh 9s] [6s]
|
||||||
|
Dealt to s0rrow [5d Ks 2h 9h Js] [4c]
|
||||||
|
Dealt to rdiezchang [3d 7s Jh] [5c]
|
||||||
|
123smoothie joins the table at seat #2
|
||||||
|
gashpor: checks
|
||||||
|
denny501: checks
|
||||||
|
s0rrow: checks
|
||||||
|
rdiezchang: bets $0.08
|
||||||
|
gashpor: folds
|
||||||
|
denny501: folds
|
||||||
|
s0rrow: folds
|
||||||
|
Uncalled bet ($0.08) returned to rdiezchang
|
||||||
|
rdiezchang collected $0.12 from pot
|
||||||
|
rdiezchang: doesn't show hand
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.12 | Rake $0
|
||||||
|
Seat 3: gashpor folded on the 6th Street
|
||||||
|
Seat 4: denny501 folded on the 6th Street
|
||||||
|
Seat 5: s0rrow folded on the 6th Street
|
||||||
|
Seat 8: rdiezchang collected ($0.12)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874523510: 7 Card Stud Hi/Lo Limit ($0.04/$0.08 USD) - 2009/11/26 10:23:32 ET
|
||||||
|
Table 'Dawn II' 8-max
|
||||||
|
Seat 2: 123smoothie ($1.60 in chips)
|
||||||
|
Seat 3: gashpor ($1.43 in chips)
|
||||||
|
Seat 4: denny501 ($0.90 in chips)
|
||||||
|
Seat 5: s0rrow ($1.57 in chips)
|
||||||
|
Seat 7: Soroka69 ($1 in chips)
|
||||||
|
Seat 8: rdiezchang ($1.25 in chips)
|
||||||
|
123smoothie: posts the ante $0.01
|
||||||
|
gashpor: posts the ante $0.01
|
||||||
|
denny501: posts the ante $0.01
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
Soroka69: posts the ante $0.01
|
||||||
|
rdiezchang: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to 123smoothie [9h]
|
||||||
|
Dealt to gashpor [4s]
|
||||||
|
Dealt to denny501 [Qs]
|
||||||
|
Dealt to s0rrow [Qd Js Kc]
|
||||||
|
Dealt to Soroka69 [6s]
|
||||||
|
Dealt to rdiezchang [8d]
|
||||||
|
poconoman was removed from the table for failing to post
|
||||||
|
gashpor: brings in for $0.02
|
||||||
|
TomSludge joins the table at seat #6
|
||||||
|
denny501: calls $0.02
|
||||||
|
s0rrow: folds
|
||||||
|
Soroka69: calls $0.02
|
||||||
|
rdiezchang: calls $0.02
|
||||||
|
u.pressure joins the table at seat #1
|
||||||
|
123smoothie: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to 123smoothie [9h] [Ah]
|
||||||
|
Dealt to gashpor [4s] [6h]
|
||||||
|
Dealt to denny501 [Qs] [4d]
|
||||||
|
Dealt to Soroka69 [6s] [3c]
|
||||||
|
Dealt to rdiezchang [8d] [Ac]
|
||||||
|
123smoothie: checks
|
||||||
|
gashpor: checks
|
||||||
|
denny501: checks
|
||||||
|
Soroka69: checks
|
||||||
|
rdiezchang: checks
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to 123smoothie [9h Ah] [5d]
|
||||||
|
Dealt to gashpor [4s 6h] [8h]
|
||||||
|
Dealt to denny501 [Qs 4d] [Tc]
|
||||||
|
Dealt to Soroka69 [6s 3c] [6c]
|
||||||
|
Dealt to rdiezchang [8d Ac] [8c]
|
||||||
|
rdiezchang: bets $0.08
|
||||||
|
123smoothie: calls $0.08
|
||||||
|
gashpor: calls $0.08
|
||||||
|
denny501: folds
|
||||||
|
Soroka69: folds
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to 123smoothie [9h Ah 5d] [4c]
|
||||||
|
Dealt to gashpor [4s 6h 8h] [Qh]
|
||||||
|
Dealt to rdiezchang [8d Ac 8c] [Jd]
|
||||||
|
rdiezchang: bets $0.08
|
||||||
|
123smoothie: calls $0.08
|
||||||
|
gashpor: calls $0.08
|
||||||
|
*** RIVER ***
|
||||||
|
rdiezchang: bets $0.08
|
||||||
|
123smoothie: calls $0.08
|
||||||
|
gashpor: folds
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
rdiezchang: shows [Ad 5s 8d Ac 8c Jd Th] (HI: two pair, Aces and Eights)
|
||||||
|
123smoothie: mucks hand
|
||||||
|
rdiezchang collected $0.77 from pot
|
||||||
|
No low hand qualified
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.80 | Rake $0.03
|
||||||
|
Seat 2: 123smoothie mucked [9c Jc 9h Ah 5d 4c Qc]
|
||||||
|
Seat 3: gashpor folded on the River
|
||||||
|
Seat 4: denny501 folded on the 5th Street
|
||||||
|
Seat 5: s0rrow folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 7: Soroka69 folded on the 5th Street
|
||||||
|
Seat 8: rdiezchang showed [Ad 5s 8d Ac 8c Jd Th] and won ($0.77) with HI: two pair, Aces and Eights
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874576282: 7 Card Stud Hi/Lo Limit ($0.04/$0.08 USD) - 2009/11/26 10:24:59 ET
|
||||||
|
Table 'Dawn II' 8-max
|
||||||
|
Seat 1: u.pressure ($11 in chips)
|
||||||
|
Seat 2: 123smoothie ($1.33 in chips)
|
||||||
|
Seat 3: gashpor ($1.24 in chips)
|
||||||
|
Seat 4: denny501 ($0.87 in chips)
|
||||||
|
Seat 5: s0rrow ($1.56 in chips)
|
||||||
|
Seat 6: TomSludge ($1.60 in chips)
|
||||||
|
Seat 7: Soroka69 ($0.97 in chips)
|
||||||
|
Seat 8: rdiezchang ($1.75 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 [Qs]
|
||||||
|
Dealt to 123smoothie [4h]
|
||||||
|
Dealt to gashpor [4c]
|
||||||
|
Dealt to denny501 [8s]
|
||||||
|
Dealt to s0rrow [Ah Kd 8d]
|
||||||
|
Dealt to TomSludge [Ks]
|
||||||
|
Dealt to Soroka69 [3h]
|
||||||
|
Dealt to rdiezchang [5s]
|
||||||
|
Soroka69: brings in for $0.02
|
||||||
|
rdiezchang: calls $0.02
|
||||||
|
u.pressure: calls $0.02
|
||||||
|
123smoothie: calls $0.02
|
||||||
|
gashpor: calls $0.02
|
||||||
|
denny501: folds
|
||||||
|
s0rrow: calls $0.02
|
||||||
|
TomSludge: folds
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to u.pressure [Qs] [Td]
|
||||||
|
Dealt to 123smoothie [4h] [9d]
|
||||||
|
Dealt to gashpor [4c] [Jc]
|
||||||
|
Dealt to s0rrow [Ah Kd 8d] [Kc]
|
||||||
|
Dealt to Soroka69 [3h] [Ad]
|
||||||
|
Dealt to rdiezchang [5s] [7c]
|
||||||
|
Soroka69: checks
|
||||||
|
rdiezchang: checks
|
||||||
|
u.pressure: checks
|
||||||
|
123smoothie: checks
|
||||||
|
gashpor: checks
|
||||||
|
s0rrow: checks
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to u.pressure [Qs Td] [Jh]
|
||||||
|
Dealt to 123smoothie [4h 9d] [2c]
|
||||||
|
Dealt to gashpor [4c Jc] [5h]
|
||||||
|
Dealt to s0rrow [Ah Kd 8d Kc] [2d]
|
||||||
|
Dealt to Soroka69 [3h Ad] [Qd]
|
||||||
|
Dealt to rdiezchang [5s 7c] [4d]
|
||||||
|
Soroka69: checks
|
||||||
|
rdiezchang: checks
|
||||||
|
u.pressure: checks
|
||||||
|
123smoothie: checks
|
||||||
|
gashpor: bets $0.08
|
||||||
|
s0rrow: folds
|
||||||
|
Soroka69: calls $0.08
|
||||||
|
rdiezchang: calls $0.08
|
||||||
|
u.pressure: calls $0.08
|
||||||
|
123smoothie: folds
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to u.pressure [Qs Td Jh] [6d]
|
||||||
|
Dealt to gashpor [4c Jc 5h] [7s]
|
||||||
|
Dealt to Soroka69 [3h Ad Qd] [9s]
|
||||||
|
Dealt to rdiezchang [5s 7c 4d] [Th]
|
||||||
|
Soroka69: checks
|
||||||
|
rdiezchang: checks
|
||||||
|
u.pressure: checks
|
||||||
|
gashpor: checks
|
||||||
|
*** RIVER ***
|
||||||
|
Soroka69: checks
|
||||||
|
rdiezchang: checks
|
||||||
|
u.pressure: checks
|
||||||
|
gashpor: bets $0.08
|
||||||
|
Soroka69: folds
|
||||||
|
rdiezchang: calls $0.08
|
||||||
|
u.pressure: calls $0.08
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
gashpor: shows [7h 2h 4c Jc 5h 7s 8c] (HI: a pair of Sevens; LO: 8,7,5,4,2)
|
||||||
|
rdiezchang: shows [As Qh 5s 7c 4d Th Ac] (HI: a pair of Aces)
|
||||||
|
u.pressure: shows [Qc Kh Qs Td Jh 6d 6s] (HI: two pair, Queens and Sixes)
|
||||||
|
u.pressure collected $0.37 from pot
|
||||||
|
gashpor collected $0.36 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.76 | Rake $0.03
|
||||||
|
Seat 1: u.pressure showed [Qc Kh Qs Td Jh 6d 6s] and won ($0.37) with HI: two pair, Queens and Sixes
|
||||||
|
Seat 2: 123smoothie folded on the 5th Street
|
||||||
|
Seat 3: gashpor showed [7h 2h 4c Jc 5h 7s 8c] and won ($0.36) with HI: a pair of Sevens; LO: 8,7,5,4,2
|
||||||
|
Seat 4: denny501 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 5: s0rrow folded on the 5th Street
|
||||||
|
Seat 6: TomSludge folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 7: Soroka69 folded on the River
|
||||||
|
Seat 8: rdiezchang showed [As Qh 5s 7c 4d Th Ac] and lost with HI: a pair of Aces
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874635170: 7 Card Stud Hi/Lo Limit ($0.04/$0.08 USD) - 2009/11/26 10:26:37 ET
|
||||||
|
Table 'Dawn II' 8-max
|
||||||
|
Seat 1: u.pressure ($11.18 in chips)
|
||||||
|
Seat 2: 123smoothie ($1.30 in chips)
|
||||||
|
Seat 3: gashpor ($1.41 in chips)
|
||||||
|
Seat 4: denny501 ($0.86 in chips)
|
||||||
|
Seat 5: s0rrow ($1.53 in chips)
|
||||||
|
Seat 6: TomSludge ($1.59 in chips)
|
||||||
|
Seat 7: Soroka69 ($0.86 in chips)
|
||||||
|
Seat 8: rdiezchang ($1.56 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 [8c]
|
||||||
|
Dealt to 123smoothie [2c]
|
||||||
|
Dealt to gashpor [Qd]
|
||||||
|
Dealt to denny501 [9d]
|
||||||
|
Dealt to s0rrow [Ts 5c Js]
|
||||||
|
Dealt to TomSludge [3h]
|
||||||
|
Dealt to Soroka69 [7s]
|
||||||
|
Dealt to rdiezchang [6c]
|
||||||
|
123smoothie: brings in for $0.02
|
||||||
|
gashpor: folds
|
||||||
|
denny501: calls $0.02
|
||||||
|
s0rrow: folds
|
||||||
|
TomSludge: folds
|
||||||
|
Soroka69: calls $0.02
|
||||||
|
rdiezchang: calls $0.02
|
||||||
|
u.pressure: folds
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to 123smoothie [2c] [8d]
|
||||||
|
Dealt to denny501 [9d] [3d]
|
||||||
|
Dealt to Soroka69 [7s] [Th]
|
||||||
|
Dealt to rdiezchang [6c] [Ac]
|
||||||
|
rdiezchang: bets $0.04
|
||||||
|
123smoothie: calls $0.04
|
||||||
|
denny501: calls $0.04
|
||||||
|
Soroka69: folds
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to 123smoothie [2c 8d] [3c]
|
||||||
|
Dealt to denny501 [9d 3d] [As]
|
||||||
|
Dealt to rdiezchang [6c Ac] [6s]
|
||||||
|
rdiezchang: bets $0.08
|
||||||
|
123smoothie: calls $0.08
|
||||||
|
denny501: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to 123smoothie [2c 8d 3c] [3s]
|
||||||
|
Dealt to denny501 [9d 3d As] [Kc]
|
||||||
|
Dealt to rdiezchang [6c Ac 6s] [Qc]
|
||||||
|
rdiezchang: bets $0.08
|
||||||
|
123smoothie: calls $0.08
|
||||||
|
denny501: folds
|
||||||
|
*** RIVER ***
|
||||||
|
rdiezchang: bets $0.08
|
||||||
|
123smoothie: calls $0.08
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
rdiezchang: shows [8s 7c 6c Ac 6s Qc Qs] (HI: two pair, Queens and Sixes)
|
||||||
|
123smoothie: mucks hand
|
||||||
|
rdiezchang collected $0.80 from pot
|
||||||
|
No low hand qualified
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.84 | Rake $0.04
|
||||||
|
Seat 1: u.pressure folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 2: 123smoothie mucked [2d 7d 2c 8d 3c 3s Tc]
|
||||||
|
Seat 3: gashpor folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 4: denny501 folded on the 6th Street
|
||||||
|
Seat 5: s0rrow folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 6: TomSludge folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 7: Soroka69 folded on the 4th Street
|
||||||
|
Seat 8: rdiezchang showed [8s 7c 6c Ac 6s Qc Qs] and won ($0.80) with HI: two pair, Queens and Sixes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874733203: 7 Card Stud Hi/Lo Limit ($0.04/$0.08 USD) - 2009/11/26 10:29:22 ET
|
||||||
|
Table 'Dawn II' 8-max
|
||||||
|
Seat 1: u.pressure ($11.16 in chips)
|
||||||
|
Seat 2: 123smoothie ($0.96 in chips)
|
||||||
|
Seat 3: gashpor ($1.53 in chips)
|
||||||
|
Seat 4: LainaRahat ($2 in chips)
|
||||||
|
Seat 5: s0rrow ($1.65 in chips)
|
||||||
|
Seat 6: TomSludge ($1.57 in chips)
|
||||||
|
Seat 7: Soroka69 ($0.64 in chips)
|
||||||
|
Seat 8: rdiezchang ($2.02 in chips)
|
||||||
|
u.pressure: posts the ante $0.01
|
||||||
|
123smoothie: posts the ante $0.01
|
||||||
|
gashpor: posts the ante $0.01
|
||||||
|
LainaRahat: 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 [Js]
|
||||||
|
Dealt to 123smoothie [Kc]
|
||||||
|
Dealt to gashpor [Kd]
|
||||||
|
Dealt to LainaRahat [Ts]
|
||||||
|
Dealt to s0rrow [Qd Ad 2s]
|
||||||
|
Dealt to TomSludge [4h]
|
||||||
|
Dealt to Soroka69 [3c]
|
||||||
|
Dealt to rdiezchang [3h]
|
||||||
|
s0rrow: brings in for $0.02
|
||||||
|
TomSludge: folds
|
||||||
|
Soroka69: calls $0.02
|
||||||
|
rdiezchang: folds
|
||||||
|
u.pressure: folds
|
||||||
|
123smoothie: calls $0.02
|
||||||
|
gashpor: folds
|
||||||
|
LainaRahat: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to 123smoothie [Kc] [7d]
|
||||||
|
Dealt to LainaRahat [Ts] [4c]
|
||||||
|
Dealt to s0rrow [Qd Ad 2s] [As]
|
||||||
|
Dealt to Soroka69 [3c] [Qc]
|
||||||
|
rdiezchang leaves the table
|
||||||
|
s0rrow: bets $0.04
|
||||||
|
Soroka69: raises $0.04 to $0.08
|
||||||
|
geo_441 joins the table at seat #8
|
||||||
|
123smoothie: folds
|
||||||
|
LainaRahat: calls $0.08
|
||||||
|
s0rrow: calls $0.04
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to LainaRahat [Ts 4c] [Ks]
|
||||||
|
Dealt to s0rrow [Qd Ad 2s As] [2h]
|
||||||
|
Dealt to Soroka69 [3c Qc] [6h]
|
||||||
|
s0rrow: checks
|
||||||
|
Soroka69: bets $0.08
|
||||||
|
LainaRahat: calls $0.08
|
||||||
|
s0rrow: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to LainaRahat [Ts 4c Ks] [Tc]
|
||||||
|
Dealt to s0rrow [Qd Ad 2s As 2h] [8d]
|
||||||
|
Dealt to Soroka69 [3c Qc 6h] [7h]
|
||||||
|
LainaRahat: checks
|
||||||
|
s0rrow: checks
|
||||||
|
Soroka69: checks
|
||||||
|
*** RIVER ***
|
||||||
|
Dealt to s0rrow [Qd Ad 2s As 2h 8d] [6c]
|
||||||
|
LainaRahat: checks
|
||||||
|
s0rrow: checks
|
||||||
|
Soroka69: checks
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
LainaRahat: shows [Ac 3s Ts 4c Ks Tc Kh] (HI: two pair, Kings and Tens)
|
||||||
|
s0rrow: shows [Qd Ad 2s As 2h 8d 6c] (HI: two pair, Aces and Deuces)
|
||||||
|
Soroka69: mucks hand
|
||||||
|
s0rrow collected $0.61 from pot
|
||||||
|
No low hand qualified
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.64 | Rake $0.03
|
||||||
|
Seat 1: u.pressure folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 2: 123smoothie folded on the 4th Street
|
||||||
|
Seat 3: gashpor folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 4: LainaRahat showed [Ac 3s Ts 4c Ks Tc Kh] and lost with HI: two pair, Kings and Tens
|
||||||
|
Seat 5: s0rrow showed [Qd Ad 2s As 2h 8d 6c] and won ($0.61) with HI: two pair, Aces and Deuces
|
||||||
|
Seat 6: TomSludge folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 7: Soroka69 mucked [2d Qh 3c Qc 6h 7h Jd]
|
||||||
|
Seat 8: rdiezchang folded on the 3rd Street (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874789183: 7 Card Stud Hi/Lo Limit ($0.04/$0.08 USD) - 2009/11/26 10:30:56 ET
|
||||||
|
Table 'Dawn II' 8-max
|
||||||
|
Seat 1: u.pressure ($11.15 in chips)
|
||||||
|
Seat 2: 123smoothie ($0.93 in chips)
|
||||||
|
Seat 3: gashpor ($1.52 in chips)
|
||||||
|
Seat 4: LainaRahat ($1.81 in chips)
|
||||||
|
Seat 5: s0rrow ($2.07 in chips)
|
||||||
|
Seat 6: TomSludge ($1.56 in chips)
|
||||||
|
Seat 7: Soroka69 ($0.45 in chips)
|
||||||
|
Seat 8: geo_441 ($1.60 in chips)
|
||||||
|
u.pressure: posts the ante $0.01
|
||||||
|
123smoothie: posts the ante $0.01
|
||||||
|
gashpor: posts the ante $0.01
|
||||||
|
LainaRahat: posts the ante $0.01
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
TomSludge: posts the ante $0.01
|
||||||
|
Soroka69: posts the ante $0.01
|
||||||
|
geo_441: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to u.pressure [5c]
|
||||||
|
Dealt to 123smoothie [8c]
|
||||||
|
Dealt to gashpor [5s]
|
||||||
|
Dealt to LainaRahat [2c]
|
||||||
|
Dealt to s0rrow [8d Qs Kc]
|
||||||
|
Dealt to TomSludge [As]
|
||||||
|
Dealt to Soroka69 [Tc]
|
||||||
|
Dealt to geo_441 [4d]
|
||||||
|
LainaRahat: brings in for $0.02
|
||||||
|
s0rrow: folds
|
||||||
|
TomSludge: calls $0.02
|
||||||
|
Soroka69: calls $0.02
|
||||||
|
geo_441: calls $0.02
|
||||||
|
u.pressure: folds
|
||||||
|
123smoothie: calls $0.02
|
||||||
|
gashpor: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to 123smoothie [8c] [9d]
|
||||||
|
Dealt to gashpor [5s] [5d]
|
||||||
|
Dealt to LainaRahat [2c] [2d]
|
||||||
|
Dealt to TomSludge [As] [8h]
|
||||||
|
Dealt to Soroka69 [Tc] [2h]
|
||||||
|
Dealt to geo_441 [4d] [3s]
|
||||||
|
gashpor: checks
|
||||||
|
LainaRahat: checks
|
||||||
|
TomSludge: bets $0.04
|
||||||
|
Soroka69: calls $0.04
|
||||||
|
geo_441: calls $0.04
|
||||||
|
123smoothie: calls $0.04
|
||||||
|
gashpor: calls $0.04
|
||||||
|
LainaRahat: folds
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to 123smoothie [8c 9d] [Jd]
|
||||||
|
Dealt to gashpor [5s 5d] [Td]
|
||||||
|
Dealt to TomSludge [As 8h] [Js]
|
||||||
|
Dealt to Soroka69 [Tc 2h] [Qc]
|
||||||
|
Dealt to geo_441 [4d 3s] [7c]
|
||||||
|
gashpor: checks
|
||||||
|
TomSludge: checks
|
||||||
|
Soroka69: bets $0.08
|
||||||
|
geo_441: calls $0.08
|
||||||
|
123smoothie: calls $0.08
|
||||||
|
gashpor: calls $0.08
|
||||||
|
TomSludge: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to 123smoothie [8c 9d Jd] [3c]
|
||||||
|
Dealt to gashpor [5s 5d Td] [9h]
|
||||||
|
Dealt to TomSludge [As 8h Js] [6c]
|
||||||
|
Dealt to Soroka69 [Tc 2h Qc] [5h]
|
||||||
|
Dealt to geo_441 [4d 3s 7c] [Jh]
|
||||||
|
gashpor: checks
|
||||||
|
TomSludge: checks
|
||||||
|
Soroka69: bets $0.08
|
||||||
|
geo_441: calls $0.08
|
||||||
|
123smoothie: calls $0.08
|
||||||
|
gashpor: calls $0.08
|
||||||
|
TomSludge: calls $0.08
|
||||||
|
*** RIVER ***
|
||||||
|
gashpor: checks
|
||||||
|
TomSludge: checks
|
||||||
|
Soroka69: checks
|
||||||
|
geo_441: checks
|
||||||
|
123smoothie: bets $0.08
|
||||||
|
gashpor: calls $0.08
|
||||||
|
TomSludge: calls $0.08
|
||||||
|
Soroka69: calls $0.08
|
||||||
|
geo_441: folds
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
123smoothie: shows [Qd Ks 8c 9d Jd 3c 9c] (HI: a pair of Nines)
|
||||||
|
gashpor: shows [4c Th 5s 5d Td 9h Ad] (HI: two pair, Tens and Fives)
|
||||||
|
TomSludge: shows [7s Ah As 8h Js 6c Jc] (HI: two pair, Aces and Jacks)
|
||||||
|
Soroka69: mucks hand
|
||||||
|
TomSludge collected $1.45 from pot
|
||||||
|
No low hand qualified
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $1.52 | Rake $0.07
|
||||||
|
Seat 1: u.pressure folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 2: 123smoothie showed [Qd Ks 8c 9d Jd 3c 9c] and lost with HI: a pair of Nines
|
||||||
|
Seat 3: gashpor showed [4c Th 5s 5d Td 9h Ad] and lost with HI: two pair, Tens and Fives
|
||||||
|
Seat 4: LainaRahat folded on the 4th Street
|
||||||
|
Seat 5: s0rrow folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 6: TomSludge showed [7s Ah As 8h Js 6c Jc] and won ($1.45) with HI: two pair, Aces and Jacks
|
||||||
|
Seat 7: Soroka69 mucked [Qh Ts Tc 2h Qc 5h 6s]
|
||||||
|
Seat 8: geo_441 folded on the River
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,574 @@
|
||||||
|
PokerStars Game #35874566077: Razz Limit ($0.04/$0.08 USD) - 2009/11/26 10:24:42 ET
|
||||||
|
Table 'Gotha II' 8-max
|
||||||
|
Seat 1: kobreli ($1.33 in chips)
|
||||||
|
Seat 3: willy32948 ($2.17 in chips)
|
||||||
|
Seat 5: meg100 ($1.71 in chips)
|
||||||
|
Seat 7: s0rrow ($1.60 in chips)
|
||||||
|
Seat 8: SilkZone ($1.65 in chips)
|
||||||
|
kobreli: posts the ante $0.01
|
||||||
|
willy32948: posts the ante $0.01
|
||||||
|
meg100: posts the ante $0.01
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
SilkZone: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to kobreli [Qc]
|
||||||
|
Dealt to willy32948 [6h]
|
||||||
|
Dealt to meg100 [3s]
|
||||||
|
Dealt to s0rrow [Td 2s 9s]
|
||||||
|
Dealt to SilkZone [3h]
|
||||||
|
kobreli: brings in for $0.02
|
||||||
|
willy32948: calls $0.02
|
||||||
|
meg100: calls $0.02
|
||||||
|
s0rrow: folds
|
||||||
|
SilkZone: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to kobreli [Qc] [8s]
|
||||||
|
Dealt to willy32948 [6h] [7h]
|
||||||
|
Dealt to meg100 [3s] [Js]
|
||||||
|
Dealt to SilkZone [3h] [3d]
|
||||||
|
kurczakkr2 is disconnected
|
||||||
|
willy32948: bets $0.04
|
||||||
|
meg100: calls $0.04
|
||||||
|
SilkZone: calls $0.04
|
||||||
|
kobreli: folds
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to willy32948 [6h 7h] [7s]
|
||||||
|
Dealt to meg100 [3s Js] [Kh]
|
||||||
|
Dealt to SilkZone [3h 3d] [4h]
|
||||||
|
meg100: checks
|
||||||
|
SilkZone: bets $0.08
|
||||||
|
willy32948: calls $0.08
|
||||||
|
meg100: folds
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to willy32948 [6h 7h 7s] [Jh]
|
||||||
|
Dealt to SilkZone [3h 3d 4h] [9c]
|
||||||
|
SilkZone: bets $0.08
|
||||||
|
willy32948: folds
|
||||||
|
Uncalled bet ($0.08) returned to SilkZone
|
||||||
|
willy32948 leaves the table
|
||||||
|
SilkZone collected $0.39 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.41 | Rake $0.02
|
||||||
|
Seat 1: kobreli folded on the 4th Street
|
||||||
|
Seat 3: willy32948 folded on the 6th Street
|
||||||
|
Seat 5: meg100 folded on the 5th Street
|
||||||
|
Seat 7: s0rrow folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 8: SilkZone collected ($0.39)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874590575: Razz Limit ($0.04/$0.08 USD) - 2009/11/26 10:25:23 ET
|
||||||
|
Table 'Gotha II' 8-max
|
||||||
|
Seat 1: kobreli ($1.30 in chips)
|
||||||
|
Seat 5: meg100 ($1.64 in chips)
|
||||||
|
Seat 7: s0rrow ($1.59 in chips)
|
||||||
|
Seat 8: SilkZone ($1.89 in chips)
|
||||||
|
kobreli: posts the ante $0.01
|
||||||
|
meg100: posts the ante $0.01
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
SilkZone: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to kobreli [3h]
|
||||||
|
Dealt to meg100 [6s]
|
||||||
|
Dealt to s0rrow [4c 2h 8h]
|
||||||
|
Dealt to SilkZone [Jc]
|
||||||
|
SilkZone: brings in for $0.02
|
||||||
|
kobreli: calls $0.02
|
||||||
|
meg100: calls $0.02
|
||||||
|
s0rrow: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to kobreli [3h] [Ks]
|
||||||
|
Dealt to meg100 [6s] [2d]
|
||||||
|
Dealt to s0rrow [4c 2h 8h] [7c]
|
||||||
|
Dealt to SilkZone [Jc] [3c]
|
||||||
|
meg100: checks
|
||||||
|
s0rrow: bets $0.04
|
||||||
|
SilkZone: calls $0.04
|
||||||
|
kobreli: folds
|
||||||
|
meg100: calls $0.04
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to meg100 [6s 2d] [5d]
|
||||||
|
Dealt to s0rrow [4c 2h 8h 7c] [Ah]
|
||||||
|
Dealt to SilkZone [Jc 3c] [8c]
|
||||||
|
meg100: checks
|
||||||
|
s0rrow: bets $0.08
|
||||||
|
SilkZone: calls $0.08
|
||||||
|
meg100: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to meg100 [6s 2d 5d] [Qs]
|
||||||
|
Dealt to s0rrow [4c 2h 8h 7c Ah] [2s]
|
||||||
|
Dealt to SilkZone [Jc 3c 8c] [Kh]
|
||||||
|
s0rrow: checks
|
||||||
|
SilkZone: checks
|
||||||
|
meg100: checks
|
||||||
|
*** RIVER ***
|
||||||
|
Dealt to s0rrow [4c 2h 8h 7c Ah 2s] [5h]
|
||||||
|
s0rrow: bets $0.08
|
||||||
|
HIWAII2 joins the table at seat #6
|
||||||
|
SilkZone: folds
|
||||||
|
meg100: folds
|
||||||
|
Uncalled bet ($0.08) returned to s0rrow
|
||||||
|
s0rrow collected $0.46 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.48 | Rake $0.02
|
||||||
|
Seat 1: kobreli folded on the 4th Street
|
||||||
|
Seat 5: meg100 folded on the River
|
||||||
|
Seat 7: s0rrow collected ($0.46)
|
||||||
|
Seat 8: SilkZone folded on the River
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874623967: Razz Limit ($0.04/$0.08 USD) - 2009/11/26 10:26:19 ET
|
||||||
|
Table 'Gotha II' 8-max
|
||||||
|
Seat 1: kobreli ($1.27 in chips)
|
||||||
|
Seat 5: meg100 ($1.49 in chips)
|
||||||
|
Seat 6: HIWAII2 ($1.13 in chips)
|
||||||
|
Seat 7: s0rrow ($1.90 in chips)
|
||||||
|
Seat 8: SilkZone ($1.74 in chips)
|
||||||
|
kobreli: posts the ante $0.01
|
||||||
|
meg100: posts the ante $0.01
|
||||||
|
HIWAII2: posts the ante $0.01
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
SilkZone: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to kobreli [8c]
|
||||||
|
Dealt to meg100 [7h]
|
||||||
|
Dealt to HIWAII2 [Kh]
|
||||||
|
Dealt to s0rrow [9h 2s 7c]
|
||||||
|
Dealt to SilkZone [6s]
|
||||||
|
HIWAII2: brings in for $0.02
|
||||||
|
manga130 joins the table at seat #3
|
||||||
|
s0rrow: calls $0.02
|
||||||
|
SilkZone: calls $0.02
|
||||||
|
kobreli: calls $0.02
|
||||||
|
meg100: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to kobreli [8c] [8s]
|
||||||
|
Dealt to meg100 [7h] [As]
|
||||||
|
Dealt to HIWAII2 [Kh] [6h]
|
||||||
|
Dealt to s0rrow [9h 2s 7c] [6c]
|
||||||
|
Dealt to SilkZone [6s] [9c]
|
||||||
|
meg100: checks
|
||||||
|
HIWAII2: checks
|
||||||
|
s0rrow: checks
|
||||||
|
SilkZone: checks
|
||||||
|
kobreli: checks
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to kobreli [8c 8s] [3c]
|
||||||
|
Dealt to meg100 [7h As] [5d]
|
||||||
|
Dealt to HIWAII2 [Kh 6h] [3d]
|
||||||
|
Dealt to s0rrow [9h 2s 7c 6c] [Qh]
|
||||||
|
Dealt to SilkZone [6s 9c] [Qs]
|
||||||
|
meg100: checks
|
||||||
|
HIWAII2: bets $0.08
|
||||||
|
s0rrow: calls $0.08
|
||||||
|
SilkZone: folds
|
||||||
|
kobreli: folds
|
||||||
|
meg100: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to meg100 [7h As 5d] [5c]
|
||||||
|
Dealt to HIWAII2 [Kh 6h 3d] [6d]
|
||||||
|
Dealt to s0rrow [9h 2s 7c 6c Qh] [Ad]
|
||||||
|
s0rrow: checks
|
||||||
|
meg100: checks
|
||||||
|
HIWAII2: checks
|
||||||
|
*** RIVER ***
|
||||||
|
Dealt to s0rrow [9h 2s 7c 6c Qh Ad] [Ac]
|
||||||
|
s0rrow: bets $0.08
|
||||||
|
meg100: folds
|
||||||
|
HIWAII2: raises $0.08 to $0.16
|
||||||
|
s0rrow: calls $0.08
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
HIWAII2: shows [2h 8d Kh 6h 3d 6d 4h] (Lo: 8,6,4,3,2)
|
||||||
|
s0rrow: mucks hand
|
||||||
|
HIWAII2 collected $0.68 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.71 | Rake $0.03
|
||||||
|
Seat 1: kobreli folded on the 5th Street
|
||||||
|
Seat 5: meg100 folded on the River
|
||||||
|
Seat 6: HIWAII2 showed [2h 8d Kh 6h 3d 6d 4h] and won ($0.68) with Lo: 8,6,4,3,2
|
||||||
|
Seat 7: s0rrow mucked [9h 2s 7c 6c Qh Ad Ac]
|
||||||
|
Seat 8: SilkZone folded on the 5th Street
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874664176: Razz Limit ($0.04/$0.08 USD) - 2009/11/26 10:27:26 ET
|
||||||
|
Table 'Gotha II' 8-max
|
||||||
|
Seat 1: kobreli ($1.24 in chips)
|
||||||
|
Seat 3: manga130 ($0.68 in chips)
|
||||||
|
Seat 5: meg100 ($1.38 in chips)
|
||||||
|
Seat 6: HIWAII2 ($1.54 in chips)
|
||||||
|
Seat 7: s0rrow ($1.63 in chips)
|
||||||
|
Seat 8: SilkZone ($1.71 in chips)
|
||||||
|
kobreli: posts the ante $0.01
|
||||||
|
manga130: posts the ante $0.01
|
||||||
|
meg100: posts the ante $0.01
|
||||||
|
HIWAII2: posts the ante $0.01
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
SilkZone: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to kobreli [Kd]
|
||||||
|
Dealt to manga130 [Td]
|
||||||
|
Dealt to meg100 [Qh]
|
||||||
|
Dealt to HIWAII2 [5h]
|
||||||
|
Dealt to s0rrow [9s Qd 2s]
|
||||||
|
Dealt to SilkZone [As]
|
||||||
|
kobreli: brings in for $0.02
|
||||||
|
manga130: folds
|
||||||
|
meg100: folds
|
||||||
|
HIWAII2: calls $0.02
|
||||||
|
s0rrow: folds
|
||||||
|
SilkZone: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to kobreli [Kd] [4s]
|
||||||
|
Dealt to HIWAII2 [5h] [4h]
|
||||||
|
Dealt to SilkZone [As] [Ah]
|
||||||
|
HIWAII2: bets $0.04
|
||||||
|
SilkZone: folds
|
||||||
|
kobreli: folds
|
||||||
|
Uncalled bet ($0.04) returned to HIWAII2
|
||||||
|
HIWAII2 collected $0.12 from pot
|
||||||
|
HIWAII2: shows [3d 3s 5h 4h] (Lo: 3,3,5,4)
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.12 | Rake $0
|
||||||
|
Seat 1: kobreli folded on the 4th Street
|
||||||
|
Seat 3: manga130 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 5: meg100 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 6: HIWAII2 collected ($0.12)
|
||||||
|
Seat 7: s0rrow folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 8: SilkZone folded on the 4th Street
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874682808: Razz Limit ($0.04/$0.08 USD) - 2009/11/26 10:27:57 ET
|
||||||
|
Table 'Gotha II' 8-max
|
||||||
|
Seat 1: kobreli ($1.21 in chips)
|
||||||
|
Seat 3: manga130 ($0.67 in chips)
|
||||||
|
Seat 5: meg100 ($1.37 in chips)
|
||||||
|
Seat 6: HIWAII2 ($1.63 in chips)
|
||||||
|
Seat 7: s0rrow ($1.62 in chips)
|
||||||
|
Seat 8: SilkZone ($1.68 in chips)
|
||||||
|
kobreli: posts the ante $0.01
|
||||||
|
manga130: posts the ante $0.01
|
||||||
|
meg100: posts the ante $0.01
|
||||||
|
HIWAII2: posts the ante $0.01
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
SilkZone: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to kobreli [Tc]
|
||||||
|
Dealt to manga130 [Qd]
|
||||||
|
Dealt to meg100 [9h]
|
||||||
|
Dealt to HIWAII2 [5s]
|
||||||
|
Dealt to s0rrow [7h 9c Th]
|
||||||
|
Dealt to SilkZone [Kh]
|
||||||
|
SilkZone: brings in for $0.02
|
||||||
|
kobreli: folds
|
||||||
|
manga130: calls $0.02
|
||||||
|
meg100: calls $0.02
|
||||||
|
HIWAII2: calls $0.02
|
||||||
|
s0rrow: folds
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to manga130 [Qd] [8s]
|
||||||
|
Dealt to meg100 [9h] [Kd]
|
||||||
|
Dealt to HIWAII2 [5s] [6s]
|
||||||
|
Dealt to SilkZone [Kh] [2d]
|
||||||
|
HIWAII2: bets $0.04
|
||||||
|
SilkZone: raises $0.04 to $0.08
|
||||||
|
manga130: calls $0.08
|
||||||
|
meg100: folds
|
||||||
|
HIWAII2: calls $0.04
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to manga130 [Qd 8s] [3h]
|
||||||
|
Dealt to HIWAII2 [5s 6s] [4s]
|
||||||
|
Dealt to SilkZone [Kh 2d] [Js]
|
||||||
|
HIWAII2: bets $0.08
|
||||||
|
SilkZone: calls $0.08
|
||||||
|
manga130: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to manga130 [Qd 8s 3h] [Ks]
|
||||||
|
Dealt to HIWAII2 [5s 6s 4s] [Qs]
|
||||||
|
Dealt to SilkZone [Kh 2d Js] [6c]
|
||||||
|
HIWAII2: bets $0.08
|
||||||
|
SilkZone: calls $0.08
|
||||||
|
manga130: calls $0.08
|
||||||
|
*** RIVER ***
|
||||||
|
HIWAII2: bets $0.08
|
||||||
|
SilkZone: raises $0.08 to $0.16
|
||||||
|
manga130: folds
|
||||||
|
HIWAII2: folds
|
||||||
|
Uncalled bet ($0.08) returned to SilkZone
|
||||||
|
SilkZone collected $0.98 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $1.02 | Rake $0.04
|
||||||
|
Seat 1: kobreli folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 3: manga130 folded on the River
|
||||||
|
Seat 5: meg100 folded on the 4th Street
|
||||||
|
Seat 6: HIWAII2 folded on the River
|
||||||
|
Seat 7: s0rrow folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 8: SilkZone collected ($0.98)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874721245: Razz Limit ($0.04/$0.08 USD) - 2009/11/26 10:29:02 ET
|
||||||
|
Table 'Gotha II' 8-max
|
||||||
|
Seat 1: kobreli ($1.20 in chips)
|
||||||
|
Seat 3: manga130 ($0.40 in chips)
|
||||||
|
Seat 5: meg100 ($1.34 in chips)
|
||||||
|
Seat 6: HIWAII2 ($1.28 in chips)
|
||||||
|
Seat 7: s0rrow ($1.61 in chips)
|
||||||
|
Seat 8: SilkZone ($2.31 in chips)
|
||||||
|
kobreli: posts the ante $0.01
|
||||||
|
manga130: posts the ante $0.01
|
||||||
|
meg100: posts the ante $0.01
|
||||||
|
HIWAII2: posts the ante $0.01
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
SilkZone: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to kobreli [3d]
|
||||||
|
Dealt to manga130 [Qc]
|
||||||
|
Dealt to meg100 [Qd]
|
||||||
|
Dealt to HIWAII2 [Js]
|
||||||
|
Dealt to s0rrow [Th Ah Qh]
|
||||||
|
Dealt to SilkZone [9d]
|
||||||
|
s0rrow: brings in for $0.02
|
||||||
|
SilkZone: calls $0.02
|
||||||
|
kobreli: calls $0.02
|
||||||
|
manga130: calls $0.02
|
||||||
|
meg100: folds
|
||||||
|
HIWAII2: folds
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to kobreli [3d] [Ad]
|
||||||
|
Dealt to manga130 [Qc] [6d]
|
||||||
|
Dealt to s0rrow [Th Ah Qh] [8s]
|
||||||
|
Dealt to SilkZone [9d] [7c]
|
||||||
|
kobreli: bets $0.04
|
||||||
|
manga130: folds
|
||||||
|
s0rrow: folds
|
||||||
|
SilkZone: raises $0.04 to $0.08
|
||||||
|
kobreli: raises $0.04 to $0.12
|
||||||
|
SilkZone: calls $0.04
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to kobreli [3d Ad] [Ac]
|
||||||
|
Dealt to SilkZone [9d 7c] [Ts]
|
||||||
|
SilkZone: checks
|
||||||
|
kobreli: bets $0.08
|
||||||
|
SilkZone: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to kobreli [3d Ad Ac] [Kh]
|
||||||
|
Dealt to SilkZone [9d 7c Ts] [5s]
|
||||||
|
SilkZone: bets $0.08
|
||||||
|
kobreli: calls $0.08
|
||||||
|
*** RIVER ***
|
||||||
|
SilkZone: checks
|
||||||
|
kobreli: checks
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
kobreli: shows [6h 8h 3d Ad Ac Kh 8c] (Lo: K,8,6,3,A)
|
||||||
|
SilkZone: shows [2d 4s 9d 7c Ts 5s Tc] (Lo: 9,7,5,4,2)
|
||||||
|
SilkZone collected $0.67 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.70 | Rake $0.03
|
||||||
|
Seat 1: kobreli showed [6h 8h 3d Ad Ac Kh 8c] and lost with Lo: K,8,6,3,A
|
||||||
|
Seat 3: manga130 folded on the 4th Street
|
||||||
|
Seat 5: meg100 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 6: HIWAII2 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 7: s0rrow folded on the 4th Street
|
||||||
|
Seat 8: SilkZone showed [2d 4s 9d 7c Ts 5s Tc] and won ($0.67) with Lo: 9,7,5,4,2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874756552: Razz Limit ($0.04/$0.08 USD) - 2009/11/26 10:30:02 ET
|
||||||
|
Table 'Gotha II' 8-max
|
||||||
|
Seat 1: kobreli ($0.89 in chips)
|
||||||
|
Seat 3: manga130 ($0.37 in chips)
|
||||||
|
Seat 5: meg100 ($1.33 in chips)
|
||||||
|
Seat 6: HIWAII2 ($1.27 in chips)
|
||||||
|
Seat 7: s0rrow ($1.58 in chips)
|
||||||
|
Seat 8: SilkZone ($2.67 in chips)
|
||||||
|
kobreli: posts the ante $0.01
|
||||||
|
manga130: posts the ante $0.01
|
||||||
|
meg100: posts the ante $0.01
|
||||||
|
HIWAII2: posts the ante $0.01
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
SilkZone: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to kobreli [4s]
|
||||||
|
Dealt to manga130 [5h]
|
||||||
|
Dealt to meg100 [3h]
|
||||||
|
Dealt to HIWAII2 [Qh]
|
||||||
|
Dealt to s0rrow [Kd Ad 7d]
|
||||||
|
Dealt to SilkZone [9d]
|
||||||
|
kobreli said, "this.is.lucky"
|
||||||
|
HIWAII2: brings in for $0.02
|
||||||
|
s0rrow: folds
|
||||||
|
SilkZone: folds
|
||||||
|
kobreli: calls $0.02
|
||||||
|
manga130: folds
|
||||||
|
meg100: calls $0.02
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to kobreli [4s] [Tc]
|
||||||
|
Dealt to meg100 [3h] [2s]
|
||||||
|
Dealt to HIWAII2 [Qh] [7s]
|
||||||
|
meg100: bets $0.04
|
||||||
|
HIWAII2: folds
|
||||||
|
kobreli: calls $0.04
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to kobreli [4s Tc] [8d]
|
||||||
|
Dealt to meg100 [3h 2s] [Jh]
|
||||||
|
kobreli: bets $0.08
|
||||||
|
meg100: folds
|
||||||
|
Uncalled bet ($0.08) returned to kobreli
|
||||||
|
kobreli collected $0.19 from pot
|
||||||
|
kobreli: doesn't show hand
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.20 | Rake $0.01
|
||||||
|
Seat 1: kobreli collected ($0.19)
|
||||||
|
Seat 3: manga130 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 5: meg100 folded on the 5th Street
|
||||||
|
Seat 6: HIWAII2 folded on the 4th Street
|
||||||
|
Seat 7: s0rrow folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 8: SilkZone folded on the 3rd Street (didn't bet)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874780027: Razz Limit ($0.04/$0.08 USD) - 2009/11/26 10:30:41 ET
|
||||||
|
Table 'Gotha II' 8-max
|
||||||
|
Seat 1: kobreli ($1.01 in chips)
|
||||||
|
Seat 3: manga130 ($0.36 in chips)
|
||||||
|
Seat 5: meg100 ($1.26 in chips)
|
||||||
|
Seat 6: HIWAII2 ($1.24 in chips)
|
||||||
|
Seat 7: s0rrow ($1.57 in chips)
|
||||||
|
Seat 8: SilkZone ($2.66 in chips)
|
||||||
|
kobreli: posts the ante $0.01
|
||||||
|
manga130: posts the ante $0.01
|
||||||
|
meg100: posts the ante $0.01
|
||||||
|
HIWAII2: posts the ante $0.01
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
SilkZone: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to kobreli [6s]
|
||||||
|
Dealt to manga130 [9d]
|
||||||
|
Dealt to meg100 [5c]
|
||||||
|
Dealt to HIWAII2 [Qs]
|
||||||
|
Dealt to s0rrow [6d 9c 3d]
|
||||||
|
Dealt to SilkZone [Qc]
|
||||||
|
HIWAII2: brings in for $0.02
|
||||||
|
s0rrow: raises $0.02 to $0.04
|
||||||
|
SilkZone: calls $0.04
|
||||||
|
kobreli: calls $0.04
|
||||||
|
manga130: folds
|
||||||
|
meg100: calls $0.04
|
||||||
|
HIWAII2: folds
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to kobreli [6s] [7h]
|
||||||
|
Dealt to meg100 [5c] [5h]
|
||||||
|
Dealt to s0rrow [6d 9c 3d] [8s]
|
||||||
|
Dealt to SilkZone [Qc] [2c]
|
||||||
|
kobreli: bets $0.04
|
||||||
|
meg100: folds
|
||||||
|
s0rrow: raises $0.04 to $0.08
|
||||||
|
SilkZone: raises $0.04 to $0.12
|
||||||
|
kobreli: calls $0.08
|
||||||
|
s0rrow: calls $0.04
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to kobreli [6s 7h] [2h]
|
||||||
|
Dealt to s0rrow [6d 9c 3d 8s] [Jh]
|
||||||
|
Dealt to SilkZone [Qc 2c] [7c]
|
||||||
|
kobreli: bets $0.08
|
||||||
|
s0rrow: folds
|
||||||
|
SilkZone: calls $0.08
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to kobreli [6s 7h 2h] [3h]
|
||||||
|
Dealt to SilkZone [Qc 2c 7c] [Kd]
|
||||||
|
kobreli: bets $0.08
|
||||||
|
SilkZone: calls $0.08
|
||||||
|
*** RIVER ***
|
||||||
|
kobreli: bets $0.08
|
||||||
|
SilkZone: raises $0.08 to $0.16
|
||||||
|
kobreli: raises $0.08 to $0.24
|
||||||
|
SilkZone: raises $0.08 to $0.32
|
||||||
|
Betting is capped
|
||||||
|
kobreli: calls $0.08
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
SilkZone: shows [3s 5d Qc 2c 7c Kd As] (Lo: 7,5,3,2,A)
|
||||||
|
kobreli: shows [Ac Qd 6s 7h 2h 3h 4c] (Lo: 6,4,3,2,A)
|
||||||
|
kobreli collected $1.49 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $1.56 | Rake $0.07
|
||||||
|
Seat 1: kobreli showed [Ac Qd 6s 7h 2h 3h 4c] and won ($1.49) with Lo: 6,4,3,2,A
|
||||||
|
Seat 3: manga130 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 5: meg100 folded on the 4th Street
|
||||||
|
Seat 6: HIWAII2 folded on the 3rd Street
|
||||||
|
Seat 7: s0rrow folded on the 5th Street
|
||||||
|
Seat 8: SilkZone showed [3s 5d Qc 2c 7c Kd As] and lost with Lo: 7,5,3,2,A
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PokerStars Game #35874817957: Razz Limit ($0.04/$0.08 USD) - 2009/11/26 10:31:45 ET
|
||||||
|
Table 'Gotha II' 8-max
|
||||||
|
Seat 1: kobreli ($1.85 in chips)
|
||||||
|
Seat 3: manga130 ($0.35 in chips)
|
||||||
|
Seat 5: meg100 ($1.21 in chips)
|
||||||
|
Seat 6: HIWAII2 ($1.21 in chips)
|
||||||
|
Seat 7: s0rrow ($1.40 in chips)
|
||||||
|
Seat 8: SilkZone ($2.01 in chips)
|
||||||
|
kobreli: posts the ante $0.01
|
||||||
|
manga130: posts the ante $0.01
|
||||||
|
meg100: posts the ante $0.01
|
||||||
|
HIWAII2: posts the ante $0.01
|
||||||
|
s0rrow: posts the ante $0.01
|
||||||
|
SilkZone: posts the ante $0.01
|
||||||
|
*** 3rd STREET ***
|
||||||
|
Dealt to kobreli [As]
|
||||||
|
Dealt to manga130 [Ac]
|
||||||
|
Dealt to meg100 [Ah]
|
||||||
|
Dealt to HIWAII2 [Jd]
|
||||||
|
Dealt to s0rrow [6d 4h 3h]
|
||||||
|
Dealt to SilkZone [2c]
|
||||||
|
HIWAII2: brings in for $0.02
|
||||||
|
s0rrow: calls $0.02
|
||||||
|
SilkZone: calls $0.02
|
||||||
|
kobreli: calls $0.02
|
||||||
|
manga130: calls $0.02
|
||||||
|
meg100: folds
|
||||||
|
*** 4th STREET ***
|
||||||
|
Dealt to kobreli [As] [6s]
|
||||||
|
Dealt to manga130 [Ac] [6h]
|
||||||
|
Dealt to HIWAII2 [Jd] [Qc]
|
||||||
|
Dealt to s0rrow [6d 4h 3h] [3c]
|
||||||
|
Dealt to SilkZone [2c] [Th]
|
||||||
|
kobreli: bets $0.04
|
||||||
|
manga130: calls $0.04
|
||||||
|
HIWAII2: folds
|
||||||
|
s0rrow: calls $0.04
|
||||||
|
SilkZone: folds
|
||||||
|
*** 5th STREET ***
|
||||||
|
Dealt to kobreli [As 6s] [5c]
|
||||||
|
Dealt to manga130 [Ac 6h] [5s]
|
||||||
|
Dealt to s0rrow [6d 4h 3h 3c] [9s]
|
||||||
|
kobreli: bets $0.08
|
||||||
|
manga130: calls $0.08
|
||||||
|
s0rrow: folds
|
||||||
|
*** 6th STREET ***
|
||||||
|
Dealt to kobreli [As 6s 5c] [5d]
|
||||||
|
Dealt to manga130 [Ac 6h 5s] [9h]
|
||||||
|
manga130: bets $0.08
|
||||||
|
kobreli: raises $0.08 to $0.16
|
||||||
|
manga130: calls $0.08
|
||||||
|
*** RIVER ***
|
||||||
|
manga130: bets $0.04 and is all-in
|
||||||
|
kobreli: calls $0.04
|
||||||
|
*** SHOW DOWN ***
|
||||||
|
manga130: shows [Ad 8h Ac 6h 5s 9h Kh] (Lo: 9,8,6,5,A)
|
||||||
|
kobreli: shows [3d 2s As 6s 5c 5d 2d] (Lo: 6,5,3,2,A)
|
||||||
|
kobreli collected $0.80 from pot
|
||||||
|
*** SUMMARY ***
|
||||||
|
Total pot $0.84 | Rake $0.04
|
||||||
|
Seat 1: kobreli showed [3d 2s As 6s 5c 5d 2d] and won ($0.80) with Lo: 6,5,3,2,A
|
||||||
|
Seat 3: manga130 showed [Ad 8h Ac 6h 5s 9h Kh] and lost with Lo: 9,8,6,5,A
|
||||||
|
Seat 5: meg100 folded on the 3rd Street (didn't bet)
|
||||||
|
Seat 6: HIWAII2 folded on the 4th Street
|
||||||
|
Seat 7: s0rrow folded on the 5th Street
|
||||||
|
Seat 8: SilkZone folded on the 4th Street
|
||||||
|
|
||||||
|
|
||||||
|
|
17390
pyfpdb/regression-test-files/tour/Stars/Flop/NLHE-USD-MTT-5r-200710.txt
Normal file
17390
pyfpdb/regression-test-files/tour/Stars/Flop/NLHE-USD-MTT-5r-200710.txt
Normal file
File diff suppressed because it is too large
Load Diff
67
pyfpdb/test_Database.py
Normal file
67
pyfpdb/test_Database.py
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import sqlite3
|
||||||
|
import fpdb_db
|
||||||
|
import math
|
||||||
|
|
||||||
|
# Should probably use our wrapper classes - creating sqlite db in memory
|
||||||
|
sqlite3.register_converter("bool", lambda x: bool(int(x)))
|
||||||
|
sqlite3.register_adapter(bool, lambda x: "1" if x else "0")
|
||||||
|
|
||||||
|
con = sqlite3.connect(":memory:")
|
||||||
|
con.isolation_level = None
|
||||||
|
|
||||||
|
#Floor function
|
||||||
|
con.create_function("floor", 1, math.floor)
|
||||||
|
|
||||||
|
#Mod function
|
||||||
|
tmp = fpdb_db.sqlitemath()
|
||||||
|
con.create_function("mod", 2, tmp.mod)
|
||||||
|
|
||||||
|
# Aggregate function VARIANCE()
|
||||||
|
con.create_aggregate("variance", 1, fpdb_db.VARIANCE)
|
||||||
|
|
||||||
|
|
||||||
|
cur = con.cursor()
|
||||||
|
|
||||||
|
def testSQLiteVarianceFunction():
|
||||||
|
cur.execute("CREATE TABLE test(i)")
|
||||||
|
cur.execute("INSERT INTO test(i) values (1)")
|
||||||
|
cur.execute("INSERT INTO test(i) values (2)")
|
||||||
|
cur.execute("INSERT INTO test(i) values (3)")
|
||||||
|
cur.execute("SELECT variance(i) from test")
|
||||||
|
result = cur.fetchone()[0]
|
||||||
|
|
||||||
|
print "DEBUG: Testing variance function"
|
||||||
|
print "DEBUG: result: %s expecting: 0.666666 (result-expecting ~= 0.0): %s" % (result, (result - 0.66666))
|
||||||
|
cur.execute("DROP TABLE test")
|
||||||
|
assert (result - 0.66666) <= 0.0001
|
||||||
|
|
||||||
|
def testSQLiteFloorFunction():
|
||||||
|
vars = [0.1, 1.5, 2.6, 3.5, 4.9]
|
||||||
|
cur.execute("CREATE TABLE test(i float)")
|
||||||
|
for var in vars:
|
||||||
|
cur.execute("INSERT INTO test(i) values(%f)" % var)
|
||||||
|
cur.execute("SELECT floor(i) from test")
|
||||||
|
result = cur.fetchall()
|
||||||
|
print "DEBUG: result: %s" % result
|
||||||
|
answer = 0
|
||||||
|
for i in result:
|
||||||
|
print "DEBUG: int(var): %s" % int(i[0])
|
||||||
|
assert answer == int(i[0])
|
||||||
|
answer = answer + 1
|
||||||
|
cur.execute("DROP TABLE test")
|
||||||
|
|
||||||
|
def testSQLiteModFunction():
|
||||||
|
vars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 ,17, 18]
|
||||||
|
cur.execute("CREATE TABLE test(i int)")
|
||||||
|
for var in vars:
|
||||||
|
cur.execute("INSERT INTO test(i) values(%i)" % var)
|
||||||
|
cur.execute("SELECT mod(i,13) from test")
|
||||||
|
result = cur.fetchall()
|
||||||
|
idx = 0
|
||||||
|
for i in result:
|
||||||
|
print "DEBUG: int(var): %s" % i[0]
|
||||||
|
assert vars[idx]%13 == int(i[0])
|
||||||
|
idx = idx+1
|
||||||
|
|
||||||
|
cur.execute("DROP TABLE test")
|
|
@ -3,6 +3,21 @@ import PokerStarsToFpdb
|
||||||
from Hand import *
|
from Hand import *
|
||||||
import py
|
import py
|
||||||
|
|
||||||
|
import Configuration
|
||||||
|
import Database
|
||||||
|
import SQL
|
||||||
|
import fpdb_import
|
||||||
|
|
||||||
|
config = Configuration.Config(file = "HUD_config.test.xml")
|
||||||
|
db = Database.Database(config)
|
||||||
|
sql = SQL.Sql(db_server = 'sqlite')
|
||||||
|
|
||||||
|
settings = {}
|
||||||
|
settings.update(config.get_db_parameters())
|
||||||
|
settings.update(config.get_tv_parameters())
|
||||||
|
settings.update(config.get_import_parameters())
|
||||||
|
settings.update(config.get_default_paths())
|
||||||
|
|
||||||
#regression-test-files/stars/badugi/ring-fl-badugi.txt
|
#regression-test-files/stars/badugi/ring-fl-badugi.txt
|
||||||
# s0rrow: input: $30.00 end: $22.65 total: ($7.35)
|
# s0rrow: input: $30.00 end: $22.65 total: ($7.35)
|
||||||
#regression-test-files/stars/plo/PLO-6max.txt
|
#regression-test-files/stars/plo/PLO-6max.txt
|
||||||
|
@ -45,37 +60,66 @@ def testGameInfo():
|
||||||
yield checkGameInfo, hhc, header, info
|
yield checkGameInfo, hhc, header, info
|
||||||
|
|
||||||
|
|
||||||
def testHandInfo():
|
def testFlopImport():
|
||||||
text = u"""PokerStars Game #20461877044: Hold'em No Limit ($1/$2) - 2008/09/16 18:58:01 ET"""
|
db.recreate_tables()
|
||||||
hhc = PokerStarsToFpdb.PokerStars(autostart=False)
|
importer = fpdb_import.Importer(False, settings, config)
|
||||||
h = HoldemOmahaHand(None, "PokerStars", gametype, text, builtFrom = "Test")
|
importer.setDropIndexes("don't drop")
|
||||||
hhc.readHandInfo(h)
|
importer.setFailOnError(True)
|
||||||
assert h.handid == '20461877044'
|
importer.setThreads(-1)
|
||||||
assert h.sitename == 'PokerStars'
|
importer.addBulkImportImportFileOrDir(
|
||||||
assert h.starttime == (2008, 9, 16, 18, 58, 1, 1, 260, -1)
|
"""regression-test-files/cash/Stars/Flop/NLHE-6max-EUR-0.05-0.10-200911.txt""", site="PokerStars")
|
||||||
|
importer.addBulkImportImportFileOrDir(
|
||||||
text = u"""PokerStars Game #18707234955: Razz Limit ($0.50/$1.00) - 2008/07/09 - 21:41:43 (ET)
|
"""regression-test-files/cash/Stars/Flop/NLHE-6max-USD-0.05-0.10-200911.txt""", site="PokerStars")
|
||||||
Table 'Lepus II' 8-max"""
|
#importer.addBulkImportImportFileOrDir(
|
||||||
hhc = PokerStarsToFpdb.PokerStars(autostart=False)
|
# """regression-test-files/tour/Stars/Flop/NLHE-USD-MTT-5r-200710.txt""", site="PokerStars")
|
||||||
h = HoldemOmahaHand(None, "PokerStars", gametype, text, builtFrom = "Test")
|
importer.addBulkImportImportFileOrDir(
|
||||||
hhc.readHandInfo(h)
|
"""regression-test-files/cash/Stars/Flop/PLO8-6max-USD-0.01-0.02-200911.txt""", site="PokerStars")
|
||||||
assert h.handid == '18707234955'
|
importer.setCallHud(False)
|
||||||
assert h.sitename == 'PokerStars'
|
(stored, dups, partial, errs, ttime) = importer.runImport()
|
||||||
assert h.maxseats == 8
|
importer.clearFileList()
|
||||||
assert h.tablename == 'Lepus II'
|
|
||||||
assert h.starttime == (2008,7 , 9, 21, 41, 43, 2, 191, -1)
|
# Should actually do some testing here
|
||||||
|
assert 1 == 1
|
||||||
|
|
||||||
text = u"""PokerStars Game #22073591924: Hold'em No Limit ($0.50/$1.00) - 2008/11/16 1:22:21 CET [2008/11/15 19:22:21 ET]
|
def testStudImport():
|
||||||
Table 'Caia II' 6-max Seat #2 is the button"""
|
db.recreate_tables()
|
||||||
hhc = PokerStarsToFpdb.PokerStars(autostart=False)
|
importer = fpdb_import.Importer(False, settings, config)
|
||||||
h = HoldemOmahaHand(None, "PokerStars", gametype, text, builtFrom = "Test")
|
importer.setDropIndexes("don't drop")
|
||||||
hhc.readHandInfo(h)
|
importer.setFailOnError(True)
|
||||||
assert h.handid == '22073591924'
|
importer.setThreads(-1)
|
||||||
assert h.sitename == 'PokerStars'
|
importer.addBulkImportImportFileOrDir(
|
||||||
assert h.maxseats == 6
|
"""regression-test-files/cash/Stars/Stud/7-Stud-USD-0.04-0.08-200911.txt""", site="PokerStars")
|
||||||
assert h.tablename == 'Caia II'
|
importer.addBulkImportImportFileOrDir(
|
||||||
assert h.buttonpos == '2' # TODO: should this be an int?
|
"""regression-test-files/cash/Stars/Stud/7-StudHL-USD-0.04-0.08-200911.txt""", site="PokerStars")
|
||||||
assert h.starttime == (2008,11 , 15, 19, 22, 21, 5, 320, -1)
|
importer.addBulkImportImportFileOrDir(
|
||||||
|
"""regression-test-files/cash/Stars/Stud/Razz-USD-0.04-0.08-200911.txt""", site="PokerStars")
|
||||||
|
importer.setCallHud(False)
|
||||||
|
(stored, dups, partial, errs, ttime) = importer.runImport()
|
||||||
|
importer.clearFileList()
|
||||||
|
|
||||||
|
# Should actually do some testing here
|
||||||
|
assert 1 == 1
|
||||||
|
|
||||||
|
def testDrawImport():
|
||||||
|
try:
|
||||||
|
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/Stars/Draw/3-Draw-Limit-USD-0.10-0.20-200911.txt""", site="PokerStars")
|
||||||
|
importer.addBulkImportImportFileOrDir(
|
||||||
|
"""regression-test-files/cash/Stars/Draw/5-Carddraw-USD-0.10-0.20-200911.txt""", site="PokerStars")
|
||||||
|
importer.setCallHud(False)
|
||||||
|
(stored, dups, partial, errs, ttime) = importer.runImport()
|
||||||
|
importer.clearFileList()
|
||||||
|
except FpdbError:
|
||||||
|
if Configuration.NEWIMPORT == False:
|
||||||
|
#Old import code doesn't support draw
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
assert 0 == 1
|
||||||
|
|
||||||
|
# Should actually do some testing here
|
||||||
|
assert 1 == 1
|
||||||
|
|
Loading…
Reference in New Issue
Block a user